]> granicus.if.org Git - zfs/commitdiff
Prefetch start and end of volumes
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 18 Aug 2015 20:51:20 +0000 (13:51 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 9 Sep 2015 21:38:29 +0000 (14:38 -0700)
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 <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #3659

man/man5/zfs-module-parameters.5
module/zfs/zvol.c

index 6d4a8c3048ccf8b0dc32f272ce8cbebf605d1efe..015ab0186957950d3459ca75283e486260b7e4da 100644 (file)
@@ -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
index 7c1f024ca37e7db6bdb41758d2d71b1896a72459..bcdd8e8def6db9c6325a3fc05c9ab61836c8046d 100644 (file)
@@ -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");