]> granicus.if.org Git - zfs/commitdiff
Allow setting a lower ashift with -o ashift
authorMartin Matuska <martin@matuska.org>
Fri, 12 Apr 2013 17:26:03 +0000 (10:26 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 12 Apr 2013 17:50:46 +0000 (10:50 -0700)
Previous patches have allowed you to set an increased ashift to
avoid doing 512b IO with 4k sector devices.  However, it was not
possible to set the ashift lower than the reported physical sector
size even when a smaller logical size was supported.  In practice,
there are several cases where settong a lower ashift is useful:

* Most modern drives now correctly report their physical sector
  size as 4k.  This causes zfs to correctly default to using a 4k
  sector size (ashift=12).  However, for some usage models this
  new default ashift value causes an unacceptable increase in
  space usage.  Filesystems with many small files may see the
  total available space reduced to 30-40% which is unacceptable.

* When replacing a drive in an existing pool which was created
  with ashift=9 a modern 4k sector drive cannot be used.  The
  'zpool replace' command will issue an error that the new drive
  has an 'incompatible sector alignment'.  However, by allowing
  the ashift to be manual specified as smaller, non-optimal,
  value the device may still be safely used.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #1381
Closes #1328
Issue #967
Issue #548

module/zfs/vdev.c

index 06097f355767d7f9f74cb7feda0469ca40ee98c7..afff4d423deac58ef1770f61c28010774ac7cee0 100644 (file)
@@ -1258,11 +1258,12 @@ vdev_open(vdev_t *vd)
        if (vd->vdev_asize == 0) {
                /*
                 * This is the first-ever open, so use the computed values.
-                * For testing purposes, a higher ashift can be requested.
+                * For compatibility, a different ashift can be requested.
                 */
                vd->vdev_asize = asize;
                vd->vdev_max_asize = max_asize;
-               vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
+               if (vd->vdev_ashift == 0)
+                       vd->vdev_ashift = ashift;
        } else {
                /*
                 * Detect if the alignment requirement has increased.