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

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

xfs: factor the ag length extension code into libxfs



Growfs currently manually codes the extension of the last AG in a
filesytem during the growfs process. Factor that out of the growfs
code and move it into libxfs along with teh rest of the AG header
modification code.

Signed-Off-By: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent b16817b6
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include "xfs_alloc_btree.h"
#include "xfs_rmap_btree.h"
#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"

@@ -402,3 +403,62 @@ xfs_ag_init_headers(
	}
	return error;
}

/*
 * Extent the AG indicated by the @id by the length passed in
 */
int
xfs_ag_extend_space(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct aghdr_init_data	*id,
	xfs_extlen_t		len)
{
	struct xfs_owner_info	oinfo;
	struct xfs_buf		*bp;
	struct xfs_agi		*agi;
	struct xfs_agf		*agf;
	int			error;

	/*
	 * Change the agi length.
	 */
	error = xfs_ialloc_read_agi(mp, tp, id->agno, &bp);
	if (error)
		return error;

	agi = XFS_BUF_TO_AGI(bp);
	be32_add_cpu(&agi->agi_length, len);
	ASSERT(id->agno == mp->m_sb.sb_agcount - 1 ||
	       be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
	xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);

	/*
	 * Change agf length.
	 */
	error = xfs_alloc_read_agf(mp, tp, id->agno, 0, &bp);
	if (error)
		return error;

	agf = XFS_BUF_TO_AGF(bp);
	be32_add_cpu(&agf->agf_length, len);
	ASSERT(agf->agf_length == agi->agi_length);
	xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);

	/*
	 * Free the new space.
	 *
	 * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that
	 * this doesn't actually exist in the rmap btree.
	 */
	xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL);
	error = xfs_rmap_free(tp, bp, id->agno,
				be32_to_cpu(agf->agf_length) - len,
				len, &oinfo);
	if (error)
		return error;

	return  xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, id->agno,
					be32_to_cpu(agf->agf_length) - len),
				len, &oinfo, XFS_AG_RESV_NONE);
}
+6 −1
Original line number Diff line number Diff line
@@ -7,6 +7,9 @@
#ifndef __LIBXFS_AG_H
#define __LIBXFS_AG_H 1

struct xfs_mount;
struct xfs_trans;

struct aghdr_init_data {
	/* per ag data */
	xfs_agblock_t		agno;		/* ag to init */
@@ -21,5 +24,7 @@ struct aghdr_init_data {
};

int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
int xfs_ag_extend_space(struct xfs_mount *mp, struct xfs_trans *tp,
			struct aghdr_init_data *id, xfs_extlen_t len);

#endif /* __LIBXFS_AG_H */
+2 −56
Original line number Diff line number Diff line
@@ -27,16 +27,12 @@
#include "xfs_trans.h"
#include "xfs_error.h"
#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_trans_space.h"
#include "xfs_rtalloc.h"
#include "xfs_trace.h"
#include "xfs_log.h"
#include "xfs_rmap.h"
#include "xfs_ag.h"
#include "xfs_ag_resv.h"

@@ -48,8 +44,6 @@ xfs_growfs_data_private(
	xfs_mount_t		*mp,		/* mount point for filesystem */
	xfs_growfs_data_t	*in)		/* growfs data input struct */
{
	xfs_agf_t		*agf;
	xfs_agi_t		*agi;
	xfs_buf_t		*bp;
	int			error;
	xfs_agnumber_t		nagcount;
@@ -132,57 +126,9 @@ xfs_growfs_data_private(

	xfs_trans_agblocks_delta(tp, id.nfree);

	/*
	 * There are new blocks in the old last a.g.
	 */
	/* If there are new blocks in the old last AG, extend it. */
	if (new) {
		struct xfs_owner_info	oinfo;

		/*
		 * Change the agi length.
		 */
		error = xfs_ialloc_read_agi(mp, tp, id.agno, &bp);
		if (error)
			goto out_trans_cancel;

		ASSERT(bp);
		agi = XFS_BUF_TO_AGI(bp);
		be32_add_cpu(&agi->agi_length, new);
		ASSERT(nagcount == oagcount ||
		       be32_to_cpu(agi->agi_length) == mp->m_sb.sb_agblocks);
		xfs_ialloc_log_agi(tp, bp, XFS_AGI_LENGTH);

		/*
		 * Change agf length.
		 */
		error = xfs_alloc_read_agf(mp, tp, id.agno, 0, &bp);
		if (error)
			goto out_trans_cancel;

		ASSERT(bp);
		agf = XFS_BUF_TO_AGF(bp);
		be32_add_cpu(&agf->agf_length, new);
		ASSERT(be32_to_cpu(agf->agf_length) ==
		       be32_to_cpu(agi->agi_length));

		xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH);

		/*
		 * Free the new space.
		 *
		 * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that
		 * this doesn't actually exist in the rmap btree.
		 */
		xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_NULL);
		error = xfs_rmap_free(tp, bp, id.agno,
				be32_to_cpu(agf->agf_length) - new,
				new, &oinfo);
		if (error)
			goto out_trans_cancel;
		error = xfs_free_extent(tp,
				XFS_AGB_TO_FSB(mp, id.agno,
					be32_to_cpu(agf->agf_length) - new),
				new, &oinfo, XFS_AG_RESV_NONE);
		error = xfs_ag_extend_space(mp, tp, &id, new);
		if (error)
			goto out_trans_cancel;
	}