diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 188e2a61402d..b47dd1387766 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -541,11 +541,10 @@ error: * true If it is the same device. * false If it is not the same device or on error. */ -static bool device_matched(const struct btrfs_device *device, const char *path) +static bool device_matched(const struct btrfs_device *device, dev_t dev_new) { char *device_name; dev_t dev_old; - dev_t dev_new; int ret; /* @@ -568,29 +567,26 @@ static bool device_matched(const struct btrfs_device *device, const char *path) if (ret) return false; - ret = lookup_bdev(path, &dev_new); - if (ret) - return false; - if (dev_old == dev_new) return true; return false; } -/* - * Search and remove all stale (devices which are not mounted) devices. +/** + * Search and remove all stale devices (which are not mounted). * When both inputs are NULL, it will search and release all stale devices. - * path: Optional. When provided will it release all unmounted devices - * matching this path only. - * skip_dev: Optional. Will skip this device when searching for the stale + * + * @devt: Optional. When provided will it release all unmounted devices + * matching this devt only. + * @skip_device: Optional. Will skip this device when searching for the stale * devices. - * Return: 0 for success or if @path is NULL. - * -EBUSY if @path is a mounted device. - * -ENOENT if @path does not match any device in the list. + * + * Return: 0 for success or if @devt is 0. + * -EBUSY if @devt is a mounted device. + * -ENOENT if @devt does not match any device in the list. */ -static int btrfs_free_stale_devices(const char *path, - struct btrfs_device *skip_device) +static int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device) { struct btrfs_fs_devices *fs_devices, *tmp_fs_devices; struct btrfs_device *device, *tmp_device; @@ -598,7 +594,7 @@ static int btrfs_free_stale_devices(const char *path, lockdep_assert_held(&uuid_mutex); - if (path) + if (devt) ret = -ENOENT; list_for_each_entry_safe(fs_devices, tmp_fs_devices, &fs_uuids, fs_list) { @@ -608,11 +604,11 @@ static int btrfs_free_stale_devices(const char *path, &fs_devices->devices, dev_list) { if (skip_device && skip_device == device) continue; - if (path && !device_matched(device, path)) + if (devt && !device_matched(device, devt)) continue; if (fs_devices->opened) { /* for an already deleted device return 0 */ - if (path && ret != 0) + if (devt && ret != 0) ret = -EBUSY; break; } @@ -1362,12 +1358,12 @@ static struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev return disk_super; } -int btrfs_forget_devices(const char *path) +int btrfs_forget_devices(dev_t devt) { int ret; mutex_lock(&uuid_mutex); - ret = btrfs_free_stale_devices(strlen(path) ? path : NULL, NULL); + ret = btrfs_free_stale_devices(devt, NULL); mutex_unlock(&uuid_mutex); return ret; @@ -1416,9 +1412,15 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags, } device = device_list_add(path, disk_super, &new_device_added); - if (!IS_ERR(device)) { - if (new_device_added) - btrfs_free_stale_devices(path, device); + if (!IS_ERR(device) && new_device_added) { + dev_t devt; + + /* + * It is ok to ignore if we fail to free the stale device (if + * any). As there is nothing much that can be done about it. + */ + if (lookup_bdev(path, &devt) == 0) + btrfs_free_stale_devices(devt, device); } btrfs_release_disk_super(disk_super); @@ -2650,6 +2652,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path int ret = 0; bool seeding_dev = false; bool locked = false; + dev_t devt; if (sb_rdonly(sb) && !fs_devices->seeding) return -EROFS; @@ -2842,10 +2845,13 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path * Now that we have written a new super block to this device, check all * other fs_devices list if device_path alienates any other scanned * device. + * Skip forget_deivces if lookup_bdev() fails as there is nothing much + * that can be done about it. * We can ignore the return value as it typically returns -EINVAL and * only succeeds if the device was an alien. */ - btrfs_forget_devices(device_path); + if (lookup_bdev(device_path, &devt) == 0) + btrfs_forget_devices(devt); /* Update ctime/mtime for blkid or udev */ update_dev_time(device_path); |