Commit 8ddcd653 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: introduce GENHD_FL_HIDDEN



With this flag a driver can create a gendisk that can be used for I/O
submission inside the kernel, but which is not registered as user
facing block device.  This will be useful for the NVMe multipath
implementation.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 517bf3c3
Loading
Loading
Loading
Loading
+50 −18
Original line number Diff line number Diff line
@@ -585,6 +585,11 @@ static void register_disk(struct device *parent, struct gendisk *disk)
	 */
	pm_runtime_set_memalloc_noio(ddev, true);

	if (disk->flags & GENHD_FL_HIDDEN) {
		dev_set_uevent_suppress(ddev, 0);
		return;
	}

	disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj);
	disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);

@@ -616,6 +621,11 @@ exit:
	while ((part = disk_part_iter_next(&piter)))
		kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
	disk_part_iter_exit(&piter);

	err = sysfs_create_link(&ddev->kobj,
				&disk->queue->backing_dev_info->dev->kobj,
				"bdi");
	WARN_ON(err);
}

/**
@@ -630,7 +640,6 @@ exit:
 */
void device_add_disk(struct device *parent, struct gendisk *disk)
{
	struct backing_dev_info *bdi;
	dev_t devt;
	int retval;

@@ -639,7 +648,8 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
	 * parameters make sense.
	 */
	WARN_ON(disk->minors && !(disk->major || disk->first_minor));
	WARN_ON(!disk->minors && !(disk->flags & GENHD_FL_EXT_DEVT));
	WARN_ON(!disk->minors &&
		!(disk->flags & (GENHD_FL_EXT_DEVT | GENHD_FL_HIDDEN)));

	disk->flags |= GENHD_FL_UP;

@@ -648,18 +658,26 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
		WARN_ON(1);
		return;
	}
	disk_to_dev(disk)->devt = devt;
	disk->major = MAJOR(devt);
	disk->first_minor = MINOR(devt);

	disk_alloc_events(disk);

	if (disk->flags & GENHD_FL_HIDDEN) {
		/*
		 * Don't let hidden disks show up in /proc/partitions,
		 * and don't bother scanning for partitions either.
		 */
		disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
		disk->flags |= GENHD_FL_NO_PART_SCAN;
	} else {
		/* Register BDI before referencing it from bdev */
	bdi = disk->queue->backing_dev_info;
	bdi_register_owner(bdi, disk_to_dev(disk));

		disk_to_dev(disk)->devt = devt;
		bdi_register_owner(disk->queue->backing_dev_info,
				disk_to_dev(disk));
		blk_register_region(disk_devt(disk), disk->minors, NULL,
				    exact_match, exact_lock, disk);
	}
	register_disk(parent, disk);
	blk_register_queue(disk);

@@ -669,10 +687,6 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
	 */
	WARN_ON_ONCE(!blk_get_queue(disk->queue));

	retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj,
				   "bdi");
	WARN_ON(retval);

	disk_add_events(disk);
	blk_integrity_add(disk);
}
@@ -701,6 +715,7 @@ void del_gendisk(struct gendisk *disk)
	set_capacity(disk, 0);
	disk->flags &= ~GENHD_FL_UP;

	if (!(disk->flags & GENHD_FL_HIDDEN))
		sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
	if (disk->queue) {
		/*
@@ -712,13 +727,15 @@ void del_gendisk(struct gendisk *disk)
	} else {
		WARN_ON(1);
	}

	if (!(disk->flags & GENHD_FL_HIDDEN)) {
		blk_unregister_region(disk_devt(disk), disk->minors);
		kobject_put(disk->part0.holder_dir);
		kobject_put(disk->slave_dir);
	}

	part_stat_set_all(&disk->part0, 0);
	disk->part0.stamp = 0;

	kobject_put(disk->part0.holder_dir);
	kobject_put(disk->slave_dir);
	if (!sysfs_deprecated)
		sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk)));
	pm_runtime_set_memalloc_noio(disk_to_dev(disk), false);
@@ -781,6 +798,10 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
		spin_unlock_bh(&ext_devt_lock);
	}

	if (unlikely(disk->flags & GENHD_FL_HIDDEN)) {
		put_disk(disk);
		disk = NULL;
	}
	return disk;
}
EXPORT_SYMBOL(get_gendisk);
@@ -1024,6 +1045,15 @@ static ssize_t disk_removable_show(struct device *dev,
		       (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
}

static ssize_t disk_hidden_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct gendisk *disk = dev_to_disk(dev);

	return sprintf(buf, "%d\n",
		       (disk->flags & GENHD_FL_HIDDEN ? 1 : 0));
}

static ssize_t disk_ro_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
@@ -1061,6 +1091,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev,
static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL);
static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
static DEVICE_ATTR(hidden, S_IRUGO, disk_hidden_show, NULL);
static DEVICE_ATTR(ro, S_IRUGO, disk_ro_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
static DEVICE_ATTR(alignment_offset, S_IRUGO, disk_alignment_offset_show, NULL);
@@ -1085,6 +1116,7 @@ static struct attribute *disk_attrs[] = {
	&dev_attr_range.attr,
	&dev_attr_ext_range.attr,
	&dev_attr_removable.attr,
	&dev_attr_hidden.attr,
	&dev_attr_ro.attr,
	&dev_attr_size.attr,
	&dev_attr_alignment_offset.attr,
+1 −0
Original line number Diff line number Diff line
@@ -140,6 +140,7 @@ struct hd_struct {
#define GENHD_FL_NATIVE_CAPACITY		128
#define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE	256
#define GENHD_FL_NO_PART_SCAN			512
#define GENHD_FL_HIDDEN				1024

enum {
	DISK_EVENT_MEDIA_CHANGE			= 1 << 0, /* media changed */