Re: [PATCH v2 1/2] fuse: Add support for FUSE_SETXATTR_V2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Vivek Goyal <vgoyal@xxxxxxxxxx> writes:

> On Mon, Mar 29, 2021 at 03:54:03PM +0100, Luis Henriques wrote:
>> On Thu, Mar 25, 2021 at 11:18:22AM -0400, Vivek Goyal wrote:
>> > Fuse client needs to send additional information to file server when
>> > it calls SETXATTR(system.posix_acl_access). Right now there is no extra
>> > space in fuse_setxattr_in. So introduce a v2 of the structure which has
>> > more space in it and can be used to send extra flags.
>> > 
>> > "struct fuse_setxattr_in_v2" is only used if file server opts-in for it using
>> > flag FUSE_SETXATTR_V2 during feature negotiations.
>> > 
>> > Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx>
>> > ---
>> >  fs/fuse/acl.c             |  2 +-
>> >  fs/fuse/fuse_i.h          |  5 ++++-
>> >  fs/fuse/inode.c           |  4 +++-
>> >  fs/fuse/xattr.c           | 21 +++++++++++++++------
>> >  include/uapi/linux/fuse.h | 10 ++++++++++
>> >  5 files changed, 33 insertions(+), 9 deletions(-)
>> > 
>> > diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c
>> > index e9c0f916349d..d31260a139d4 100644
>> > --- a/fs/fuse/acl.c
>> > +++ b/fs/fuse/acl.c
>> > @@ -94,7 +94,7 @@ int fuse_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
>> >  			return ret;
>> >  		}
>> >  
>> > -		ret = fuse_setxattr(inode, name, value, size, 0);
>> > +		ret = fuse_setxattr(inode, name, value, size, 0, 0);
>> >  		kfree(value);
>> >  	} else {
>> >  		ret = fuse_removexattr(inode, name);
>> > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
>> > index 63d97a15ffde..d00bf0b9a38c 100644
>> > --- a/fs/fuse/fuse_i.h
>> > +++ b/fs/fuse/fuse_i.h
>> > @@ -668,6 +668,9 @@ struct fuse_conn {
>> >  	/** Is setxattr not implemented by fs? */
>> >  	unsigned no_setxattr:1;
>> >  
>> > +	/** Does file server support setxattr_v2 */
>> > +	unsigned setxattr_v2:1;
>> > +
>> >  	/** Is getxattr not implemented by fs? */
>> >  	unsigned no_getxattr:1;
>> >  
>> > @@ -1170,7 +1173,7 @@ void fuse_unlock_inode(struct inode *inode, bool locked);
>> >  bool fuse_lock_inode(struct inode *inode);
>> >  
>> >  int fuse_setxattr(struct inode *inode, const char *name, const void *value,
>> > -		  size_t size, int flags);
>> > +		  size_t size, int flags, unsigned extra_flags);
>> >  ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
>> >  		      size_t size);
>> >  ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size);
>> > diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
>> > index b0e18b470e91..1c726df13f80 100644
>> > --- a/fs/fuse/inode.c
>> > +++ b/fs/fuse/inode.c
>> > @@ -1052,6 +1052,8 @@ static void process_init_reply(struct fuse_mount *fm, struct fuse_args *args,
>> >  				fc->handle_killpriv_v2 = 1;
>> >  				fm->sb->s_flags |= SB_NOSEC;
>> >  			}
>> > +			if (arg->flags & FUSE_SETXATTR_V2)
>> > +				fc->setxattr_v2 = 1;
>> >  		} else {
>> >  			ra_pages = fc->max_read / PAGE_SIZE;
>> >  			fc->no_lock = 1;
>> > @@ -1095,7 +1097,7 @@ void fuse_send_init(struct fuse_mount *fm)
>> >  		FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV | FUSE_POSIX_ACL |
>> >  		FUSE_ABORT_ERROR | FUSE_MAX_PAGES | FUSE_CACHE_SYMLINKS |
>> >  		FUSE_NO_OPENDIR_SUPPORT | FUSE_EXPLICIT_INVAL_DATA |
>> > -		FUSE_HANDLE_KILLPRIV_V2;
>> > +		FUSE_HANDLE_KILLPRIV_V2 | FUSE_SETXATTR_V2;
>> >  #ifdef CONFIG_FUSE_DAX
>> >  	if (fm->fc->dax)
>> >  		ia->in.flags |= FUSE_MAP_ALIGNMENT;
>> > diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c
>> > index 1a7d7ace54e1..f2aae72653dc 100644
>> > --- a/fs/fuse/xattr.c
>> > +++ b/fs/fuse/xattr.c
>> > @@ -12,24 +12,33 @@
>> >  #include <linux/posix_acl_xattr.h>
>> >  
>> >  int fuse_setxattr(struct inode *inode, const char *name, const void *value,
>> > -		  size_t size, int flags)
>> > +		  size_t size, int flags, unsigned extra_flags)
>> >  {
>> >  	struct fuse_mount *fm = get_fuse_mount(inode);
>> >  	FUSE_ARGS(args);
>> >  	struct fuse_setxattr_in inarg;
>> > +	struct fuse_setxattr_in_v2 inarg_v2;
>> > +	bool setxattr_v2 = fm->fc->setxattr_v2;
>> >  	int err;
>> >  
>> >  	if (fm->fc->no_setxattr)
>> >  		return -EOPNOTSUPP;
>> >  
>> >  	memset(&inarg, 0, sizeof(inarg));
>> > -	inarg.size = size;
>> > -	inarg.flags = flags;
>> > +	memset(&inarg_v2, 0, sizeof(inarg_v2));
>> > +	if (setxattr_v2) {
>> > +		inarg_v2.size = size;
>> > +		inarg_v2.flags = flags;
>> > +		inarg_v2.setxattr_flags = extra_flags;
>> > +	} else {
>> > +		inarg.size = size;
>> > +		inarg.flags = flags;
>> > +	}
>> >  	args.opcode = FUSE_SETXATTR;
>> >  	args.nodeid = get_node_id(inode);
>> >  	args.in_numargs = 3;
>> > -	args.in_args[0].size = sizeof(inarg);
>> > -	args.in_args[0].value = &inarg;
>> > +	args.in_args[0].size = setxattr_v2 ? sizeof(inarg_v2) : sizeof(inarg);
>> > +	args.in_args[0].value = setxattr_v2 ? &inarg_v2 : (void *)&inarg;
>> 
>> And yet another minor:
>> 
>> It's a bit awkward to have to cast '&inarg' to 'void *' just because
>> you're using the ternary operator.  Why not use an 'if' statement instead
>> for initializing .size and .value?
>
> Yes, I had to use (void *), otherwise compiler was complaining about
> returning different types of pointers. Interesting that compiler
> expects to return same type of pointer.

IIRC, K&R (which I unfortunately don't have at hand right now) says that
the types of both expressions need to match, so probably a different
compiler would show the same warning.

Cheers,
-- 
Luis

> I think I am fine with this as well as adding explicit if statement. I
> guess just a matter of taste. 
>
> Miklos, what do you think? If you also prefer if statement instead,
> I will make changes and post again.
>
> Vivek



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux