All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] btrfs: some fixes around check send root flags
@ 2024-11-06 11:50 fdmanana
  2024-11-06 11:50 ` [PATCH 1/2] btrfs: send: check for dead send root under critical section fdmanana
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: fdmanana @ 2024-11-06 11:50 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

Do proper checks for dead and read-only send roots while under the
protection of the necessary lock. More details in the change logs.

Filipe Manana (2):
  btrfs: send: check for dead send root under critical section
  btrfs: send: check for read-only send root under critical section

 fs/btrfs/send.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

-- 
2.45.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] btrfs: send: check for dead send root under critical section
  2024-11-06 11:50 [PATCH 0/2] btrfs: some fixes around check send root flags fdmanana
@ 2024-11-06 11:50 ` fdmanana
  2024-11-06 11:50 ` [PATCH 2/2] btrfs: send: check for read-only " fdmanana
  2024-11-06 18:31 ` [PATCH 0/2] btrfs: some fixes around check send root flags David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: fdmanana @ 2024-11-06 11:50 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

We're checking if the send root is dead without the protection of the
root's root_item_lock spinlock, which is what protects the root's flags.
The inverse, setting the dead flag on a root, is done under the protection
of that lock, at btrfs_delete_subvolume(). Also checking and updating the
root's send_in_progress counter is supposed to be done in the same
critical section as checking for or setting the root dead flag, so that
these operations are done atomically as a single step (which is correctly
done by btrfs_delete_subvolume()).

So fix this by checking if the send root is dead in the same critical
section that updates the send_in_progress counter, which is protected by
the root's root_item_lock spinlock.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index cadb945bb345..3fcc8113641d 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -8125,6 +8125,14 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 	 * making it RW. This also protects against deletion.
 	 */
 	spin_lock(&send_root->root_item_lock);
+	/*
+	 * Unlikely but possible, if the subvolume is marked for deletion but
+	 * is slow to remove the directory entry, send can still be started.
+	 */
+	if (btrfs_root_dead(send_root)) {
+		spin_unlock(&send_root->root_item_lock);
+		return -EPERM;
+	}
 	if (btrfs_root_readonly(send_root) && send_root->dedupe_in_progress) {
 		dedupe_in_progress_warn(send_root);
 		spin_unlock(&send_root->root_item_lock);
@@ -8207,15 +8215,6 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 	}
 
 	sctx->send_root = send_root;
-	/*
-	 * Unlikely but possible, if the subvolume is marked for deletion but
-	 * is slow to remove the directory entry, send can still be started
-	 */
-	if (btrfs_root_dead(sctx->send_root)) {
-		ret = -EPERM;
-		goto out;
-	}
-
 	sctx->clone_roots_cnt = arg->clone_sources_count;
 
 	if (sctx->proto >= 2) {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] btrfs: send: check for read-only send root under critical section
  2024-11-06 11:50 [PATCH 0/2] btrfs: some fixes around check send root flags fdmanana
  2024-11-06 11:50 ` [PATCH 1/2] btrfs: send: check for dead send root under critical section fdmanana
@ 2024-11-06 11:50 ` fdmanana
  2024-11-06 18:31 ` [PATCH 0/2] btrfs: some fixes around check send root flags David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: fdmanana @ 2024-11-06 11:50 UTC (permalink / raw)
  To: linux-btrfs

From: Filipe Manana <fdmanana@suse.com>

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>
---
 fs/btrfs/send.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 3fcc8113641d..7254279c3cc9 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -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);
 		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;
@@ -8141,15 +8146,6 @@ long btrfs_ioctl_send(struct btrfs_inode *inode, const struct btrfs_ioctl_send_a
 	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
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] btrfs: some fixes around check send root flags
  2024-11-06 11:50 [PATCH 0/2] btrfs: some fixes around check send root flags fdmanana
  2024-11-06 11:50 ` [PATCH 1/2] btrfs: send: check for dead send root under critical section fdmanana
  2024-11-06 11:50 ` [PATCH 2/2] btrfs: send: check for read-only " fdmanana
@ 2024-11-06 18:31 ` David Sterba
  2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2024-11-06 18:31 UTC (permalink / raw)
  To: fdmanana; +Cc: linux-btrfs

On Wed, Nov 06, 2024 at 11:50:44AM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
> 
> Do proper checks for dead and read-only send roots while under the
> protection of the necessary lock. More details in the change logs.
> 
> Filipe Manana (2):
>   btrfs: send: check for dead send root under critical section
>   btrfs: send: check for read-only send root under critical section

Reviewed-by: David Sterba <dsterba@suse.com>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-11-06 18:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-06 11:50 [PATCH 0/2] btrfs: some fixes around check send root flags fdmanana
2024-11-06 11:50 ` [PATCH 1/2] btrfs: send: check for dead send root under critical section fdmanana
2024-11-06 11:50 ` [PATCH 2/2] btrfs: send: check for read-only " fdmanana
2024-11-06 18:31 ` [PATCH 0/2] btrfs: some fixes around check send root flags David Sterba

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.