There's a patch in fuse.git #for-next doing almost exactly the same thing: https://git.kernel.org/cgit/linux/kernel/git/mszeredi/fuse.git/commit/?h=for-next&id=03955f581b26bdcc0059d900058a352460aa3aaf Would you mind picking that one instead to avoid conflict with the followups in the fuse tree? Thanks, Miklos On Wed, Sep 28, 2016 at 4:57 PM, Andreas Gruenbacher <agruenba@xxxxxxxxxx> wrote: > Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx> > --- > fs/fuse/dir.c | 58 ++++++++++++++++++++++++++++++++++++++++++-------------- > fs/fuse/fuse_i.h | 2 ++ > fs/fuse/inode.c | 1 + > 3 files changed, 47 insertions(+), 14 deletions(-) > > diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c > index c47b778..3408a37 100644 > --- a/fs/fuse/dir.c > +++ b/fs/fuse/dir.c > @@ -13,6 +13,7 @@ > #include <linux/sched.h> > #include <linux/namei.h> > #include <linux/slab.h> > +#include <linux/xattr.h> > > static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx) > { > @@ -1724,9 +1725,8 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, > return fuse_update_attributes(inode, stat, NULL, NULL); > } > > -static int fuse_setxattr(struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > +static int fuse_setxattr(struct inode *inode, const char *name, > + const void *value, size_t size, int flags) > { > struct fuse_conn *fc = get_fuse_conn(inode); > FUSE_ARGS(args); > @@ -1843,9 +1843,8 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) > return ret; > } > > -static int fuse_removexattr(struct dentry *entry, const char *name) > +static int fuse_removexattr(struct inode *inode, const char *name) > { > - struct inode *inode = d_inode(entry); > struct fuse_conn *fc = get_fuse_conn(inode); > FUSE_ARGS(args); > int err; > @@ -1884,10 +1883,10 @@ static const struct inode_operations fuse_dir_inode_operations = { > .mknod = fuse_mknod, > .permission = fuse_permission, > .getattr = fuse_getattr, > - .setxattr = fuse_setxattr, > - .getxattr = fuse_getxattr, > + .setxattr = generic_setxattr, > + .getxattr = generic_getxattr, > .listxattr = fuse_listxattr, > - .removexattr = fuse_removexattr, > + .removexattr = generic_removexattr, > }; > > static const struct file_operations fuse_dir_operations = { > @@ -1905,10 +1904,10 @@ static const struct inode_operations fuse_common_inode_operations = { > .setattr = fuse_setattr, > .permission = fuse_permission, > .getattr = fuse_getattr, > - .setxattr = fuse_setxattr, > - .getxattr = fuse_getxattr, > + .setxattr = generic_setxattr, > + .getxattr = generic_getxattr, > .listxattr = fuse_listxattr, > - .removexattr = fuse_removexattr, > + .removexattr = generic_removexattr, > }; > > static const struct inode_operations fuse_symlink_inode_operations = { > @@ -1916,10 +1915,10 @@ static const struct inode_operations fuse_symlink_inode_operations = { > .get_link = fuse_get_link, > .readlink = generic_readlink, > .getattr = fuse_getattr, > - .setxattr = fuse_setxattr, > - .getxattr = fuse_getxattr, > + .setxattr = generic_setxattr, > + .getxattr = generic_getxattr, > .listxattr = fuse_listxattr, > - .removexattr = fuse_removexattr, > + .removexattr = generic_removexattr, > }; > > void fuse_init_common(struct inode *inode) > @@ -1937,3 +1936,34 @@ void fuse_init_symlink(struct inode *inode) > { > inode->i_op = &fuse_symlink_inode_operations; > } > + > +static int fuse_xattr_get(const struct xattr_handler *handler, > + struct dentry *dentry, struct inode *inode, > + const char *name, void *buffer, size_t size) > +{ > + return fuse_getxattr(dentry, inode, name, buffer, size); > +} > + > +static int fuse_xattr_set(const struct xattr_handler *handler, > + struct dentry *dentry, struct inode *inode, > + const char *name, const void *value, size_t size, > + int flags) > +{ > + if (value) > + return fuse_setxattr(inode, name, value, size, flags); > + else { > + BUG_ON(flags != XATTR_REPLACE); > + return fuse_removexattr(inode, name); > + } > +} > + > +const struct xattr_handler fuse_xattr_handler = { > + .prefix = "", /* match anything */ > + .get = fuse_xattr_get, > + .set = fuse_xattr_set, > +}; > + > +const struct xattr_handler *fuse_xattr_handlers[] = { > + &fuse_xattr_handler, > + NULL > +}; > diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h > index d98d8cc..87938dc 100644 > --- a/fs/fuse/fuse_i.h > +++ b/fs/fuse/fuse_i.h > @@ -966,4 +966,6 @@ void fuse_set_initialized(struct fuse_conn *fc); > void fuse_unlock_inode(struct inode *inode); > void fuse_lock_inode(struct inode *inode); > > +extern const struct xattr_handler *fuse_xattr_handlers[]; > + > #endif /* _FS_FUSE_I_H */ > diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c > index 4e05b51..1e535f3 100644 > --- a/fs/fuse/inode.c > +++ b/fs/fuse/inode.c > @@ -1071,6 +1071,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) > } > sb->s_magic = FUSE_SUPER_MAGIC; > sb->s_op = &fuse_super_operations; > + sb->s_xattr = fuse_xattr_handlers; > sb->s_maxbytes = MAX_LFS_FILESIZE; > sb->s_time_gran = 1; > sb->s_export_op = &fuse_export_operations; > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html