diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 603cce85764f2587ef07a468989256b229ce160c..0db165ee43405fccbcc044c5c56606e145503d92 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -3463,7 +3463,7 @@ static int btrfs_uuid_scan_kthread(void *data) int slot; struct btrfs_root_item root_item; u32 item_size; - struct btrfs_trans_handle *trans; + struct btrfs_trans_handle *trans = NULL; path = btrfs_alloc_path(); if (!path) { @@ -3501,13 +3501,18 @@ static int btrfs_uuid_scan_kthread(void *data) if (item_size < sizeof(root_item)) goto skip; - trans = NULL; read_extent_buffer(eb, &root_item, btrfs_item_ptr_offset(eb, slot), (int)sizeof(root_item)); if (btrfs_root_refs(&root_item) == 0) goto skip; - if (!btrfs_is_empty_uuid(root_item.uuid)) { + + if (!btrfs_is_empty_uuid(root_item.uuid) || + !btrfs_is_empty_uuid(root_item.received_uuid)) { + if (trans) + goto update_tree; + + btrfs_release_path(path); /* * 1 - subvol uuid item * 1 - received_subvol uuid item @@ -3517,6 +3522,12 @@ static int btrfs_uuid_scan_kthread(void *data) ret = PTR_ERR(trans); break; } + continue; + } else { + goto skip; + } +update_tree: + if (!btrfs_is_empty_uuid(root_item.uuid)) { ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, root_item.uuid, BTRFS_UUID_KEY_SUBVOL, @@ -3524,22 +3535,11 @@ static int btrfs_uuid_scan_kthread(void *data) if (ret < 0) { pr_warn("btrfs: uuid_tree_add failed %d\n", ret); - btrfs_end_transaction(trans, - fs_info->uuid_root); break; } } if (!btrfs_is_empty_uuid(root_item.received_uuid)) { - if (!trans) { - /* 1 - received_subvol uuid item */ - trans = btrfs_start_transaction( - fs_info->uuid_root, 1); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - break; - } - } ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, root_item.received_uuid, BTRFS_UUID_KEY_RECEIVED_SUBVOL, @@ -3547,19 +3547,18 @@ static int btrfs_uuid_scan_kthread(void *data) if (ret < 0) { pr_warn("btrfs: uuid_tree_add failed %d\n", ret); - btrfs_end_transaction(trans, - fs_info->uuid_root); break; } } +skip: if (trans) { ret = btrfs_end_transaction(trans, fs_info->uuid_root); + trans = NULL; if (ret) break; } -skip: btrfs_release_path(path); if (key.offset < (u64)-1) { key.offset++; @@ -3578,6 +3577,8 @@ static int btrfs_uuid_scan_kthread(void *data) out: btrfs_free_path(path); + if (trans && !IS_ERR(trans)) + btrfs_end_transaction(trans, fs_info->uuid_root); if (ret) pr_warn("btrfs: btrfs_uuid_scan_kthread failed %d\n", ret); else