char *mopts[] = {
#define M_CRC 0
"crc",
+#define M_FINOBT 1
+ "finobt",
NULL
};
struct fs_topology ft;
int lazy_sb_counters;
int crcs_enabled;
+ int finobt;
progname = basename(argv[0]);
setlocale(LC_ALL, "");
worst_freelist = 0;
lazy_sb_counters = 1;
crcs_enabled = 0;
+ finobt = 0;
memset(&fsx, 0, sizeof(fsx));
memset(&xi, 0, sizeof(xi));
usage();
}
break;
+ case M_FINOBT:
+ if (!value || *value == '\0')
+ reqval('m', mopts, M_CRC);
+ c = atoi(value);
+ if (c < 0 || c > 1)
+ illegal(value, "m finobt");
+ finobt = c;
+ break;
default:
unknown('m', value);
}
}
}
+ /*
+ * The kernel doesn't currently support crc=0,finobt=1 filesystems.
+ * Catch it here, disable finobt and warn the user.
+ */
+ if (finobt && !crcs_enabled) {
+ fprintf(stderr,
+_("warning: finobt not supported without CRC support, disabled.\n"));
+ finobt = 0;
+ }
+
if (nsflag || nlflag) {
if (dirblocksize < blocksize ||
dirblocksize > XFS_MAX_BLOCKSIZE) {
mp->m_blkbb_log = sbp->sb_blocklog - BBSHIFT;
mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT;
+ /*
+ * sb_versionnum and finobt flags must be set before we use
+ * XFS_PREALLOC_BLOCKS().
+ */
+ sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters,
+ attrversion == 2, !projid16bit, 0,
+ (!crcs_enabled && dirftype));
+ sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag,
+ dsunit != 0,
+ logversion == 2, attrversion == 1,
+ (sectorsize != BBSIZE ||
+ lsectorsize != BBSIZE),
+ nci, sbp->sb_features2 != 0);
+ /*
+ * Due to a structure alignment issue, sb_features2 ended up in one
+ * of two locations, the second "incorrect" location represented by
+ * the sb_bad_features2 field. To avoid older kernels mounting
+ * filesystems they shouldn't, set both field to the same value.
+ */
+ sbp->sb_bad_features2 = sbp->sb_features2;
+
+ if (finobt)
+ sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT;
+
if (loginternal) {
/*
* Readjust the log size to fit within an AG if it was sized
printf(_(
"meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n"
" =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n"
- " =%-22s crc=%u\n"
+ " =%-22s crc=%-8u finobt=%u\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 ftype=%d\n"
"realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"),
dfile, isize, (long long)agcount, (long long)agsize,
"", sectorsize, attrversion, !projid16bit,
- "", crcs_enabled,
+ "", crcs_enabled, finobt,
"", blocksize, (long long)dblocks, imaxpct,
"", dsunit, dswidth,
dirversion, dirblocksize, nci, dirftype,
sbp->sb_logsectsize = 0;
}
- sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters,
- attrversion == 2, !projid16bit, 0,
- (!crcs_enabled && dirftype));
- sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag,
- dsunit != 0,
- logversion == 2, attrversion == 1,
- (sectorsize != BBSIZE ||
- lsectorsize != BBSIZE),
- nci, sbp->sb_features2 != 0);
- /*
- * Due to a structure alignment issue, sb_features2 ended up in one
- * of two locations, the second "incorrect" location represented by
- * the sb_bad_features2 field. To avoid older kernels mounting
- * filesystems they shouldn't, set both field to the same value.
- */
- sbp->sb_bad_features2 = sbp->sb_features2;
-
if (force_overwrite)
zero_old_xfs_structures(&xi, sbp);
agi->agi_count = 0;
agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
agi->agi_level = cpu_to_be32(1);
+ if (finobt) {
+ agi->agi_free_root = cpu_to_be32(XFS_FIBT_BLOCK(mp));
+ agi->agi_free_level = cpu_to_be32(1);
+ }
agi->agi_freecount = 0;
agi->agi_newino = cpu_to_be32(NULLAGINO);
agi->agi_dirino = cpu_to_be32(NULLAGINO);
xfs_btree_init_block(mp, buf, XFS_IBT_MAGIC, 0, 0,
agno, 0);
libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
+ /*
+ * Free INO btree root block
+ */
+ if (!finobt)
+ continue;
+
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
+ bsize);
+ buf->b_ops = &xfs_inobt_buf_ops;
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, blocksize);
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ xfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0,
+ agno, XFS_BTREE_CRC_BLOCKS);
+ else
+ xfs_btree_init_block(mp, buf, XFS_FIBT_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\
+/* metadata */ [-m crc=0|1,finobt=0|1]\n\
/* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
(sunit=value,swidth=value|su=num,sw=num|noalign),\n\
sectlog=n|sectsize=num\n\