]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - mkfs/xfs_mkfs.c
Undoes mod: xfs-cmds:slinx:120772a
[thirdparty/xfsprogs-dev.git] / mkfs / xfs_mkfs.c
index c6a287b886749d84ba616d0657f27349d910f0d5..5c18439db5efcd9d73c2c3f5019a99854279dfc6 100644 (file)
@@ -379,7 +379,6 @@ main(int argc, char **argv)
        int                     imaxpct;
        int                     imflag;
        int                     inodelog;
-       int                     inodebits;
        int                     inopblock;
        int                     ipflag;
        int                     isflag;
@@ -891,7 +890,7 @@ main(int argc, char **argv)
                        break;
                case 'V':
                        printf("%s version %s\n", progname, VERSION);
-                       break;
+                       exit(0);
                case '?':
                        unknown(optopt, "");
                }
@@ -1120,6 +1119,17 @@ main(int argc, char **argv)
                usage();
        }
 
+       /*
+        * Ok, Linux only has a 1024-byte resolution on device _size_,
+        * and the sizes below are in basic 512-byte blocks,
+        * so if we have (size % 2), on any partition, we can't get
+        * to the last 512 bytes.  Just chop it down by a block.
+        */
+
+       xi.dsize -= (xi.dsize % 2);
+       xi.rtsize -= (xi.rtsize % 2);
+       xi.logBBsize -= (xi.logBBsize % 2);
+
        if (!force_overwrite) {
                if (check_overwrite(dfile) ||
                    check_overwrite(logfile) ||
@@ -1385,12 +1395,14 @@ main(int argc, char **argv)
        }
 
        /*
-        * if user set the AG size, and if the last AG is too small,
-        * reduce the filesystem size and drop the blocks.
+        * If the last AG is too small, reduce the filesystem size
+        * and drop the blocks.
         */
-       if (!daflag &&
-           (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
-               dblocks -= dblocks % agsize;
+       if ( dblocks % agsize != 0 &&
+            (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
+               dblocks = (xfs_drfsbno_t)((agcount - 1) * agsize);
+               agcount--;
+               ASSERT(agcount != 0);
        }
 
        /*
@@ -1400,14 +1412,17 @@ main(int argc, char **argv)
        if (!daflag && !dasize &&
            (agsize > XFS_AG_BEST_BLOCKS(blocklog,dblocks))) {
                agsize = XFS_AG_BEST_BLOCKS(blocklog,dblocks);
+               agcount = dblocks / agsize + (dblocks % agsize != 0);
                /*
                 * If the last AG is too small, reduce the filesystem size
                 * and drop the blocks.
                 */
-               if (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog)) {
-                       dblocks -= dblocks % agsize;
+               if ( dblocks % agsize != 0 &&
+                   (dblocks % agsize < XFS_AG_MIN_BLOCKS(blocklog))) {
+                       dblocks = (xfs_drfsbno_t)((agcount - 1) * agsize);
+                       agcount--;
+                       ASSERT(agcount != 0);
                }
-               agcount = dblocks / agsize + (dblocks % agsize != 0);
        }
 
        /*
@@ -1443,13 +1458,11 @@ main(int argc, char **argv)
                        fprintf(stderr, "%s: "
   "Specified data stripe unit %d is not the same as the xlv stripe unit %d\n", 
                                progname, dsunit, xlv_dsunit);
-                       exit(1);
                }
                if (xlv_dswidth && xlv_dswidth != dswidth) {
                        fprintf(stderr, "%s: "
-"Specified data stripe width (%d) is not the same as the xlv stripe width (%d)\n",
+"Specified data stripe width %d is not the same as the xlv stripe width %d\n",
                                progname, dswidth, xlv_dswidth);
-                       exit(1);
                }
        } else {
                dsunit = xlv_dsunit;
@@ -1505,6 +1518,37 @@ main(int argc, char **argv)
                                }
                        }
                }
+               if ((agsize % dswidth) == 0) {
+                       /* This is a non-optimal configuration because all AGs
+                        * start on the same disk in the stripe.  Decreasing
+                        * the AG size by one sunit will guarantee that this
+                        * does not happen
+                        */
+                       tmp_agsize = agsize - dsunit;
+                       if (tmp_agsize < XFS_AG_MIN_BLOCKS(blocklog))
+                               tmp_agsize = agsize + dsunit;
+                       if (daflag || dasize) {
+                               fprintf(stderr,
+"Warning: AG size is a multiple of stripe width.  This can cause performance\n"
+"problems by aligning all AGs on the same disk.  To avoid this, rerun mkfs with\n"
+"an AG size that is one stripe unit smaller, for example %lld\n",
+                                       tmp_agsize);
+                       } else {
+                               agsize = tmp_agsize;
+                               agcount = dblocks/agsize + (dblocks % agsize != 0);
+                               /*
+                                * If the last AG is too small, reduce the
+                                * filesystem size and drop the blocks.
+                                */
+                               if ( dblocks % agsize != 0 &&
+                                   (dblocks % agsize <
+                                   XFS_AG_MIN_BLOCKS(blocklog))) {
+                                       dblocks = (xfs_drfsbno_t)((agcount - 1) * agsize);
+                                       agcount--;
+                                       ASSERT(agcount != 0);
+                               }
+                       }
+               }
        } else {
                if (nodsflag)
                        dsunit = dswidth = 0;
@@ -1516,67 +1560,8 @@ main(int argc, char **argv)
                }
        }
 
-       /*
-        * Check to see if inode number will be > 32 significant bits
-        * Note that libxfs_highbitXX returns 0 -> XX-1,
-        * so to get the bit count, add one to what we get.
-        */
-
-       inodebits = (libxfs_highbit32(blocksize/isize - 1) + 1)
-                 + (libxfs_highbit64(agsize - 1) + 1)
-                 + (libxfs_highbit64(agcount - 1) + 1);
-
-       if (inodebits > XFS_MAX_INODE_SIG_BITS) {
-
-               int new_isize;
-               int new_isize_ok;
-
-               new_isize = isize << (inodebits - XFS_MAX_INODE_SIG_BITS);
-
-               new_isize_ok = (new_isize <= blocksize / XFS_MIN_INODE_PERBLOCK
-                               && new_isize <= XFS_DINODE_MAX_SIZE);
-               
-               if (ilflag + ipflag + isflag == 0) {
-                       /*
-                        * If we didn't specify inode size, just bump it up
-                        * unless we can't go far enough.
-                        */
-
-                       if (new_isize_ok) {
-                               isize = new_isize;
-                               /* re-calc inodebits */
-                               inodebits = (libxfs_highbit32(blocksize/isize - 1) + 1)
-                                         + (libxfs_highbit64(agsize - 1) + 1)
-                                         + (libxfs_highbit64(agcount - 1) + 1);
-                               /* Let's not get too chatty, no fprintf here */
-                       } else {
-                               /*
-                                * Can't do nothin' for ya, man!
-                                * Don't bother changing isize at all,
-                                * one bit over is as bad as 20.
-                                */
-                               fprintf(stderr,
-                                       "warning: inode numbers exceed %d "
-                                       " significant bits (%d)\n",
-                                       XFS_MAX_INODE_SIG_BITS, inodebits);
-                       }
-               } else {
-                       /* if isize specified, just warn the user */
-                       fprintf(stderr, 
-                               "warning: inode numbers exceed %d "
-                               "significant bits (%d)\n",
-                               XFS_MAX_INODE_SIG_BITS, inodebits);
-                       if (new_isize_ok) {
-                               fprintf(stderr,
-                                       "         increase inode size to %d to "
-                                       "avoid this\n", new_isize);
-                       }
-               }
-       }
-
        protostring = setup_proto(protofile);
        bsize = 1 << (blocklog - BBSHIFT);
-       buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, 1);
        mp = &mbuf;
        sbp = &mp->m_sb;
        bzero(mp, sizeof(xfs_mount_t));
@@ -1584,6 +1569,14 @@ main(int argc, char **argv)
        sbp->sb_agblklog = (__uint8_t)libxfs_log2_roundup((unsigned int)agsize);
        mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
        if (loginternal) {
+               /*
+                * Readjust the log size to fit within an AG if it was sized
+                * automaticly.
+                */
+               if (!logsize) {
+                       logblocks = MIN(logblocks,
+                                       agsize - XFS_PREALLOC_BLOCKS(mp));
+               }
                if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) {
                        fprintf(stderr,
        "internal log size %lld too large, must fit in allocation group\n",
@@ -1690,6 +1683,19 @@ main(int argc, char **argv)
                XFS_SB_VERSION_MKFS(iaflag, dsunit != 0, extent_flagging,
                        dirversion == 2);
 
+       /*
+        * Zero out the first 68k in on the device, to obliterate any old 
+        * filesystem signatures out there.  This should take care of 
+        * swap (somewhere around the page size), jfs (32k), 
+        * ext[2,3] and reiser (64k) - and hopefully all else.
+        */
+        
+       buf = libxfs_getbuf(xi.ddev, 0, 136);
+       bzero(XFS_BUF_PTR(buf), 136*BBSIZE);
+       libxfs_writebuf(buf, 1);
+
+       /* OK, now write the superblock */
+       buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, 1);
        bzero(XFS_BUF_PTR(buf), BBSIZE);
        libxfs_xlate_sb(XFS_BUF_PTR(buf), sbp, -1, ARCH_CONVERT,
                        XFS_SB_ALL_BITS);
@@ -1700,14 +1706,12 @@ main(int argc, char **argv)
                   "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
                   "data     =%-22s bsize=%-6d blocks=%lld, imaxpct=%d\n"
                   "         =%-22s sunit=%-6d swidth=%d blks, unwritten=%d\n"
-                  "         =%-22s imaxbits=%-6d\n"
                   "naming   =version %-14d bsize=%-6d\n"
                   "log      =%-22s bsize=%-6d blocks=%lld\n"
                   "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n",
                        dfile, isize, (long long)agcount, (long long)agsize,
                        "", blocksize, (long long)dblocks, sbp->sb_imax_pct,
                        "", dsunit, dswidth, extent_flagging,
-                       "", inodebits,
                        dirversion, dirversion == 1 ? blocksize : dirblocksize,
                        logfile, 1 << blocklog, (long long)logblocks,
                        rtfile, rtextblocks << blocklog,
@@ -1722,6 +1726,18 @@ main(int argc, char **argv)
                        progname);
                exit(1);
        }
+
+       /*
+        * Zero out the last 64k on the device, to obliterate any
+        * old MD RAID (or other) metadata at the end of the device.
+        */
+       if (!xi.disfile) {
+               buf = libxfs_getbuf(xi.ddev, (xi.dsize - BTOBB(65536)), 
+                                   BTOBB(65536));
+               bzero(XFS_BUF_PTR(buf), 65536);
+               libxfs_writebuf(buf, 1);
+       }
+
        /*
         * Zero the log if there is one.
         */
@@ -1736,8 +1752,8 @@ main(int argc, char **argv)
                     XLOG_FMT);
 
        mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 1);
-       if (!mp) {
-               fprintf(stderr, "%s: mount initialization failed\n", progname);
+       if (mp == NULL) {
+               fprintf(stderr, "%s: filesystem failed to initialize\n", progname);
                exit(1);
        }
        if (xi.logdev &&