All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@lst.de>
To: Jens Axboe <axboe@kernel.dk>
Cc: Keith Busch <keith.busch@intel.com>,
	Sagi Grimberg <sagi@grimberg.me>, Hannes Reinecke <hare@suse.de>,
	Johannes Thumshirn <jthumshirn@suse.de>,
	linux-nvme@lists.infradead.org, linux-block@vger.kernel.org
Subject: [PATCH 06/17] block: introduce GENHD_FL_HIDDEN
Date: Wed, 18 Oct 2017 18:52:47 +0200	[thread overview]
Message-ID: <20171018165258.23212-7-hch@lst.de> (raw)
In-Reply-To: <20171018165258.23212-1-hch@lst.de>

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: Christoph Hellwig <hch@lst.de>
---
 block/genhd.c         | 53 ++++++++++++++++++++++++++++++++++-----------------
 include/linux/genhd.h |  1 +
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 1174d24e405e..0b28cd491b1d 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -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 @@ static void register_disk(struct device *parent, struct gendisk *disk)
 	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 @@ static void register_disk(struct device *parent, struct gendisk *disk)
  */
 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);
 
-	/* Register BDI before referencing it from bdev */
-	bdi = disk->queue->backing_dev_info;
-	bdi_register_owner(bdi, disk_to_dev(disk));
-
-	blk_register_region(disk_devt(disk), disk->minors, NULL,
-			    exact_match, exact_lock, 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 */
+		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,7 +715,8 @@ void del_gendisk(struct gendisk *disk)
 	set_capacity(disk, 0);
 	disk->flags &= ~GENHD_FL_UP;
 
-	sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
+	if (!(disk->flags & GENHD_FL_HIDDEN))
+		sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
 	if (disk->queue) {
 		/*
 		 * Unregister bdi before releasing device numbers (as they can
@@ -712,13 +727,15 @@ void del_gendisk(struct gendisk *disk)
 	} else {
 		WARN_ON(1);
 	}
-	blk_unregister_region(disk_devt(disk), disk->minors);
+
+	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);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 5c0ed5db33c2..93aae3476f58 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -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 */
-- 
2.14.1

WARNING: multiple messages have this Message-ID (diff)
From: hch@lst.de (Christoph Hellwig)
Subject: [PATCH 06/17] block: introduce GENHD_FL_HIDDEN
Date: Wed, 18 Oct 2017 18:52:47 +0200	[thread overview]
Message-ID: <20171018165258.23212-7-hch@lst.de> (raw)
In-Reply-To: <20171018165258.23212-1-hch@lst.de>

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: Christoph Hellwig <hch at lst.de>
---
 block/genhd.c         | 53 ++++++++++++++++++++++++++++++++++-----------------
 include/linux/genhd.h |  1 +
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index 1174d24e405e..0b28cd491b1d 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -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 @@ static void register_disk(struct device *parent, struct gendisk *disk)
 	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 @@ static void register_disk(struct device *parent, struct gendisk *disk)
  */
 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);
 
-	/* Register BDI before referencing it from bdev */
-	bdi = disk->queue->backing_dev_info;
-	bdi_register_owner(bdi, disk_to_dev(disk));
-
-	blk_register_region(disk_devt(disk), disk->minors, NULL,
-			    exact_match, exact_lock, 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 */
+		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,7 +715,8 @@ void del_gendisk(struct gendisk *disk)
 	set_capacity(disk, 0);
 	disk->flags &= ~GENHD_FL_UP;
 
-	sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
+	if (!(disk->flags & GENHD_FL_HIDDEN))
+		sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
 	if (disk->queue) {
 		/*
 		 * Unregister bdi before releasing device numbers (as they can
@@ -712,13 +727,15 @@ void del_gendisk(struct gendisk *disk)
 	} else {
 		WARN_ON(1);
 	}
-	blk_unregister_region(disk_devt(disk), disk->minors);
+
+	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);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 5c0ed5db33c2..93aae3476f58 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -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 */
-- 
2.14.1

  parent reply	other threads:[~2017-10-18 16:52 UTC|newest]

Thread overview: 150+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-18 16:52 nvme multipath support V4 Christoph Hellwig
2017-10-18 16:52 ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 01/17] block: move REQ_NOWAIT Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  5:48   ` Hannes Reinecke
2017-10-19  5:48     ` Hannes Reinecke
2017-10-19  6:46   ` Johannes Thumshirn
2017-10-19  6:46     ` Johannes Thumshirn
2017-10-18 16:52 ` [PATCH 02/17] block: add REQ_DRV bit Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  5:48   ` Hannes Reinecke
2017-10-19  5:48     ` Hannes Reinecke
2017-10-19  6:47   ` Johannes Thumshirn
2017-10-19  6:47     ` Johannes Thumshirn
2017-10-18 16:52 ` [PATCH 03/17] block: provide a direct_make_request helper Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19 10:35   ` Sagi Grimberg
2017-10-19 10:35     ` Sagi Grimberg
2017-10-19 10:36     ` Sagi Grimberg
2017-10-19 10:36       ` Sagi Grimberg
2017-10-19 13:54     ` Christoph Hellwig
2017-10-19 13:54       ` Christoph Hellwig
2017-10-19 14:42       ` Sagi Grimberg
2017-10-19 14:42         ` Sagi Grimberg
2017-10-18 16:52 ` [PATCH 04/17] block: add a blk_steal_bios helper Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 05/17] block: don't look at the struct device dev_t in disk_devt Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  8:32   ` Johannes Thumshirn
2017-10-19  8:32     ` Johannes Thumshirn
2017-10-18 16:52 ` Christoph Hellwig [this message]
2017-10-18 16:52   ` [PATCH 06/17] block: introduce GENHD_FL_HIDDEN Christoph Hellwig
2017-10-19  8:31   ` Johannes Thumshirn
2017-10-19  8:31     ` Johannes Thumshirn
2017-10-19 12:45   ` Hannes Reinecke
2017-10-19 12:45     ` Hannes Reinecke
2017-10-19 13:15     ` Christoph Hellwig
2017-10-19 13:15       ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 07/17] nvme: use ida_simple_{get,remove} for the controller instance Christoph Hellwig
2017-10-18 16:52   ` [PATCH 07/17] nvme: use ida_simple_{get, remove} " Christoph Hellwig
2017-10-19  6:53   ` [PATCH 07/17] nvme: use ida_simple_{get,remove} " Johannes Thumshirn
2017-10-19  6:53     ` [PATCH 07/17] nvme: use ida_simple_{get, remove} " Johannes Thumshirn
2017-10-19  6:58   ` [PATCH 07/17] nvme: use ida_simple_{get,remove} " Sagi Grimberg
2017-10-19  6:58     ` Sagi Grimberg
2017-10-19 15:14   ` Keith Busch
2017-10-19 15:14     ` Keith Busch
2017-10-19 15:12     ` Christoph Hellwig
2017-10-19 15:12       ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 08/17] nvme: use kref_get_unless_zero in nvme_find_get_ns Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  6:54   ` Johannes Thumshirn
2017-10-19  6:54     ` Johannes Thumshirn
2017-10-19  6:59   ` Sagi Grimberg
2017-10-19  6:59     ` Sagi Grimberg
2017-10-18 16:52 ` [PATCH 09/17] nvme: simplify nvme_open Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  6:55   ` Johannes Thumshirn
2017-10-19  6:55     ` Johannes Thumshirn
2017-10-19  6:59   ` Sagi Grimberg
2017-10-19  6:59     ` Sagi Grimberg
2017-10-18 16:52 ` [PATCH 10/17] nvme: switch controller refcounting to use struct device Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  7:17   ` Sagi Grimberg
2017-10-19  7:17     ` Sagi Grimberg
2017-10-19  7:20     ` Christoph Hellwig
2017-10-19  7:20       ` Christoph Hellwig
2017-10-19  7:31       ` Sagi Grimberg
2017-10-19  7:31         ` Sagi Grimberg
2017-10-19  7:37         ` Christoph Hellwig
2017-10-19  7:37           ` Christoph Hellwig
2017-10-19 10:02           ` Sagi Grimberg
2017-10-19 10:02             ` Sagi Grimberg
2017-10-19 10:18             ` Christoph Hellwig
2017-10-19 10:18               ` Christoph Hellwig
2017-10-19 10:33               ` Sagi Grimberg
2017-10-19 10:33                 ` Sagi Grimberg
2017-10-19 13:54                 ` Christoph Hellwig
2017-10-19 13:54                   ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 11/17] nvme: get rid of nvme_ctrl_list Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  7:18   ` Sagi Grimberg
2017-10-19  7:18     ` Sagi Grimberg
2017-10-19  7:22   ` Johannes Thumshirn
2017-10-19  7:22     ` Johannes Thumshirn
2017-10-19  7:24     ` Christoph Hellwig
2017-10-19  7:24       ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 12/17] nvme: check for a live controller in nvme_dev_open Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  7:18   ` Sagi Grimberg
2017-10-19  7:18     ` Sagi Grimberg
2017-10-19  7:23   ` Johannes Thumshirn
2017-10-19  7:23     ` Johannes Thumshirn
2017-10-18 16:52 ` [PATCH 13/17] nvme: track subsystems Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-18 22:39   ` Keith Busch
2017-10-18 22:39     ` Keith Busch
2017-10-18 22:53     ` Keith Busch
2017-10-18 22:53       ` Keith Busch
2017-10-19  7:14     ` Christoph Hellwig
2017-10-19  7:14       ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 14/17] nvme: introduce a nvme_ns_ids structure Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 15/17] nvme: track shared namespaces Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  7:36   ` Johannes Thumshirn
2017-10-19  7:36     ` Johannes Thumshirn
2017-10-19 11:06   ` Sagi Grimberg
2017-10-19 11:06     ` Sagi Grimberg
2017-10-19 13:51     ` Christoph Hellwig
2017-10-19 13:51       ` Christoph Hellwig
2017-10-20 19:03   ` Javier González
2017-10-20 19:03     ` Javier González
2017-10-18 16:52 ` [PATCH 16/17] nvme: implement multipath access to nvme subsystems Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-18 16:52 ` [PATCH 17/17] nvme: also expose the namespace identification sysfs files for mpath nodes Christoph Hellwig
2017-10-18 16:52   ` Christoph Hellwig
2017-10-19  7:45   ` Johannes Thumshirn
2017-10-19  7:45     ` Johannes Thumshirn
2017-10-19 15:24   ` Sagi Grimberg
2017-10-19 15:24     ` Sagi Grimberg
2017-10-23  2:08 ` nvme multipath support V4 Guan Junxiong
2017-10-23  2:08   ` Guan Junxiong
2017-10-23  6:33   ` Sagi Grimberg
2017-10-23  6:33     ` Sagi Grimberg
2017-10-23 14:51 nvme multipath support V5 Christoph Hellwig
2017-10-23 14:51 ` [PATCH 06/17] block: introduce GENHD_FL_HIDDEN Christoph Hellwig
2017-10-23 14:51   ` Christoph Hellwig
2017-10-24  7:18   ` Hannes Reinecke
2017-10-24  7:18     ` Hannes Reinecke
2017-10-28  6:15     ` Christoph Hellwig
2017-10-28  6:15       ` Christoph Hellwig
2017-10-24 21:40   ` Mike Snitzer
2017-10-24 21:40     ` Mike Snitzer
2017-10-28  6:38     ` Christoph Hellwig
2017-10-28  6:38       ` Christoph Hellwig
2017-10-28  7:20       ` Guan Junxiong
2017-10-28  7:20         ` Guan Junxiong
2017-10-28  7:42         ` Christoph Hellwig
2017-10-28  7:42           ` Christoph Hellwig
2017-10-28 10:09           ` Guan Junxiong
2017-10-28 10:09             ` Guan Junxiong
2017-10-29  8:00             ` Anish Jhaveri
2017-10-29  8:00               ` Anish Jhaveri
2017-10-29  8:57             ` Christoph Hellwig
2017-10-29  8:57               ` Christoph Hellwig
2017-10-28 14:17       ` Mike Snitzer
2017-10-28 14:17         ` Mike Snitzer
2017-10-29 10:01         ` Hannes Reinecke
2017-10-29 10:01           ` Hannes Reinecke
2017-10-30  4:09           ` Guan Junxiong
2017-10-30  4:09             ` Guan Junxiong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171018165258.23212-7-hch@lst.de \
    --to=hch@lst.de \
    --cc=axboe@kernel.dk \
    --cc=hare@suse.de \
    --cc=jthumshirn@suse.de \
    --cc=keith.busch@intel.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=sagi@grimberg.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.