|
@@ -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 @@ skip:
|
|
|
|
|
|
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
|