aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2020-02-14 15:02:56 -0500
committerJosef Bacik <josef@toxicpanda.com>2020-02-14 15:02:56 -0500
commit55aaa556e8f6a69064b17ca9abc02d52c48d5638 (patch)
tree52a1fd9f48feb7124858172da25570574943c6e1
parent03e6ada7b55eefbf3fbdf3999c9db2bb79318963 (diff)
downloadbtrfs-next-55aaa556e8f6a69064b17ca9abc02d52c48d5638.tar.gz
btrfs: bail out of uuid tree scanning if we're closing
In doing my fsstress+EIO stress testing I started running into issues where umount would get stuck forever because the uuid checker was chewing through the thousands of subvolumes I had created. We shouldn't block umount on this, simply bail if we're unmounting the fs. We need to make sure we don't mark the UUID tree as ok, so we only set that bit if we made it through the whole rescan operation, but otherwise this is completely safe. Signed-off-by: Josef Bacik <josef@toxicpanda.com>
-rw-r--r--fs/btrfs/uuid-tree.c4
-rw-r--r--fs/btrfs/volumes.c11
2 files changed, 13 insertions, 2 deletions
diff --git a/fs/btrfs/uuid-tree.c b/fs/btrfs/uuid-tree.c
index 76b84f2397b1bc..30078b74220efb 100644
--- a/fs/btrfs/uuid-tree.c
+++ b/fs/btrfs/uuid-tree.c
@@ -278,6 +278,10 @@ again_search_slot:
}
while (1) {
+ if (btrfs_fs_closing(fs_info)) {
+ ret = -EINTR;
+ goto out;
+ }
cond_resched();
leaf = path->nodes[0];
slot = path->slots[0];
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 387f80656476cf..e40adf38ae5ceb 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4286,6 +4286,7 @@ static int btrfs_uuid_scan_kthread(void *data)
struct btrfs_root_item root_item;
u32 item_size;
struct btrfs_trans_handle *trans = NULL;
+ bool closing = false;
path = btrfs_alloc_path();
if (!path) {
@@ -4298,6 +4299,10 @@ static int btrfs_uuid_scan_kthread(void *data)
key.offset = 0;
while (1) {
+ if (btrfs_fs_closing(fs_info)) {
+ closing = true;
+ break;
+ }
ret = btrfs_search_forward(root, &key, path,
BTRFS_OLDEST_GENERATION);
if (ret) {
@@ -4397,7 +4402,7 @@ out:
btrfs_end_transaction(trans);
if (ret)
btrfs_warn(fs_info, "btrfs_uuid_scan_kthread failed %d", ret);
- else
+ else if (!closing)
set_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags);
up(&fs_info->uuid_tree_rescan_sem);
return 0;
@@ -4460,7 +4465,9 @@ static int btrfs_uuid_rescan_kthread(void *data)
*/
ret = btrfs_uuid_tree_iterate(fs_info, btrfs_check_uuid_tree_entry);
if (ret < 0) {
- btrfs_warn(fs_info, "iterating uuid_tree failed %d", ret);
+ if (ret != -EINTR)
+ btrfs_warn(fs_info, "iterating uuid_tree failed %d",
+ ret);
up(&fs_info->uuid_tree_rescan_sem);
return ret;
}