diff options
| -rw-r--r-- | fs/btrfs/ioctl.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 4482cf35522e..80fe3c654612 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -2928,8 +2928,14 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) | |||
| 2928 | ret = btrfs_defrag_root(root); | 2928 | ret = btrfs_defrag_root(root); |
| 2929 | break; | 2929 | break; |
| 2930 | case S_IFREG: | 2930 | case S_IFREG: |
| 2931 | if (!(file->f_mode & FMODE_WRITE)) { | 2931 | /* |
| 2932 | ret = -EINVAL; | 2932 | * Note that this does not check the file descriptor for write |
| 2933 | * access. This prevents defragmenting executables that are | ||
| 2934 | * running and allows defrag on files open in read-only mode. | ||
| 2935 | */ | ||
| 2936 | if (!capable(CAP_SYS_ADMIN) && | ||
| 2937 | inode_permission(inode, MAY_WRITE)) { | ||
| 2938 | ret = -EPERM; | ||
| 2933 | goto out; | 2939 | goto out; |
| 2934 | } | 2940 | } |
| 2935 | 2941 | ||
