diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 603cce85764f..0db165ee4340 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -3463,7 +3463,7 @@ static int btrfs_uuid_scan_kthread(void *data) | |||
3463 | int slot; | 3463 | int slot; |
3464 | struct btrfs_root_item root_item; | 3464 | struct btrfs_root_item root_item; |
3465 | u32 item_size; | 3465 | u32 item_size; |
3466 | struct btrfs_trans_handle *trans; | 3466 | struct btrfs_trans_handle *trans = NULL; |
3467 | 3467 | ||
3468 | path = btrfs_alloc_path(); | 3468 | path = btrfs_alloc_path(); |
3469 | if (!path) { | 3469 | if (!path) { |
@@ -3501,13 +3501,18 @@ static int btrfs_uuid_scan_kthread(void *data) | |||
3501 | if (item_size < sizeof(root_item)) | 3501 | if (item_size < sizeof(root_item)) |
3502 | goto skip; | 3502 | goto skip; |
3503 | 3503 | ||
3504 | trans = NULL; | ||
3505 | read_extent_buffer(eb, &root_item, | 3504 | read_extent_buffer(eb, &root_item, |
3506 | btrfs_item_ptr_offset(eb, slot), | 3505 | btrfs_item_ptr_offset(eb, slot), |
3507 | (int)sizeof(root_item)); | 3506 | (int)sizeof(root_item)); |
3508 | if (btrfs_root_refs(&root_item) == 0) | 3507 | if (btrfs_root_refs(&root_item) == 0) |
3509 | goto skip; | 3508 | goto skip; |
3510 | if (!btrfs_is_empty_uuid(root_item.uuid)) { | 3509 | |
3510 | if (!btrfs_is_empty_uuid(root_item.uuid) || | ||
3511 | !btrfs_is_empty_uuid(root_item.received_uuid)) { | ||
3512 | if (trans) | ||
3513 | goto update_tree; | ||
3514 | |||
3515 | btrfs_release_path(path); | ||
3511 | /* | 3516 | /* |
3512 | * 1 - subvol uuid item | 3517 | * 1 - subvol uuid item |
3513 | * 1 - received_subvol uuid item | 3518 | * 1 - received_subvol uuid item |
@@ -3517,6 +3522,12 @@ static int btrfs_uuid_scan_kthread(void *data) | |||
3517 | ret = PTR_ERR(trans); | 3522 | ret = PTR_ERR(trans); |
3518 | break; | 3523 | break; |
3519 | } | 3524 | } |
3525 | continue; | ||
3526 | } else { | ||
3527 | goto skip; | ||
3528 | } | ||
3529 | update_tree: | ||
3530 | if (!btrfs_is_empty_uuid(root_item.uuid)) { | ||
3520 | ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, | 3531 | ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, |
3521 | root_item.uuid, | 3532 | root_item.uuid, |
3522 | BTRFS_UUID_KEY_SUBVOL, | 3533 | BTRFS_UUID_KEY_SUBVOL, |
@@ -3524,22 +3535,11 @@ static int btrfs_uuid_scan_kthread(void *data) | |||
3524 | if (ret < 0) { | 3535 | if (ret < 0) { |
3525 | pr_warn("btrfs: uuid_tree_add failed %d\n", | 3536 | pr_warn("btrfs: uuid_tree_add failed %d\n", |
3526 | ret); | 3537 | ret); |
3527 | btrfs_end_transaction(trans, | ||
3528 | fs_info->uuid_root); | ||
3529 | break; | 3538 | break; |
3530 | } | 3539 | } |
3531 | } | 3540 | } |
3532 | 3541 | ||
3533 | if (!btrfs_is_empty_uuid(root_item.received_uuid)) { | 3542 | if (!btrfs_is_empty_uuid(root_item.received_uuid)) { |
3534 | if (!trans) { | ||
3535 | /* 1 - received_subvol uuid item */ | ||
3536 | trans = btrfs_start_transaction( | ||
3537 | fs_info->uuid_root, 1); | ||
3538 | if (IS_ERR(trans)) { | ||
3539 | ret = PTR_ERR(trans); | ||
3540 | break; | ||
3541 | } | ||
3542 | } | ||
3543 | ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, | 3543 | ret = btrfs_uuid_tree_add(trans, fs_info->uuid_root, |
3544 | root_item.received_uuid, | 3544 | root_item.received_uuid, |
3545 | BTRFS_UUID_KEY_RECEIVED_SUBVOL, | 3545 | BTRFS_UUID_KEY_RECEIVED_SUBVOL, |
@@ -3547,19 +3547,18 @@ static int btrfs_uuid_scan_kthread(void *data) | |||
3547 | if (ret < 0) { | 3547 | if (ret < 0) { |
3548 | pr_warn("btrfs: uuid_tree_add failed %d\n", | 3548 | pr_warn("btrfs: uuid_tree_add failed %d\n", |
3549 | ret); | 3549 | ret); |
3550 | btrfs_end_transaction(trans, | ||
3551 | fs_info->uuid_root); | ||
3552 | break; | 3550 | break; |
3553 | } | 3551 | } |
3554 | } | 3552 | } |
3555 | 3553 | ||
3554 | skip: | ||
3556 | if (trans) { | 3555 | if (trans) { |
3557 | ret = btrfs_end_transaction(trans, fs_info->uuid_root); | 3556 | ret = btrfs_end_transaction(trans, fs_info->uuid_root); |
3557 | trans = NULL; | ||
3558 | if (ret) | 3558 | if (ret) |
3559 | break; | 3559 | break; |
3560 | } | 3560 | } |
3561 | 3561 | ||
3562 | skip: | ||
3563 | btrfs_release_path(path); | 3562 | btrfs_release_path(path); |
3564 | if (key.offset < (u64)-1) { | 3563 | if (key.offset < (u64)-1) { |
3565 | key.offset++; | 3564 | key.offset++; |
@@ -3578,6 +3577,8 @@ skip: | |||
3578 | 3577 | ||
3579 | out: | 3578 | out: |
3580 | btrfs_free_path(path); | 3579 | btrfs_free_path(path); |
3580 | if (trans && !IS_ERR(trans)) | ||
3581 | btrfs_end_transaction(trans, fs_info->uuid_root); | ||
3581 | if (ret) | 3582 | if (ret) |
3582 | pr_warn("btrfs: btrfs_uuid_scan_kthread failed %d\n", ret); | 3583 | pr_warn("btrfs: btrfs_uuid_scan_kthread failed %d\n", ret); |
3583 | else | 3584 | else |