59 lines
2.1 KiB
Diff
59 lines
2.1 KiB
Diff
From: Filipe Manana <fdmanana@suse.com>
|
|
Date: Mon, 2 Mar 2015 20:53:53 +0000
|
|
Subject: [PATCH] Btrfs: send, don't leave without decrementing clone root's
|
|
send_progress
|
|
|
|
If the clone root was not readonly or the dead flag was set on it, we were
|
|
leaving without decrementing the root's send_progress counter (and before
|
|
we just incremented it). If a concurrent snapshot deletion was in progress
|
|
and ended up being aborted, it would be impossible to later attempt to
|
|
delete again the snapshot, since the root's send_in_progress counter could
|
|
never go back to 0.
|
|
|
|
We were also setting clone_sources_to_rollback to i + 1 too early - if we
|
|
bailed out because the clone root we got is not readonly or flagged as dead
|
|
we ended up later derreferencing a null pointer because we didn't assign
|
|
the clone root to sctx->clone_roots[i].root:
|
|
|
|
for (i = 0; sctx && i < clone_sources_to_rollback; i++)
|
|
btrfs_root_dec_send_in_progress(
|
|
sctx->clone_roots[i].root);
|
|
|
|
So just don't increment the send_in_progress counter if the root is readonly
|
|
or flagged as dead.
|
|
|
|
Signed-off-by: Filipe Manana <fdmanana@suse.com>
|
|
Reviewed-by: David Sterba <dsterba@suse.cz>
|
|
Signed-off-by: Chris Mason <clm@fb.com>
|
|
---
|
|
fs/btrfs/send.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
|
|
index 6ec28f13659e..571de5a08fe7 100644
|
|
--- a/fs/btrfs/send.c
|
|
+++ b/fs/btrfs/send.c
|
|
@@ -5852,9 +5852,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
|
|
ret = PTR_ERR(clone_root);
|
|
goto out;
|
|
}
|
|
- clone_sources_to_rollback = i + 1;
|
|
spin_lock(&clone_root->root_item_lock);
|
|
- clone_root->send_in_progress++;
|
|
if (!btrfs_root_readonly(clone_root) ||
|
|
btrfs_root_dead(clone_root)) {
|
|
spin_unlock(&clone_root->root_item_lock);
|
|
@@ -5862,10 +5860,12 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
|
|
ret = -EPERM;
|
|
goto out;
|
|
}
|
|
+ clone_root->send_in_progress++;
|
|
spin_unlock(&clone_root->root_item_lock);
|
|
srcu_read_unlock(&fs_info->subvol_srcu, index);
|
|
|
|
sctx->clone_roots[i].root = clone_root;
|
|
+ clone_sources_to_rollback = i + 1;
|
|
}
|
|
vfree(clone_sources_tmp);
|
|
clone_sources_tmp = NULL;
|