Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions drivers/block/ublk_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
(UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD | \
UBLK_PARAM_TYPE_DEVT | UBLK_PARAM_TYPE_ZONED | \
UBLK_PARAM_TYPE_DMA_ALIGN | UBLK_PARAM_TYPE_SEGMENT | \
UBLK_PARAM_TYPE_INTEGRITY)
UBLK_PARAM_TYPE_INTEGRITY | UBLK_PARAM_TYPE_UUID)

#define UBLK_BATCH_F_ALL \
(UBLK_BATCH_F_HAS_ZONE_LBA | \
Expand Down Expand Up @@ -976,6 +976,14 @@ static int ublk_validate_params(const struct ublk_device *ub)
return -EINVAL;
}

if (ub->params.types & UBLK_PARAM_TYPE_UUID) {
const struct ublk_param_uuid *p = &ub->params.uuid;
uuid_t uuid;

import_uuid(&uuid, p->uuid);
if (uuid_is_null(&uuid))
return -EINVAL;
}
return 0;
}

Expand Down Expand Up @@ -4313,6 +4321,49 @@ static int ublk_add_chdev(struct ublk_device *ub)
return ret;
}

static ssize_t uuid_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct gendisk *disk = dev_to_disk(dev);
struct ublk_device *ub = disk->private_data;
const struct ublk_param_uuid *p = &ub->params.uuid;
uuid_t uuid;

import_uuid(&uuid, p->uuid);
return sprintf(buf, "%pU\n", &uuid);
}

static DEVICE_ATTR_RO(uuid);

static struct attribute *ublk_attrs[] = {
&dev_attr_uuid.attr,
NULL,
};

static umode_t ublk_attrs_are_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = kobj_to_dev(kobj);
struct gendisk *disk = dev_to_disk(dev);
struct ublk_device *ub = disk->private_data;

if (a == &dev_attr_uuid.attr &&
(ub->params.types & UBLK_PARAM_TYPE_UUID))
return S_IRUGO;

return a->mode;
}

static const struct attribute_group ublk_attr_group = {
.attrs = ublk_attrs,
.is_visible = ublk_attrs_are_visible,
};

static const struct attribute_group *ublk_attr_groups[] = {
&ublk_attr_group,
NULL,
};

/* align max io buffer size with PAGE_SIZE */
static void ublk_align_max_io_size(struct ublk_device *ub)
{
Expand Down Expand Up @@ -4508,7 +4559,7 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub,
goto out_put_cdev;
}

ret = add_disk(disk);
ret = device_add_disk(NULL, disk, ublk_attr_groups);
if (ret)
goto out_put_cdev;

Expand Down
6 changes: 6 additions & 0 deletions include/uapi/linux/ublk_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,10 @@ struct ublk_param_integrity {
__u8 pad[5];
};

struct ublk_param_uuid {
__u8 uuid[16];
};

struct ublk_params {
/*
* Total length of parameters, userspace has to set 'len' for both
Expand All @@ -785,6 +789,7 @@ struct ublk_params {
#define UBLK_PARAM_TYPE_DMA_ALIGN (1 << 4)
#define UBLK_PARAM_TYPE_SEGMENT (1 << 5)
#define UBLK_PARAM_TYPE_INTEGRITY (1 << 6) /* requires UBLK_F_INTEGRITY */
#define UBLK_PARAM_TYPE_UUID (1 << 7)
__u32 types; /* types of parameter included */

struct ublk_param_basic basic;
Expand All @@ -794,6 +799,7 @@ struct ublk_params {
struct ublk_param_dma_align dma;
struct ublk_param_segment seg;
struct ublk_param_integrity integrity;
struct ublk_param_uuid uuid;
};

/*
Expand Down