mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-16 02:14:58 +00:00
btrfs: send: check for read-only send root under critical section
We're checking if the send root is read-only without being under the protection of the root's root_item_lock spinlock, which is what protects the root's flags when clearing the read-only flag, done at btrfs_ioctl_subvol_setflags(). Furthermore, it should be done in the same critical section that increments the root's send_in_progress counter, as btrfs_ioctl_subvol_setflags() clears the read-only flag in the same critical section that checks the counter's value. So fix this by moving the read-only check under the critical section delimited by the root's root_item_lock which also increments the root's send_in_progress counter. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
dc058f5fda
commit
e82c936293
@ -8133,7 +8133,12 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
|
|||||||
spin_unlock(&send_root->root_item_lock);
|
spin_unlock(&send_root->root_item_lock);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
if (btrfs_root_readonly(send_root) && send_root->dedupe_in_progress) {
|
/* Userspace tools do the checks and warn the user if it's not RO. */
|
||||||
|
if (!btrfs_root_readonly(send_root)) {
|
||||||
|
spin_unlock(&send_root->root_item_lock);
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
if (send_root->dedupe_in_progress) {
|
||||||
dedupe_in_progress_warn(send_root);
|
dedupe_in_progress_warn(send_root);
|
||||||
spin_unlock(&send_root->root_item_lock);
|
spin_unlock(&send_root->root_item_lock);
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@ -8141,15 +8146,6 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
|
|||||||
send_root->send_in_progress++;
|
send_root->send_in_progress++;
|
||||||
spin_unlock(&send_root->root_item_lock);
|
spin_unlock(&send_root->root_item_lock);
|
||||||
|
|
||||||
/*
|
|
||||||
* Userspace tools do the checks and warn the user if it's
|
|
||||||
* not RO.
|
|
||||||
*/
|
|
||||||
if (!btrfs_root_readonly(send_root)) {
|
|
||||||
ret = -EPERM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that we don't overflow at later allocations, we request
|
* Check that we don't overflow at later allocations, we request
|
||||||
* clone_sources_count + 1 items, and compare to unsigned long inside
|
* clone_sources_count + 1 items, and compare to unsigned long inside
|
||||||
|
Loading…
x
Reference in New Issue
Block a user