int imaxpct;
int imflag;
int inodelog;
- int inodebits;
int inopblock;
int ipflag;
int isflag;
break;
case 'V':
printf("%s version %s\n", progname, VERSION);
- break;
+ exit(0);
case '?':
unknown(optopt, "");
}
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) ||
}
/*
- * 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);
}
/*
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);
}
/*
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;
}
}
}
+ 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;
}
}
- /*
- * 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));
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",
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);
"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,
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.
*/
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 &&