diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ioctl.c | 51 |
1 files changed, 13 insertions, 38 deletions
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 74648d42c69b..442f7ef873fc 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -312,16 +312,9 @@ static int ext4_ioctl_setflags(struct inode *inode, /* The JOURNAL_DATA flag is modifiable only by root */ jflag = flags & EXT4_JOURNAL_DATA_FL; - /* - * The IMMUTABLE and APPEND_ONLY flags can only be changed by - * the relevant capability. - * - * This test looks nicer. Thanks to Pauline Middelink - */ - if ((flags ^ oldflags) & (EXT4_APPEND_FL | EXT4_IMMUTABLE_FL)) { - if (!capable(CAP_LINUX_IMMUTABLE)) - goto flags_out; - } + err = vfs_ioc_setflags_prepare(inode, oldflags, flags); + if (err) + goto flags_out; /* * The JOURNAL_DATA flag can only be changed by @@ -741,28 +734,15 @@ group_add_out: return err; } -static int ext4_ioctl_check_project(struct inode *inode, struct fsxattr *fa) +static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa) { - /* - * Project Quota ID state is only allowed to change from within the init - * namespace. Enforce that restriction only if we are trying to change - * the quota ID state. Everything else is allowed in user namespaces. - */ - if (current_user_ns() == &init_user_ns) - return 0; - - if (__kprojid_val(EXT4_I(inode)->i_projid) != fa->fsx_projid) - return -EINVAL; + struct ext4_inode_info *ei = EXT4_I(inode); - if (ext4_test_inode_flag(inode, EXT4_INODE_PROJINHERIT)) { - if (!(fa->fsx_xflags & FS_XFLAG_PROJINHERIT)) - return -EINVAL; - } else { - if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT) - return -EINVAL; - } + simple_fill_fsxattr(fa, ext4_iflags_to_xflags(ei->i_flags & + EXT4_FL_USER_VISIBLE)); - return 0; + if (ext4_has_feature_project(inode->i_sb)) + fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid); } long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) @@ -1139,13 +1119,7 @@ resizefs_out: { struct fsxattr fa; - memset(&fa, 0, sizeof(struct fsxattr)); - fa.fsx_xflags = ext4_iflags_to_xflags(ei->i_flags & EXT4_FL_USER_VISIBLE); - - if (ext4_has_feature_project(inode->i_sb)) { - fa.fsx_projid = (__u32)from_kprojid(&init_user_ns, - EXT4_I(inode)->i_projid); - } + ext4_fill_fsxattr(inode, &fa); if (copy_to_user((struct fsxattr __user *)arg, &fa, sizeof(fa))) @@ -1154,7 +1128,7 @@ resizefs_out: } case EXT4_IOC_FSSETXATTR: { - struct fsxattr fa; + struct fsxattr fa, old_fa; int err; if (copy_from_user(&fa, (struct fsxattr __user *)arg, @@ -1177,7 +1151,8 @@ resizefs_out: return err; inode_lock(inode); - err = ext4_ioctl_check_project(inode, &fa); + ext4_fill_fsxattr(inode, &old_fa); + err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); if (err) goto out; flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) | |