Skip to content

Commit d75e184

Browse files
Hannes Reineckekawasaki
authored andcommitted
ublk: persistent device links
Implement a 'uuid' parameter to export a device UUID in a sysfs attribute 'uuid'. The ublk server is required to set the uuid parameter when creating the device. This allows udev to create persistent device links for ublk devices eg with this rule: KERNEL=="ublk*", ATTRS{uuid}=="?*", SYMLINK+="disk/by-id/ublk-$attr{uuid}" Signed-off-by: Hannes Reinecke <[email protected]> Reviewed-by: Ming Lei <[email protected]> Reviewed-by: Ming Lei <[email protected]>
1 parent 857ada9 commit d75e184

2 files changed

Lines changed: 59 additions & 2 deletions

File tree

drivers/block/ublk_drv.c

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
(UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD | \
101101
UBLK_PARAM_TYPE_DEVT | UBLK_PARAM_TYPE_ZONED | \
102102
UBLK_PARAM_TYPE_DMA_ALIGN | UBLK_PARAM_TYPE_SEGMENT | \
103-
UBLK_PARAM_TYPE_INTEGRITY)
103+
UBLK_PARAM_TYPE_INTEGRITY | UBLK_PARAM_TYPE_UUID)
104104

105105
#define UBLK_BATCH_F_ALL \
106106
(UBLK_BATCH_F_HAS_ZONE_LBA | \
@@ -976,6 +976,14 @@ static int ublk_validate_params(const struct ublk_device *ub)
976976
return -EINVAL;
977977
}
978978

979+
if (ub->params.types & UBLK_PARAM_TYPE_UUID) {
980+
const struct ublk_param_uuid *p = &ub->params.uuid;
981+
uuid_t uuid;
982+
983+
import_uuid(&uuid, p->uuid);
984+
if (uuid_is_null(&uuid))
985+
return -EINVAL;
986+
}
979987
return 0;
980988
}
981989

@@ -4313,6 +4321,49 @@ static int ublk_add_chdev(struct ublk_device *ub)
43134321
return ret;
43144322
}
43154323

4324+
static ssize_t uuid_show(struct device *dev,
4325+
struct device_attribute *attr, char *buf)
4326+
{
4327+
struct gendisk *disk = dev_to_disk(dev);
4328+
struct ublk_device *ub = disk->private_data;
4329+
const struct ublk_param_uuid *p = &ub->params.uuid;
4330+
uuid_t uuid;
4331+
4332+
import_uuid(&uuid, p->uuid);
4333+
return sprintf(buf, "%pU\n", &uuid);
4334+
}
4335+
4336+
static DEVICE_ATTR_RO(uuid);
4337+
4338+
static struct attribute *ublk_attrs[] = {
4339+
&dev_attr_uuid.attr,
4340+
NULL,
4341+
};
4342+
4343+
static umode_t ublk_attrs_are_visible(struct kobject *kobj,
4344+
struct attribute *a, int n)
4345+
{
4346+
struct device *dev = kobj_to_dev(kobj);
4347+
struct gendisk *disk = dev_to_disk(dev);
4348+
struct ublk_device *ub = disk->private_data;
4349+
4350+
if (a == &dev_attr_uuid.attr &&
4351+
(ub->params.types & UBLK_PARAM_TYPE_UUID))
4352+
return S_IRUGO;
4353+
4354+
return a->mode;
4355+
}
4356+
4357+
static const struct attribute_group ublk_attr_group = {
4358+
.attrs = ublk_attrs,
4359+
.is_visible = ublk_attrs_are_visible,
4360+
};
4361+
4362+
static const struct attribute_group *ublk_attr_groups[] = {
4363+
&ublk_attr_group,
4364+
NULL,
4365+
};
4366+
43164367
/* align max io buffer size with PAGE_SIZE */
43174368
static void ublk_align_max_io_size(struct ublk_device *ub)
43184369
{
@@ -4508,7 +4559,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub,
45084559
goto out_put_cdev;
45094560
}
45104561

4511-
ret = add_disk(disk);
4562+
ret = device_add_disk(NULL, disk, ublk_attr_groups);
45124563
if (ret)
45134564
goto out_put_cdev;
45144565

include/uapi/linux/ublk_cmd.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,10 @@ struct ublk_param_integrity {
770770
__u8 pad[5];
771771
};
772772

773+
struct ublk_param_uuid {
774+
__u8 uuid[16];
775+
};
776+
773777
struct ublk_params {
774778
/*
775779
* Total length of parameters, userspace has to set 'len' for both
@@ -785,6 +789,7 @@ struct ublk_params {
785789
#define UBLK_PARAM_TYPE_DMA_ALIGN (1 << 4)
786790
#define UBLK_PARAM_TYPE_SEGMENT (1 << 5)
787791
#define UBLK_PARAM_TYPE_INTEGRITY (1 << 6) /* requires UBLK_F_INTEGRITY */
792+
#define UBLK_PARAM_TYPE_UUID (1 << 7)
788793
__u32 types; /* types of parameter included */
789794

790795
struct ublk_param_basic basic;
@@ -794,6 +799,7 @@ struct ublk_params {
794799
struct ublk_param_dma_align dma;
795800
struct ublk_param_segment seg;
796801
struct ublk_param_integrity integrity;
802+
struct ublk_param_uuid uuid;
797803
};
798804

799805
/*

0 commit comments

Comments
 (0)