static int check_tree_block_fsid(struct extent_buffer *eb)
 {
        struct btrfs_fs_info *fs_info = eb->fs_info;
-       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs;
        u8 fsid[BTRFS_FSID_SIZE];
-       int ret = 1;
+       u8 *metadata_uuid;
 
        read_extent_buffer(eb, fsid, offsetof(struct btrfs_header, fsid),
                           BTRFS_FSID_SIZE);
-       while (fs_devices) {
-               u8 *metadata_uuid;
+       /*
+        * Checking the incompat flag is only valid for the current fs. For
+        * seed devices it's forbidden to have their uuid changed so reading
+        * ->fsid in this case is fine
+        */
+       if (btrfs_fs_incompat(fs_info, METADATA_UUID))
+               metadata_uuid = fs_devices->metadata_uuid;
+       else
+               metadata_uuid = fs_devices->fsid;
 
-               /*
-                * Checking the incompat flag is only valid for the current
-                * fs. For seed devices it's forbidden to have their uuid
-                * changed so reading ->fsid in this case is fine
-                */
-               if (fs_devices == fs_info->fs_devices &&
-                   btrfs_fs_incompat(fs_info, METADATA_UUID))
-                       metadata_uuid = fs_devices->metadata_uuid;
-               else
-                       metadata_uuid = fs_devices->fsid;
+       if (!memcmp(fsid, metadata_uuid, BTRFS_FSID_SIZE))
+               return 0;
 
-               if (!memcmp(fsid, metadata_uuid, BTRFS_FSID_SIZE)) {
-                       ret = 0;
-                       break;
-               }
-               fs_devices = fs_devices->seed;
-       }
-       return ret;
+       list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list)
+               if (!memcmp(fsid, seed_devs->fsid, BTRFS_FSID_SIZE))
+                       return 0;
+
+       return 1;
 }
 
 static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
 
        INIT_LIST_HEAD(&fs_devs->devices);
        INIT_LIST_HEAD(&fs_devs->alloc_list);
        INIT_LIST_HEAD(&fs_devs->fs_list);
+       INIT_LIST_HEAD(&fs_devs->seed_list);
        if (fsid)
                memcpy(fs_devs->fsid, fsid, BTRFS_FSID_SIZE);
 
 void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, int step)
 {
        struct btrfs_device *latest_dev = NULL;
+       struct btrfs_fs_devices *seed_dev;
 
        mutex_lock(&uuid_mutex);
-again:
        __btrfs_free_extra_devids(fs_devices, step, &latest_dev);
-       if (fs_devices->seed) {
-               fs_devices = fs_devices->seed;
-               goto again;
-       }
+
+       list_for_each_entry(seed_dev, &fs_devices->seed_list, seed_list)
+               __btrfs_free_extra_devids(seed_dev, step, &latest_dev);
 
        fs_devices->latest_bdev = latest_dev->bdev;
 
 
 void btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
 {
-       struct btrfs_fs_devices *seed_devices = NULL;
+       LIST_HEAD(list);
+       struct btrfs_fs_devices *tmp;
 
        mutex_lock(&uuid_mutex);
        close_fs_devices(fs_devices);
-       if (!fs_devices->opened) {
-               seed_devices = fs_devices->seed;
-               fs_devices->seed = NULL;
-       }
+       if (!fs_devices->opened)
+               list_splice_init(&fs_devices->seed_list, &list);
        mutex_unlock(&uuid_mutex);
 
-       while (seed_devices) {
-               fs_devices = seed_devices;
-               seed_devices = fs_devices->seed;
+       list_for_each_entry_safe(fs_devices, tmp, &list, seed_list) {
                close_fs_devices(fs_devices);
+               list_del(&fs_devices->seed_list);
                free_fs_devices(fs_devices);
        }
 }
        btrfs_free_device(device);
 
        if (cur_devices->open_devices == 0) {
-               while (fs_devices) {
-                       if (fs_devices->seed == cur_devices) {
-                               fs_devices->seed = cur_devices->seed;
-                               break;
-                       }
-                       fs_devices = fs_devices->seed;
-               }
-               cur_devices->seed = NULL;
+               list_del_init(&cur_devices->seed_list);
                close_fs_devices(cur_devices);
                free_fs_devices(cur_devices);
        }
 
        /* if this is no devs we rather delete the fs_devices */
        if (!fs_devices->num_devices) {
-               struct btrfs_fs_devices *tmp_fs_devices;
-
                /*
                 * On a mounted FS, num_devices can't be zero unless it's a
                 * seed. In case of a seed device being replaced, the replace
                 */
                ASSERT(fs_devices->seeding);
 
-               tmp_fs_devices = fs_info->fs_devices;
-               while (tmp_fs_devices) {
-                       if (tmp_fs_devices->seed == fs_devices) {
-                               tmp_fs_devices->seed = fs_devices->seed;
-                               break;
-                       }
-                       tmp_fs_devices = tmp_fs_devices->seed;
-               }
-               fs_devices->seed = NULL;
+               list_del_init(&fs_devices->seed_list);
                close_fs_devices(fs_devices);
                free_fs_devices(fs_devices);
        }
        fs_devices->open_devices = 0;
        fs_devices->missing_devices = 0;
        fs_devices->rotating = false;
-       fs_devices->seed = seed_devices;
+       list_add(&seed_devices->seed_list, &fs_devices->seed_list);
 
        generate_random_uuid(fs_devices->fsid);
        memcpy(fs_devices->metadata_uuid, fs_devices->fsid, BTRFS_FSID_SIZE);
                                       bool seed)
 {
        struct btrfs_device *device;
+       struct btrfs_fs_devices *seed_devs;
+
+       if (!fsid || !memcmp(fs_devices->metadata_uuid, fsid, BTRFS_FSID_SIZE)) {
+               list_for_each_entry(device, &fs_devices->devices, dev_list) {
+                       if (device->devid == devid &&
+                           (!uuid || memcmp(device->uuid, uuid,
+                                            BTRFS_UUID_SIZE) == 0))
+                               return device;
+               }
+       }
 
-       while (fs_devices) {
+       list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
                if (!fsid ||
-                   !memcmp(fs_devices->metadata_uuid, fsid, BTRFS_FSID_SIZE)) {
-                       list_for_each_entry(device, &fs_devices->devices,
+                   !memcmp(seed_devs->metadata_uuid, fsid, BTRFS_FSID_SIZE)) {
+                       list_for_each_entry(device, &seed_devs->devices,
                                            dev_list) {
                                if (device->devid == devid &&
                                    (!uuid || memcmp(device->uuid, uuid,
                                        return device;
                        }
                }
-               if (seed)
-                       fs_devices = fs_devices->seed;
-               else
-                       return NULL;
        }
+
        return NULL;
 }
 
        lockdep_assert_held(&uuid_mutex);
        ASSERT(fsid);
 
-       fs_devices = fs_info->fs_devices->seed;
-       while (fs_devices) {
+       list_for_each_entry(fs_devices, &fs_info->fs_devices->seed_list, seed_list)
                if (!memcmp(fs_devices->fsid, fsid, BTRFS_FSID_SIZE))
                        return fs_devices;
 
-               fs_devices = fs_devices->seed;
-       }
 
        fs_devices = find_fsid(fsid, NULL);
        if (!fs_devices) {
                goto out;
        }
 
-       fs_devices->seed = fs_info->fs_devices->seed;
-       fs_info->fs_devices->seed = fs_devices;
+       list_add(&fs_devices->seed_list, &fs_info->fs_devices->seed_list);
 out:
        return fs_devices;
 }
 
 void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
 {
-       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
+       struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs;
        struct btrfs_device *device;
 
-       while (fs_devices) {
-               mutex_lock(&fs_devices->device_list_mutex);
-               list_for_each_entry(device, &fs_devices->devices, dev_list)
+       fs_devices->fs_info = fs_info;
+
+       mutex_lock(&fs_devices->device_list_mutex);
+       list_for_each_entry(device, &fs_devices->devices, dev_list)
+               device->fs_info = fs_info;
+       mutex_unlock(&fs_devices->device_list_mutex);
+
+       list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
+               mutex_lock(&seed_devs->device_list_mutex);
+               list_for_each_entry(device, &seed_devs->devices, dev_list)
                        device->fs_info = fs_info;
-               mutex_unlock(&fs_devices->device_list_mutex);
+               mutex_unlock(&seed_devs->device_list_mutex);
 
-               fs_devices->fs_info = fs_info;
-               fs_devices = fs_devices->seed;
+               seed_devs->fs_info = fs_info;
        }
 }
 
 
        /* It's possible this device is a dummy for seed device */
        if (dev->disk_total_bytes == 0) {
-               dev = btrfs_find_device(fs_info->fs_devices->seed, devid, NULL,
-                                       NULL, false);
+               struct btrfs_fs_devices *devs;
+
+               devs = list_first_entry(&fs_info->fs_devices->seed_list,
+                                       struct btrfs_fs_devices, seed_list);
+               dev = btrfs_find_device(devs, devid, NULL, NULL, false);
                if (!dev) {
                        btrfs_err(fs_info, "failed to find seed devid %llu",
                                  devid);