Skip to content

Commit d5f01ac

Browse files
bcodding-rhMikulas Patocka
authored andcommitted
dm: add support for get_unique_id
This adds support to obtain a device's unique id through dm, similar to the existing ioctl and persistent resevation handling. We limit this to single-target devices. This enables knfsd to export pNFS SCSI luns that have been exported from multipath devices. Signed-off-by: Benjamin Coddington <[email protected]> Signed-off-by: Mikulas Patocka <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 19ac19e commit d5f01ac

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

drivers/md/dm.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,6 +3343,59 @@ void dm_free_md_mempools(struct dm_md_mempools *pools)
33433343
kfree(pools);
33443344
}
33453345

3346+
struct dm_blkdev_id {
3347+
u8 *id;
3348+
enum blk_unique_id type;
3349+
};
3350+
3351+
static int __dm_get_unique_id(struct dm_target *ti, struct dm_dev *dev,
3352+
sector_t start, sector_t len, void *data)
3353+
{
3354+
struct dm_blkdev_id *dm_id = data;
3355+
const struct block_device_operations *fops = dev->bdev->bd_disk->fops;
3356+
3357+
if (!fops->get_unique_id)
3358+
return 0;
3359+
3360+
return fops->get_unique_id(dev->bdev->bd_disk, dm_id->id, dm_id->type);
3361+
}
3362+
3363+
/*
3364+
* Allow access to get_unique_id() for the first device returning a
3365+
* non-zero result. Reasonable use expects all devices to have the
3366+
* same unique id.
3367+
*/
3368+
static int dm_blk_get_unique_id(struct gendisk *disk, u8 *id,
3369+
enum blk_unique_id type)
3370+
{
3371+
struct mapped_device *md = disk->private_data;
3372+
struct dm_table *table;
3373+
struct dm_target *ti;
3374+
int ret = 0, srcu_idx;
3375+
3376+
struct dm_blkdev_id dm_id = {
3377+
.id = id,
3378+
.type = type,
3379+
};
3380+
3381+
table = dm_get_live_table(md, &srcu_idx);
3382+
if (!table || !dm_table_get_size(table))
3383+
goto out;
3384+
3385+
/* We only support devices that have a single target */
3386+
if (table->num_targets != 1)
3387+
goto out;
3388+
ti = dm_table_get_target(table, 0);
3389+
3390+
if (!ti->type->iterate_devices)
3391+
goto out;
3392+
3393+
ret = ti->type->iterate_devices(ti, __dm_get_unique_id, &dm_id);
3394+
out:
3395+
dm_put_live_table(md, srcu_idx);
3396+
return ret;
3397+
}
3398+
33463399
struct dm_pr {
33473400
u64 old_key;
33483401
u64 new_key;
@@ -3668,6 +3721,7 @@ static const struct block_device_operations dm_blk_dops = {
36683721
.ioctl = dm_blk_ioctl,
36693722
.getgeo = dm_blk_getgeo,
36703723
.report_zones = dm_blk_report_zones,
3724+
.get_unique_id = dm_blk_get_unique_id,
36713725
.pr_ops = &dm_pr_ops,
36723726
.owner = THIS_MODULE
36733727
};
@@ -3677,6 +3731,7 @@ static const struct block_device_operations dm_rq_blk_dops = {
36773731
.release = dm_blk_close,
36783732
.ioctl = dm_blk_ioctl,
36793733
.getgeo = dm_blk_getgeo,
3734+
.get_unique_id = dm_blk_get_unique_id,
36803735
.pr_ops = &dm_pr_ops,
36813736
.owner = THIS_MODULE
36823737
};

0 commit comments

Comments
 (0)