Skip to content

Commit 321a818

Browse files
josefbacikgregkh
authored andcommitted
btrfs: add a btrfs_get_dev_args_from_path helper
[ Upstream commit faa775c ] We are going to want to populate our device lookup args outside of any locks and then do the actual device lookup later, so add a helper to do this work and make btrfs_find_device_by_devspec() use this helper for now. Reviewed-by: Nikolay Borisov <[email protected]> Reviewed-by: Anand Jain <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: David Sterba <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 5578b68 commit 321a818

File tree

2 files changed

+68
-32
lines changed

2 files changed

+68
-32
lines changed

fs/btrfs/volumes.c

Lines changed: 64 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,45 +2361,81 @@ void btrfs_destroy_dev_replace_tgtdev(struct btrfs_device *tgtdev)
23612361
btrfs_free_device(tgtdev);
23622362
}
23632363

2364-
static struct btrfs_device *btrfs_find_device_by_path(
2365-
struct btrfs_fs_info *fs_info, const char *device_path)
2364+
/**
2365+
* Populate args from device at path
2366+
*
2367+
* @fs_info: the filesystem
2368+
* @args: the args to populate
2369+
* @path: the path to the device
2370+
*
2371+
* This will read the super block of the device at @path and populate @args with
2372+
* the devid, fsid, and uuid. This is meant to be used for ioctls that need to
2373+
* lookup a device to operate on, but need to do it before we take any locks.
2374+
* This properly handles the special case of "missing" that a user may pass in,
2375+
* and does some basic sanity checks. The caller must make sure that @path is
2376+
* properly NUL terminated before calling in, and must call
2377+
* btrfs_put_dev_args_from_path() in order to free up the temporary fsid and
2378+
* uuid buffers.
2379+
*
2380+
* Return: 0 for success, -errno for failure
2381+
*/
2382+
int btrfs_get_dev_args_from_path(struct btrfs_fs_info *fs_info,
2383+
struct btrfs_dev_lookup_args *args,
2384+
const char *path)
23662385
{
2367-
BTRFS_DEV_LOOKUP_ARGS(args);
2368-
int ret = 0;
23692386
struct btrfs_super_block *disk_super;
23702387
struct block_device *bdev;
2371-
struct btrfs_device *device;
2388+
int ret;
23722389

2373-
ret = btrfs_get_bdev_and_sb(device_path, FMODE_READ,
2374-
fs_info->bdev_holder, 0, &bdev, &disk_super);
2375-
if (ret)
2376-
return ERR_PTR(ret);
2390+
if (!path || !path[0])
2391+
return -EINVAL;
2392+
if (!strcmp(path, "missing")) {
2393+
args->missing = true;
2394+
return 0;
2395+
}
2396+
2397+
args->uuid = kzalloc(BTRFS_UUID_SIZE, GFP_KERNEL);
2398+
args->fsid = kzalloc(BTRFS_FSID_SIZE, GFP_KERNEL);
2399+
if (!args->uuid || !args->fsid) {
2400+
btrfs_put_dev_args_from_path(args);
2401+
return -ENOMEM;
2402+
}
23772403

2378-
args.devid = btrfs_stack_device_id(&disk_super->dev_item);
2379-
args.uuid = disk_super->dev_item.uuid;
2404+
ret = btrfs_get_bdev_and_sb(path, FMODE_READ, fs_info->bdev_holder, 0,
2405+
&bdev, &disk_super);
2406+
if (ret)
2407+
return ret;
2408+
args->devid = btrfs_stack_device_id(&disk_super->dev_item);
2409+
memcpy(args->uuid, disk_super->dev_item.uuid, BTRFS_UUID_SIZE);
23802410
if (btrfs_fs_incompat(fs_info, METADATA_UUID))
2381-
args.fsid = disk_super->metadata_uuid;
2411+
memcpy(args->fsid, disk_super->metadata_uuid, BTRFS_FSID_SIZE);
23822412
else
2383-
args.fsid = disk_super->fsid;
2384-
2385-
device = btrfs_find_device(fs_info->fs_devices, &args);
2386-
2413+
memcpy(args->fsid, disk_super->fsid, BTRFS_FSID_SIZE);
23872414
btrfs_release_disk_super(disk_super);
2388-
if (!device)
2389-
device = ERR_PTR(-ENOENT);
23902415
blkdev_put(bdev, FMODE_READ);
2391-
return device;
2416+
return 0;
23922417
}
23932418

23942419
/*
2395-
* Lookup a device given by device id, or the path if the id is 0.
2420+
* Only use this jointly with btrfs_get_dev_args_from_path() because we will
2421+
* allocate our ->uuid and ->fsid pointers, everybody else uses local variables
2422+
* that don't need to be freed.
23962423
*/
2424+
void btrfs_put_dev_args_from_path(struct btrfs_dev_lookup_args *args)
2425+
{
2426+
kfree(args->uuid);
2427+
kfree(args->fsid);
2428+
args->uuid = NULL;
2429+
args->fsid = NULL;
2430+
}
2431+
23972432
struct btrfs_device *btrfs_find_device_by_devspec(
23982433
struct btrfs_fs_info *fs_info, u64 devid,
23992434
const char *device_path)
24002435
{
24012436
BTRFS_DEV_LOOKUP_ARGS(args);
24022437
struct btrfs_device *device;
2438+
int ret;
24032439

24042440
if (devid) {
24052441
args.devid = devid;
@@ -2409,18 +2445,14 @@ struct btrfs_device *btrfs_find_device_by_devspec(
24092445
return device;
24102446
}
24112447

2412-
if (!device_path || !device_path[0])
2413-
return ERR_PTR(-EINVAL);
2414-
2415-
if (strcmp(device_path, "missing") == 0) {
2416-
args.missing = true;
2417-
device = btrfs_find_device(fs_info->fs_devices, &args);
2418-
if (!device)
2419-
return ERR_PTR(-ENOENT);
2420-
return device;
2421-
}
2422-
2423-
return btrfs_find_device_by_path(fs_info, device_path);
2448+
ret = btrfs_get_dev_args_from_path(fs_info, &args, device_path);
2449+
if (ret)
2450+
return ERR_PTR(ret);
2451+
device = btrfs_find_device(fs_info->fs_devices, &args);
2452+
btrfs_put_dev_args_from_path(&args);
2453+
if (!device)
2454+
return ERR_PTR(-ENOENT);
2455+
return device;
24242456
}
24252457

24262458
/*

fs/btrfs/volumes.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,13 @@ void btrfs_assign_next_active_device(struct btrfs_device *device,
487487
struct btrfs_device *btrfs_find_device_by_devspec(struct btrfs_fs_info *fs_info,
488488
u64 devid,
489489
const char *devpath);
490+
int btrfs_get_dev_args_from_path(struct btrfs_fs_info *fs_info,
491+
struct btrfs_dev_lookup_args *args,
492+
const char *path);
490493
struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
491494
const u64 *devid,
492495
const u8 *uuid);
496+
void btrfs_put_dev_args_from_path(struct btrfs_dev_lookup_args *args);
493497
void btrfs_free_device(struct btrfs_device *device);
494498
int btrfs_rm_device(struct btrfs_fs_info *fs_info,
495499
const char *device_path, u64 devid,

0 commit comments

Comments
 (0)