summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/man5/zfs-module-parameters.515
-rw-r--r--module/zfs/zvol.c17
2 files changed, 32 insertions, 0 deletions
diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5
index 6d4a8c304..015ab0186 100644
--- a/man/man5/zfs-module-parameters.5
+++ b/man/man5/zfs-module-parameters.5
@@ -1631,6 +1631,21 @@ Max number of blocks to discard at once
Default value: \fB16,384\fR.
.RE
+.sp
+.ne 2
+.na
+\fBzvol_prefetch_bytes\fR (uint)
+.ad
+.RS 12n
+When adding a zvol to the system prefetch \fBzvol_prefetch_bytes\fR
+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 \fBblkid(8)\fR or by the kernel scanning for a partition
+table.
+.sp
+Default value: \fB131,072\fR.
+.RE
+
.SH ZFS I/O SCHEDULER
ZFS issues I/O operations to leaf vdevs to satisfy and complete I/Os.
The I/O scheduler determines when and in what order those operations are
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");