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");