summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2013-12-17 15:07:20 +0100
committerChris Mason <clm@fb.com>2014-01-28 13:20:04 -0800
commit66ef7d65c3fc6e5300b9359f1c6537efb23781bb (patch)
treeeaba562491ad69b90c542a7e9854c62730ade7d0
parent41ce9970a8a6a362ae8df145f7a03d789e9ef9d2 (diff)
downloadlinux-66ef7d65c3fc6e5300b9359f1c6537efb23781bb.tar.gz
linux-66ef7d65c3fc6e5300b9359f1c6537efb23781bb.tar.bz2
linux-66ef7d65c3fc6e5300b9359f1c6537efb23781bb.zip
btrfs: check balance of send_in_progress
Warn if the balance goes below zero, which appears to be unlikely though. Otherwise cleans up the code a bit. Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/send.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 78a43b2e5c8e..8877adc45394 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -4725,6 +4725,21 @@ out:
return ret;
}
+static void btrfs_root_dec_send_in_progress(struct btrfs_root* root)
+{
+ spin_lock(&root->root_item_lock);
+ root->send_in_progress--;
+ /*
+ * Not much left to do, we don't know why it's unbalanced and
+ * can't blindly reset it to 0.
+ */
+ if (root->send_in_progress < 0)
+ btrfs_err(root->fs_info,
+ "send_in_progres unbalanced %d root %llu\n",
+ root->send_in_progress, root->root_key.objectid);
+ spin_unlock(&root->root_item_lock);
+}
+
long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
{
int ret = 0;
@@ -4942,24 +4957,11 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)
}
out:
- for (i = 0; sctx && i < clone_sources_to_rollback; i++) {
- struct btrfs_root *r = sctx->clone_roots[i].root;
-
- spin_lock(&r->root_item_lock);
- r->send_in_progress--;
- spin_unlock(&r->root_item_lock);
- }
- if (sctx && !IS_ERR_OR_NULL(sctx->parent_root)) {
- struct btrfs_root *r = sctx->parent_root;
-
- spin_lock(&r->root_item_lock);
- r->send_in_progress--;
- spin_unlock(&r->root_item_lock);
- }
-
- spin_lock(&send_root->root_item_lock);
- send_root->send_in_progress--;
- spin_unlock(&send_root->root_item_lock);
+ for (i = 0; sctx && i < clone_sources_to_rollback; i++)
+ btrfs_root_dec_send_in_progress(sctx->clone_roots[i].root);
+ if (sctx && !IS_ERR_OR_NULL(sctx->parent_root))
+ btrfs_root_dec_send_in_progress(sctx->parent_root);
+ btrfs_root_dec_send_in_progress(send_root);
kfree(arg);
vfree(clone_sources_tmp);