]> git.proxmox.com Git - mirror_zfs-debian.git/commitdiff
Align parition end on 1 MiB boundary
authorNed Bass <bass6@llnl.gov>
Wed, 29 Feb 2012 18:08:20 +0000 (10:08 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 5 Mar 2012 17:49:50 +0000 (09:49 -0800)
Some devices have exhibited sensitivity to the ending alignment of
partitions.  In particular, even if the first partition begins at 1
MiB, we have seen many sd driver task abort errors with certain SSDs
if the first partition doesn't end on a 1 MiB boundary.  This occurs
when the vdev label is read during pool creation or importation and
causes a delay of about 30 seconds per device.  It can also be
simulated with dd when the pool isn't imported:

  dd if=/dev/sda1 of=/dev/null bs=262144 count=1

For the record, this problem was observed with SMARTMOD
SG9XCA2E200GE01 200GB SSDs.  Unfortunately I don't have a good
explanation for this behavior. It seems to have something to do with
highly fragmented single-sector requests being issued to the device,
which it may not support.  With end-aligned partitions at least
page-sized requests were queued and issued to the driver according
to blktrace. In any case, aligning the partition end is a fairly
innocuous work-around, wasting at most 1 MiB of space.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #574

lib/libzfs/libzfs_pool.c

index 4b4d81f7b865cde873e4b6cbfb1cac2e10c2213d..311def6b6279ce54c6b2b18474a29b48ab5c21f2 100644 (file)
@@ -672,10 +672,12 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
  * Don't start the slice at the default block of 34; many storage
  * devices will use a stripe width of 128k, other vendors prefer a 1m
  * alignment.  It is best to play it safe and ensure a 1m alignment
- * give 512b blocks.  When the block size is larger by a power of 2
- * we will still be 1m aligned.
+ * given 512B blocks.  When the block size is larger by a power of 2
+ * we will still be 1m aligned.  Some devices are sensitive to the
+ * partition ending alignment as well.
  */
-#define        NEW_START_BLOCK 2048
+#define        NEW_START_BLOCK         2048
+#define        PARTITION_END_ALIGNMENT 2048
 
 /*
  * Validate the given pool name, optionally putting an extended error message in
@@ -3786,6 +3788,7 @@ zpool_label_disk(libzfs_handle_t *hdl, zpool_handle_t *zhp, char *name)
        if (start_block == MAXOFFSET_T)
                start_block = NEW_START_BLOCK;
        slice_size -= start_block;
+       slice_size = P2ALIGN(slice_size, PARTITION_END_ALIGNMENT);
 
        vtoc->efi_parts[0].p_start = start_block;
        vtoc->efi_parts[0].p_size = slice_size;