Darrick J. Wong
2019-Aug-27 21:36 UTC
[Ocfs2-devel] [PATCH v8] Add flags option to get xattr method paired to __vfs_getxattr
On Tue, Aug 27, 2019 at 08:05:15AM -0700, Mark Salyzyn wrote:> Replace arguments for get and set xattr methods, and __vfs_getxattr > and __vfs_setaxtr functions with a reference to the following now > common argument structure: > > struct xattr_gs_args { > struct dentry *dentry; > struct inode *inode; > const char *name; > union { > void *buffer; > const void *value; > }; > size_t size; > int flags; > }; > > Which in effect adds a flags option to the get method and > __vfs_getxattr function. > > Add a flag option to get xattr method that has bit flag of > XATTR_NOSECURITY passed to it. XATTR_NOSECURITY is generally then > set in the __vfs_getxattr path when called by security > infrastructure. > > This handles the case of a union filesystem driver that is being > requested by the security layer to report back the xattr data. > > For the use case where access is to be blocked by the security layer. > > The path then could be security(dentry) -> > __vfs_getxattr({dentry...XATTR_NOSECURITY}) -> > handler->get({dentry...XATTR_NOSECURITY}) -> > __vfs_getxattr({lower_dentry...XATTR_NOSECURITY}) -> > lower_handler->get({lower_dentry...XATTR_NOSECURITY}) > which would report back through the chain data and success as > expected, the logging security layer at the top would have the > data to determine the access permissions and report back the target > context that was blocked. > > Without the get handler flag, the path on a union filesystem would be > the errant security(dentry) -> __vfs_getxattr(dentry) -> > handler->get(dentry) -> vfs_getxattr(lower_dentry) -> nested -> > security(lower_dentry, log off) -> lower_handler->get(lower_dentry) > which would report back through the chain no data, and -EACCES. > > For selinux for both cases, this would translate to a correctly > determined blocked access. In the first case with this change a correct avc > log would be reported, in the second legacy case an incorrect avc log > would be reported against an uninitialized u:object_r:unlabeled:s0 > context making the logs cosmetically useless for audit2allow. > > This patch series is inert and is the wide-spread addition of the > flags option for xattr functions, and a replacement of __vfs_getxattr > with __vfs_getxattr({...XATTR_NOSECURITY}). > > Signed-off-by: Mark Salyzyn <salyzyn at android.com> > Reviewed-by: Jan Kara <jack at suse.cz> > Cc: Stephen Smalley <sds at tycho.nsa.gov> > Cc: linux-kernel at vger.kernel.org > Cc: kernel-team at android.com > Cc: linux-security-module at vger.kernel.org > Cc: stable at vger.kernel.org # 4.4, 4.9, 4.14 & 4.19For the XFS part, Acked-by: Darrick J. Wong <darrick.wong at oracle.com>> --- > v8: > - Documentation reported 'struct xattr_gs_flags' rather than > 'struct xattr_gs_flags *args' as argument to get and set methods. > > v7: > - missed spots in fs/9p/acl.c, fs/afs/xattr.c, fs/ecryptfs/crypto.c, > fs/ubifs/xattr.c, fs/xfs/libxfs/xfs_attr.c, > security/integrity/evm/evm_main.c and security/smack/smack_lsm.c. > > v6: > - kernfs missed a spot > > v5: > - introduce struct xattr_gs_args for get and set methods, > __vfs_getxattr and __vfs_setxattr functions. > - cover a missing spot in ext2. > - switch from snprintf to scnprintf for correctness. > > v4: > - ifdef __KERNEL__ around XATTR_NOSECURITY to > keep it colocated in uapi headers. > > v3: > - poor aim on ubifs not ubifs_xattr_get, but static xattr_get > > v2: > - Missed a spot: ubifs, erofs and afs. > > v1: > - Removed from an overlayfs patch set, and made independent. > Expect this to be the basis of some security improvements. > --- > Documentation/filesystems/Locking | 10 ++- > drivers/staging/erofs/xattr.c | 8 +-- > fs/9p/acl.c | 51 +++++++------- > fs/9p/xattr.c | 19 +++-- > fs/afs/xattr.c | 112 +++++++++++++----------------- > fs/btrfs/xattr.c | 36 +++++----- > fs/ceph/xattr.c | 40 +++++------ > fs/cifs/xattr.c | 72 +++++++++---------- > fs/ecryptfs/crypto.c | 20 +++--- > fs/ecryptfs/inode.c | 36 ++++++---- > fs/ecryptfs/mmap.c | 39 ++++++----- > fs/ext2/xattr_security.c | 16 ++--- > fs/ext2/xattr_trusted.c | 15 ++-- > fs/ext2/xattr_user.c | 19 +++-- > fs/ext4/xattr_security.c | 15 ++-- > fs/ext4/xattr_trusted.c | 15 ++-- > fs/ext4/xattr_user.c | 19 +++-- > fs/f2fs/xattr.c | 42 +++++------ > fs/fuse/xattr.c | 23 +++--- > fs/gfs2/xattr.c | 18 ++--- > fs/hfs/attr.c | 15 ++-- > fs/hfsplus/xattr.c | 17 +++-- > fs/hfsplus/xattr_security.c | 13 ++-- > fs/hfsplus/xattr_trusted.c | 13 ++-- > fs/hfsplus/xattr_user.c | 13 ++-- > fs/jffs2/security.c | 16 ++--- > fs/jffs2/xattr_trusted.c | 16 ++--- > fs/jffs2/xattr_user.c | 16 ++--- > fs/jfs/xattr.c | 33 ++++----- > fs/kernfs/inode.c | 23 +++--- > fs/nfs/nfs4proc.c | 28 ++++---- > fs/ocfs2/xattr.c | 52 ++++++-------- > fs/orangefs/xattr.c | 19 ++--- > fs/overlayfs/inode.c | 43 ++++++------ > fs/overlayfs/overlayfs.h | 6 +- > fs/overlayfs/super.c | 53 ++++++-------- > fs/posix_acl.c | 23 +++--- > fs/reiserfs/xattr.c | 2 +- > fs/reiserfs/xattr_security.c | 22 +++--- > fs/reiserfs/xattr_trusted.c | 22 +++--- > fs/reiserfs/xattr_user.c | 22 +++--- > fs/squashfs/xattr.c | 10 +-- > fs/ubifs/xattr.c | 33 +++++---- > fs/xattr.c | 112 ++++++++++++++++++------------ > fs/xfs/libxfs/xfs_attr.c | 4 +- > fs/xfs/libxfs/xfs_attr.h | 2 +- > fs/xfs/xfs_xattr.c | 35 +++++----- > include/linux/xattr.h | 26 ++++--- > include/uapi/linux/xattr.h | 7 +- > mm/shmem.c | 21 +++--- > net/socket.c | 16 ++--- > security/commoncap.c | 29 +++++--- > security/integrity/evm/evm_main.c | 13 +++- > security/selinux/hooks.c | 28 ++++++-- > security/smack/smack_lsm.c | 38 ++++++---- > 55 files changed, 732 insertions(+), 734 deletions(-) > > diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking > index 204dd3ea36bb..c16752a41959 100644 > --- a/Documentation/filesystems/Locking > +++ b/Documentation/filesystems/Locking > @@ -101,12 +101,10 @@ of the locking scheme for directory operations. > ----------------------- xattr_handler operations ----------------------- > prototypes: > bool (*list)(struct dentry *dentry); > - int (*get)(const struct xattr_handler *handler, struct dentry *dentry, > - struct inode *inode, const char *name, void *buffer, > - size_t size); > - int (*set)(const struct xattr_handler *handler, struct dentry *dentry, > - struct inode *inode, const char *name, const void *buffer, > - size_t size, int flags); > + int (*get)(const struct xattr_handler *handler, > + struct xattr_gs_flags *args); > + int (*set)(const struct xattr_handler *handler, > + struct xattr_gs_flags *args); > > locking rules: > all may block > diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c > index df40654b9fbb..41dcfc82f0b2 100644 > --- a/drivers/staging/erofs/xattr.c > +++ b/drivers/staging/erofs/xattr.c > @@ -462,10 +462,9 @@ int erofs_getxattr(struct inode *inode, int index, > } > > static int erofs_xattr_generic_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct erofs_sb_info *const sbi = EROFS_I_SB(inode); > + struct erofs_sb_info *const sbi = EROFS_I_SB(args->inode); > > switch (handler->flags) { > case EROFS_XATTR_INDEX_USER: > @@ -482,7 +481,8 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler, > return -EINVAL; > } > > - return erofs_getxattr(inode, handler->flags, name, buffer, size); > + return erofs_getxattr(args->inode, handler->flags, args->name, > + args->buffer, args->size); > } > > const struct xattr_handler erofs_xattr_user_handler = { > diff --git a/fs/9p/acl.c b/fs/9p/acl.c > index 6261719f6f2a..2f5184de75c4 100644 > --- a/fs/9p/acl.c > +++ b/fs/9p/acl.c > @@ -213,60 +213,61 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep, > } > > static int v9fs_xattr_get_acl(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > struct v9fs_session_info *v9ses; > struct posix_acl *acl; > int error; > > - v9ses = v9fs_dentry2v9ses(dentry); > + v9ses = v9fs_dentry2v9ses(args->dentry); > /* > * We allow set/get/list of acl when access=client is not specified > */ > if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) > - return v9fs_xattr_get(dentry, handler->name, buffer, size); > + return v9fs_xattr_get(args->dentry, handler->name, > + args->buffer, args->size); > > - acl = v9fs_get_cached_acl(inode, handler->flags); > + acl = v9fs_get_cached_acl(args->inode, handler->flags); > if (IS_ERR(acl)) > return PTR_ERR(acl); > if (acl == NULL) > return -ENODATA; > - error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); > + error = posix_acl_to_xattr(&init_user_ns, acl, > + args->buffer, args->size); > posix_acl_release(acl); > > return error; > } > > static int v9fs_xattr_set_acl(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > int retval; > struct posix_acl *acl; > struct v9fs_session_info *v9ses; > > - v9ses = v9fs_dentry2v9ses(dentry); > + v9ses = v9fs_dentry2v9ses(args->dentry); > /* > * set the attribute on the remote. Without even looking at the > * xattr value. We leave it to the server to validate > */ > if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) > - return v9fs_xattr_set(dentry, handler->name, value, size, > - flags); > + return v9fs_xattr_set(args->dentry, handler->name, > + args->value, args->size, args->flags); > > - if (S_ISLNK(inode->i_mode)) > + if (S_ISLNK(args->inode->i_mode)) > return -EOPNOTSUPP; > - if (!inode_owner_or_capable(inode)) > + if (!inode_owner_or_capable(args->inode)) > return -EPERM; > - if (value) { > + if (args->value) { > /* update the cached acl value */ > - acl = posix_acl_from_xattr(&init_user_ns, value, size); > + acl = posix_acl_from_xattr(&init_user_ns, > + args->value, args->size); > if (IS_ERR(acl)) > return PTR_ERR(acl); > else if (acl) { > - retval = posix_acl_valid(inode->i_sb->s_user_ns, acl); > + retval = posix_acl_valid(args->inode->i_sb->s_user_ns, > + acl); > if (retval) > goto err_out; > } > @@ -279,7 +280,8 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, > struct iattr iattr = { 0 }; > struct posix_acl *old_acl = acl; > > - retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl); > + retval = posix_acl_update_mode(args->inode, > + &iattr.ia_mode, &acl); > if (retval) > goto err_out; > if (!acl) { > @@ -289,19 +291,19 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, > * update ACL. > */ > posix_acl_release(old_acl); > - value = NULL; > - size = 0; > + args->value = NULL; > + args->size = 0; > } > iattr.ia_valid = ATTR_MODE; > /* FIXME should we update ctime ? > * What is the following setxattr update the > * mode ? > */ > - v9fs_vfs_setattr_dotl(dentry, &iattr); > + v9fs_vfs_setattr_dotl(args->dentry, &iattr); > } > break; > case ACL_TYPE_DEFAULT: > - if (!S_ISDIR(inode->i_mode)) { > + if (!S_ISDIR(args->inode->i_mode)) { > retval = acl ? -EINVAL : 0; > goto err_out; > } > @@ -309,9 +311,10 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler, > default: > BUG(); > } > - retval = v9fs_xattr_set(dentry, handler->name, value, size, flags); > + retval = v9fs_xattr_set(args->dentry, handler->name, > + args->value, args->size, args->flags); > if (!retval) > - set_cached_acl(inode, handler->flags, acl); > + set_cached_acl(args->inode, handler->flags, acl); > err_out: > posix_acl_release(acl); > return retval; > diff --git a/fs/9p/xattr.c b/fs/9p/xattr.c > index ac8ff8ca4c11..36d4c309be08 100644 > --- a/fs/9p/xattr.c > +++ b/fs/9p/xattr.c > @@ -138,22 +138,19 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) > } > > static int v9fs_xattr_handler_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - const char *full_name = xattr_full_name(handler, name); > - > - return v9fs_xattr_get(dentry, full_name, buffer, size); > + return v9fs_xattr_get(args->dentry, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int v9fs_xattr_handler_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - const char *full_name = xattr_full_name(handler, name); > - > - return v9fs_xattr_set(dentry, full_name, value, size, flags); > + return v9fs_xattr_set(args->dentry, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static struct xattr_handler v9fs_xattr_user_handler = { > diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c > index 5552d034090a..787ae107642d 100644 > --- a/fs/afs/xattr.c > +++ b/fs/afs/xattr.c > @@ -38,13 +38,11 @@ ssize_t afs_listxattr(struct dentry *dentry, char *buffer, size_t size) > * Get a file's ACL. > */ > static int afs_xattr_get_acl(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - void *buffer, size_t size) > + struct xattr_gs_args *args) > { > struct afs_fs_cursor fc; > struct afs_status_cb *scb; > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > struct afs_acl *acl = NULL; > struct key *key; > int ret = -ENOMEM; > @@ -76,9 +74,9 @@ static int afs_xattr_get_acl(const struct xattr_handler *handler, > > if (ret == 0) { > ret = acl->size; > - if (size > 0) { > - if (acl->size <= size) > - memcpy(buffer, acl->data, acl->size); > + if (args->size > 0) { > + if (acl->size <= args->size) > + memcpy(args->buffer, acl->data, acl->size); > else > ret = -ERANGE; > } > @@ -96,25 +94,23 @@ static int afs_xattr_get_acl(const struct xattr_handler *handler, > * Set a file's AFS3 ACL. > */ > static int afs_xattr_set_acl(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - const void *buffer, size_t size, int flags) > + struct xattr_gs_args *args) > { > struct afs_fs_cursor fc; > struct afs_status_cb *scb; > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > struct afs_acl *acl = NULL; > struct key *key; > int ret = -ENOMEM; > > - if (flags == XATTR_CREATE) > + if (args->flags == XATTR_CREATE) > return -EINVAL; > > scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); > if (!scb) > goto error; > > - acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); > + acl = kmalloc(sizeof(*acl) + args->size, GFP_KERNEL); > if (!acl) > goto error_scb; > > @@ -124,8 +120,8 @@ static int afs_xattr_set_acl(const struct xattr_handler *handler, > goto error_acl; > } > > - acl->size = size; > - memcpy(acl->data, buffer, size); > + acl->size = args->size; > + memcpy(acl->data, args->value, args->size); > > ret = -ERESTARTSYS; > if (afs_begin_vnode_operation(&fc, vnode, key, true)) { > @@ -161,25 +157,23 @@ static const struct xattr_handler afs_xattr_afs_acl_handler = { > * Get a file's YFS ACL. > */ > static int afs_xattr_get_yfs(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - void *buffer, size_t size) > + struct xattr_gs_args *args) > { > struct afs_fs_cursor fc; > struct afs_status_cb *scb; > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > struct yfs_acl *yacl = NULL; > struct key *key; > char buf[16], *data; > int which = 0, dsize, ret = -ENOMEM; > > - if (strcmp(name, "acl") == 0) > + if (strcmp(args->name, "acl") == 0) > which = 0; > - else if (strcmp(name, "acl_inherited") == 0) > + else if (strcmp(args->name, "acl_inherited") == 0) > which = 1; > - else if (strcmp(name, "acl_num_cleaned") == 0) > + else if (strcmp(args->name, "acl_num_cleaned") == 0) > which = 2; > - else if (strcmp(name, "vol_acl") == 0) > + else if (strcmp(args->name, "vol_acl") == 0) > which = 3; > else > return -EOPNOTSUPP; > @@ -228,11 +222,11 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, > break; > case 1: > data = buf; > - dsize = snprintf(buf, sizeof(buf), "%u", yacl->inherit_flag); > + dsize = scnprintf(buf, sizeof(buf), "%u", yacl->inherit_flag); > break; > case 2: > data = buf; > - dsize = snprintf(buf, sizeof(buf), "%u", yacl->num_cleaned); > + dsize = scnprintf(buf, sizeof(buf), "%u", yacl->num_cleaned); > break; > case 3: > data = yacl->vol_acl->data; > @@ -244,12 +238,12 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, > } > > ret = dsize; > - if (size > 0) { > - if (dsize > size) { > + if (args->size > 0) { > + if (dsize > args->size) { > ret = -ERANGE; > goto error_key; > } > - memcpy(buffer, data, dsize); > + memcpy(args->buffer, data, dsize); > } > > error_key: > @@ -266,31 +260,29 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, > * Set a file's YFS ACL. > */ > static int afs_xattr_set_yfs(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - const void *buffer, size_t size, int flags) > + struct xattr_gs_args *args) > { > struct afs_fs_cursor fc; > struct afs_status_cb *scb; > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > struct afs_acl *acl = NULL; > struct key *key; > int ret = -ENOMEM; > > - if (flags == XATTR_CREATE || > - strcmp(name, "acl") != 0) > + if (args->flags == XATTR_CREATE || > + strcmp(args->name, "acl") != 0) > return -EINVAL; > > scb = kzalloc(sizeof(struct afs_status_cb), GFP_NOFS); > if (!scb) > goto error; > > - acl = kmalloc(sizeof(*acl) + size, GFP_KERNEL); > + acl = kmalloc(sizeof(*acl) + args->size, GFP_KERNEL); > if (!acl) > goto error_scb; > > - acl->size = size; > - memcpy(acl->data, buffer, size); > + acl->size = args->size; > + memcpy(acl->data, args->value, args->size); > > key = afs_request_key(vnode->volume->cell); > if (IS_ERR(key)) { > @@ -332,20 +324,18 @@ static const struct xattr_handler afs_xattr_yfs_handler = { > * Get the name of the cell on which a file resides. > */ > static int afs_xattr_get_cell(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > struct afs_cell *cell = vnode->volume->cell; > size_t namelen; > > namelen = cell->name_len; > - if (size == 0) > + if (args->size == 0) > return namelen; > - if (namelen > size) > + if (namelen > args->size) > return -ERANGE; > - memcpy(buffer, cell->name, namelen); > + memcpy(args->buffer, cell->name, namelen); > return namelen; > } > > @@ -359,30 +349,30 @@ static const struct xattr_handler afs_xattr_afs_cell_handler = { > * hex numbers separated by colons. > */ > static int afs_xattr_get_fid(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > char text[16 + 1 + 24 + 1 + 8 + 1]; > size_t len; > > /* The volume ID is 64-bit, the vnode ID is 96-bit and the > * uniquifier is 32-bit. > */ > - len = sprintf(text, "%llx:", vnode->fid.vid); > + len = scnprintf(text, sizeof(text), "%llx:", vnode->fid.vid); > if (vnode->fid.vnode_hi) > - len += sprintf(text + len, "%x%016llx", > + len += scnprintf(text + len, sizeof(text) - len, "%x%016llx", > vnode->fid.vnode_hi, vnode->fid.vnode); > else > - len += sprintf(text + len, "%llx", vnode->fid.vnode); > - len += sprintf(text + len, ":%x", vnode->fid.unique); > + len += scnprintf(text + len, sizeof(text) - len, "%llx", > + vnode->fid.vnode); > + len += scnprintf(text + len, sizeof(text) - len, ":%x", > + vnode->fid.unique); > > - if (size == 0) > + if (args->size == 0) > return len; > - if (len > size) > + if (len > args->size) > return -ERANGE; > - memcpy(buffer, text, len); > + memcpy(args->buffer, text, len); > return len; > } > > @@ -395,20 +385,18 @@ static const struct xattr_handler afs_xattr_afs_fid_handler = { > * Get the name of the volume on which a file resides. > */ > static int afs_xattr_get_volume(const struct xattr_handler *handler, > - struct dentry *dentry, > - struct inode *inode, const char *name, > - void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct afs_vnode *vnode = AFS_FS_I(inode); > + struct afs_vnode *vnode = AFS_FS_I(args->inode); > const char *volname = vnode->volume->name; > size_t namelen; > > namelen = strlen(volname); > - if (size == 0) > + if (args->size == 0) > return namelen; > - if (namelen > size) > + if (namelen > args->size) > return -ERANGE; > - memcpy(buffer, volname, namelen); > + memcpy(args->buffer, volname, namelen); > return namelen; > } > > diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c > index 95d9aebff2c4..e47a0e461bd2 100644 > --- a/fs/btrfs/xattr.c > +++ b/fs/btrfs/xattr.c > @@ -352,33 +352,30 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) > } > > static int btrfs_xattr_handler_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - name = xattr_full_name(handler, name); > - return btrfs_getxattr(inode, name, buffer, size); > + return btrfs_getxattr(args->inode, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int btrfs_xattr_handler_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - name = xattr_full_name(handler, name); > - return btrfs_setxattr_trans(inode, name, buffer, size, flags); > + return btrfs_setxattr_trans(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > int ret; > struct btrfs_trans_handle *trans; > - struct btrfs_root *root = BTRFS_I(inode)->root; > + struct btrfs_root *root = BTRFS_I(args->inode)->root; > > - name = xattr_full_name(handler, name); > - ret = btrfs_validate_prop(name, value, size); > + ret = btrfs_validate_prop(xattr_full_name(handler, args->name), > + args->value, args->size); > if (ret) > return ret; > > @@ -386,11 +383,12 @@ static int btrfs_xattr_handler_set_prop(const struct xattr_handler *handler, > if (IS_ERR(trans)) > return PTR_ERR(trans); > > - ret = btrfs_set_prop(trans, inode, name, value, size, flags); > + ret = btrfs_set_prop(trans, args->inode, args->name, > + args->value, args->size, args->flags); > if (!ret) { > - inode_inc_iversion(inode); > - inode->i_ctime = current_time(inode); > - ret = btrfs_update_inode(trans, root, inode); > + inode_inc_iversion(args->inode); > + args->inode->i_ctime = current_time(args->inode); > + ret = btrfs_update_inode(trans, root, args->inode); > BUG_ON(ret); > } > > diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c > index 939eab7aa219..c4fee624291b 100644 > --- a/fs/ceph/xattr.c > +++ b/fs/ceph/xattr.c > @@ -1179,22 +1179,21 @@ int __ceph_setxattr(struct inode *inode, const char *name, > } > > static int ceph_get_xattr_handler(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > - if (!ceph_is_valid_xattr(name)) > + if (!ceph_is_valid_xattr(args->name)) > return -EOPNOTSUPP; > - return __ceph_getxattr(inode, name, value, size); > + return __ceph_getxattr(args->inode, args->name, > + args->buffer, args->size); > } > > static int ceph_set_xattr_handler(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - if (!ceph_is_valid_xattr(name)) > + if (!ceph_is_valid_xattr(args->name)) > return -EOPNOTSUPP; > - return __ceph_setxattr(inode, name, value, size, flags); > + return __ceph_setxattr(args->inode, args->name, > + args->value, args->size, args->flags); > } > > static const struct xattr_handler ceph_other_xattr_handler = { > @@ -1300,25 +1299,22 @@ void ceph_security_invalidate_secctx(struct inode *inode) > } > > static int ceph_xattr_set_security_label(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *key, const void *buf, > - size_t buflen, int flags) > + struct xattr_gs_args *args) > { > - if (security_ismaclabel(key)) { > - const char *name = xattr_full_name(handler, key); > - return __ceph_setxattr(inode, name, buf, buflen, flags); > - } > + if (security_ismaclabel(args->name)) > + return __ceph_setxattr(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > return -EOPNOTSUPP; > } > > static int ceph_xattr_get_security_label(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *key, void *buf, size_t buflen) > + struct xattr_gs_args *args) > { > - if (security_ismaclabel(key)) { > - const char *name = xattr_full_name(handler, key); > - return __ceph_getxattr(inode, name, buf, buflen); > - } > + if (security_ismaclabel(args->name)) > + return __ceph_getxattr(args->inode, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > return -EOPNOTSUPP; > } > > diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c > index 9076150758d8..2506d12c7e5d 100644 > --- a/fs/cifs/xattr.c > +++ b/fs/cifs/xattr.c > @@ -48,13 +48,11 @@ > enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT }; > > static int cifs_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > int rc = -EOPNOTSUPP; > unsigned int xid; > - struct super_block *sb = dentry->d_sb; > + struct super_block *sb = args->dentry->d_sb; > struct cifs_sb_info *cifs_sb = CIFS_SB(sb); > struct tcon_link *tlink; > struct cifs_tcon *pTcon; > @@ -67,7 +65,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, > > xid = get_xid(); > > - full_path = build_path_from_dentry(dentry); > + full_path = build_path_from_dentry(args->dentry); > if (full_path == NULL) { > rc = -ENOMEM; > goto out; > @@ -78,7 +76,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, > /* if proc/fs/cifs/streamstoxattr is set then > search server for EAs or streams to > returns as xattrs */ > - if (size > MAX_EA_VALUE_SIZE) { > + if (args->size > MAX_EA_VALUE_SIZE) { > cifs_dbg(FYI, "size of EA value too large\n"); > rc = -EOPNOTSUPP; > goto out; > @@ -91,29 +89,30 @@ static int cifs_xattr_set(const struct xattr_handler *handler, > > if (pTcon->ses->server->ops->set_EA) > rc = pTcon->ses->server->ops->set_EA(xid, pTcon, > - full_path, name, value, (__u16)size, > + full_path, args->name, > + args->value, (__u16)args->size, > cifs_sb->local_nls, cifs_sb); > break; > > case XATTR_CIFS_ACL: { > struct cifs_ntsd *pacl; > > - if (!value) > + if (!args->value) > goto out; > - pacl = kmalloc(size, GFP_KERNEL); > + pacl = kmalloc(args->size, GFP_KERNEL); > if (!pacl) { > rc = -ENOMEM; > } else { > - memcpy(pacl, value, size); > - if (value && > + memcpy(pacl, args->value, args->size); > + if (args->value && > pTcon->ses->server->ops->set_acl) > rc = pTcon->ses->server->ops->set_acl(pacl, > - size, inode, > + args->size, args->inode, > full_path, CIFS_ACL_DACL); > else > rc = -EOPNOTSUPP; > if (rc == 0) /* force revalidate of the inode */ > - CIFS_I(inode)->time = 0; > + CIFS_I(args->inode)->time = 0; > kfree(pacl); > } > break; > @@ -121,11 +120,11 @@ static int cifs_xattr_set(const struct xattr_handler *handler, > > case XATTR_ACL_ACCESS: > #ifdef CONFIG_CIFS_POSIX > - if (!value) > + if (!args->value) > goto out; > if (sb->s_flags & SB_POSIXACL) > rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, > - value, (const int)size, > + args->value, (const int)args->size, > ACL_TYPE_ACCESS, cifs_sb->local_nls, > cifs_remap(cifs_sb)); > #endif /* CONFIG_CIFS_POSIX */ > @@ -133,11 +132,11 @@ static int cifs_xattr_set(const struct xattr_handler *handler, > > case XATTR_ACL_DEFAULT: > #ifdef CONFIG_CIFS_POSIX > - if (!value) > + if (!args->value) > goto out; > if (sb->s_flags & SB_POSIXACL) > rc = CIFSSMBSetPosixACL(xid, pTcon, full_path, > - value, (const int)size, > + args->value, (const int)args->size, > ACL_TYPE_DEFAULT, cifs_sb->local_nls, > cifs_remap(cifs_sb)); > #endif /* CONFIG_CIFS_POSIX */ > @@ -198,12 +197,11 @@ static int cifs_creation_time_get(struct dentry *dentry, struct inode *inode, > > > static int cifs_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > ssize_t rc = -EOPNOTSUPP; > unsigned int xid; > - struct super_block *sb = dentry->d_sb; > + struct super_block *sb = args->dentry->d_sb; > struct cifs_sb_info *cifs_sb = CIFS_SB(sb); > struct tcon_link *tlink; > struct cifs_tcon *pTcon; > @@ -216,7 +214,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, > > xid = get_xid(); > > - full_path = build_path_from_dentry(dentry); > + full_path = build_path_from_dentry(args->dentry); > if (full_path == NULL) { > rc = -ENOMEM; > goto out; > @@ -225,14 +223,17 @@ static int cifs_xattr_get(const struct xattr_handler *handler, > /* return alt name if available as pseudo attr */ > switch (handler->flags) { > case XATTR_USER: > - cifs_dbg(FYI, "%s:querying user xattr %s\n", __func__, name); > - if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) || > - (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) { > - rc = cifs_attrib_get(dentry, inode, value, size); > + cifs_dbg(FYI, "%s:querying user xattr %s\n", __func__, > + args->name); > + if ((strcmp(args->name, CIFS_XATTR_ATTRIB) == 0) || > + (strcmp(args->name, SMB3_XATTR_ATTRIB) == 0)) { > + rc = cifs_attrib_get(args->dentry, args->inode, > + args->buffer, args->size); > break; > - } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) || > - (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) { > - rc = cifs_creation_time_get(dentry, inode, value, size); > + } else if ((strcmp(args->name, CIFS_XATTR_CREATETIME) == 0) || > + (strcmp(args->name, SMB3_XATTR_CREATETIME) == 0)) { > + rc = cifs_creation_time_get(args->dentry, args->inode, > + args->buffer, args->size); > break; > } > > @@ -241,7 +242,8 @@ static int cifs_xattr_get(const struct xattr_handler *handler, > > if (pTcon->ses->server->ops->query_all_EAs) > rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon, > - full_path, name, value, size, cifs_sb); > + full_path, args->name, > + args->buffer, args->size, cifs_sb); > break; > > case XATTR_CIFS_ACL: { > @@ -252,17 +254,17 @@ static int cifs_xattr_get(const struct xattr_handler *handler, > goto out; /* rc already EOPNOTSUPP */ > > pacl = pTcon->ses->server->ops->get_acl(cifs_sb, > - inode, full_path, &acllen); > + args->inode, full_path, &acllen); > if (IS_ERR(pacl)) { > rc = PTR_ERR(pacl); > cifs_dbg(VFS, "%s: error %zd getting sec desc\n", > __func__, rc); > } else { > - if (value) { > - if (acllen > size) > + if (args->buffer) { > + if (acllen > args->size) > acllen = -ERANGE; > else > - memcpy(value, pacl, acllen); > + memcpy(args->buffer, pacl, acllen); > } > rc = acllen; > kfree(pacl); > @@ -274,7 +276,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, > #ifdef CONFIG_CIFS_POSIX > if (sb->s_flags & SB_POSIXACL) > rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, > - value, size, ACL_TYPE_ACCESS, > + args->buffer, args->size, ACL_TYPE_ACCESS, > cifs_sb->local_nls, > cifs_remap(cifs_sb)); > #endif /* CONFIG_CIFS_POSIX */ > @@ -284,7 +286,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, > #ifdef CONFIG_CIFS_POSIX > if (sb->s_flags & SB_POSIXACL) > rc = CIFSSMBGetPosixACL(xid, pTcon, full_path, > - value, size, ACL_TYPE_DEFAULT, > + args->buffer, args->size, ACL_TYPE_DEFAULT, > cifs_sb->local_nls, > cifs_remap(cifs_sb)); > #endif /* CONFIG_CIFS_POSIX */ > diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c > index f91db24bbf3b..5fbda6491920 100644 > --- a/fs/ecryptfs/crypto.c > +++ b/fs/ecryptfs/crypto.c > @@ -1114,20 +1114,24 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, > char *page_virt, size_t size) > { > int rc; > - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); > - struct inode *lower_inode = d_inode(lower_dentry); > + struct xattr_gs_args lower = {}; > > - if (!(lower_inode->i_opflags & IOP_XATTR)) { > + lower.dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); > + lower.inode = d_inode(lower.dentry); > + > + if (!(lower.inode->i_opflags & IOP_XATTR)) { > rc = -EOPNOTSUPP; > goto out; > } > > - inode_lock(lower_inode); > - rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, > - page_virt, size, 0); > + lower.name = ECRYPTFS_XATTR_NAME; > + lower.value = page_virt; > + lower.size = size; > + inode_lock(lower.inode); > + rc = __vfs_setxattr(&lower); > if (!rc && ecryptfs_inode) > - fsstack_copy_attr_all(ecryptfs_inode, lower_inode); > - inode_unlock(lower_inode); > + fsstack_copy_attr_all(ecryptfs_inode, lower.inode); > + inode_unlock(lower.inode); > out: > return rc; > } > diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c > index 18426f4855f1..fc4435847a45 100644 > --- a/fs/ecryptfs/inode.c > +++ b/fs/ecryptfs/inode.c > @@ -1009,16 +1009,24 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode, > > ssize_t > ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode, > - const char *name, void *value, size_t size) > + const char *name, void *buffer, size_t size) > { > int rc; > + struct xattr_gs_args args; > > if (!(lower_inode->i_opflags & IOP_XATTR)) { > rc = -EOPNOTSUPP; > goto out; > } > + memset(&args, 0, sizeof(args)); > + args.dentry = lower_dentry; > + args.inode = lower_inode; > + args.name = name; > + args.buffer = buffer; > + args.size = size; > + args.flags = XATTR_NOSECURITY; > inode_lock(lower_inode); > - rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size); > + rc = __vfs_getxattr(&args); > inode_unlock(lower_inode); > out: > return rc; > @@ -1102,23 +1110,23 @@ const struct inode_operations ecryptfs_main_iops = { > }; > > static int ecryptfs_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ecryptfs_getxattr(dentry, inode, name, buffer, size); > + return ecryptfs_getxattr(args->dentry, args->inode, args->name, > + args->buffer, args->size); > } > > static int ecryptfs_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, size_t size, > - int flags) > + struct xattr_gs_args *args) > { > - if (value) > - return ecryptfs_setxattr(dentry, inode, name, value, size, flags); > - else { > - BUG_ON(flags != XATTR_REPLACE); > - return ecryptfs_removexattr(dentry, inode, name); > - } > + if (args->value) > + return ecryptfs_setxattr(args->dentry, args->inode, args->name, > + args->value, args->size, args->flags); > + else if (args->flags != XATTR_REPLACE) > + return -EINVAL; > + else > + return ecryptfs_removexattr(args->dentry, args->inode, > + args->name); > } > > static const struct xattr_handler ecryptfs_xattr_handler = { > diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c > index cffa0c1ec829..90dc0354ec5e 100644 > --- a/fs/ecryptfs/mmap.c > +++ b/fs/ecryptfs/mmap.c > @@ -402,37 +402,40 @@ struct kmem_cache *ecryptfs_xattr_cache; > > static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) > { > - ssize_t size; > - void *xattr_virt; > - struct dentry *lower_dentry > - ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_path.dentry; > - struct inode *lower_inode = d_inode(lower_dentry); > + struct xattr_gs_args args; > int rc; > > - if (!(lower_inode->i_opflags & IOP_XATTR)) { > + memset(&args, 0, sizeof(args)); > + args.dentry = ecryptfs_inode_to_private(ecryptfs_inode)-> > + lower_file->f_path.dentry; > + args.inode = d_inode(args.dentry); > + if (!(args.inode->i_opflags & IOP_XATTR)) { > printk(KERN_WARNING > "No support for setting xattr in lower filesystem\n"); > rc = -ENOSYS; > goto out; > } > - xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); > - if (!xattr_virt) { > + args.buffer = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); > + if (!args.buffer) { > rc = -ENOMEM; > goto out; > } > - inode_lock(lower_inode); > - size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, > - xattr_virt, PAGE_SIZE); > - if (size < 0) > - size = 8; > - put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt); > - rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, > - xattr_virt, size, 0); > - inode_unlock(lower_inode); > + args.name = ECRYPTFS_XATTR_NAME; > + args.size = PAGE_SIZE; > + args.flags = XATTR_NOSECURITY; > + inode_lock(args.inode); > + args.size = __vfs_getxattr(&args); > + if (args.size < 0) > + args.size = 8; > + put_unaligned_be64(i_size_read(ecryptfs_inode), args.buffer); > + args.flags = 0; > + args.value = args.buffer; > + rc = __vfs_setxattr(&args); > + inode_unlock(args.inode); > if (rc) > printk(KERN_ERR "Error whilst attempting to write inode size " > "to lower file xattr; rc = [%d]\n", rc); > - kmem_cache_free(ecryptfs_xattr_cache, xattr_virt); > + kmem_cache_free(ecryptfs_xattr_cache, args.buffer); > out: > return rc; > } > diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c > index 9a682e440acb..d651d4a7c9ca 100644 > --- a/fs/ext2/xattr_security.c > +++ b/fs/ext2/xattr_security.c > @@ -10,21 +10,19 @@ > > static int > ext2_xattr_security_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name, > - buffer, size); > + return ext2_xattr_get(args->inode, EXT2_XATTR_INDEX_SECURITY, > + args->name, args->buffer, args->size); > } > > static int > ext2_xattr_security_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, name, > - value, size, flags); > + return ext2_xattr_set(args->inode, EXT2_XATTR_INDEX_SECURITY, > + args->name, args->value, args->size, > + args->flags); > } > > static int ext2_initxattrs(struct inode *inode, const struct xattr *xattr_array, > diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c > index 49add1107850..41390dd0386a 100644 > --- a/fs/ext2/xattr_trusted.c > +++ b/fs/ext2/xattr_trusted.c > @@ -17,21 +17,18 @@ ext2_xattr_trusted_list(struct dentry *dentry) > > static int > ext2_xattr_trusted_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name, > - buffer, size); > + return ext2_xattr_get(args->inode, EXT2_XATTR_INDEX_TRUSTED, args->name, > + args->buffer, args->size); > } > > static int > ext2_xattr_trusted_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name, > - value, size, flags); > + return ext2_xattr_set(args->inode, EXT2_XATTR_INDEX_TRUSTED, args->name, > + args->value, args->size, args->flags); > } > > const struct xattr_handler ext2_xattr_trusted_handler = { > diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c > index c243a3b4d69d..1ef881890dde 100644 > --- a/fs/ext2/xattr_user.c > +++ b/fs/ext2/xattr_user.c > @@ -19,26 +19,23 @@ ext2_xattr_user_list(struct dentry *dentry) > > static int > ext2_xattr_user_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - if (!test_opt(inode->i_sb, XATTR_USER)) > + if (!test_opt(args->inode->i_sb, XATTR_USER)) > return -EOPNOTSUPP; > - return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, > - name, buffer, size); > + return ext2_xattr_get(args->inode, EXT2_XATTR_INDEX_USER, args->name, > + args->buffer, args->size); > } > > static int > ext2_xattr_user_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - if (!test_opt(inode->i_sb, XATTR_USER)) > + if (!test_opt(args->inode->i_sb, XATTR_USER)) > return -EOPNOTSUPP; > > - return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, > - name, value, size, flags); > + return ext2_xattr_set(args->inode, EXT2_XATTR_INDEX_USER, args->name, > + args->value, args->size, args->flags); > } > > const struct xattr_handler ext2_xattr_user_handler = { > diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c > index 197a9d8a15ef..71ed703e01fe 100644 > --- a/fs/ext4/xattr_security.c > +++ b/fs/ext4/xattr_security.c > @@ -14,21 +14,18 @@ > > static int > ext4_xattr_security_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY, > - name, buffer, size); > + return ext4_xattr_get(args->inode, EXT4_XATTR_INDEX_SECURITY, > + args->name, args->buffer, args->size); > } > > static int > ext4_xattr_security_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ext4_xattr_set(inode, EXT4_XATTR_INDEX_SECURITY, > - name, value, size, flags); > + return ext4_xattr_set(args->inode, EXT4_XATTR_INDEX_SECURITY, > + args->name, args->value, args->size, args->flags); > } > > static int > diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c > index e9389e5d75c3..ed347a978102 100644 > --- a/fs/ext4/xattr_trusted.c > +++ b/fs/ext4/xattr_trusted.c > @@ -21,21 +21,18 @@ ext4_xattr_trusted_list(struct dentry *dentry) > > static int > ext4_xattr_trusted_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED, > - name, buffer, size); > + return ext4_xattr_get(args->inode, EXT4_XATTR_INDEX_TRUSTED, > + args->name, args->buffer, args->size); > } > > static int > ext4_xattr_trusted_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED, > - name, value, size, flags); > + return ext4_xattr_set(args->inode, EXT4_XATTR_INDEX_TRUSTED, > + args->name, args->value, args->size, args->flags); > } > > const struct xattr_handler ext4_xattr_trusted_handler = { > diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c > index d4546184b34b..86e9f5a9284d 100644 > --- a/fs/ext4/xattr_user.c > +++ b/fs/ext4/xattr_user.c > @@ -20,25 +20,22 @@ ext4_xattr_user_list(struct dentry *dentry) > > static int > ext4_xattr_user_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - if (!test_opt(inode->i_sb, XATTR_USER)) > + if (!test_opt(args->inode->i_sb, XATTR_USER)) > return -EOPNOTSUPP; > - return ext4_xattr_get(inode, EXT4_XATTR_INDEX_USER, > - name, buffer, size); > + return ext4_xattr_get(args->inode, EXT4_XATTR_INDEX_USER, > + args->name, args->buffer, args->size); > } > > static int > ext4_xattr_user_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - if (!test_opt(inode->i_sb, XATTR_USER)) > + if (!test_opt(args->inode->i_sb, XATTR_USER)) > return -EOPNOTSUPP; > - return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER, > - name, value, size, flags); > + return ext4_xattr_set(args->inode, EXT4_XATTR_INDEX_USER, > + args->name, args->value, args->size, args->flags); > } > > const struct xattr_handler ext4_xattr_user_handler = { > diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c > index b32c45621679..4fd47b84616f 100644 > --- a/fs/f2fs/xattr.c > +++ b/fs/f2fs/xattr.c > @@ -23,10 +23,9 @@ > #include "xattr.h" > > static int f2fs_xattr_generic_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); > + struct f2fs_sb_info *sbi = F2FS_SB(args->inode->i_sb); > > switch (handler->flags) { > case F2FS_XATTR_INDEX_USER: > @@ -39,16 +38,14 @@ static int f2fs_xattr_generic_get(const struct xattr_handler *handler, > default: > return -EINVAL; > } > - return f2fs_getxattr(inode, handler->flags, name, > - buffer, size, NULL); > + return f2fs_getxattr(args->inode, handler->flags, args->name, > + args->buffer, args->size, NULL); > } > > static int f2fs_xattr_generic_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); > + struct f2fs_sb_info *sbi = F2FS_SB(args->inode->i_sb); > > switch (handler->flags) { > case F2FS_XATTR_INDEX_USER: > @@ -61,8 +58,8 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler, > default: > return -EINVAL; > } > - return f2fs_setxattr(inode, handler->flags, name, > - value, size, NULL, flags); > + return f2fs_setxattr(args->inode, handler->flags, args->name, > + args->value, args->size, NULL, args->flags); > } > > static bool f2fs_xattr_user_list(struct dentry *dentry) > @@ -78,36 +75,33 @@ static bool f2fs_xattr_trusted_list(struct dentry *dentry) > } > > static int f2fs_xattr_advise_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - if (buffer) > - *((char *)buffer) = F2FS_I(inode)->i_advise; > + if (args->buffer) > + *((char *)args->buffer) = F2FS_I(args->inode)->i_advise; > return sizeof(char); > } > > static int f2fs_xattr_advise_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - unsigned char old_advise = F2FS_I(inode)->i_advise; > + unsigned char old_advise = F2FS_I(args->inode)->i_advise; > unsigned char new_advise; > > - if (!inode_owner_or_capable(inode)) > + if (!inode_owner_or_capable(args->inode)) > return -EPERM; > - if (value == NULL) > + if (args->value == NULL) > return -EINVAL; > > - new_advise = *(char *)value; > + new_advise = *(char *)args->value; > if (new_advise & ~FADVISE_MODIFIABLE_BITS) > return -EINVAL; > > new_advise = new_advise & FADVISE_MODIFIABLE_BITS; > new_advise |= old_advise & ~FADVISE_MODIFIABLE_BITS; > > - F2FS_I(inode)->i_advise = new_advise; > - f2fs_mark_inode_dirty_sync(inode, true); > + F2FS_I(args->inode)->i_advise = new_advise; > + f2fs_mark_inode_dirty_sync(args->inode, true); > return 0; > } > > diff --git a/fs/fuse/xattr.c b/fs/fuse/xattr.c > index 433717640f78..8b8fb719d498 100644 > --- a/fs/fuse/xattr.c > +++ b/fs/fuse/xattr.c > @@ -175,21 +175,19 @@ int fuse_removexattr(struct inode *inode, const char *name) > } > > static int fuse_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > - return fuse_getxattr(inode, name, value, size); > + return fuse_getxattr(args->inode, args->name, args->buffer, args->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) > + struct xattr_gs_args *args) > { > - if (!value) > - return fuse_removexattr(inode, name); > + if (!args->value) > + return fuse_removexattr(args->inode, args->name); > > - return fuse_setxattr(inode, name, value, size, flags); > + return fuse_setxattr(args->inode, args->name, > + args->value, args->size, args->flags); > } > > static bool no_xattr_list(struct dentry *dentry) > @@ -198,16 +196,13 @@ static bool no_xattr_list(struct dentry *dentry) > } > > static int no_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > return -EOPNOTSUPP; > } > > static int no_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *nodee, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > return -EOPNOTSUPP; > } > diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c > index bbe593d16bea..bf8e1bd17a29 100644 > --- a/fs/gfs2/xattr.c > +++ b/fs/gfs2/xattr.c > @@ -587,10 +587,9 @@ static int __gfs2_xattr_get(struct inode *inode, const char *name, > } > > static int gfs2_xattr_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct gfs2_inode *ip = GFS2_I(inode); > + struct gfs2_inode *ip = GFS2_I(args->inode); > struct gfs2_holder gh; > int ret; > > @@ -603,7 +602,8 @@ static int gfs2_xattr_get(const struct xattr_handler *handler, > } else { > gfs2_holder_mark_uninitialized(&gh); > } > - ret = __gfs2_xattr_get(inode, name, buffer, size, handler->flags); > + ret = __gfs2_xattr_get(args->inode, args->name, > + args->buffer, args->size, handler->flags); > if (gfs2_holder_initialized(&gh)) > gfs2_glock_dq_uninit(&gh); > return ret; > @@ -1214,11 +1214,9 @@ int __gfs2_xattr_set(struct inode *inode, const char *name, > } > > static int gfs2_xattr_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - struct gfs2_inode *ip = GFS2_I(inode); > + struct gfs2_inode *ip = GFS2_I(args->inode); > struct gfs2_holder gh; > int ret; > > @@ -1237,7 +1235,9 @@ static int gfs2_xattr_set(const struct xattr_handler *handler, > return -EIO; > gfs2_holder_mark_uninitialized(&gh); > } > - ret = __gfs2_xattr_set(inode, name, value, size, flags, handler->flags); > + ret = __gfs2_xattr_set(args->inode, args->name, > + args->value, args->size, > + args->flags, handler->flags); > if (gfs2_holder_initialized(&gh)) > gfs2_glock_dq_uninit(&gh); > return ret; > diff --git a/fs/hfs/attr.c b/fs/hfs/attr.c > index 74fa62643136..b3355368dc58 100644 > --- a/fs/hfs/attr.c > +++ b/fs/hfs/attr.c > @@ -114,21 +114,20 @@ static ssize_t __hfs_getxattr(struct inode *inode, enum hfs_xattr_type type, > } > > static int hfs_xattr_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > - return __hfs_getxattr(inode, handler->flags, value, size); > + return __hfs_getxattr(args->inode, handler->flags, > + args->buffer, args->size); > } > > static int hfs_xattr_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, size_t size, > - int flags) > + struct xattr_gs_args *args) > { > - if (!value) > + if (!args->value) > return -EOPNOTSUPP; > > - return __hfs_setxattr(inode, handler->flags, value, size, flags); > + return __hfs_setxattr(args->inode, handler->flags, > + args->value, args->size, args->flags); > } > > static const struct xattr_handler hfs_creator_handler = { > diff --git a/fs/hfsplus/xattr.c b/fs/hfsplus/xattr.c > index bb0b27d88e50..b6cc7f18bce8 100644 > --- a/fs/hfsplus/xattr.c > +++ b/fs/hfsplus/xattr.c > @@ -838,14 +838,13 @@ static int hfsplus_removexattr(struct inode *inode, const char *name) > } > > static int hfsplus_osx_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > /* > * Don't allow retrieving properly prefixed attributes > * by prepending them with "osx." > */ > - if (is_known_namespace(name)) > + if (is_known_namespace(args->name)) > return -EOPNOTSUPP; > > /* > @@ -854,19 +853,18 @@ static int hfsplus_osx_getxattr(const struct xattr_handler *handler, > * creates), so we pass the name through unmodified (after > * ensuring it doesn't conflict with another namespace). > */ > - return __hfsplus_getxattr(inode, name, buffer, size); > + return __hfsplus_getxattr(args->inode, args->name, > + args->buffer, args->size); > } > > static int hfsplus_osx_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > /* > * Don't allow setting properly prefixed attributes > * by prepending them with "osx." > */ > - if (is_known_namespace(name)) > + if (is_known_namespace(args->name)) > return -EOPNOTSUPP; > > /* > @@ -875,7 +873,8 @@ static int hfsplus_osx_setxattr(const struct xattr_handler *handler, > * creates), so we pass the name through unmodified (after > * ensuring it doesn't conflict with another namespace). > */ > - return __hfsplus_setxattr(inode, name, buffer, size, flags); > + return __hfsplus_setxattr(args->inode, args->name, > + args->value, args->size, args->flags); > } > > const struct xattr_handler hfsplus_xattr_osx_handler = { > diff --git a/fs/hfsplus/xattr_security.c b/fs/hfsplus/xattr_security.c > index cfbe6a3bfb1e..8a8185eca12e 100644 > --- a/fs/hfsplus/xattr_security.c > +++ b/fs/hfsplus/xattr_security.c > @@ -14,20 +14,19 @@ > #include "xattr.h" > > static int hfsplus_security_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return hfsplus_getxattr(inode, name, buffer, size, > + return hfsplus_getxattr(args->inode, args->name, > + args->buffer, args->size, > XATTR_SECURITY_PREFIX, > XATTR_SECURITY_PREFIX_LEN); > } > > static int hfsplus_security_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return hfsplus_setxattr(inode, name, buffer, size, flags, > + return hfsplus_setxattr(args->inode, args->name, > + args->value, args->size, args->flags, > XATTR_SECURITY_PREFIX, > XATTR_SECURITY_PREFIX_LEN); > } > diff --git a/fs/hfsplus/xattr_trusted.c b/fs/hfsplus/xattr_trusted.c > index fbad91e1dada..a682a2e363e7 100644 > --- a/fs/hfsplus/xattr_trusted.c > +++ b/fs/hfsplus/xattr_trusted.c > @@ -13,20 +13,19 @@ > #include "xattr.h" > > static int hfsplus_trusted_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return hfsplus_getxattr(inode, name, buffer, size, > + return hfsplus_getxattr(args->inode, args->name, > + args->buffer, args->size, > XATTR_TRUSTED_PREFIX, > XATTR_TRUSTED_PREFIX_LEN); > } > > static int hfsplus_trusted_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return hfsplus_setxattr(inode, name, buffer, size, flags, > + return hfsplus_setxattr(args->inode, args->name, > + args->buffer, args->size, args->flags, > XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN); > } > > diff --git a/fs/hfsplus/xattr_user.c b/fs/hfsplus/xattr_user.c > index 74d19faf255e..9b58d7ec263d 100644 > --- a/fs/hfsplus/xattr_user.c > +++ b/fs/hfsplus/xattr_user.c > @@ -13,20 +13,19 @@ > #include "xattr.h" > > static int hfsplus_user_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > > - return hfsplus_getxattr(inode, name, buffer, size, > + return hfsplus_getxattr(args->inode, args->name, > + args->buffer, args->size, > XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); > } > > static int hfsplus_user_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return hfsplus_setxattr(inode, name, buffer, size, flags, > + return hfsplus_setxattr(args->inode, args->name, > + args->value, args->size, args->flags, > XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN); > } > > diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c > index c2332e30f218..6aa552db3807 100644 > --- a/fs/jffs2/security.c > +++ b/fs/jffs2/security.c > @@ -49,20 +49,18 @@ int jffs2_init_security(struct inode *inode, struct inode *dir, > > /* ---- XATTR Handler for "security.*" ----------------- */ > static int jffs2_security_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY, > - name, buffer, size); > + return do_jffs2_getxattr(args->inode, JFFS2_XPREFIX_SECURITY, > + args->name, args->buffer, args->size); > } > > static int jffs2_security_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, > - name, buffer, size, flags); > + return do_jffs2_setxattr(args->inode, JFFS2_XPREFIX_SECURITY, > + args->name, args->value, args->size, > + args->flags); > } > > const struct xattr_handler jffs2_security_xattr_handler = { > diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c > index 5d6030826c52..5d235175d6fd 100644 > --- a/fs/jffs2/xattr_trusted.c > +++ b/fs/jffs2/xattr_trusted.c > @@ -17,20 +17,18 @@ > #include "nodelist.h" > > static int jffs2_trusted_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED, > - name, buffer, size); > + return do_jffs2_getxattr(args->inode, JFFS2_XPREFIX_TRUSTED, > + args->name, args->buffer, args->size); > } > > static int jffs2_trusted_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED, > - name, buffer, size, flags); > + return do_jffs2_setxattr(args->inode, JFFS2_XPREFIX_TRUSTED, > + args->name, args->value, args->size, > + args->flags); > } > > static bool jffs2_trusted_listxattr(struct dentry *dentry) > diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c > index 9d027b4abcf9..a35a0785e72b 100644 > --- a/fs/jffs2/xattr_user.c > +++ b/fs/jffs2/xattr_user.c > @@ -17,20 +17,18 @@ > #include "nodelist.h" > > static int jffs2_user_getxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER, > - name, buffer, size); > + return do_jffs2_getxattr(args->inode, JFFS2_XPREFIX_USER, > + args->name, args->buffer, args->size); > } > > static int jffs2_user_setxattr(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *buffer, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER, > - name, buffer, size, flags); > + return do_jffs2_setxattr(args->inode, JFFS2_XPREFIX_USER, > + args->name, args->value, args->size, > + args->flags); > } > > const struct xattr_handler jffs2_user_xattr_handler = { > diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c > index db41e7803163..225fc440ff62 100644 > --- a/fs/jfs/xattr.c > +++ b/fs/jfs/xattr.c > @@ -924,39 +924,36 @@ static int __jfs_xattr_set(struct inode *inode, const char *name, > } > > static int jfs_xattr_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > - name = xattr_full_name(handler, name); > - return __jfs_getxattr(inode, name, value, size); > + return __jfs_getxattr(args->inode, xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int jfs_xattr_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - name = xattr_full_name(handler, name); > - return __jfs_xattr_set(inode, name, value, size, flags); > + return __jfs_xattr_set(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static int jfs_xattr_get_os2(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > - if (is_known_namespace(name)) > + if (is_known_namespace(args->name)) > return -EOPNOTSUPP; > - return __jfs_getxattr(inode, name, value, size); > + return __jfs_getxattr(args->inode, args->name, > + args->buffer, args->size); > } > > static int jfs_xattr_set_os2(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - if (is_known_namespace(name)) > + if (is_known_namespace(args->name)) > return -EOPNOTSUPP; > - return __jfs_xattr_set(inode, name, value, size, flags); > + return __jfs_xattr_set(args->inode, args->name, > + args->value, args->size, args->flags); > } > > static const struct xattr_handler jfs_user_xattr_handler = { > diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c > index f3f3984cce80..1ae646a0b20b 100644 > --- a/fs/kernfs/inode.c > +++ b/fs/kernfs/inode.c > @@ -288,13 +288,13 @@ int kernfs_iop_permission(struct inode *inode, int mask) > } > > int kernfs_xattr_get(struct kernfs_node *kn, const char *name, > - void *value, size_t size) > + void *buffer, size_t size) > { > struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn); > if (!attrs) > return -ENODATA; > > - return simple_xattr_get(&attrs->xattrs, name, value, size); > + return simple_xattr_get(&attrs->xattrs, name, buffer, size); > } > > int kernfs_xattr_set(struct kernfs_node *kn, const char *name, > @@ -308,24 +308,21 @@ int kernfs_xattr_set(struct kernfs_node *kn, const char *name, > } > > static int kernfs_vfs_xattr_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *suffix, void *value, size_t size) > + struct xattr_gs_args *args) > { > - const char *name = xattr_full_name(handler, suffix); > - struct kernfs_node *kn = inode->i_private; > + struct kernfs_node *kn = args->inode->i_private; > > - return kernfs_xattr_get(kn, name, value, size); > + return kernfs_xattr_get(kn, xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int kernfs_vfs_xattr_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *suffix, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - const char *name = xattr_full_name(handler, suffix); > - struct kernfs_node *kn = inode->i_private; > + struct kernfs_node *kn = args->inode->i_private; > > - return kernfs_xattr_set(kn, name, value, size, flags); > + return kernfs_xattr_set(kn, xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static const struct xattr_handler kernfs_trusted_xattr_handler = { > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 1406858bae6c..1f0388440ec9 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -7209,18 +7209,15 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) > #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" > > static int nfs4_xattr_set_nfs4_acl(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *key, const void *buf, > - size_t buflen, int flags) > + struct xattr_gs_args *args) > { > - return nfs4_proc_set_acl(inode, buf, buflen); > + return nfs4_proc_set_acl(args->inode, args->value, args->size); > } > > static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *key, void *buf, size_t buflen) > + struct xattr_gs_args *args) > { > - return nfs4_proc_get_acl(inode, buf, buflen); > + return nfs4_proc_get_acl(args->inode, args->buffer, args->size); > } > > static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry) > @@ -7231,22 +7228,21 @@ static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry) > #ifdef CONFIG_NFS_V4_SECURITY_LABEL > > static int nfs4_xattr_set_nfs4_label(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *key, const void *buf, > - size_t buflen, int flags) > + struct xattr_gs_args *args) > { > - if (security_ismaclabel(key)) > - return nfs4_set_security_label(inode, buf, buflen); > + if (security_ismaclabel(args->name)) > + return nfs4_set_security_label(args->inode, > + args->value, args->size); > > return -EOPNOTSUPP; > } > > static int nfs4_xattr_get_nfs4_label(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *key, void *buf, size_t buflen) > + struct xattr_gs_args *args) > { > - if (security_ismaclabel(key)) > - return nfs4_get_security_label(inode, buf, buflen); > + if (security_ismaclabel(args->name)) > + return nfs4_get_security_label(args->inode, > + args->buffer, args->size); > return -EOPNOTSUPP; > } > > diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c > index 90c830e3758e..25ac1557e303 100644 > --- a/fs/ocfs2/xattr.c > +++ b/fs/ocfs2/xattr.c > @@ -7241,20 +7241,18 @@ int ocfs2_init_security_and_acl(struct inode *dir, > * 'security' attributes support > */ > static int ocfs2_xattr_security_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_SECURITY, > - name, buffer, size); > + return ocfs2_xattr_get(args->inode, OCFS2_XATTR_INDEX_SECURITY, > + args->name, args->buffer, args->size); > } > > static int ocfs2_xattr_security_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, > - name, value, size, flags); > + return ocfs2_xattr_set(args->inode, OCFS2_XATTR_INDEX_SECURITY, > + args->name, args->value, args->size, > + args->flags); > } > > static int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array, > @@ -7313,20 +7311,18 @@ const struct xattr_handler ocfs2_xattr_security_handler = { > * 'trusted' attributes support > */ > static int ocfs2_xattr_trusted_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_TRUSTED, > - name, buffer, size); > + return ocfs2_xattr_get(args->inode, OCFS2_XATTR_INDEX_TRUSTED, > + args->name, args->buffer, args->size); > } > > static int ocfs2_xattr_trusted_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_TRUSTED, > - name, value, size, flags); > + return ocfs2_xattr_set(args->inode, OCFS2_XATTR_INDEX_TRUSTED, > + args->name, args->value, args->size, > + args->flags); > } > > const struct xattr_handler ocfs2_xattr_trusted_handler = { > @@ -7339,29 +7335,27 @@ const struct xattr_handler ocfs2_xattr_trusted_handler = { > * 'user' attributes support > */ > static int ocfs2_xattr_user_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); > + struct ocfs2_super *osb = OCFS2_SB(args->inode->i_sb); > > if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) > return -EOPNOTSUPP; > - return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_USER, name, > - buffer, size); > + return ocfs2_xattr_get(args->inode, OCFS2_XATTR_INDEX_USER, args->name, > + args->buffer, args->size); > } > > static int ocfs2_xattr_user_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); > + struct ocfs2_super *osb = OCFS2_SB(args->inode->i_sb); > > if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR) > return -EOPNOTSUPP; > > - return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_USER, > - name, value, size, flags); > + return ocfs2_xattr_set(args->inode, OCFS2_XATTR_INDEX_USER, > + args->name, args->value, args->size, > + args->flags); > } > > const struct xattr_handler ocfs2_xattr_user_handler = { > diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c > index bdc285aea360..d222922af141 100644 > --- a/fs/orangefs/xattr.c > +++ b/fs/orangefs/xattr.c > @@ -526,24 +526,17 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) > } > > static int orangefs_xattr_set_default(const struct xattr_handler *handler, > - struct dentry *unused, > - struct inode *inode, > - const char *name, > - const void *buffer, > - size_t size, > - int flags) > + struct xattr_gs_args *args) > { > - return orangefs_inode_setxattr(inode, name, buffer, size, flags); > + return orangefs_inode_setxattr(args->inode, args->name, > + args->value, args->size, args->flags); > } > > static int orangefs_xattr_get_default(const struct xattr_handler *handler, > - struct dentry *unused, > - struct inode *inode, > - const char *name, > - void *buffer, > - size_t size) > + struct xattr_gs_args *args) > { > - return orangefs_inode_getxattr(inode, name, buffer, size); > + return orangefs_inode_getxattr(args->inode, args->name, > + args->buffer, args->size); > > } > > diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c > index 7663aeb85fa3..a14d450b8564 100644 > --- a/fs/overlayfs/inode.c > +++ b/fs/overlayfs/inode.c > @@ -318,60 +318,61 @@ bool ovl_is_private_xattr(const char *name) > sizeof(OVL_XATTR_PREFIX) - 1) == 0; > } > > -int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, > - const void *value, size_t size, int flags) > +int ovl_xattr_set(struct xattr_gs_args *args) > { > int err; > - struct dentry *upperdentry = ovl_i_dentry_upper(inode); > - struct dentry *realdentry = upperdentry ?: ovl_dentry_lower(dentry); > + struct dentry *upperdentry = ovl_i_dentry_upper(args->inode); > + struct dentry *realdentry > + upperdentry ?: ovl_dentry_lower(args->dentry); > const struct cred *old_cred; > > - err = ovl_want_write(dentry); > + err = ovl_want_write(args->dentry); > if (err) > goto out; > > - if (!value && !upperdentry) { > - err = vfs_getxattr(realdentry, name, NULL, 0); > + if (!args->value && !upperdentry) { > + err = vfs_getxattr(realdentry, args->name, NULL, 0); > if (err < 0) > goto out_drop_write; > } > > if (!upperdentry) { > - err = ovl_copy_up(dentry); > + err = ovl_copy_up(args->dentry); > if (err) > goto out_drop_write; > > - realdentry = ovl_dentry_upper(dentry); > + realdentry = ovl_dentry_upper(args->dentry); > } > > - old_cred = ovl_override_creds(dentry->d_sb); > - if (value) > - err = vfs_setxattr(realdentry, name, value, size, flags); > + old_cred = ovl_override_creds(args->dentry->d_sb); > + if (args->value) > + err = vfs_setxattr(realdentry, args->name, > + args->value, args->size, args->flags); > else { > - WARN_ON(flags != XATTR_REPLACE); > - err = vfs_removexattr(realdentry, name); > + WARN_ON(args->flags != XATTR_REPLACE); > + err = vfs_removexattr(realdentry, args->name); > } > revert_creds(old_cred); > > /* copy c/mtime */ > - ovl_copyattr(d_inode(realdentry), inode); > + ovl_copyattr(d_inode(realdentry), args->inode); > > out_drop_write: > - ovl_drop_write(dentry); > + ovl_drop_write(args->dentry); > out: > return err; > } > > -int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, > - void *value, size_t size) > +int ovl_xattr_get(struct xattr_gs_args *args) > { > ssize_t res; > const struct cred *old_cred; > struct dentry *realdentry > - ovl_i_dentry_upper(inode) ?: ovl_dentry_lower(dentry); > + ovl_i_dentry_upper(args->inode) ?: > + ovl_dentry_lower(args->dentry); > > - old_cred = ovl_override_creds(dentry->d_sb); > - res = vfs_getxattr(realdentry, name, value, size); > + old_cred = ovl_override_creds(args->dentry->d_sb); > + res = vfs_getxattr(realdentry, args->name, args->buffer, args->size); > revert_creds(old_cred); > return res; > } > diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h > index 6934bcf030f0..c6a8ec049099 100644 > --- a/fs/overlayfs/overlayfs.h > +++ b/fs/overlayfs/overlayfs.h > @@ -353,10 +353,8 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr); > int ovl_getattr(const struct path *path, struct kstat *stat, > u32 request_mask, unsigned int flags); > int ovl_permission(struct inode *inode, int mask); > -int ovl_xattr_set(struct dentry *dentry, struct inode *inode, const char *name, > - const void *value, size_t size, int flags); > -int ovl_xattr_get(struct dentry *dentry, struct inode *inode, const char *name, > - void *value, size_t size); > +int ovl_xattr_set(struct xattr_gs_args *args); > +int ovl_xattr_get(struct xattr_gs_args *args); > ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); > struct posix_acl *ovl_get_acl(struct inode *inode, int type); > int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags); > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c > index b368e2e102fa..e41359ba9159 100644 > --- a/fs/overlayfs/super.c > +++ b/fs/overlayfs/super.c > @@ -853,26 +853,24 @@ static unsigned int ovl_split_lowerdirs(char *str) > > static int __maybe_unused > ovl_posix_acl_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ovl_xattr_get(dentry, inode, handler->name, buffer, size); > + return ovl_xattr_get(args); > } > > static int __maybe_unused > ovl_posix_acl_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - struct dentry *workdir = ovl_workdir(dentry); > - struct inode *realinode = ovl_inode_real(inode); > + struct dentry *workdir = ovl_workdir(args->dentry); > + struct inode *realinode = ovl_inode_real(args->inode); > struct posix_acl *acl = NULL; > int err; > > /* Check that everything is OK before copy-up */ > - if (value) { > - acl = posix_acl_from_xattr(&init_user_ns, value, size); > + if (args->value) { > + acl = posix_acl_from_xattr(&init_user_ns, > + args->value, args->size); > if (IS_ERR(acl)) > return PTR_ERR(acl); > } > @@ -881,12 +879,13 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, > goto out_acl_release; > if (!realinode->i_op->set_acl) > goto out_acl_release; > - if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) { > + if (handler->flags == ACL_TYPE_DEFAULT && > + !S_ISDIR(args->inode->i_mode)) { > err = acl ? -EACCES : 0; > goto out_acl_release; > } > err = -EPERM; > - if (!inode_owner_or_capable(inode)) > + if (!inode_owner_or_capable(args->inode)) > goto out_acl_release; > > posix_acl_release(acl); > @@ -895,20 +894,20 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, > * Check if sgid bit needs to be cleared (actual setacl operation will > * be done with mounter's capabilities and so that won't do it for us). > */ > - if (unlikely(inode->i_mode & S_ISGID) && > + if (unlikely(args->inode->i_mode & S_ISGID) && > handler->flags == ACL_TYPE_ACCESS && > - !in_group_p(inode->i_gid) && > - !capable_wrt_inode_uidgid(inode, CAP_FSETID)) { > + !in_group_p(args->inode->i_gid) && > + !capable_wrt_inode_uidgid(args->inode, CAP_FSETID)) { > struct iattr iattr = { .ia_valid = ATTR_KILL_SGID }; > > - err = ovl_setattr(dentry, &iattr); > + err = ovl_setattr(args->dentry, &iattr); > if (err) > return err; > } > > - err = ovl_xattr_set(dentry, inode, handler->name, value, size, flags); > + err = ovl_xattr_set(args); > if (!err) > - ovl_copyattr(ovl_inode_real(inode), inode); > + ovl_copyattr(ovl_inode_real(args->inode), args->inode); > > return err; > > @@ -918,33 +917,27 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler, > } > > static int ovl_own_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > return -EOPNOTSUPP; > } > > static int ovl_own_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > return -EOPNOTSUPP; > } > > static int ovl_other_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return ovl_xattr_get(dentry, inode, name, buffer, size); > + return ovl_xattr_get(args); > } > > static int ovl_other_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - return ovl_xattr_set(dentry, inode, name, value, size, flags); > + return ovl_xattr_set(args); > } > > static const struct xattr_handler __maybe_unused > diff --git a/fs/posix_acl.c b/fs/posix_acl.c > index 84ad1c90d535..8cc7310386fe 100644 > --- a/fs/posix_acl.c > +++ b/fs/posix_acl.c > @@ -831,24 +831,24 @@ EXPORT_SYMBOL (posix_acl_to_xattr); > > static int > posix_acl_xattr_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *value, size_t size) > + struct xattr_gs_args *args) > { > struct posix_acl *acl; > int error; > > - if (!IS_POSIXACL(inode)) > + if (!IS_POSIXACL(args->inode)) > return -EOPNOTSUPP; > - if (S_ISLNK(inode->i_mode)) > + if (S_ISLNK(args->inode->i_mode)) > return -EOPNOTSUPP; > > - acl = get_acl(inode, handler->flags); > + acl = get_acl(args->inode, handler->flags); > if (IS_ERR(acl)) > return PTR_ERR(acl); > if (acl == NULL) > return -ENODATA; > > - error = posix_acl_to_xattr(&init_user_ns, acl, value, size); > + error = posix_acl_to_xattr(&init_user_ns, acl, > + args->buffer, args->size); > posix_acl_release(acl); > > return error; > @@ -878,19 +878,18 @@ EXPORT_SYMBOL(set_posix_acl); > > static int > posix_acl_xattr_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > struct posix_acl *acl = NULL; > int ret; > > - if (value) { > - acl = posix_acl_from_xattr(&init_user_ns, value, size); > + if (args->value) { > + acl = posix_acl_from_xattr(&init_user_ns, > + args->value, args->size); > if (IS_ERR(acl)) > return PTR_ERR(acl); > } > - ret = set_posix_acl(inode, handler->flags, acl); > + ret = set_posix_acl(args->inode, handler->flags, acl); > posix_acl_release(acl); > return ret; > } > diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c > index b5b26d8a192c..b949a55b95bd 100644 > --- a/fs/reiserfs/xattr.c > +++ b/fs/reiserfs/xattr.c > @@ -765,7 +765,7 @@ reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer, > /* This is the implementation for the xattr plugin infrastructure */ > static inline const struct xattr_handler * > find_xattr_handler_prefix(const struct xattr_handler **handlers, > - const char *name) > + const char *name) > { > const struct xattr_handler *xah; > > diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c > index 20be9a0e5870..6d436ef207d1 100644 > --- a/fs/reiserfs/xattr_security.c > +++ b/fs/reiserfs/xattr_security.c > @@ -10,27 +10,25 @@ > #include <linux/uaccess.h> > > static int > -security_get(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, void *buffer, size_t size) > +security_get(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > - if (IS_PRIVATE(inode)) > + if (IS_PRIVATE(args->inode)) > return -EPERM; > > - return reiserfs_xattr_get(inode, xattr_full_name(handler, name), > - buffer, size); > + return reiserfs_xattr_get(args->inode, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int > -security_set(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, const void *buffer, > - size_t size, int flags) > +security_set(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > - if (IS_PRIVATE(inode)) > + if (IS_PRIVATE(args->inode)) > return -EPERM; > > - return reiserfs_xattr_set(inode, > - xattr_full_name(handler, name), > - buffer, size, flags); > + return reiserfs_xattr_set(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static bool security_list(struct dentry *dentry) > diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c > index 5ed48da3d02b..46dfc6e2e150 100644 > --- a/fs/reiserfs/xattr_trusted.c > +++ b/fs/reiserfs/xattr_trusted.c > @@ -9,27 +9,25 @@ > #include <linux/uaccess.h> > > static int > -trusted_get(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, void *buffer, size_t size) > +trusted_get(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > - if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) > + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(args->inode)) > return -EPERM; > > - return reiserfs_xattr_get(inode, xattr_full_name(handler, name), > - buffer, size); > + return reiserfs_xattr_get(args->inode, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int > -trusted_set(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, const void *buffer, > - size_t size, int flags) > +trusted_set(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > - if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) > + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(args->inode)) > return -EPERM; > > - return reiserfs_xattr_set(inode, > - xattr_full_name(handler, name), > - buffer, size, flags); > + return reiserfs_xattr_set(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static bool trusted_list(struct dentry *dentry) > diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c > index a573ca45bacc..4a0bafe62d05 100644 > --- a/fs/reiserfs/xattr_user.c > +++ b/fs/reiserfs/xattr_user.c > @@ -8,25 +8,23 @@ > #include <linux/uaccess.h> > > static int > -user_get(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, void *buffer, size_t size) > +user_get(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > - if (!reiserfs_xattrs_user(inode->i_sb)) > + if (!reiserfs_xattrs_user(args->inode->i_sb)) > return -EOPNOTSUPP; > - return reiserfs_xattr_get(inode, xattr_full_name(handler, name), > - buffer, size); > + return reiserfs_xattr_get(args->inode, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int > -user_set(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, const void *buffer, > - size_t size, int flags) > +user_set(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > - if (!reiserfs_xattrs_user(inode->i_sb)) > + if (!reiserfs_xattrs_user(args->inode->i_sb)) > return -EOPNOTSUPP; > - return reiserfs_xattr_set(inode, > - xattr_full_name(handler, name), > - buffer, size, flags); > + return reiserfs_xattr_set(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static bool user_list(struct dentry *dentry) > diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c > index e1e3f3dd5a06..c6403f187ced 100644 > --- a/fs/squashfs/xattr.c > +++ b/fs/squashfs/xattr.c > @@ -199,15 +199,11 @@ static int squashfs_xattr_get(struct inode *inode, int name_index, > return err; > } > > - > static int squashfs_xattr_handler_get(const struct xattr_handler *handler, > - struct dentry *unused, > - struct inode *inode, > - const char *name, > - void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - return squashfs_xattr_get(inode, handler->flags, name, > - buffer, size); > + return squashfs_xattr_get(args->inode, handler->flags, args->name, > + args->buffer, args->size); > } > > /* > diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c > index 9aefbb60074f..aec02d94f2d6 100644 > --- a/fs/ubifs/xattr.c > +++ b/fs/ubifs/xattr.c > @@ -668,30 +668,29 @@ int ubifs_init_security(struct inode *dentry, struct inode *inode, > #endif > > static int xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name, > - inode->i_ino, dentry, size); > + dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", args->name, > + args->inode->i_ino, args->dentry, args->size); > > - name = xattr_full_name(handler, name); > - return ubifs_xattr_get(inode, name, buffer, size); > + return ubifs_xattr_get(args->inode, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd", > - name, inode->i_ino, dentry, size); > - > - name = xattr_full_name(handler, name); > - > - if (value) > - return ubifs_xattr_set(inode, name, value, size, flags, true); > - else > - return ubifs_xattr_remove(inode, name); > + args->name, args->inode->i_ino, args->dentry, args->size); > + > + if (args->value) > + return ubifs_xattr_set(args->inode, > + xattr_full_name(handler, args->name), > + args->value, args->size, > + args->flags, true); > + return ubifs_xattr_remove(args->inode, > + xattr_full_name(handler, args->name)); > } > > static const struct xattr_handler ubifs_user_xattr_handler = { > diff --git a/fs/xattr.c b/fs/xattr.c > index 90dd78f0eb27..dceb5afe79be 100644 > --- a/fs/xattr.c > +++ b/fs/xattr.c > @@ -135,19 +135,18 @@ xattr_permission(struct inode *inode, const char *name, int mask) > } > > int > -__vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, > - const void *value, size_t size, int flags) > +__vfs_setxattr(struct xattr_gs_args *args) > { > const struct xattr_handler *handler; > > - handler = xattr_resolve_name(inode, &name); > + handler = xattr_resolve_name(args->inode, &args->name); > if (IS_ERR(handler)) > return PTR_ERR(handler); > if (!handler->set) > return -EOPNOTSUPP; > - if (size == 0) > - value = ""; /* empty EA, do not remove */ > - return handler->set(handler, dentry, inode, name, value, size, flags); > + if (args->size == 0) > + args->value = ""; /* empty EA, do not remove */ > + return handler->set(handler, args); > } > EXPORT_SYMBOL(__vfs_setxattr); > > @@ -178,7 +177,16 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, > if (issec) > inode->i_flags &= ~S_NOSEC; > if (inode->i_opflags & IOP_XATTR) { > - error = __vfs_setxattr(dentry, inode, name, value, size, flags); > + struct xattr_gs_args args = { > + .dentry = dentry, > + .inode = inode, > + .name = name, > + .value = value, > + .size = size, > + .flags = flags, > + }; > + > + error = __vfs_setxattr(&args); > if (!error) { > fsnotify_xattr(dentry); > security_inode_post_setxattr(dentry, name, value, > @@ -268,68 +276,61 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, > size_t xattr_size, gfp_t flags) > { > const struct xattr_handler *handler; > - struct inode *inode = dentry->d_inode; > - char *value = *xattr_value; > + struct xattr_gs_args args; > int error; > > - error = xattr_permission(inode, name, MAY_READ); > + error = xattr_permission(dentry->d_inode, name, MAY_READ); > if (error) > return error; > > - handler = xattr_resolve_name(inode, &name); > + handler = xattr_resolve_name(dentry->d_inode, &name); > if (IS_ERR(handler)) > return PTR_ERR(handler); > if (!handler->get) > return -EOPNOTSUPP; > - error = handler->get(handler, dentry, inode, name, NULL, 0); > + memset(&args, 0, sizeof(args)); > + args.inode = dentry->d_inode; > + args.dentry = dentry; > + args.name = name; > + error = handler->get(handler, &args); > if (error < 0) > return error; > > - if (!value || (error > xattr_size)) { > - value = krealloc(*xattr_value, error + 1, flags); > - if (!value) > + args.buffer = *xattr_value; > + if (!*xattr_value || (error > xattr_size)) { > + args.buffer = krealloc(*xattr_value, error + 1, flags); > + if (!args.buffer) > return -ENOMEM; > - memset(value, 0, error + 1); > + memset(args.buffer, 0, error + 1); > } > > - error = handler->get(handler, dentry, inode, name, value, error); > - *xattr_value = value; > + args.size = error; > + error = handler->get(handler, &args); > + *xattr_value = args.buffer; > return error; > } > > ssize_t > -__vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, > - void *value, size_t size) > +__vfs_getxattr(struct xattr_gs_args *args) > { > const struct xattr_handler *handler; > - > - handler = xattr_resolve_name(inode, &name); > - if (IS_ERR(handler)) > - return PTR_ERR(handler); > - if (!handler->get) > - return -EOPNOTSUPP; > - return handler->get(handler, dentry, inode, name, value, size); > -} > -EXPORT_SYMBOL(__vfs_getxattr); > - > -ssize_t > -vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) > -{ > - struct inode *inode = dentry->d_inode; > int error; > > - error = xattr_permission(inode, name, MAY_READ); > + if (args->flags & XATTR_NOSECURITY) > + goto nolsm; > + error = xattr_permission(args->inode, args->name, MAY_READ); > if (error) > return error; > > - error = security_inode_getxattr(dentry, name); > + error = security_inode_getxattr(args->dentry, args->name); > if (error) > return error; > > - if (!strncmp(name, XATTR_SECURITY_PREFIX, > + if (!strncmp(args->name, XATTR_SECURITY_PREFIX, > XATTR_SECURITY_PREFIX_LEN)) { > - const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; > - int ret = xattr_getsecurity(inode, suffix, value, size); > + const char *suffix = args->name + XATTR_SECURITY_PREFIX_LEN; > + int ret = xattr_getsecurity(args->inode, suffix, > + args->buffer, args->size); > /* > * Only overwrite the return value if a security module > * is actually active. > @@ -339,7 +340,27 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) > return ret; > } > nolsm: > - return __vfs_getxattr(dentry, inode, name, value, size); > + handler = xattr_resolve_name(args->inode, &args->name); > + if (IS_ERR(handler)) > + return PTR_ERR(handler); > + if (!handler->get) > + return -EOPNOTSUPP; > + return handler->get(handler, args); > +} > +EXPORT_SYMBOL(__vfs_getxattr); > + > +ssize_t > +vfs_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size) > +{ > + struct xattr_gs_args args = { > + .dentry = dentry, > + .inode = dentry->d_inode, > + .name = name, > + .buffer = buffer, > + .size = size, > + }; > + > + return __vfs_getxattr(&args); > } > EXPORT_SYMBOL_GPL(vfs_getxattr); > > @@ -366,15 +387,20 @@ EXPORT_SYMBOL_GPL(vfs_listxattr); > int > __vfs_removexattr(struct dentry *dentry, const char *name) > { > - struct inode *inode = d_inode(dentry); > const struct xattr_handler *handler; > + struct xattr_gs_args args; > > - handler = xattr_resolve_name(inode, &name); > + handler = xattr_resolve_name(d_inode(dentry), &name); > if (IS_ERR(handler)) > return PTR_ERR(handler); > if (!handler->set) > return -EOPNOTSUPP; > - return handler->set(handler, dentry, inode, name, NULL, 0, XATTR_REPLACE); > + memset(&args, 0, sizeof(args)); > + args.dentry = dentry; > + args.inode = d_inode(dentry); > + args.name = name; > + args.flags = XATTR_REPLACE; > + return handler->set(handler, &args); > } > EXPORT_SYMBOL(__vfs_removexattr); > > diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c > index d48fcf11cc35..60fec712f60b 100644 > --- a/fs/xfs/libxfs/xfs_attr.c > +++ b/fs/xfs/libxfs/xfs_attr.c > @@ -305,7 +305,7 @@ int > xfs_attr_set( > struct xfs_inode *dp, > const unsigned char *name, > - unsigned char *value, > + const unsigned char *value, > int valuelen, > int flags) > { > @@ -324,7 +324,7 @@ xfs_attr_set( > if (error) > return error; > > - args.value = value; > + args.value = (unsigned char *)value; > args.valuelen = valuelen; > args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; > args.total = xfs_attr_calc_size(&args, &local); > diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h > index ff28ebf3b635..afe184e5fb01 100644 > --- a/fs/xfs/libxfs/xfs_attr.h > +++ b/fs/xfs/libxfs/xfs_attr.h > @@ -145,7 +145,7 @@ int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args); > int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name, > unsigned char *value, int *valuelenp, int flags); > int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, > - unsigned char *value, int valuelen, int flags); > + const unsigned char *value, int valuelen, int flags); > int xfs_attr_set_args(struct xfs_da_args *args); > int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); > int xfs_attr_remove_args(struct xfs_da_args *args); > diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c > index 3123b5aaad2a..313a828a3d1f 100644 > --- a/fs/xfs/xfs_xattr.c > +++ b/fs/xfs/xfs_xattr.c > @@ -17,20 +17,20 @@ > > > static int > -xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, void *value, size_t size) > +xfs_xattr_get(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > int xflags = handler->flags; > - struct xfs_inode *ip = XFS_I(inode); > - int error, asize = size; > + struct xfs_inode *ip = XFS_I(args->inode); > + int error, asize = args->size; > > /* Convert Linux syscall to XFS internal ATTR flags */ > - if (!size) { > + if (!args->size) { > xflags |= ATTR_KERNOVAL; > - value = NULL; > + args->buffer = NULL; > } > > - error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags); > + error = xfs_attr_get(ip, (const unsigned char *)args->name, > + args->buffer, &asize, xflags); > if (error) > return error; > return asize; > @@ -59,26 +59,25 @@ xfs_forget_acl( > } > > static int > -xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused, > - struct inode *inode, const char *name, const void *value, > - size_t size, int flags) > +xfs_xattr_set(const struct xattr_handler *handler, struct xattr_gs_args *args) > { > int xflags = handler->flags; > - struct xfs_inode *ip = XFS_I(inode); > + struct xfs_inode *ip = XFS_I(args->inode); > int error; > > /* Convert Linux syscall to XFS internal ATTR flags */ > - if (flags & XATTR_CREATE) > + if (args->flags & XATTR_CREATE) > xflags |= ATTR_CREATE; > - if (flags & XATTR_REPLACE) > + if (args->flags & XATTR_REPLACE) > xflags |= ATTR_REPLACE; > > - if (!value) > - return xfs_attr_remove(ip, (unsigned char *)name, xflags); > - error = xfs_attr_set(ip, (unsigned char *)name, > - (void *)value, size, xflags); > + if (!args->value) > + return xfs_attr_remove(ip, (const unsigned char *)args->name, > + xflags); > + error = xfs_attr_set(ip, (const unsigned char *)args->name, > + args->value, args->size, xflags); > if (!error) > - xfs_forget_acl(inode, name, xflags); > + xfs_forget_acl(args->inode, args->name, xflags); > > return error; > } > diff --git a/include/linux/xattr.h b/include/linux/xattr.h > index 6dad031be3c2..b2afbdcf000f 100644 > --- a/include/linux/xattr.h > +++ b/include/linux/xattr.h > @@ -25,17 +25,27 @@ struct dentry; > * name. When @prefix is set instead, match attributes with that prefix and > * with a non-empty suffix. > */ > +struct xattr_gs_args { > + struct dentry *dentry; > + struct inode *inode; > + const char *name; > + union { > + void *buffer; > + const void *value; > + }; > + size_t size; > + int flags; > +}; > + > struct xattr_handler { > const char *name; > const char *prefix; > int flags; /* fs private flags */ > bool (*list)(struct dentry *dentry); > - int (*get)(const struct xattr_handler *, struct dentry *dentry, > - struct inode *inode, const char *name, void *buffer, > - size_t size); > - int (*set)(const struct xattr_handler *, struct dentry *dentry, > - struct inode *inode, const char *name, const void *buffer, > - size_t size, int flags); > + int (*get)(const struct xattr_handler *handler, > + struct xattr_gs_args *args); > + int (*set)(const struct xattr_handler *handler, > + struct xattr_gs_args *args); > }; > > const char *xattr_full_name(const struct xattr_handler *, const char *); > @@ -46,10 +56,10 @@ struct xattr { > size_t value_len; > }; > > -ssize_t __vfs_getxattr(struct dentry *, struct inode *, const char *, void *, size_t); > +ssize_t __vfs_getxattr(struct xattr_gs_args *args); > ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); > ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); > -int __vfs_setxattr(struct dentry *, struct inode *, const char *, const void *, size_t, int); > +int __vfs_setxattr(struct xattr_gs_args *args); > int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int); > int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); > int __vfs_removexattr(struct dentry *, const char *); > diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h > index c1395b5bd432..1eba02616274 100644 > --- a/include/uapi/linux/xattr.h > +++ b/include/uapi/linux/xattr.h > @@ -17,8 +17,11 @@ > #if __UAPI_DEF_XATTR > #define __USE_KERNEL_XATTR_DEFS > > -#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ > -#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ > +#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ > +#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ > +#ifdef __KERNEL__ /* following is kernel internal, colocated for maintenance */ > +#define XATTR_NOSECURITY 0x4 /* get value, do not involve security check */ > +#endif > #endif > > /* Namespaces */ > diff --git a/mm/shmem.c b/mm/shmem.c > index 2bed4761f279..c84687f57e43 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -3205,24 +3205,23 @@ static int shmem_initxattrs(struct inode *inode, > } > > static int shmem_xattr_handler_get(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, void *buffer, size_t size) > + struct xattr_gs_args *args) > { > - struct shmem_inode_info *info = SHMEM_I(inode); > + struct shmem_inode_info *info = SHMEM_I(args->inode); > > - name = xattr_full_name(handler, name); > - return simple_xattr_get(&info->xattrs, name, buffer, size); > + return simple_xattr_get(&info->xattrs, > + xattr_full_name(handler, args->name), > + args->buffer, args->size); > } > > static int shmem_xattr_handler_set(const struct xattr_handler *handler, > - struct dentry *unused, struct inode *inode, > - const char *name, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > - struct shmem_inode_info *info = SHMEM_I(inode); > + struct shmem_inode_info *info = SHMEM_I(args->inode); > > - name = xattr_full_name(handler, name); > - return simple_xattr_set(&info->xattrs, name, value, size, flags); > + return simple_xattr_set(&info->xattrs, > + xattr_full_name(handler, args->name), > + args->value, args->size, args->flags); > } > > static const struct xattr_handler shmem_security_xattr_handler = { > diff --git a/net/socket.c b/net/socket.c > index 6a9ab7a8b1d2..7920caece7cc 100644 > --- a/net/socket.c > +++ b/net/socket.c > @@ -299,15 +299,15 @@ static const struct dentry_operations sockfs_dentry_operations = { > }; > > static int sockfs_xattr_get(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *suffix, void *value, size_t size) > + struct xattr_gs_args *args) > { > - if (value) { > - if (dentry->d_name.len + 1 > size) > + if (args->buffer) { > + if (args->dentry->d_name.len + 1 > args->size) > return -ERANGE; > - memcpy(value, dentry->d_name.name, dentry->d_name.len + 1); > + memcpy(args->buffer, args->dentry->d_name.name, > + args->dentry->d_name.len + 1); > } > - return dentry->d_name.len + 1; > + return args->dentry->d_name.len + 1; > } > > #define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname" > @@ -320,9 +320,7 @@ static const struct xattr_handler sockfs_xattr_handler = { > }; > > static int sockfs_security_xattr_set(const struct xattr_handler *handler, > - struct dentry *dentry, struct inode *inode, > - const char *suffix, const void *value, > - size_t size, int flags) > + struct xattr_gs_args *args) > { > /* Handled by LSM. */ > return -EAGAIN; > diff --git a/security/commoncap.c b/security/commoncap.c > index f4ee0ae106b2..c58b684d5d9a 100644 > --- a/security/commoncap.c > +++ b/security/commoncap.c > @@ -294,11 +294,15 @@ int cap_capset(struct cred *new, > */ > int cap_inode_need_killpriv(struct dentry *dentry) > { > - struct inode *inode = d_backing_inode(dentry); > - int error; > + struct xattr_gs_args args; > + > + memset(&args, 0, sizeof(args)); > + args.dentry = dentry; > + args.inode = d_backing_inode(dentry); > + args.name = XATTR_NAME_CAPS; > + args.flags = XATTR_NOSECURITY; > > - error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0); > - return error > 0; > + return __vfs_getxattr(&args) > 0; > } > > /** > @@ -570,7 +574,7 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps, > */ > int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps) > { > - struct inode *inode = d_backing_inode(dentry); > + struct xattr_gs_args args; > __u32 magic_etc; > unsigned tocopy, i; > int size; > @@ -580,13 +584,20 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data > struct user_namespace *fs_ns; > > memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data)); > + memset(&args, 0, sizeof(args)); > > - if (!inode) > + args.dentry = (struct dentry *)dentry; > + args.inode = d_backing_inode(args.dentry); > + if (!args.inode) > return -ENODATA; > > - fs_ns = inode->i_sb->s_user_ns; > - size = __vfs_getxattr((struct dentry *)dentry, inode, > - XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ); > + fs_ns = args.inode->i_sb->s_user_ns; > + > + args.name = XATTR_NAME_CAPS; > + args.buffer = &data; > + args.size = XATTR_CAPS_SZ; > + args.flags = XATTR_NOSECURITY; > + size = __vfs_getxattr(&args); > if (size == -ENODATA || size == -EOPNOTSUPP) > /* no data, that's ok */ > return -ENODATA; > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c > index f9a81b187fae..a53ef9281186 100644 > --- a/security/integrity/evm/evm_main.c > +++ b/security/integrity/evm/evm_main.c > @@ -91,16 +91,23 @@ static bool evm_key_loaded(void) > > static int evm_find_protected_xattrs(struct dentry *dentry) > { > - struct inode *inode = d_backing_inode(dentry); > + struct xattr_gs_args args; > struct xattr_list *xattr; > int error; > int count = 0; > > - if (!(inode->i_opflags & IOP_XATTR)) > + memset(&args, 0, sizeof(args)); > + args.dentry = dentry; > + args.inode = d_backing_inode(dentry); > + > + if (!(args.inode->i_opflags & IOP_XATTR)) > return -EOPNOTSUPP; > > + args.flags = XATTR_NOSECURITY; > + > list_for_each_entry_rcu(xattr, &evm_config_xattrnames, list) { > - error = __vfs_getxattr(dentry, inode, xattr->name, NULL, 0); > + args.name = xattr->name; > + error = __vfs_getxattr(&args); > if (error < 0) { > if (error == -ENODATA) > continue; > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index 74dd46de01b6..23c3a2c468f7 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -540,6 +540,8 @@ static int sb_finish_set_opts(struct super_block *sb) > int rc = 0; > > if (sbsec->behavior == SECURITY_FS_USE_XATTR) { > + struct xattr_gs_args args; > + > /* Make sure that the xattr handler exists and that no > error other than -ENODATA is returned by getxattr on > the root directory. -ENODATA is ok, as this may be > @@ -552,7 +554,12 @@ static int sb_finish_set_opts(struct super_block *sb) > goto out; > } > > - rc = __vfs_getxattr(root, root_inode, XATTR_NAME_SELINUX, NULL, 0); > + memset(&args, 0, sizeof(args)); > + args.dentry = root; > + args.inode = root_inode; > + args.name = XATTR_NAME_SELINUX; > + args.flags = XATTR_NOSECURITY; > + rc = __vfs_getxattr(&args); > if (rc < 0 && rc != -ENODATA) { > if (rc == -EOPNOTSUPP) > pr_warn("SELinux: (dev %s, type " > @@ -1371,6 +1378,7 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry, > char *context; > unsigned int len; > int rc; > + struct xattr_gs_args args; > > len = INITCONTEXTLEN; > context = kmalloc(len + 1, GFP_NOFS); > @@ -1378,12 +1386,21 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry, > return -ENOMEM; > > context[len] = '\0'; > - rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len); > + memset(&args, 0, sizeof(args)); > + args.dentry = dentry; > + args.inode = inode; > + args.name = XATTR_NAME_SELINUX; > + args.buffer = context; > + args.size = len; > + args.flags = XATTR_NOSECURITY; > + rc = __vfs_getxattr(&args); > if (rc == -ERANGE) { > kfree(context); > > /* Need a larger buffer. Query for the right size. */ > - rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0); > + args.buffer = NULL; > + args.size = 0; > + rc = __vfs_getxattr(&args); > if (rc < 0) > return rc; > > @@ -1393,8 +1410,9 @@ static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry, > return -ENOMEM; > > context[len] = '\0'; > - rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, > - context, len); > + args.buffer = context; > + args.size = len; > + rc = __vfs_getxattr(&args); > } > if (rc < 0) { > kfree(context); > diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c > index 4c5e5a438f8b..91e585bd1823 100644 > --- a/security/smack/smack_lsm.c > +++ b/security/smack/smack_lsm.c > @@ -282,25 +282,32 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, > struct dentry *dp) > { > int rc; > - char *buffer; > struct smack_known *skp = NULL; > + struct xattr_gs_args args; > > if (!(ip->i_opflags & IOP_XATTR)) > return ERR_PTR(-EOPNOTSUPP); > > - buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); > - if (buffer == NULL) > + memset(&args, 0, sizeof(args)); > + args.dentry = dp; > + args.inode = ip; > + args.name = name; > + args.buffer = kzalloc(SMK_LONGLABEL, GFP_KERNEL); > + args.size = SMK_LONGLABEL; > + args.flags = XATTR_NOSECURITY; > + > + if (args.buffer == NULL) > return ERR_PTR(-ENOMEM); > > - rc = __vfs_getxattr(dp, ip, name, buffer, SMK_LONGLABEL); > + rc = __vfs_getxattr(&args); > if (rc < 0) > skp = ERR_PTR(rc); > else if (rc == 0) > skp = NULL; > else > - skp = smk_import_entry(buffer, rc); > + skp = smk_import_entry(args.buffer, rc); > > - kfree(buffer); > + kfree(args.buffer); > > return skp; > } > @@ -3424,6 +3431,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) > * Transmuting directory > */ > if (S_ISDIR(inode->i_mode)) { > + struct xattr_gs_args args; > + > /* > * If this is a new directory and the label was > * transmuted when the inode was initialized > @@ -3433,16 +3442,19 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) > * If there is a transmute attribute on the > * directory mark the inode. > */ > + memset(&args, 0, sizeof(args)); > + args.dentry = dp; > + args.inode = inode; > + args.name = XATTR_NAME_SMACKTRANSMUTE; > + args.size = TRANS_TRUE_SIZE; > if (isp->smk_flags & SMK_INODE_CHANGED) { > isp->smk_flags &= ~SMK_INODE_CHANGED; > - rc = __vfs_setxattr(dp, inode, > - XATTR_NAME_SMACKTRANSMUTE, > - TRANS_TRUE, TRANS_TRUE_SIZE, > - 0); > + args.value = TRANS_TRUE; > + rc = __vfs_setxattr(&args); > } else { > - rc = __vfs_getxattr(dp, inode, > - XATTR_NAME_SMACKTRANSMUTE, trattr, > - TRANS_TRUE_SIZE); > + args.buffer = trattr; > + args.flags = XATTR_NOSECURITY; > + rc = __vfs_getxattr(&args); > if (rc >= 0 && strncmp(trattr, TRANS_TRUE, > TRANS_TRUE_SIZE) != 0) > rc = -EINVAL; > -- > 2.23.0.187.g17f5b7556c-goog >