Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e70d829f authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Dave Chinner
Browse files

xfs: add rmap btree growfs support



Originally-From: Dave Chinner <dchinner@redhat.com>

Now we can read and write rmap btree blocks, we can add support to
the growfs code to initialise new rmap btree blocks.

[darrick.wong@oracle.com: fill out the rmap offset fields]

Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent 035e00ac
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "xfs_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_rmap_btree.h"
#include "xfs_ialloc.h"
#include "xfs_fsops.h"
#include "xfs_itable.h"
@@ -241,6 +242,12 @@ xfs_growfs_data_private(
		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);
		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_flfirst = cpu_to_be32(1);
		agf->agf_fllast = 0;
		agf->agf_flcount = 0;
@@ -380,6 +387,72 @@ xfs_growfs_data_private(
		if (error)
			goto error0;

		/* RMAP btree root block */
		if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
			struct xfs_rmap_rec	*rrec;
			struct xfs_btree_block	*block;

			bp = xfs_growfs_get_hdr_buf(mp,
				XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)),
				BTOBB(mp->m_sb.sb_blocksize), 0,
				&xfs_rmapbt_buf_ops);
			if (!bp) {
				error = -ENOMEM;
				goto error0;
			}

			xfs_btree_init_block(mp, bp, XFS_RMAP_CRC_MAGIC, 0, 0,
						agno, XFS_BTREE_CRC_BLOCKS);
			block = XFS_BUF_TO_BLOCK(bp);


			/*
			 * 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.
			 *
			 * Note: unlike mkfs, we never have to account for log
			 * space when growing the data regions
			 */
			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);

			error = xfs_bwrite(bp);
			xfs_buf_relse(bp);
			if (error)
				goto error0;
		}

		/*
		 * INO btree root block
		 */