Skip to content

Commit

Permalink
btrfs: send: check for read-only send root under critical section
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
fdmanana authored and kdave committed Nov 11, 2024
1 parent dc058f5 commit e82c936
Showing 1 changed file with 6 additions and 10 deletions.
16 changes: 6 additions & 10 deletions fs/btrfs/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -8133,23 +8133,19 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
spin_unlock(&send_root->root_item_lock);
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);
spin_unlock(&send_root->root_item_lock);
return -EAGAIN;
}
send_root->send_in_progress++;
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
* clone_sources_count + 1 items, and compare to unsigned long inside
Expand Down

0 comments on commit e82c936

Please sign in to comment.