NULL
};
+char *mopts[] = {
+#define M_CRC 0
+ "crc",
+ NULL
+};
+
#define TERABYTES(count, blog) ((__uint64_t)(count) << (40 - (blog)))
#define GIGABYTES(count, blog) ((__uint64_t)(count) << (30 - (blog)))
#define MEGABYTES(count, blog) ((__uint64_t)(count) << (20 - (blog)))
libxfs_init_t xi;
struct fs_topology ft;
int lazy_sb_counters;
+ int crcs_enabled;
progname = basename(argv[0]);
setlocale(LC_ALL, "");
force_overwrite = 0;
worst_freelist = 0;
lazy_sb_counters = 1;
+ crcs_enabled = 0;
memset(&fsx, 0, sizeof(fsx));
memset(&xi, 0, sizeof(xi));
xi.isdirect = LIBXFS_DIRECT;
xi.isreadonly = LIBXFS_EXCLUSIVELY;
- while ((c = getopt(argc, argv, "b:d:i:l:L:n:KNp:qr:s:CfV")) != EOF) {
+ while ((c = getopt(argc, argv, "b:d:i:l:L:m:n:KNp:qr:s:CfV")) != EOF) {
switch (c) {
case 'C':
case 'f':
illegal(optarg, "L");
label = optarg;
break;
+ case 'm':
+ p = optarg;
+ while (*p != '\0') {
+ char *value;
+
+ switch (getsubopt(&p, (constpp)mopts, &value)) {
+ case M_CRC:
+ if (!value || *value == '\0')
+ reqval('m', mopts, M_CRC);
+ c = atoi(value);
+ if (c < 0 || c > 1)
+ illegal(value, "m crc");
+ crcs_enabled = c;
+ break;
+ default:
+ unknown('m', value);
+ }
+ }
+ break;
case 'n':
p = optarg;
while (*p != '\0') {
inodelog = blocklog - libxfs_highbit32(inopblock);
isize = 1 << inodelog;
} else if (!ilflag && !isflag) {
- inodelog = XFS_DINODE_DFL_LOG;
+ inodelog = crcs_enabled ? XFS_DINODE_DFL_CRC_LOG
+ : XFS_DINODE_DFL_LOG;
isize = 1 << inodelog;
}
+ if (crcs_enabled && inodelog < XFS_DINODE_DFL_CRC_LOG) {
+ fprintf(stderr,
+ _("Minimum inode size for CRCs is %d bytes\n"),
+ 1 << XFS_DINODE_DFL_CRC_LOG);
+ usage();
+ }
+
if (xi.lisfile && (!logsize || !xi.logname)) {
fprintf(stderr,
_("if -l file then -l name and -l size are required\n"));
sectorsize, xi.rtbsize);
}
- max_tr_res = max_trans_res(dirversion,
+ max_tr_res = max_trans_res(crcs_enabled, dirversion,
sectorlog, blocklog, inodelog, dirblocklog);
ASSERT(max_tr_res);
min_logblocks = max_tr_res * XFS_MIN_LOG_FACTOR;
*/
if (!logsize) {
logblocks = MIN(logblocks,
- agsize - XFS_PREALLOC_BLOCKS(mp));
+ XFS_ALLOC_AG_MAX_USABLE(mp));
}
if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) {
fprintf(stderr,
printf(_(
"meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
+ " =%-22s crc=%-5u\n"
"data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n"
" =%-22s sunit=%-6u swidth=%u blks\n"
"naming =version %-14u bsize=%-6u ascii-ci=%d\n"
"realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
dfile, isize, (long long)agcount, (long long)agsize,
"", sectorsize, attrversion, projid32bit,
+ "", crcs_enabled,
"", blocksize, (long long)dblocks, imaxpct,
"", dsunit, dswidth,
dirversion, dirblocksize, nci,
sbp->sb_logsectlog = 0;
sbp->sb_logsectsize = 0;
}
- sbp->sb_features2 = XFS_SB_VERSION2_MKFS(lazy_sb_counters,
+ sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters,
attrversion == 2, projid32bit == 1, 0);
- sbp->sb_versionnum = XFS_SB_VERSION_MKFS(iaflag, dsunit != 0,
+ sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag,
+ dsunit != 0,
logversion == 2, attrversion == 1,
(sectorsize != BBSIZE ||
lsectorsize != BBSIZE),
* kernel/userspace header initialisation code the same.
*/
for (agno = 0; agno < agcount; agno++) {
+ struct xfs_agfl *agfl;
+ int bucket;
+
/*
* Superblock.
*/
nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp));
agf->agf_freeblks = cpu_to_be32(nbmblocks);
agf->agf_longest = cpu_to_be32(nbmblocks);
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ platform_uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_uuid);
+
if (loginternal && agno == logagno) {
be32_add_cpu(&agf->agf_freeblks, -logblocks);
agf->agf_longest = cpu_to_be32(agsize -
worst_freelist = XFS_MIN_FREELIST(agf, mp);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ /*
+ * AG freelist header block
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
+ XFS_FSS_TO_BB(mp, 1));
+ buf->b_ops = &xfs_agfl_buf_ops;
+ agfl = XFS_BUF_TO_AGFL(buf);
+ /* setting to 0xff results in initialisation to NULLAGBLOCK */
+ memset(agfl, 0xff, sectorsize);
+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
+ agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
+ agfl->agfl_seqno = cpu_to_be32(agno);
+ platform_uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_uuid);
+ for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
+ agfl->agfl_bno[bucket] = cpu_to_be32(NULLAGBLOCK);
+ }
+
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
/*
* AG header block: inodes
*/
agi->agi_freecount = 0;
agi->agi_newino = cpu_to_be32(NULLAGINO);
agi->agi_dirino = cpu_to_be32(NULLAGINO);
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ platform_uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_uuid);
for (c = 0; c < XFS_AGI_UNLINKED_BUCKETS; c++)
agi->agi_unlinked[c] = cpu_to_be32(NULLAGINO);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
buf->b_ops = &xfs_allocbt_buf_ops;
block = XFS_BUF_TO_BLOCK(buf);
memset(block, 0, blocksize);
- block->bb_magic = cpu_to_be32(XFS_ABTB_MAGIC);
- block->bb_level = 0;
- block->bb_numrecs = cpu_to_be16(1);
- block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ xfs_btree_init_block(mp, buf, XFS_ABTB_CRC_MAGIC, 0, 1,
+ agno, XFS_BTREE_CRC_BLOCKS);
+ else
+ xfs_btree_init_block(mp, buf, XFS_ABTB_MAGIC, 0, 1,
+ agno, 0);
+
arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
if (loginternal && agno == logagno) {
buf->b_ops = &xfs_allocbt_buf_ops;
block = XFS_BUF_TO_BLOCK(buf);
memset(block, 0, blocksize);
- block->bb_magic = cpu_to_be32(XFS_ABTC_MAGIC);
- block->bb_level = 0;
- block->bb_numrecs = cpu_to_be16(1);
- block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ xfs_btree_init_block(mp, buf, XFS_ABTC_CRC_MAGIC, 0, 1,
+ agno, XFS_BTREE_CRC_BLOCKS);
+ else
+ xfs_btree_init_block(mp, buf, XFS_ABTC_MAGIC, 0, 1,
+ agno, 0);
+
arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp));
if (loginternal && agno == logagno) {
buf->b_ops = &xfs_inobt_buf_ops;
block = XFS_BUF_TO_BLOCK(buf);
memset(block, 0, blocksize);
- block->bb_magic = cpu_to_be32(XFS_IBT_MAGIC);
- block->bb_level = 0;
- block->bb_numrecs = 0;
- block->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
- block->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ xfs_btree_init_block(mp, buf, XFS_IBT_CRC_MAGIC, 0, 0,
+ agno, XFS_BTREE_CRC_BLOCKS);
+ else
+ xfs_btree_init_block(mp, buf, XFS_IBT_MAGIC, 0, 0,
+ agno, 0);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
}
{
fprintf(stderr, _("Usage: %s\n\
/* blocksize */ [-b log=n|size=num]\n\
+/* metadata */ [-m crc=[0|1]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
(sunit=value,swidth=value|su=num,sw=num),\n\
sectlog=n|sectsize=num\n\
XFS_SB_VERSION_EXTFLGBIT | \
XFS_SB_VERSION_DIRV2BIT)
-#define XFS_SB_VERSION_MKFS(ia,dia,log2,attr1,sflag,ci,more) (\
- ((ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \
- ( XFS_SB_VERSION_4 | \
+#define XFS_SB_VERSION_MKFS(crc,ia,dia,log2,attr1,sflag,ci,more) (\
+ ((crc)||(ia)||(dia)||(log2)||(attr1)||(sflag)||(ci)||(more)) ? \
+ (((crc) ? XFS_SB_VERSION_5 : XFS_SB_VERSION_4) | \
((ia) ? XFS_SB_VERSION_ALIGNBIT : 0) | \
((dia) ? XFS_SB_VERSION_DALIGNBIT : 0) | \
((log2) ? XFS_SB_VERSION_LOGV2BIT : 0) | \
XFS_DFL_SB_VERSION_BITS | \
0 ) : XFS_SB_VERSION_1 )
-#define XFS_SB_VERSION2_MKFS(lazycount, attr2, projid32bit, parent) (\
+#define XFS_SB_VERSION2_MKFS(crc, lazycount, attr2, projid32bit, parent) (\
((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) | \
((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) | \
((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) | \
((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) | \
+ ((crc) ? XFS_SB_VERSION2_CRCBIT : 0) | \
0 )
#define XFS_DFL_BLOCKSIZE_LOG 12 /* 4096 byte blocks */
#define XFS_DINODE_DFL_LOG 8 /* 256 byte inodes */
+#define XFS_DINODE_DFL_CRC_LOG 9 /* 512 byte inodes for CRCs */
#define XFS_MIN_DATA_BLOCKS 100
#define XFS_MIN_INODE_PERBLOCK 2 /* min inodes per block */
#define XFS_DFL_IMAXIMUM_PCT 25 /* max % of space for inodes */
extern void res_failed (int err);
/* maxtrres.c */
-extern int max_trans_res (int dirversion,
+extern int max_trans_res (int crcs_enabled, int dirversion,
int sectorlog, int blocklog, int inodelog, int dirblocklog);
#endif /* __XFS_MKFS_H__ */