summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2015-08-18 13:51:20 -0700
committerBrian Behlendorf <[email protected]>2015-09-09 14:38:29 -0700
commit9965059ab9991a5fc7df9a489021e73880b3bcc0 (patch)
tree0770e9f65b22908acd9e22f925fdd393e8fb312e /module/zfs
parent8198d18ca7e05ec30139e10d658a8b06c0ec4c55 (diff)
Prefetch start and end of volumes
When adding a zvol to the system prefetch zvol_prefetch_bytes from the start and end of the volume. Prefetching these regions of the volume is desirable because they are likely to be accessed immediately by blkid(8), the kernel scanning for a partition table, or another task which probes the devices. Signed-off-by: Richard Yao <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #3659
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/zvol.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
index 7c1f024ca..bcdd8e8de 100644
--- a/module/zfs/zvol.c
+++ b/module/zfs/zvol.c
@@ -50,6 +50,7 @@
unsigned int zvol_inhibit_dev = 0;
unsigned int zvol_major = ZVOL_MAJOR;
+unsigned int zvol_prefetch_bytes = (128 * 1024);
unsigned long zvol_max_discard_blocks = 16384;
static kmutex_t zvol_state_lock;
@@ -1296,6 +1297,7 @@ __zvol_create_minor(const char *name, boolean_t ignore_snapdev)
objset_t *os;
dmu_object_info_t *doi;
uint64_t volsize;
+ uint64_t len;
unsigned minor = 0;
int error = 0;
@@ -1369,6 +1371,18 @@ __zvol_create_minor(const char *name, boolean_t ignore_snapdev)
zil_replay(os, zv, zvol_replay_vector);
}
+ /*
+ * When udev detects the addition of the device it will immediately
+ * invoke blkid(8) to determine the type of content on the device.
+ * Prefetching the blocks commonly scanned by blkid(8) will speed
+ * up this process.
+ */
+ len = MIN(MAX(zvol_prefetch_bytes, 0), SPA_MAXBLOCKSIZE);
+ if (len > 0) {
+ dmu_prefetch(os, ZVOL_OBJ, 0, len);
+ dmu_prefetch(os, ZVOL_OBJ, volsize - len, len);
+ }
+
zv->zv_objset = NULL;
out_dmu_objset_disown:
dmu_objset_disown(os, zvol_tag);
@@ -1625,3 +1639,6 @@ MODULE_PARM_DESC(zvol_major, "Major number for zvol device");
module_param(zvol_max_discard_blocks, ulong, 0444);
MODULE_PARM_DESC(zvol_max_discard_blocks, "Max number of blocks to discard");
+
+module_param(zvol_prefetch_bytes, uint, 0644);
+MODULE_PARM_DESC(zvol_prefetch_bytes, "Prefetch N bytes at zvol start+end");