Commit 616d374e authored by Adam Borowski's avatar Adam Borowski Committed by David Sterba

btrfs: allow defrag on a file opened read-only that has rw permissions

Requiring a read-write descriptor conflicts both ways with exec,
returning ETXTBSY whenever you try to defrag a program that's currently
being run, or causing intermittent exec failures on a live system being
defragged.

As defrag doesn't change the file's contents in any way, there's no
reason to consider it a rw operation.  Thus, let's check only whether
the file could have been opened rw.  Such access control is still needed
as currently defrag can use extra disk space, and might trigger bugs.

We return EINVAL when the request is invalid; here it's ok but merely
the user has insufficient privileges.  Thus, the EPERM return value
reflects the error better -- as discussed in the identical case for
dedupe.

According to codesearch.debian.net, no userspace program distinguishes
these values beyond strerror().
Signed-off-by: default avatarAdam Borowski <kilobyte@angband.pl>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
[ fold the EPERM patch from Adam ]
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 3c427693
...@@ -2928,8 +2928,14 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) ...@@ -2928,8 +2928,14 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
ret = btrfs_defrag_root(root); ret = btrfs_defrag_root(root);
break; break;
case S_IFREG: case S_IFREG:
if (!(file->f_mode & FMODE_WRITE)) { /*
ret = -EINVAL; * Note that this does not check the file descriptor for write
* access. This prevents defragmenting executables that are
* running and allows defrag on files open in read-only mode.
*/
if (!capable(CAP_SYS_ADMIN) &&
inode_permission(inode, MAY_WRITE)) {
ret = -EPERM;
goto out; goto out;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment