From: Dave Chinner <david@fromorbit.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH 17/42] mkfs: factor writing AG headers
Date: Wed, 30 Aug 2017 09:50:27 +1000 [thread overview]
Message-ID: <20170829235052.21050-18-david@fromorbit.com> (raw)
In-Reply-To: <20170829235052.21050-1-david@fromorbit.com>
From: Dave Chinner <dchinner@redhat.com>
There are some slight changes to the way log alignment is calculated
in the change. Instead of using a flag, it checks the log start
block to see if it's different to the first free block in the log
AG, and if it is different then does the aligned setup. This means
we no longer have to care if the log is aligned or not, the code
will do the right thing in all cases.
Signed-Off-By: Dave Chinner <dchinner@redhat.com>
---
mkfs/xfs_mkfs.c | 750 +++++++++++++++++++++++++++++---------------------------
1 file changed, 390 insertions(+), 360 deletions(-)
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 2438e50d3f33..13af1ef1cd41 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -2084,22 +2084,401 @@ prepare_devices(
}
+/*
+ * XXX: this code is mostly common with the kernel growfs code.
+ * These initialisations should be pulled into libxfs to keep the
+ * kernel/userspace header initialisation code the same.
+ */
+static void
+initialise_ag_headers(
+ struct mkfs_params *cfg,
+ struct xfs_mount *mp,
+ struct xfs_sb *sbp,
+ xfs_agnumber_t agno,
+ int *worst_freelist)
+{
+ struct xfs_perag *pag = libxfs_perag_get(mp, agno);
+ struct xfs_agfl *agfl;
+ struct xfs_agf *agf;
+ struct xfs_agi *agi;
+ struct xfs_buf *buf;
+ struct xfs_btree_block *block;
+ struct xfs_alloc_rec *arec;
+ struct xfs_alloc_rec *nrec;
+ int bucket;
+ uint64_t agsize = cfg->agsize;
+ xfs_agblock_t agblocks;
+ bool is_log_ag = false;
+ int c;
+
+ if (cfg->loginternal && agno == cfg->logagno)
+ is_log_ag = true;
+
+ /*
+ * Superblock.
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
+ XFS_FSS_TO_BB(mp, 1));
+ buf->b_ops = &xfs_sb_buf_ops;
+ memset(XFS_BUF_PTR(buf), 0, cfg->sectorsize);
+ libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
+ /*
+ * AG header block: freespace
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
+ XFS_FSS_TO_BB(mp, 1));
+ buf->b_ops = &xfs_agf_buf_ops;
+ agf = XFS_BUF_TO_AGF(buf);
+ memset(agf, 0, cfg->sectorsize);
+ if (agno == cfg->agcount - 1)
+ agsize = cfg->dblocks - (xfs_rfsblock_t)(agno * agsize);
+ agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
+ agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
+ agf->agf_seqno = cpu_to_be32(agno);
+ agf->agf_length = cpu_to_be32(agsize);
+ agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
+ agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
+ agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
+ agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
+ pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
+ pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
+
+ if (xfs_sb_version_hasrmapbt(sbp)) {
+ agf->agf_roots[XFS_BTNUM_RMAPi] = cpu_to_be32(XFS_RMAP_BLOCK(mp));
+ agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
+ agf->agf_rmap_blocks = cpu_to_be32(1);
+ }
+
+ if (xfs_sb_version_hasreflink(sbp)) {
+ agf->agf_refcount_root = cpu_to_be32(libxfs_refc_block(mp));
+ agf->agf_refcount_level = cpu_to_be32(1);
+ agf->agf_refcount_blocks = cpu_to_be32(1);
+ }
+
+ agf->agf_flfirst = 0;
+ agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
+ agf->agf_flcount = 0;
+ agblocks = (xfs_agblock_t)(agsize - libxfs_prealloc_blocks(mp));
+ agf->agf_freeblks = cpu_to_be32(agblocks);
+ agf->agf_longest = cpu_to_be32(agblocks);
+
+ if (xfs_sb_version_hascrc(sbp))
+ platform_uuid_copy(&agf->agf_uuid, &sbp->sb_uuid);
+
+ if (is_log_ag) {
+ be32_add_cpu(&agf->agf_freeblks, -(int64_t)cfg->logblocks);
+ agf->agf_longest = cpu_to_be32(agsize -
+ XFS_FSB_TO_AGBNO(mp, cfg->logstart) - cfg->logblocks);
+ }
+ if (libxfs_alloc_min_freelist(mp, pag) > *worst_freelist)
+ *worst_freelist = libxfs_alloc_min_freelist(mp, pag);
+ 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, cfg->sectorsize);
+ if (xfs_sb_version_hascrc(sbp)) {
+ agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
+ agfl->agfl_seqno = cpu_to_be32(agno);
+ platform_uuid_copy(&agfl->agfl_uuid, &sbp->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
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
+ XFS_FSS_TO_BB(mp, 1));
+ agi = XFS_BUF_TO_AGI(buf);
+ buf->b_ops = &xfs_agi_buf_ops;
+ memset(agi, 0, cfg->sectorsize);
+ agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
+ agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
+ agi->agi_seqno = cpu_to_be32(agno);
+ agi->agi_length = cpu_to_be32(agsize);
+ agi->agi_count = 0;
+ agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
+ agi->agi_level = cpu_to_be32(1);
+ if (xfs_sb_version_hasfinobt(sbp)) {
+ 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);
+ if (xfs_sb_version_hascrc(sbp))
+ platform_uuid_copy(&agi->agi_uuid, &sbp->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);
+
+ /*
+ * BNO btree root block
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
+ BTOBB(cfg->blocksize));
+ buf->b_ops = &xfs_allocbt_buf_ops;
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, cfg->blocksize);
+ libxfs_btree_init_block(mp, buf, XFS_BTNUM_BNO, 0, 1, agno, 0);
+
+ arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
+ arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
+ if (is_log_ag) {
+ xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, cfg->logstart);
+
+ ASSERT(start >= libxfs_prealloc_blocks(mp));
+ if (start != libxfs_prealloc_blocks(mp)) {
+ /*
+ * Modify first record to pad stripe align of log
+ */
+ arec->ar_blockcount = cpu_to_be32(start -
+ libxfs_prealloc_blocks(mp));
+ nrec = arec + 1;
+ /*
+ * Insert second record at start of internal log
+ * which then gets trimmed.
+ */
+ nrec->ar_startblock = cpu_to_be32(
+ be32_to_cpu(arec->ar_startblock) +
+ be32_to_cpu(arec->ar_blockcount));
+ arec = nrec;
+ be16_add_cpu(&block->bb_numrecs, 1);
+ }
+ /*
+ * Change record start to after the internal log
+ */
+ be32_add_cpu(&arec->ar_startblock, cfg->logblocks);
+ }
+ /*
+ * Calculate the record block count and check for the case where
+ * the log might have consumed all available space in the AG. If
+ * so, reset the record count to 0 to avoid exposure of an invalid
+ * record start block.
+ */
+ arec->ar_blockcount = cpu_to_be32(agsize -
+ be32_to_cpu(arec->ar_startblock));
+ if (!arec->ar_blockcount)
+ block->bb_numrecs = 0;
+
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
+ /*
+ * CNT btree root block
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
+ BTOBB(cfg->blocksize));
+ buf->b_ops = &xfs_allocbt_buf_ops;
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, cfg->blocksize);
+ libxfs_btree_init_block(mp, buf, XFS_BTNUM_CNT, 0, 1, agno, 0);
+
+ arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
+ arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
+ if (is_log_ag) {
+ xfs_agblock_t start = XFS_FSB_TO_AGBNO(mp, cfg->logstart);
+
+ ASSERT(start >= libxfs_prealloc_blocks(mp));
+ if (start != libxfs_prealloc_blocks(mp)) {
+ arec->ar_blockcount = cpu_to_be32(start -
+ libxfs_prealloc_blocks(mp));
+ nrec = arec + 1;
+ nrec->ar_startblock = cpu_to_be32(
+ be32_to_cpu(arec->ar_startblock) +
+ be32_to_cpu(arec->ar_blockcount));
+ arec = nrec;
+ be16_add_cpu(&block->bb_numrecs, 1);
+ }
+ be32_add_cpu(&arec->ar_startblock, cfg->logblocks);
+ }
+ /*
+ * Calculate the record block count and check for the case where
+ * the log might have consumed all available space in the AG. If
+ * so, reset the record count to 0 to avoid exposure of an invalid
+ * record start block.
+ */
+ arec->ar_blockcount = cpu_to_be32(agsize -
+ be32_to_cpu(arec->ar_startblock));
+ if (!arec->ar_blockcount)
+ block->bb_numrecs = 0;
+
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
+ /*
+ * refcount btree root block
+ */
+ if (xfs_sb_version_hasreflink(sbp)) {
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, libxfs_refc_block(mp)),
+ BTOBB(cfg->blocksize));
+ buf->b_ops = &xfs_refcountbt_buf_ops;
+
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, cfg->blocksize);
+ libxfs_btree_init_block(mp, buf, XFS_BTNUM_REFC, 0, 0, agno, 0);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ }
+
+ /*
+ * INO btree root block
+ */
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
+ BTOBB(cfg->blocksize));
+ buf->b_ops = &xfs_inobt_buf_ops;
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, cfg->blocksize);
+ libxfs_btree_init_block(mp, buf, XFS_BTNUM_INO, 0, 0, agno, 0);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+
+ /*
+ * Free INO btree root block
+ */
+ if (xfs_sb_version_hasfinobt(sbp)) {
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)),
+ BTOBB(cfg->blocksize));
+ buf->b_ops = &xfs_inobt_buf_ops;
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, cfg->blocksize);
+ libxfs_btree_init_block(mp, buf, XFS_BTNUM_FINO, 0, 0, agno, 0);
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ }
+
+ /* RMAP btree root block */
+ if (xfs_sb_version_hasrmapbt(sbp)) {
+ struct xfs_rmap_rec *rrec;
+
+ buf = libxfs_getbuf(mp->m_ddev_targp,
+ XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)),
+ BTOBB(cfg->blocksize));
+ buf->b_ops = &xfs_rmapbt_buf_ops;
+ block = XFS_BUF_TO_BLOCK(buf);
+ memset(block, 0, cfg->blocksize);
+
+ libxfs_btree_init_block(mp, buf, XFS_BTNUM_RMAP, 0, 0, agno, 0);
+
+ /*
+ * mark the AG header regions as static metadata
+ * The BNO btree block is the first block after the
+ * headers, so it's location defines the size of region
+ * the static metadata consumes.
+ */
+ rrec = XFS_RMAP_REC_ADDR(block, 1);
+ rrec->rm_startblock = 0;
+ rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
+ rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
+ rrec->rm_offset = 0;
+ be16_add_cpu(&block->bb_numrecs, 1);
+
+ /* account freespace btree root blocks */
+ rrec = XFS_RMAP_REC_ADDR(block, 2);
+ rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
+ rrec->rm_blockcount = cpu_to_be32(2);
+ rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
+ rrec->rm_offset = 0;
+ be16_add_cpu(&block->bb_numrecs, 1);
+
+ /* account inode btree root blocks */
+ rrec = XFS_RMAP_REC_ADDR(block, 3);
+ rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
+ rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
+ XFS_IBT_BLOCK(mp));
+ rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
+ rrec->rm_offset = 0;
+ be16_add_cpu(&block->bb_numrecs, 1);
+
+ /* account for rmap btree root */
+ rrec = XFS_RMAP_REC_ADDR(block, 4);
+ rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
+ rrec->rm_blockcount = cpu_to_be32(1);
+ rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
+ rrec->rm_offset = 0;
+ be16_add_cpu(&block->bb_numrecs, 1);
+
+ /* account for refcount btree root */
+ if (xfs_sb_version_hasreflink(sbp)) {
+ rrec = XFS_RMAP_REC_ADDR(block, 5);
+ rrec->rm_startblock = cpu_to_be32(libxfs_refc_block(mp));
+ rrec->rm_blockcount = cpu_to_be32(1);
+ rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
+ rrec->rm_offset = 0;
+ be16_add_cpu(&block->bb_numrecs, 1);
+ }
+
+ /* account for the log space */
+ if (is_log_ag) {
+ rrec = XFS_RMAP_REC_ADDR(block,
+ be16_to_cpu(block->bb_numrecs) + 1);
+ rrec->rm_startblock = cpu_to_be32(
+ XFS_FSB_TO_AGBNO(mp, cfg->logstart));
+ rrec->rm_blockcount = cpu_to_be32(cfg->logblocks);
+ rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
+ rrec->rm_offset = 0;
+ be16_add_cpu(&block->bb_numrecs, 1);
+ }
+
+ libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
+ }
+
+ libxfs_perag_put(pag);
+}
+
+static void
+initialise_ag_freespace(
+ struct xfs_mount *mp,
+ xfs_agnumber_t agno,
+ int worst_freelist)
+{
+ struct xfs_alloc_arg args;
+ struct xfs_trans *tp;
+ struct xfs_trans_res tres = {0};
+ int c;
+
+ c = libxfs_trans_alloc(mp, &tres, worst_freelist, 0, 0, &tp);
+ if (c)
+ res_failed(c);
+
+ memset(&args, 0, sizeof(args));
+ args.tp = tp;
+ args.mp = mp;
+ args.agno = agno;
+ args.alignment = 1;
+ args.pag = libxfs_perag_get(mp, agno);
+
+ libxfs_alloc_fix_freelist(&args, 0);
+ libxfs_perag_put(args.pag);
+ libxfs_trans_commit(tp);
+}
+
int
main(
int argc,
char **argv)
{
uint64_t agcount;
- xfs_agf_t *agf;
- xfs_agi_t *agi;
xfs_agnumber_t agno;
uint64_t agsize;
- xfs_alloc_rec_t *arec;
- struct xfs_btree_block *block;
int blflag;
int blocklog;
int bsflag;
- int bsize;
xfs_buf_t *buf;
int c;
int daflag;
@@ -2152,7 +2531,6 @@ main(
int nlflag;
int nodsflag;
int norsflag;
- xfs_alloc_rec_t *nrec;
int nsflag;
int nvflag;
int Nflag;
@@ -3153,7 +3531,6 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
validate_log_size(logblocks, blocklog, min_logblocks);
protostring = setup_proto(protofile);
- bsize = 1 << (blocklog - BBSHIFT);
mp = &mbuf;
sbp = &mp->m_sb;
memset(mp, 0, sizeof(xfs_mount_t));
@@ -3284,363 +3661,16 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"),
}
/*
- * XXX: this code is effectively shared with the kernel growfs code.
- * These initialisations should be pulled into libxfs to keep the
- * kernel/userspace header initialisation code the same.
+ * Initialise all the static on disk metadata.
*/
- for (agno = 0; agno < agcount; agno++) {
- struct xfs_agfl *agfl;
- int bucket;
- struct xfs_perag *pag = libxfs_perag_get(mp, agno);
-
- /*
- * Superblock.
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
- XFS_FSS_TO_BB(mp, 1));
- buf->b_ops = &xfs_sb_buf_ops;
- memset(XFS_BUF_PTR(buf), 0, sectorsize);
- libxfs_sb_to_disk((void *)XFS_BUF_PTR(buf), sbp);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
-
- /*
- * AG header block: freespace
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1));
- buf->b_ops = &xfs_agf_buf_ops;
- agf = XFS_BUF_TO_AGF(buf);
- memset(agf, 0, sectorsize);
- if (agno == agcount - 1)
- agsize = dblocks - (xfs_rfsblock_t)(agno * agsize);
- agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
- agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
- agf->agf_seqno = cpu_to_be32(agno);
- agf->agf_length = cpu_to_be32(agsize);
- agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
- agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
- agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
- agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
- pag->pagf_levels[XFS_BTNUM_BNOi] = 1;
- pag->pagf_levels[XFS_BTNUM_CNTi] = 1;
- if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
- agf->agf_roots[XFS_BTNUM_RMAPi] =
- cpu_to_be32(XFS_RMAP_BLOCK(mp));
- agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
- agf->agf_rmap_blocks = cpu_to_be32(1);
- }
- if (xfs_sb_version_hasreflink(&mp->m_sb)) {
- agf->agf_refcount_root = cpu_to_be32(
- libxfs_refc_block(mp));
- agf->agf_refcount_level = cpu_to_be32(1);
- agf->agf_refcount_blocks = cpu_to_be32(1);
- }
- agf->agf_flfirst = 0;
- agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
- agf->agf_flcount = 0;
- nbmblocks = (xfs_extlen_t)(agsize - libxfs_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 -
- XFS_FSB_TO_AGBNO(mp, logstart) - logblocks);
- }
- if (libxfs_alloc_min_freelist(mp, pag) > worst_freelist)
- worst_freelist = libxfs_alloc_min_freelist(mp, pag);
- 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
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1));
- agi = XFS_BUF_TO_AGI(buf);
- buf->b_ops = &xfs_agi_buf_ops;
- memset(agi, 0, sectorsize);
- agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
- agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
- agi->agi_seqno = cpu_to_be32(agno);
- agi->agi_length = cpu_to_be32((xfs_agblock_t)agsize);
- agi->agi_count = 0;
- agi->agi_root = cpu_to_be32(XFS_IBT_BLOCK(mp));
- agi->agi_level = cpu_to_be32(1);
- if (sb_feat.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);
- 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);
-
- /*
- * BNO btree root block
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
- bsize);
- buf->b_ops = &xfs_allocbt_buf_ops;
- block = XFS_BUF_TO_BLOCK(buf);
- memset(block, 0, blocksize);
- libxfs_btree_init_block(mp, buf, XFS_BTNUM_BNO, 0, 1, agno, 0);
-
- arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
- arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
- if (loginternal && agno == logagno) {
- if (lalign) {
- /*
- * Have to insert two records
- * Insert pad record for stripe align of log
- */
- arec->ar_blockcount = cpu_to_be32(
- XFS_FSB_TO_AGBNO(mp, logstart) -
- be32_to_cpu(arec->ar_startblock));
- nrec = arec + 1;
- /*
- * Insert record at start of internal log
- */
- nrec->ar_startblock = cpu_to_be32(
- be32_to_cpu(arec->ar_startblock) +
- be32_to_cpu(arec->ar_blockcount));
- arec = nrec;
- be16_add_cpu(&block->bb_numrecs, 1);
- }
- /*
- * Change record start to after the internal log
- */
- be32_add_cpu(&arec->ar_startblock, logblocks);
- }
- /*
- * Calculate the record block count and check for the case where
- * the log might have consumed all available space in the AG. If
- * so, reset the record count to 0 to avoid exposure of an invalid
- * record start block.
- */
- arec->ar_blockcount = cpu_to_be32(agsize -
- be32_to_cpu(arec->ar_startblock));
- if (!arec->ar_blockcount)
- block->bb_numrecs = 0;
-
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
-
- /*
- * CNT btree root block
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
- bsize);
- buf->b_ops = &xfs_allocbt_buf_ops;
- block = XFS_BUF_TO_BLOCK(buf);
- memset(block, 0, blocksize);
- libxfs_btree_init_block(mp, buf, XFS_BTNUM_CNT, 0, 1, agno, 0);
-
- arec = XFS_ALLOC_REC_ADDR(mp, block, 1);
- arec->ar_startblock = cpu_to_be32(libxfs_prealloc_blocks(mp));
- if (loginternal && agno == logagno) {
- if (lalign) {
- arec->ar_blockcount = cpu_to_be32(
- XFS_FSB_TO_AGBNO(mp, logstart) -
- be32_to_cpu(arec->ar_startblock));
- nrec = arec + 1;
- nrec->ar_startblock = cpu_to_be32(
- be32_to_cpu(arec->ar_startblock) +
- be32_to_cpu(arec->ar_blockcount));
- arec = nrec;
- be16_add_cpu(&block->bb_numrecs, 1);
- }
- be32_add_cpu(&arec->ar_startblock, logblocks);
- }
- /*
- * Calculate the record block count and check for the case where
- * the log might have consumed all available space in the AG. If
- * so, reset the record count to 0 to avoid exposure of an invalid
- * record start block.
- */
- arec->ar_blockcount = cpu_to_be32(agsize -
- be32_to_cpu(arec->ar_startblock));
- if (!arec->ar_blockcount)
- block->bb_numrecs = 0;
-
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
-
- /*
- * refcount btree root block
- */
- if (xfs_sb_version_hasreflink(&mp->m_sb)) {
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno,
- libxfs_refc_block(mp)),
- bsize);
- buf->b_ops = &xfs_refcountbt_buf_ops;
-
- block = XFS_BUF_TO_BLOCK(buf);
- memset(block, 0, blocksize);
- libxfs_btree_init_block(mp, buf, XFS_BTNUM_REFC, 0,
- 0, agno, 0);
-
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- }
-
- /*
- * INO btree root block
- */
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
- bsize);
- buf->b_ops = &xfs_inobt_buf_ops;
- block = XFS_BUF_TO_BLOCK(buf);
- memset(block, 0, blocksize);
- libxfs_btree_init_block(mp, buf, XFS_BTNUM_INO, 0, 0, agno, 0);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
-
- /*
- * Free INO btree root block
- */
- if (sb_feat.finobt) {
- 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);
- libxfs_btree_init_block(mp, buf, XFS_BTNUM_FINO, 0, 0, agno, 0);
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- }
-
- /* RMAP btree root block */
- if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
- struct xfs_rmap_rec *rrec;
-
- buf = libxfs_getbuf(mp->m_ddev_targp,
- XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)),
- bsize);
- buf->b_ops = &xfs_rmapbt_buf_ops;
- block = XFS_BUF_TO_BLOCK(buf);
- memset(block, 0, blocksize);
-
- libxfs_btree_init_block(mp, buf, XFS_BTNUM_RMAP, 0, 0, agno, 0);
-
- /*
- * mark the AG header regions as static metadata
- * The BNO btree block is the first block after the
- * headers, so it's location defines the size of region
- * the static metadata consumes.
- */
- rrec = XFS_RMAP_REC_ADDR(block, 1);
- rrec->rm_startblock = 0;
- rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp));
- rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS);
- rrec->rm_offset = 0;
- be16_add_cpu(&block->bb_numrecs, 1);
-
- /* account freespace btree root blocks */
- rrec = XFS_RMAP_REC_ADDR(block, 2);
- rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp));
- rrec->rm_blockcount = cpu_to_be32(2);
- rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
- rrec->rm_offset = 0;
- be16_add_cpu(&block->bb_numrecs, 1);
-
- /* account inode btree root blocks */
- rrec = XFS_RMAP_REC_ADDR(block, 3);
- rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp));
- rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) -
- XFS_IBT_BLOCK(mp));
- rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT);
- rrec->rm_offset = 0;
- be16_add_cpu(&block->bb_numrecs, 1);
-
- /* account for rmap btree root */
- rrec = XFS_RMAP_REC_ADDR(block, 4);
- rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp));
- rrec->rm_blockcount = cpu_to_be32(1);
- rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG);
- rrec->rm_offset = 0;
- be16_add_cpu(&block->bb_numrecs, 1);
-
- /* account for refcount btree root */
- if (xfs_sb_version_hasreflink(&mp->m_sb)) {
- rrec = XFS_RMAP_REC_ADDR(block, 5);
- rrec->rm_startblock = cpu_to_be32(
- libxfs_refc_block(mp));
- rrec->rm_blockcount = cpu_to_be32(1);
- rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC);
- rrec->rm_offset = 0;
- be16_add_cpu(&block->bb_numrecs, 1);
- }
-
- /* account for the log space */
- if (loginternal && agno == logagno) {
- rrec = XFS_RMAP_REC_ADDR(block,
- be16_to_cpu(block->bb_numrecs) + 1);
- rrec->rm_startblock = cpu_to_be32(
- XFS_FSB_TO_AGBNO(mp, logstart));
- rrec->rm_blockcount = cpu_to_be32(logblocks);
- rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG);
- rrec->rm_offset = 0;
- be16_add_cpu(&block->bb_numrecs, 1);
- }
-
- libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE);
- }
-
- libxfs_perag_put(pag);
- }
+ for (agno = 0; agno < cfg.agcount; agno++)
+ initialise_ag_headers(&cfg, mp, sbp, agno, &worst_freelist);
/*
- * BNO, CNT free block list
+ * Initialise the freespace freelists (i.e. AGFLs) in each AG.
*/
- for (agno = 0; agno < agcount; agno++) {
- xfs_alloc_arg_t args;
- xfs_trans_t *tp;
- struct xfs_trans_res tres = {0};
-
- c = libxfs_trans_alloc(mp, &tres, worst_freelist, 0, 0, &tp);
- if (c)
- res_failed(c);
-
- memset(&args, 0, sizeof(args));
- args.tp = tp;
- args.mp = mp;
- args.agno = agno;
- args.alignment = 1;
- args.pag = libxfs_perag_get(mp,agno);
-
- libxfs_alloc_fix_freelist(&args, 0);
- libxfs_perag_put(args.pag);
- libxfs_trans_commit(tp);
- }
+ for (agno = 0; agno < cfg.agcount; agno++)
+ initialise_ag_freespace(mp, agno, worst_freelist);
/*
* Allocate the root inode and anything else in the proto file.
--
2.13.3
next prev parent reply other threads:[~2017-08-29 23:51 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-29 23:50 [PATCH 00/42] mkfs: factor the crap out of the code Dave Chinner
2017-08-29 23:50 ` [PATCH 01/42] mkfs: can't specify sector size of internal log Dave Chinner
2017-08-29 23:50 ` [PATCH 02/42] mkfs: make subopt table const Dave Chinner
2017-08-29 23:50 ` [PATCH 03/42] mkfs: introduce a structure to hold CLI options Dave Chinner
2017-08-29 23:50 ` [PATCH 04/42] mkfs: add generic subopt parsing table Dave Chinner
2017-08-29 23:50 ` [PATCH 05/42] mkfs: factor block subopts parser Dave Chinner
2017-08-29 23:50 ` [PATCH 06/42] mkfs: factor data " Dave Chinner
2017-08-29 23:50 ` [PATCH 07/42] mkfs: factor inode " Dave Chinner
2017-08-29 23:50 ` [PATCH 08/42] mkfs: factor log " Dave Chinner
2017-08-29 23:50 ` [PATCH 09/42] mkfs: factor meta " Dave Chinner
2017-08-29 23:50 ` [PATCH 10/42] mkfs: factor naming " Dave Chinner
2017-08-29 23:50 ` [PATCH 11/42] mkfs: factor rt " Dave Chinner
2017-08-29 23:50 ` [PATCH 12/42] mkfs: factor sector " Dave Chinner
2017-08-29 23:50 ` [PATCH 13/42] mkfs: Introduce mkfs configuration structure Dave Chinner
2017-08-29 23:50 ` [PATCH 14/42] mkfs: factor printing of mkfs config Dave Chinner
2017-08-29 23:50 ` [PATCH 15/42] mkfs: factor in memory superblock setup Dave Chinner
2017-08-29 23:50 ` [PATCH 16/42] mkfs: factor out device preparation Dave Chinner
2017-08-29 23:50 ` Dave Chinner [this message]
2017-08-29 23:50 ` [PATCH 18/42] mkfs: factor secondary superblock updates Dave Chinner
2017-08-29 23:50 ` [PATCH 19/42] mkfs: introduce default configuration structure Dave Chinner
2017-08-29 23:50 ` [PATCH 20/42] mkfs: rename top level CLI parameters Dave Chinner
2017-08-29 23:50 ` [PATCH 21/42] mkfs: factor sectorsize validation Dave Chinner
2017-08-29 23:50 ` [PATCH 22/42] mkfs: factor blocksize validation Dave Chinner
2017-08-29 23:50 ` [PATCH 23/42] mkfs: factor log sector size validation Dave Chinner
2017-08-29 23:50 ` [PATCH 24/42] mkfs: factor superblock feature validation Dave Chinner
2017-08-29 23:50 ` [PATCH 25/42] mkfs: factor directory blocksize validation Dave Chinner
2017-08-29 23:50 ` [PATCH 26/42] mkfs: factor inode size validation Dave Chinner
2017-08-29 23:50 ` [PATCH 27/42] mkfs: factor out device size calculations Dave Chinner
2017-08-29 23:50 ` [PATCH 28/42] mkfs: fix hidden parameter in DTOBT() Dave Chinner
2017-08-29 23:50 ` [PATCH 29/42] mkfs: factor rtdev extent size validation Dave Chinner
2017-08-29 23:50 ` [PATCH 30/42] mkfs: rework stripe calculations Dave Chinner
2017-08-29 23:50 ` [PATCH 31/42] mkfs: factor device opening Dave Chinner
2017-08-29 23:50 ` [PATCH 32/42] mkfs: factor data device validation Dave Chinner
2017-08-29 23:50 ` [PATCH 33/42] mkfs: factor log " Dave Chinner
2017-08-29 23:50 ` [PATCH 34/42] mkfs: factor rt " Dave Chinner
2017-08-29 23:50 ` [PATCH 35/42] mkfs: factor AG geometry calculations Dave Chinner
2017-08-29 23:50 ` [PATCH 36/42] mkfs: factor AG alignment Dave Chinner
2017-08-30 23:44 ` Dave Chinner
2017-08-29 23:50 ` [PATCH 37/42] mkfs: rework imaxpct calculation Dave Chinner
2017-08-29 23:50 ` [PATCH 38/42] mkfs: factor initial mount setup Dave Chinner
2017-08-29 23:50 ` [PATCH 39/42] mkfs: factor log size calculations Dave Chinner
2017-09-05 5:23 ` Dave Chinner
2017-08-29 23:50 ` [PATCH 40/42] mkfs: cleanup redundant temporary code Dave Chinner
2017-08-29 23:50 ` [PATCH 41/42] mkfs: move error functions Dave Chinner
2017-08-29 23:50 ` [PATCH 42/42] mkfs: tidy up definitions Dave Chinner
2017-08-30 1:23 ` [PATCH 00/42] mkfs: factor the crap out of the code Darrick J. Wong
2017-08-30 1:57 ` Dave Chinner
2017-08-30 4:16 ` Luis R. Rodriguez
2017-08-30 5:44 ` Dave Chinner
2017-08-30 22:10 ` Luis R. Rodriguez
2017-08-30 23:22 ` Dave Chinner
2017-08-31 0:05 ` Luis R. Rodriguez
2017-08-31 16:23 ` Jan Tulak
2017-08-30 7:44 ` Martin Steigerwald
2017-09-04 12:31 ` Chandan Rajendra
2017-09-04 15:34 ` Eric Sandeen
2017-09-04 22:40 ` Dave Chinner
2017-09-07 10:31 ` Chandan Rajendra
2017-09-07 23:38 ` Dave Chinner
2017-09-09 10:24 ` Chandan Rajendra
2017-09-15 9:42 ` Jan Tulak
2017-09-16 11:29 ` Dave Chinner
2017-10-24 3:00 ` Eric Sandeen
2017-10-25 0:59 ` Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170829235052.21050-18-david@fromorbit.com \
--to=david@fromorbit.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).