]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
mkfs.xfs: properly handle physical sector size
authorEric Sandeen <sandeen@sandeen.net>
Fri, 2 Mar 2012 04:46:35 +0000 (22:46 -0600)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 2 Mar 2012 04:46:35 +0000 (22:46 -0600)
This splits the fs_topology structure "sectorsize" into
logical & physical, and gets both via blkid_get_topology().

This primarily allows us to default to using the physical
sectorsize for mkfs's "sector size" value, the fundamental
size of any IOs the filesystem will perform.

We reduce mkfs.xfs's "sector size" to logical if
a block size < physical sector size is specified.
This is suboptimal, but permissable.

For block size < sector size, differentiate the error
message based on whether the sector size was manually
specified, or deduced.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
mkfs/xfs_mkfs.c

index 140837a64ce1fedc0b423d2fc07137a465fb3854..d0c2eb6e0bd06891925fcb92c289040fba150659 100644 (file)
@@ -33,7 +33,8 @@ struct fs_topology {
        int     dsunit;         /* stripe unit - data subvolume */
        int     dswidth;        /* stripe width - data subvolume */
        int     rtswidth;       /* stripe width - rt subvolume */
-       int     sectorsize;
+       int     lsectorsize;    /* logical sector size &*/
+       int     psectorsize;    /* physical sector size */
        int     sectoralign;
 };
 
@@ -373,7 +374,8 @@ static void blkid_get_topology(
        const char      *device,
        int             *sunit,
        int             *swidth,
-       int             *sectorsize,
+       int             *lsectorsize,
+       int             *psectorsize,
        int             force_overwrite)
 {
 
@@ -408,8 +410,11 @@ static void blkid_get_topology(
        val = blkid_topology_get_optimal_io_size(tp) >> 9;
        if (val > 1)
                *swidth = val;
-       val = blkid_probe_get_sectorsize(pr);
-       *sectorsize = val;
+
+       val = blkid_topology_get_logical_sector_size(tp);
+       *lsectorsize = val;
+       val = blkid_topology_get_physical_sector_size(tp);
+       *psectorsize = val;
 
        if (blkid_topology_get_alignment_offset(tp) != 0) {
                fprintf(stderr,
@@ -422,8 +427,8 @@ static void blkid_get_topology(
 
                        exit(EXIT_FAILURE);
                }
-               /* force a 512b sector size if the device is misaligned */
-               *sectorsize = BBSIZE;
+               /* Do not use physical sector size if the device is misaligned */
+               *psectorsize = *lsectorsize;
        }
 
        blkid_free_probe(pr);
@@ -445,14 +450,15 @@ static void get_topology(
                const char *dfile = xi->volname ? xi->volname : xi->dname;
 
                blkid_get_topology(dfile, &ft->dsunit, &ft->dswidth,
-                                  &ft->sectorsize, force_overwrite);
+                                  &ft->lsectorsize, &ft->psectorsize,
+                                  force_overwrite);
        }
 
        if (xi->rtname && !xi->risfile) {
                int dummy;
 
                blkid_get_topology(xi->rtname, &dummy, &ft->rtswidth,
-                                  &dummy, force_overwrite);
+                                  &dummy, &dummy, force_overwrite);
        }
 }
 #else /* ENABLE_BLKID */
@@ -1663,9 +1669,29 @@ main(
        } else if (!ssflag) {
                /*
                 * Unless specified manually on the command line use the
-                * advertised sector size of the device.
+                * advertised sector size of the device.  We use the physical
+                * sector size unless the requested block size is smaller
+                * than that, then we can use logical, but warn about the
+                * inefficiency.
                 */
-               sectorsize = ft.sectorsize ? ft.sectorsize : XFS_MIN_SECTORSIZE;
+
+               /* Older kernels may not have physical/logical distinction */
+               if (!ft.psectorsize)
+                       ft.psectorsize = ft.lsectorsize;
+
+               sectorsize = ft.psectorsize ? ft.psectorsize :
+                                             XFS_MIN_SECTORSIZE;
+
+               if ((blocksize < sectorsize) && (blocksize >= ft.lsectorsize)) {
+                       fprintf(stderr,
+_("specified blocksize %d is less than device physical sector size %d\n"),
+                               blocksize, ft.psectorsize);
+                       fprintf(stderr,
+_("switching to logical sector size %d\n"),
+                               ft.lsectorsize);
+                       sectorsize = ft.lsectorsize ? ft.lsectorsize :
+                                                     XFS_MIN_SECTORSIZE;
+               }
        }
 
        if (ft.sectoralign || !ssflag) {
@@ -1678,12 +1704,17 @@ main(
 
        if (sectorsize < XFS_MIN_SECTORSIZE ||
            sectorsize > XFS_MAX_SECTORSIZE || sectorsize > blocksize) {
-               fprintf(stderr, _("illegal sector size %d\n"), sectorsize);
+               if (ssflag)
+                       fprintf(stderr, _("illegal sector size %d\n"), sectorsize);
+               else
+                       fprintf(stderr,
+_("block size %d cannot be smaller than logical sector size %d\n"),
+                               blocksize, ft.lsectorsize);
                usage();
        }
-       if (sectorsize < ft.sectorsize) {
+       if (sectorsize < ft.lsectorsize) {
                fprintf(stderr, _("illegal sector size %d; hw sector is %d\n"),
-                       sectorsize, ft.sectorsize);
+                       sectorsize, ft.lsectorsize);
                usage();
        }
        if (lsectorsize < XFS_MIN_SECTORSIZE ||