Merge tag 'vfs-fix-ioctl-checking-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull common SETFLAGS/FSSETXATTR parameter checking from Darrick Wong: "Here's a patch series that sets up common parameter checking functions for the FS_IOC_SETFLAGS and FS_IOC_FSSETXATTR ioctl implementations. The goal here is to reduce the amount of behaviorial variance between the filesystems where those ioctls originated (ext2 and XFS, respectively) and everybody else. - Standardize parameter checking for the SETFLAGS and FSSETXATTR ioctls (which were the file attribute setters for ext4 and xfs and have now been hoisted to the vfs) - Only allow the DAX flag to be set on files and directories" * tag 'vfs-fix-ioctl-checking-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: vfs: only allow FSSETXATTR to set DAX flag on files and dirs vfs: teach vfs_ioc_fssetxattr_check to check extent size hints vfs: teach vfs_ioc_fssetxattr_check to check project id info vfs: create a generic checking function for FS_IOC_FSSETXATTR vfs: create a generic checking and prep function for FS_IOC_SETFLAGS
This commit is contained in:
@@ -357,11 +357,28 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int orangefs_getflags(struct inode *inode, unsigned long *uval)
|
||||
{
|
||||
__u64 val = 0;
|
||||
int ret;
|
||||
|
||||
ret = orangefs_inode_getxattr(inode,
|
||||
"user.pvfs2.meta_hint",
|
||||
&val, sizeof(val));
|
||||
if (ret < 0 && ret != -ENODATA)
|
||||
return ret;
|
||||
else if (ret == -ENODATA)
|
||||
val = 0;
|
||||
*uval = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a miscellaneous operation on a file.
|
||||
*/
|
||||
static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct inode *inode = file_inode(file);
|
||||
int ret = -ENOTTY;
|
||||
__u64 val = 0;
|
||||
unsigned long uval;
|
||||
@@ -375,20 +392,16 @@ static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long ar
|
||||
* and append flags
|
||||
*/
|
||||
if (cmd == FS_IOC_GETFLAGS) {
|
||||
val = 0;
|
||||
ret = orangefs_inode_getxattr(file_inode(file),
|
||||
"user.pvfs2.meta_hint",
|
||||
&val, sizeof(val));
|
||||
if (ret < 0 && ret != -ENODATA)
|
||||
ret = orangefs_getflags(inode, &uval);
|
||||
if (ret)
|
||||
return ret;
|
||||
else if (ret == -ENODATA)
|
||||
val = 0;
|
||||
uval = val;
|
||||
gossip_debug(GOSSIP_FILE_DEBUG,
|
||||
"orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n",
|
||||
(unsigned long long)uval);
|
||||
return put_user(uval, (int __user *)arg);
|
||||
} else if (cmd == FS_IOC_SETFLAGS) {
|
||||
unsigned long old_uval;
|
||||
|
||||
ret = 0;
|
||||
if (get_user(uval, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
@@ -404,11 +417,17 @@ static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long ar
|
||||
gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = orangefs_getflags(inode, &old_uval);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = vfs_ioc_setflags_prepare(inode, old_uval, uval);
|
||||
if (ret)
|
||||
return ret;
|
||||
val = uval;
|
||||
gossip_debug(GOSSIP_FILE_DEBUG,
|
||||
"orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n",
|
||||
(unsigned long long)val);
|
||||
ret = orangefs_inode_setxattr(file_inode(file),
|
||||
ret = orangefs_inode_setxattr(inode,
|
||||
"user.pvfs2.meta_hint",
|
||||
&val, sizeof(val), 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user