Commit 16cab91a authored by Anand Jain's avatar Anand Jain Committed by David Sterba

btrfs: match stale devices by dev_t

After the commit "btrfs: harden identification of the stale device", we
don't have to match the device path anymore. Instead, we match the dev_t.
So pass in the dev_t instead of the device path, in the call chain
btrfs_forget_devices()->btrfs_free_stale_devices().
Signed-off-by: default avatarAnand Jain <anand.jain@oracle.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 770c79fb
...@@ -2383,6 +2383,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, ...@@ -2383,6 +2383,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
{ {
struct btrfs_ioctl_vol_args *vol; struct btrfs_ioctl_vol_args *vol;
struct btrfs_device *device = NULL; struct btrfs_device *device = NULL;
dev_t devt = 0;
int ret = -ENOTTY; int ret = -ENOTTY;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
...@@ -2402,7 +2403,12 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, ...@@ -2402,7 +2403,12 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
mutex_unlock(&uuid_mutex); mutex_unlock(&uuid_mutex);
break; break;
case BTRFS_IOC_FORGET_DEV: case BTRFS_IOC_FORGET_DEV:
ret = btrfs_forget_devices(vol->name); if (vol->name[0] != 0) {
ret = lookup_bdev(vol->name, &devt);
if (ret)
break;
}
ret = btrfs_forget_devices(devt);
break; break;
case BTRFS_IOC_DEVICES_READY: case BTRFS_IOC_DEVICES_READY:
mutex_lock(&uuid_mutex); mutex_lock(&uuid_mutex);
......
...@@ -541,11 +541,10 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder, ...@@ -541,11 +541,10 @@ btrfs_get_bdev_and_sb(const char *device_path, fmode_t flags, void *holder,
* true If it is the same device. * true If it is the same device.
* false If it is not the same device or on error. * 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; char *device_name;
dev_t dev_old; dev_t dev_old;
dev_t dev_new;
int ret; int ret;
/* /*
...@@ -568,29 +567,26 @@ static bool device_matched(const struct btrfs_device *device, const char *path) ...@@ -568,29 +567,26 @@ static bool device_matched(const struct btrfs_device *device, const char *path)
if (ret) if (ret)
return false; return false;
ret = lookup_bdev(path, &dev_new);
if (ret)
return false;
if (dev_old == dev_new) if (dev_old == dev_new)
return true; return true;
return false; 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. * 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. * @devt: Optional. When provided will it release all unmounted devices
* skip_dev: Optional. Will skip this device when searching for the stale * matching this devt only.
* @skip_device: Optional. Will skip this device when searching for the stale
* devices. * devices.
* Return: 0 for success or if @path is NULL. *
* -EBUSY if @path is a mounted device. * Return: 0 for success or if @devt is 0.
* -ENOENT if @path does not match any device in the list. * -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, static int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device)
struct btrfs_device *skip_device)
{ {
struct btrfs_fs_devices *fs_devices, *tmp_fs_devices; struct btrfs_fs_devices *fs_devices, *tmp_fs_devices;
struct btrfs_device *device, *tmp_device; struct btrfs_device *device, *tmp_device;
...@@ -598,7 +594,7 @@ static int btrfs_free_stale_devices(const char *path, ...@@ -598,7 +594,7 @@ static int btrfs_free_stale_devices(const char *path,
lockdep_assert_held(&uuid_mutex); lockdep_assert_held(&uuid_mutex);
if (path) if (devt)
ret = -ENOENT; ret = -ENOENT;
list_for_each_entry_safe(fs_devices, tmp_fs_devices, &fs_uuids, fs_list) { 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, ...@@ -608,11 +604,11 @@ static int btrfs_free_stale_devices(const char *path,
&fs_devices->devices, dev_list) { &fs_devices->devices, dev_list) {
if (skip_device && skip_device == device) if (skip_device && skip_device == device)
continue; continue;
if (path && !device_matched(device, path)) if (devt && !device_matched(device, devt))
continue; continue;
if (fs_devices->opened) { if (fs_devices->opened) {
/* for an already deleted device return 0 */ /* for an already deleted device return 0 */
if (path && ret != 0) if (devt && ret != 0)
ret = -EBUSY; ret = -EBUSY;
break; break;
} }
...@@ -1362,12 +1358,12 @@ static struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev ...@@ -1362,12 +1358,12 @@ static struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev
return disk_super; return disk_super;
} }
int btrfs_forget_devices(const char *path) int btrfs_forget_devices(dev_t devt)
{ {
int ret; int ret;
mutex_lock(&uuid_mutex); 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); mutex_unlock(&uuid_mutex);
return ret; return ret;
...@@ -1416,9 +1412,15 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, fmode_t flags, ...@@ -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); device = device_list_add(path, disk_super, &new_device_added);
if (!IS_ERR(device)) { if (!IS_ERR(device) && new_device_added) {
if (new_device_added) dev_t devt;
btrfs_free_stale_devices(path, device);
/*
* 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); 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 ...@@ -2650,6 +2652,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
int ret = 0; int ret = 0;
bool seeding_dev = false; bool seeding_dev = false;
bool locked = false; bool locked = false;
dev_t devt;
if (sb_rdonly(sb) && !fs_devices->seeding) if (sb_rdonly(sb) && !fs_devices->seeding)
return -EROFS; return -EROFS;
...@@ -2842,10 +2845,13 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path ...@@ -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 * 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 * other fs_devices list if device_path alienates any other scanned
* device. * 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 * We can ignore the return value as it typically returns -EINVAL and
* only succeeds if the device was an alien. * 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 ctime/mtime for blkid or udev */
update_dev_time(device_path); update_dev_time(device_path);
......
...@@ -505,7 +505,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, ...@@ -505,7 +505,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
fmode_t flags, void *holder); fmode_t flags, void *holder);
struct btrfs_device *btrfs_scan_one_device(const char *path, struct btrfs_device *btrfs_scan_one_device(const char *path,
fmode_t flags, void *holder); fmode_t flags, void *holder);
int btrfs_forget_devices(const char *path); int btrfs_forget_devices(dev_t devt);
void btrfs_close_devices(struct btrfs_fs_devices *fs_devices); void btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices); void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices);
void btrfs_assign_next_active_device(struct btrfs_device *device, void btrfs_assign_next_active_device(struct btrfs_device *device,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment