diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1aa08c4b6dfe74..82d5723f3e1be3 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2296,37 +2296,22 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_device *tgtdev) btrfs_free_device(tgtdev); } -static struct btrfs_device *btrfs_find_device_by_path( - struct btrfs_fs_info *fs_info, const char *device_path) +static struct btrfs_device *find_device_by_path( + struct btrfs_fs_devices *fs_devices, + const char *path) { - int ret = 0; - struct btrfs_super_block *disk_super; - u64 devid; - u8 *dev_uuid; - struct block_device *bdev; struct btrfs_device *device; + bool missing = !strcmp(path, "missing"); - ret = btrfs_get_bdev_and_sb(device_path, FMODE_READ, - fs_info->bdev_holder, 0, &bdev, &disk_super); - if (ret) - return ERR_PTR(ret); - - devid = btrfs_stack_device_id(&disk_super->dev_item); - dev_uuid = disk_super->dev_item.uuid; - if (btrfs_fs_incompat(fs_info, METADATA_UUID)) - device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid, - disk_super->metadata_uuid); - else - device = btrfs_find_device(fs_info->fs_devices, devid, dev_uuid, - disk_super->fsid); - - btrfs_release_disk_super(disk_super); - if (!device) - device = ERR_PTR(-ENOENT); - blkdev_put(bdev, FMODE_READ); - return device; + list_for_each_entry(device, &fs_devices->devices, dev_list) { + if (missing && test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, + &device->dev_state) && !device->bdev) + return device; + if (!missing && device_path_matched(path, device)) + return device; + } + return NULL; } - /* * Lookup a device given by device id, or the path if the id is 0. */ @@ -2334,6 +2319,7 @@ struct btrfs_device *btrfs_find_device_by_devspec( struct btrfs_fs_info *fs_info, u64 devid, const char *device_path) { + struct btrfs_fs_devices *seed_devs; struct btrfs_device *device; if (devid) { @@ -2347,18 +2333,17 @@ struct btrfs_device *btrfs_find_device_by_devspec( if (!device_path || !device_path[0]) return ERR_PTR(-EINVAL); - if (strcmp(device_path, "missing") == 0) { - /* Find first missing device */ - list_for_each_entry(device, &fs_info->fs_devices->devices, - dev_list) { - if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, - &device->dev_state) && !device->bdev) - return device; - } - return ERR_PTR(-ENOENT); - } + device = find_device_by_path(fs_info->fs_devices, device_path); + if (device) + return device; - return btrfs_find_device_by_path(fs_info, device_path); + list_for_each_entry(seed_devs, &fs_info->fs_devices->seed_list, + seed_list) { + device = find_device_by_path(seed_devs, device_path); + if (device) + return device; + } + return ERR_PTR(-ENOENT); } /*