Btrfs: do not add replace target to the alloc_list
[deliverable/linux.git] / fs / btrfs / volumes.c
index 74614e3b5ad3a69349e695a96c2fd8933fe84237..a0577352eb6e962743adf9712c230604b409627f 100644 (file)
@@ -673,6 +673,8 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 
                if (device->can_discard)
                        fs_devices->num_can_discard--;
+               if (device->missing)
+                       fs_devices->missing_devices--;
 
                new_device = btrfs_alloc_device(NULL, &device->devid,
                                                device->uuid);
@@ -794,7 +796,8 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                        fs_devices->rotating = 1;
 
                fs_devices->open_devices++;
-               if (device->writeable && !device->is_tgtdev_for_dev_replace) {
+               if (device->writeable &&
+                   device->devid != BTRFS_DEV_REPLACE_DEVID) {
                        fs_devices->rw_devices++;
                        list_add(&device->dev_alloc_list,
                                 &fs_devices->alloc_list);
@@ -2995,10 +2998,6 @@ again:
                if (found_key.objectid != key.objectid)
                        break;
 
-               /* chunk zero is special */
-               if (found_key.offset == 0)
-                       break;
-
                chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
 
                if (!counting) {
@@ -3034,6 +3033,8 @@ again:
                        spin_unlock(&fs_info->balance_lock);
                }
 loop:
+               if (found_key.offset == 0)
+                       break;
                key.offset = found_key.offset - 1;
        }
 
@@ -3463,7 +3464,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 +3502,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 +3523,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 +3536,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 +3548,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 +3578,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
This page took 0.121054 seconds and 5 git commands to generate.