.B \-l internal \-l size=10000b
are equivalent.
.PP
-In the descriptions below, sizes are given in bytes, blocks, kilobytes,
-or megabytes.
+In the descriptions below, sizes are given in sectors, bytes, blocks,
+kilobytes, megabytes, or gigabytes.
Sizes are treated as hexadecimal if prefixed by 0x or 0X,
octal if prefixed by 0, or decimal otherwise.
+If suffixed with \f3s\f1 then the size is converted by multiplying it
+by 512 (sector size).
If suffixed with \f3b\f1 then the size is converted by multiplying it
by the filesystem's block size.
If suffixed with \f3k\f1 then the size is converted by multiplying it by 1024.
The valid suboptions are:
.BI internal[= value ],
\f3size=\f1\f2value\f1,
-\f3version=\f1\f2[1|2]\f1 and
-\f3sunit=\f1\f2value\f1.
+\f3version=\f1\f2[1|2]\f1,
+\f3sunit=\f1\f2value\f1, and
+\f3su=\f1\f2value\f1.
.IP
The
.B internal
.IP
Otherwise, the
.B size
-option is only needed if the log section of the filesystem
+suboption is only needed if the log section of the filesystem
should occupy less space than the size of the special file.
The size is specified in bytes or blocks, with a \f3b\f1 suffix
meaning multiplication by the filesystem block size, as described above.
.IP
Using the
.B version
-option to set a version 2 log enables the
+suboption to specify a version 2 log enables the
.B sunit
-option, and allows the logbsize to be increased beyond 32K.
+suboption, and allows the logbsize to be increased beyond 32K.
+.IP
The
.B sunit
-option specifies the alignment to be used for log writes,
-it can be in bytes or filesystem blocks.
+suboption specifies the alignment to be used for log writes.
+The suboption value has to be specified in 512-byte block units.
+Use the
+.B su
+suboption to specify the log stripe unit size in bytes.
Log writes will be aligned on this boundary,
and rounded up to this boundary.
This gives major improvements in performance on some configurations
such as software raid5 when the sunit is specified as the filesystem
block size.
+The equivalent byte value must be a multiple of the filesystem block
+size.
+.IP
+The
+.B su
+suboption is an alternative to using
+.B sunit.
+The
+.B su
+suboption is used to specify the log stripe.
+The suboption value has to be specified in bytes,
+(usually using the \f3s\f1 or \f3b\f1 suffixes).
+This value must be a multiple of the filesystem block size.
.TP
.B \-n
Naming options.
#include <volume.h>
#include <mountinfo.h>
#include <libxfs.h>
+#include <ctype.h>
#include "xfs_mkfs.h"
#include "maxtrres.h"
"size",
#define L_VERSION 3
"version",
-#define L_LSUNIT 4
+#define L_SUNIT 4
"sunit",
-#define L_DEV 5
+#define L_SU 5
+ "su",
+#define L_DEV 6
"logdev",
#ifdef MKFS_SIMULATION
-#define L_FILE 6
+#define L_FILE 7
"file",
-#define L_NAME 7
+#define L_NAME 8
"name",
#endif
NULL
(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) - 1) + (rb)))
static void
-calc_stripe_factors(int dsu, int dsw, int *dsunit, int *dswidth)
+calc_stripe_factors(int dsu, int dsw, int lsu, int *dsunit, int *dswidth, int *lsunit)
{
+ /* Handle data sunit/swidth options */
if (*dsunit || *dswidth) {
if (dsu || dsw) {
fprintf(stderr,
- "su/sw should not be used in conjunction with sunit/swidth\n");
+ "data su/sw should not be used in conjunction with data sunit/swidth\n");
usage();
}
if ((*dsunit && !*dswidth) || (!*dsunit && *dswidth)) {
fprintf(stderr,
- "both sunit and swidth options have to be specified\n");
+ "both data sunit and data swidth options must be specified\n");
usage();
}
}
if (dsu || dsw) {
if (*dsunit || *dswidth) {
fprintf(stderr,
- "sunit/swidth should not be used in conjunction with su/sw\n");
+ "data sunit/swidth should not be used in conjunction with data su/sw\n");
usage();
}
if ((dsu && !dsw) || (!dsu && dsw)) {
fprintf(stderr,
- "both su and sw options have to be specified\n");
+ "both data su and data sw options must be specified\n");
usage();
}
if (dsu % BBSIZE) {
- fprintf(stderr, "su must be a multiple of %d\n",
+ fprintf(stderr, "data su must be a multiple of %d\n",
BBSIZE);
usage();
}
if (*dsunit && (*dswidth % *dsunit != 0)) {
fprintf(stderr,
- "stripe width (%d) has to be a multiple of the stripe unit (%d)\n",
+ "data stripe width (%d) must be a multiple of the data stripe unit (%d)\n",
*dswidth, *dsunit);
usage();
}
+
+ /* Handle log sunit options */
+
+ if (*lsunit) {
+ if (lsu) {
+ fprintf(stderr,
+ "log su should not be used in conjunction with log sunit\n");
+ usage();
+ }
+ }
+
+ if (lsu) {
+ if (*lsunit) {
+ fprintf(stderr,
+ "log sunit should not be used in conjunction with log su\n");
+ usage();
+ }
+
+ if (lsu % BBSIZE) {
+ fprintf(stderr, "log su must be a multiple of %d\n",
+ BBSIZE);
+ usage();
+ }
+
+ *lsunit = (int)BTOBBT(lsu);
+ }
}
static int
int logversion;
int lvflag;
int lsflag;
+ int lsu;
int lsunit;
- char *logstripe;
int min_logblocks;
mnt_check_state_t *mnt_check_state;
int mnt_partition_count;
xi.notvolok = 1;
xi.setblksize = 1;
dfile = logfile = rtfile = NULL;
- dsize = logsize = logstripe = rtsize = rtextsize = protofile = NULL;
+ dsize = logsize = rtsize = rtextsize = protofile = NULL;
opterr = 0;
- dsu = dsw = dsunit = dswidth = nodsflag = lalign = lsunit = 0;
+ dsu = dsw = dsunit = dswidth = nodsflag = lalign = lsu = lsunit = 0;
do_overlap_checks = 1;
extent_flagging = 0;
force_overwrite = 0;
reqval('d', dopts, D_SUNIT);
if (dsunit)
respec('d', dopts, D_SUNIT);
- if (blflag || bsflag)
- dsunit = cvtnum(blocksize,
- value);
- else
- dsunit = cvtnum(0, value);
+ if (!isdigits(value)) {
+ fprintf(stderr,
+ "%s: Specify data sunit in 512-byte blocks, no unit suffix\n",
+ progname);
+ exit(1);
+ }
+ dsunit = cvtnum(0, value);
break;
case D_SWIDTH:
if (!value)
reqval('d', dopts, D_SWIDTH);
if (dswidth)
respec('d', dopts, D_SWIDTH);
- if (blflag || bsflag)
- dswidth = cvtnum(blocksize,
- value);
- else
- dswidth = cvtnum(0, value);
+ if (!isdigits(value)) {
+ fprintf(stderr,
+ "%s: Specify data swidth in 512-byte blocks, no unit suffix\n",
+ progname);
+ exit(1);
+ }
+ dswidth = cvtnum(0, value);
break;
case D_SU:
if (!value)
reqval('d', dopts, D_SU);
if (dsu)
respec('d', dopts, D_SU);
- dsu = cvtnum(0, value);
+ if (blflag || bsflag)
+ dsu = cvtnum(blocksize,
+ value);
+ else
+ dsu = cvtnum(0, value);
break;
case D_SW:
if (!value)
reqval('d', dopts, D_SW);
if (dsw)
respec('d', dopts, D_SW);
+ if (!isdigits(value)) {
+ fprintf(stderr,
+ "%s: Specify data sw as multiple of su, no unit suffix\n",
+ progname);
+ exit(1);
+ }
dsw = cvtnum(0, value);
break;
case D_UNWRITTEN:
illegal(value, "l internal");
liflag = 1;
break;
- case L_LSUNIT:
+ case L_SU:
if (!value)
- reqval('l', lopts, L_LSUNIT);
- if (logstripe)
- respec('l', lopts, L_LSUNIT);
- logstripe = value;
+ reqval('l', lopts, L_SU);
+ if (lsu)
+ respec('l', lopts, L_SU);
+ if (blflag || bsflag)
+ lsu = cvtnum(blocksize,
+ value);
+ else
+ lsu = cvtnum(0, value);
+ break;
+ case L_SUNIT:
+ if (!value)
+ reqval('l', lopts, L_SUNIT);
+ if (lsunit)
+ respec('l', lopts, L_SUNIT);
+ if (!isdigits(value)) {
+ fprintf(stderr,
+ "Specify log sunit in 512-byte blocks, no size suffix\n");
+ usage();
+ }
+ lsunit = cvtnum(0, value);
break;
#ifdef HAVE_VOLUME_MANAGER
case L_NAME:
(long long)logbytes, blocksize,
(long long)(logblocks << blocklog));
}
- if (logstripe) {
- lsunit = cvtnum(blocksize, logstripe);
- }
#ifdef HAVE_VOLUME_MANAGER
if (xi.risfile && (!rtsize || !xi.rtname)) {
fprintf(stderr,
usage();
}
- calc_stripe_factors(dsu, dsw, &dsunit, &dswidth);
+ calc_stripe_factors(dsu, dsw, lsu, &dsunit, &dswidth, &lsunit);
/* other global variables */
sectlog = 9; /* i.e. 512 bytes */
else {
fprintf(stderr, "%s: "
"Stripe unit(%d) or stripe width(%d) is not a multiple of the block size(%d)\n",
- progname, dsunit, dswidth, blocksize);
+ progname, BBTOB(dsunit), BBTOB(dswidth),
+ blocksize);
exit(1);
}
}
*/
if (lsunit) {
- if (lsunit % blocksize != 0) {
+ if ((BBTOB(lsunit) % blocksize != 0)) {
fprintf(stderr,
-"log stripe unit (%d) is not a multiple of the block size (%d)\n",
- lsunit, blocksize);
+"log stripe unit (%d) must be a multiple of the block size (%d)\n",
+ BBTOB(lsunit), blocksize);
exit(1);
}
+ /* convert from 512 byte blocks to fs blocks */
+ lsunit = DTOBT(lsunit);
} else if (dsunit) {
- /* lsunit is in bytes here, dsunit is fs blocks */
- lsunit = dsunit << blocklog;
+ /* lsunit and dsunit now in fs blocks */
+ lsunit = dsunit;
}
- if (lsunit > 256 * 1024) {
+ if ((lsunit * blocksize) > 256 * 1024) {
fprintf(stderr,
-"log stripe unit (%d) is too large for kernel to handle\n", lsunit);
+"log stripe unit (%d bytes) is too large for kernel to handle (max 256k)\n",
+ (lsunit * blocksize));
exit(1);
}
* Align the logstart at stripe unit boundary.
*/
- if (lsunit && ((logstart % XFS_B_TO_FSB(mp, lsunit)) != 0)) {
+ if (lsunit && ((logstart % lsunit) != 0)) {
logstart = fixup_log_stripe(mp, lsflag, logstart,
- agsize, XFS_B_TO_FSB(mp, lsunit),
- &logblocks, blocklog);
+ agsize, lsunit, &logblocks, blocklog);
lalign = 1;
} else if (dsunit && ((logstart % dsunit) != 0)) {
logstart = fixup_log_stripe(mp, lsflag, logstart,
sbp->sb_width = dswidth;
if (dirversion == 2)
sbp->sb_dirblklog = dirblocklog - blocklog;
- if (logversion == 2)
- sbp->sb_logsunit = (lsunit == 0) ? 1 : lsunit;
+ if (logversion == 2) /* This is stored in bytes */
+ sbp->sb_logsunit = (lsunit == 0) ? 1 : XFS_FSB_TO_B(mp, lsunit);
else
sbp->sb_logsunit = 0;
if (iaflag) {
" =%-22s sunit=%-6d swidth=%d blks, unwritten=%d\n"
"naming =version %-14d bsize=%-6d\n"
"log =%-22s bsize=%-6d blocks=%lld, version=%d\n"
- " =%-22s sunit=%d\n"
+ " =%-22s sunit=%d blks\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,
return rval;
}
+/* returns 1 if string contains nothing but [0-9], 0 otherwise */
+
+int
+isdigits(char *str)
+{
+ int i;
+ int n = strlen(str);
+
+ for (i = 0; i < n; i++) {
+ if (!isdigit(str[i]))
+ return 0;
+ }
+ return 1;
+}
+
long long
cvtnum(
int blocksize,
usage();
}
+ if (*sp == 's' && sp[1] == '\0')
+ return 512LL * i;
if (*sp == 'k' && sp[1] == '\0')
return 1024LL * i;
if (*sp == 'm' && sp[1] == '\0')
fprintf(stderr, "Usage: %s\n\
/* blocksize */ [-b log=n|size=num]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
- sunit=value,swidth=value,unwritten=0|1,\n\
- su=value,sw=value]\n\
+ (sunit=value,swidth=value|su=num,sw=num),\n\
+ unwritten=0|1]\n\
/* inode size */ [-i log=n|perblock=n|size=num,maxpct=n]\n\
-/* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx]\n\
- version=n,sunit=value]\n\
-/* naming */ [-n log=n|size=num|version=n]\n\
+/* log subvol */ [-l agnum=n,internal,size=num,logdev=xxx\n\
+ version=n,sunit=value|su=num]\n\
+/* naming */ [-n log=n|size=num,version=n]\n\
/* label */ [-L label (maximum 12 characters)]\n\
/* prototype file */ [-p fname]\n\
/* quiet */ [-q]\n\
based on the filesystem size. Default log reaches its largest size at 1TB.\n\
This can be overridden with the -l options or using a volume manager with a\n\
log subvolume.\n\
-<num> is xxx (bytes), or xxxb (blocks), or xxxk (xxx KB), or xxxm (xxx MB)\n\
+<num> is xxx (bytes), xxxs (512 blocks), xxxb (fs blocks), xxxk (xxx KB),\n\
+ or xxxm (xxx MB)\n\
<value> is xxx (512 blocks).\n",
progname);
exit(1);