diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d3d9b4abb09b..3cd66efdb99d 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -375,9 +375,7 @@ static int btrfs_ioctl_fsgetxattr(struct file *file, void __user *arg) | |||
375 | struct btrfs_inode *binode = BTRFS_I(file_inode(file)); | 375 | struct btrfs_inode *binode = BTRFS_I(file_inode(file)); |
376 | struct fsxattr fa; | 376 | struct fsxattr fa; |
377 | 377 | ||
378 | memset(&fa, 0, sizeof(fa)); | 378 | simple_fill_fsxattr(&fa, btrfs_inode_flags_to_xflags(binode->flags)); |
379 | fa.fsx_xflags = btrfs_inode_flags_to_xflags(binode->flags); | ||
380 | |||
381 | if (copy_to_user(arg, &fa, sizeof(fa))) | 379 | if (copy_to_user(arg, &fa, sizeof(fa))) |
382 | return -EFAULT; | 380 | return -EFAULT; |
383 | 381 | ||
@@ -390,7 +388,7 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg) | |||
390 | struct btrfs_inode *binode = BTRFS_I(inode); | 388 | struct btrfs_inode *binode = BTRFS_I(inode); |
391 | struct btrfs_root *root = binode->root; | 389 | struct btrfs_root *root = binode->root; |
392 | struct btrfs_trans_handle *trans; | 390 | struct btrfs_trans_handle *trans; |
393 | struct fsxattr fa; | 391 | struct fsxattr fa, old_fa; |
394 | unsigned old_flags; | 392 | unsigned old_flags; |
395 | unsigned old_i_flags; | 393 | unsigned old_i_flags; |
396 | int ret = 0; | 394 | int ret = 0; |
@@ -401,7 +399,6 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg) | |||
401 | if (btrfs_root_readonly(root)) | 399 | if (btrfs_root_readonly(root)) |
402 | return -EROFS; | 400 | return -EROFS; |
403 | 401 | ||
404 | memset(&fa, 0, sizeof(fa)); | ||
405 | if (copy_from_user(&fa, arg, sizeof(fa))) | 402 | if (copy_from_user(&fa, arg, sizeof(fa))) |
406 | return -EFAULT; | 403 | return -EFAULT; |
407 | 404 | ||
@@ -421,13 +418,11 @@ static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg) | |||
421 | old_flags = binode->flags; | 418 | old_flags = binode->flags; |
422 | old_i_flags = inode->i_flags; | 419 | old_i_flags = inode->i_flags; |
423 | 420 | ||
424 | /* We need the capabilities to change append-only or immutable inode */ | 421 | simple_fill_fsxattr(&old_fa, |
425 | if (((old_flags & (BTRFS_INODE_APPEND | BTRFS_INODE_IMMUTABLE)) || | 422 | btrfs_inode_flags_to_xflags(binode->flags)); |
426 | (fa.fsx_xflags & (FS_XFLAG_APPEND | FS_XFLAG_IMMUTABLE))) && | 423 | ret = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); |
427 | !capable(CAP_LINUX_IMMUTABLE)) { | 424 | if (ret) |
428 | ret = -EPERM; | ||
429 | goto out_unlock; | 425 | goto out_unlock; |
430 | } | ||
431 | 426 | ||
432 | if (fa.fsx_xflags & FS_XFLAG_SYNC) | 427 | if (fa.fsx_xflags & FS_XFLAG_SYNC) |
433 | binode->flags |= BTRFS_INODE_SYNC; | 428 | binode->flags |= BTRFS_INODE_SYNC; |