summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ioctl32.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2020-02-26 17:30:31 -0800
committerDarrick J. Wong <darrick.wong@oracle.com>2020-03-02 20:55:52 -0800
commitd0ce643911280a0f281156674203a2ca8048aed1 (patch)
tree307b78f0980a4d12828468503ec8fa94b653ab3e /fs/xfs/xfs_ioctl32.c
parent2282a9e65177b425aaab4d8228f98f5c09fc778a (diff)
downloadlinux-d0ce643911280a0f281156674203a2ca8048aed1.tar.gz
linux-d0ce643911280a0f281156674203a2ca8048aed1.tar.bz2
linux-d0ce643911280a0f281156674203a2ca8048aed1.zip
xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op
Add a new helper to handle a single attr multi ioctl operation that can be shared between the native and compat ioctl implementation. There is a slight change in behaviour in that we don't break out of the loop when copying in the attribute name fails. The previous behaviour was rather inconsistent here as it continued for any other kind of error, and that we don't clear the flags in the structure returned to userspace, a behavior only introduced as a bug fix in the last merge window. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_ioctl32.c')
-rw-r--r--fs/xfs/xfs_ioctl32.c50
1 files changed, 5 insertions, 45 deletions
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 936c2f62fb6c..e1daf095c585 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -418,7 +418,6 @@ xfs_compat_attrmulti_by_handle(
compat_xfs_fsop_attrmulti_handlereq_t am_hreq;
struct dentry *dentry;
unsigned int i, size;
- unsigned char *attr_name;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
@@ -447,50 +446,11 @@ xfs_compat_attrmulti_by_handle(
error = 0;
for (i = 0; i < am_hreq.opcount; i++) {
- if ((ops[i].am_flags & ATTR_ROOT) &&
- (ops[i].am_flags & ATTR_SECURE)) {
- ops[i].am_error = -EINVAL;
- continue;
- }
- ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
-
- attr_name = strndup_user(compat_ptr(ops[i].am_attrname),
- MAXNAMELEN);
- if (IS_ERR(attr_name)) {
- ops[i].am_error = PTR_ERR(attr_name);
- break;
- }
-
- switch (ops[i].am_opcode) {
- case ATTR_OP_GET:
- ops[i].am_error = xfs_attrmulti_attr_get(
- d_inode(dentry), attr_name,
- compat_ptr(ops[i].am_attrvalue),
- &ops[i].am_length, ops[i].am_flags);
- break;
- case ATTR_OP_SET:
- ops[i].am_error = mnt_want_write_file(parfilp);
- if (ops[i].am_error)
- break;
- ops[i].am_error = xfs_attrmulti_attr_set(
- d_inode(dentry), attr_name,
- compat_ptr(ops[i].am_attrvalue),
- ops[i].am_length, ops[i].am_flags);
- mnt_drop_write_file(parfilp);
- break;
- case ATTR_OP_REMOVE:
- ops[i].am_error = mnt_want_write_file(parfilp);
- if (ops[i].am_error)
- break;
- ops[i].am_error = xfs_attrmulti_attr_set(
- d_inode(dentry), attr_name, NULL, 0,
- ops[i].am_flags);
- mnt_drop_write_file(parfilp);
- break;
- default:
- ops[i].am_error = -EINVAL;
- }
- kfree(attr_name);
+ ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
+ d_inode(dentry), ops[i].am_opcode,
+ compat_ptr(ops[i].am_attrname),
+ compat_ptr(ops[i].am_attrvalue),
+ &ops[i].am_length, ops[i].am_flags);
}
if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))