summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/qgroup.c
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2013-05-06 19:14:17 +0000
committerJosef Bacik <jbacik@fusionio.com>2013-06-14 11:29:22 -0400
commit57254b6ebce4ceca02d9c8b615f6059c56c19238 (patch)
treea90b04313e8671e6846d09c0c14c7b08e16d0e65 /fs/btrfs/qgroup.c
parent1e8f915868c59be4d6e49d9aff928454a5d5d569 (diff)
downloadlinux-57254b6ebce4ceca02d9c8b615f6059c56c19238.tar.bz2
Btrfs: add ioctl to wait for qgroup rescan completion
btrfs_qgroup_wait_for_completion waits until the currently running qgroup operation completes. It returns immediately when no rescan process is in progress. This is useful to automate things around the rescan process (e.g. testing). Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/qgroup.c')
-rw-r--r--fs/btrfs/qgroup.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 7f38cce2528d..d059d86c3131 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2070,6 +2070,8 @@ out:
} else {
pr_err("btrfs: qgroup scan failed with %d\n", err);
}
+
+ complete_all(&fs_info->qgroup_rescan_completion);
}
static void
@@ -2110,6 +2112,7 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_RESCAN;
memset(&fs_info->qgroup_rescan_progress, 0,
sizeof(fs_info->qgroup_rescan_progress));
+ init_completion(&fs_info->qgroup_rescan_completion);
/* clear all current qgroup tracking information */
for (n = rb_first(&fs_info->qgroup_tree); n; n = rb_next(n)) {
@@ -2126,3 +2129,21 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
return 0;
}
+
+int btrfs_qgroup_wait_for_completion(struct btrfs_fs_info *fs_info)
+{
+ int running;
+ int ret = 0;
+
+ mutex_lock(&fs_info->qgroup_rescan_lock);
+ spin_lock(&fs_info->qgroup_lock);
+ running = fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_RESCAN;
+ spin_unlock(&fs_info->qgroup_lock);
+ mutex_unlock(&fs_info->qgroup_rescan_lock);
+
+ if (running)
+ ret = wait_for_completion_interruptible(
+ &fs_info->qgroup_rescan_completion);
+
+ return ret;
+}