btrfs: refactor btrfs_free_stale_devices() to get return value
Preparatory patch to add ioctl that allows to forget a device (ie. reverse of scan). Refactors btrfs_free_stale_devices() to obtain return status. As this function can fail if it can't find the given path (returns -ENOENT) or trying to delete a mounted device (returns -EBUSY). Signed-off-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Родитель
e4319cd9ca
Коммит
70bc7088aa
|
@ -734,6 +734,17 @@ static void pending_bios_fn(struct btrfs_work *work)
|
||||||
run_scheduled_bios(device);
|
run_scheduled_bios(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool device_path_matched(const char *path, struct btrfs_device *device)
|
||||||
|
{
|
||||||
|
int found;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
found = strcmp(rcu_str_deref(device->name), path);
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
|
return found == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search and remove all stale (devices which are not mounted) devices.
|
* Search and remove all stale (devices which are not mounted) devices.
|
||||||
* 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.
|
||||||
|
@ -741,52 +752,57 @@ static void pending_bios_fn(struct btrfs_work *work)
|
||||||
* matching this path only.
|
* matching this path only.
|
||||||
* skip_dev: Optional. Will skip this device when searching for the stale
|
* skip_dev: 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.
|
||||||
|
* -ENOENT if @path does not match any device in the list.
|
||||||
*/
|
*/
|
||||||
static void btrfs_free_stale_devices(const char *path,
|
static int btrfs_free_stale_devices(const char *path,
|
||||||
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;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (path)
|
||||||
|
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) {
|
||||||
mutex_lock(&fs_devices->device_list_mutex);
|
|
||||||
if (fs_devices->opened) {
|
|
||||||
mutex_unlock(&fs_devices->device_list_mutex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
mutex_lock(&fs_devices->device_list_mutex);
|
||||||
list_for_each_entry_safe(device, tmp_device,
|
list_for_each_entry_safe(device, tmp_device,
|
||||||
&fs_devices->devices, dev_list) {
|
&fs_devices->devices, dev_list) {
|
||||||
int not_found = 0;
|
|
||||||
|
|
||||||
if (skip_device && skip_device == device)
|
if (skip_device && skip_device == device)
|
||||||
continue;
|
continue;
|
||||||
if (path && !device->name)
|
if (path && !device->name)
|
||||||
continue;
|
continue;
|
||||||
|
if (path && !device_path_matched(path, device))
|
||||||
rcu_read_lock();
|
|
||||||
if (path)
|
|
||||||
not_found = strcmp(rcu_str_deref(device->name),
|
|
||||||
path);
|
|
||||||
rcu_read_unlock();
|
|
||||||
if (not_found)
|
|
||||||
continue;
|
continue;
|
||||||
|
if (fs_devices->opened) {
|
||||||
|
/* for an already deleted device return 0 */
|
||||||
|
if (path && ret != 0)
|
||||||
|
ret = -EBUSY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* delete the stale device */
|
/* delete the stale device */
|
||||||
fs_devices->num_devices--;
|
fs_devices->num_devices--;
|
||||||
list_del(&device->dev_list);
|
list_del(&device->dev_list);
|
||||||
btrfs_free_device(device);
|
btrfs_free_device(device);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
if (fs_devices->num_devices == 0)
|
if (fs_devices->num_devices == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&fs_devices->device_list_mutex);
|
mutex_unlock(&fs_devices->device_list_mutex);
|
||||||
|
|
||||||
if (fs_devices->num_devices == 0) {
|
if (fs_devices->num_devices == 0) {
|
||||||
btrfs_sysfs_remove_fsid(fs_devices);
|
btrfs_sysfs_remove_fsid(fs_devices);
|
||||||
list_del(&fs_devices->fs_list);
|
list_del(&fs_devices->fs_list);
|
||||||
free_fs_devices(fs_devices);
|
free_fs_devices(fs_devices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
|
static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче