Commit 7b13c515 authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner
Browse files

xfs: use perag for ialloc btree cursors

parent 289d38d2
Loading
Loading
Loading
Loading
+89 −88
Original line number Diff line number Diff line
@@ -172,18 +172,17 @@ xfs_inobt_insert(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct xfs_buf		*agbp,
	struct xfs_perag	*pag,
	xfs_agino_t		newino,
	xfs_agino_t		newlen,
	xfs_btnum_t		btnum)
{
	struct xfs_btree_cur	*cur;
	struct xfs_agi		*agi = agbp->b_addr;
	xfs_agnumber_t		agno = be32_to_cpu(agi->agi_seqno);
	xfs_agino_t		thisino;
	int			i;
	int			error;

	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, btnum);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, btnum);

	for (thisino = newino;
	     thisino < newino + newlen;
@@ -520,18 +519,17 @@ xfs_inobt_insert_sprec(
	struct xfs_mount		*mp,
	struct xfs_trans		*tp,
	struct xfs_buf			*agbp,
	struct xfs_perag		*pag,
	int				btnum,
	struct xfs_inobt_rec_incore	*nrec,	/* in/out: new/merged rec. */
	bool				merge)	/* merge or replace */
{
	struct xfs_btree_cur		*cur;
	struct xfs_agi			*agi = agbp->b_addr;
	xfs_agnumber_t			agno = be32_to_cpu(agi->agi_seqno);
	int				error;
	int				i;
	struct xfs_inobt_rec_incore	rec;

	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, btnum);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, btnum);

	/* the new record is pre-aligned so we know where to look */
	error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
@@ -578,14 +576,14 @@ xfs_inobt_insert_sprec(
			goto error;
		}

		trace_xfs_irec_merge_pre(mp, agno, rec.ir_startino,
		trace_xfs_irec_merge_pre(mp, pag->pag_agno, rec.ir_startino,
					 rec.ir_holemask, nrec->ir_startino,
					 nrec->ir_holemask);

		/* merge to nrec to output the updated record */
		__xfs_inobt_rec_merge(nrec, &rec);

		trace_xfs_irec_merge_post(mp, agno, nrec->ir_startino,
		trace_xfs_irec_merge_post(mp, pag->pag_agno, nrec->ir_startino,
					  nrec->ir_holemask);

		error = xfs_inobt_rec_check_count(mp, nrec);
@@ -613,21 +611,20 @@ xfs_inobt_insert_sprec(
STATIC int
xfs_ialloc_ag_alloc(
	struct xfs_trans	*tp,
	struct xfs_buf		*agbp)
	struct xfs_buf		*agbp,
	struct xfs_perag	*pag)
{
	struct xfs_agi		*agi;
	struct xfs_alloc_arg	args;
	xfs_agnumber_t		agno;
	int			error;
	xfs_agino_t		newino;		/* new first inode's number */
	xfs_agino_t		newlen;		/* new number of inodes */
	int			isaligned = 0;	/* inode allocation at stripe */
						/* unit boundary */
	/* init. to full chunk */
	uint16_t		allocmask = (uint16_t) -1;
	struct xfs_inobt_rec_incore rec;
	struct xfs_perag	*pag;
	struct xfs_ino_geometry	*igeo = M_IGEO(tp->t_mountp);
	uint16_t		allocmask = (uint16_t) -1;
	int			do_sparse = 0;

	memset(&args, 0, sizeof(args));
@@ -660,14 +657,13 @@ xfs_ialloc_ag_alloc(
	 */
	agi = agbp->b_addr;
	newino = be32_to_cpu(agi->agi_newino);
	agno = be32_to_cpu(agi->agi_seqno);
	args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
		     igeo->ialloc_blks;
	if (do_sparse)
		goto sparse_alloc;
	if (likely(newino != NULLAGINO &&
		  (args.agbno < be32_to_cpu(agi->agi_length)))) {
		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
		args.type = XFS_ALLOCTYPE_THIS_BNO;
		args.prod = 1;

@@ -727,7 +723,7 @@ xfs_ialloc_ag_alloc(
		 * For now, just allocate blocks up front.
		 */
		args.agbno = be32_to_cpu(agi->agi_root);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
		/*
		 * Allocate a fixed-size extent of inodes.
		 */
@@ -748,7 +744,7 @@ xfs_ialloc_ag_alloc(
	if (isaligned && args.fsbno == NULLFSBLOCK) {
		args.type = XFS_ALLOCTYPE_NEAR_BNO;
		args.agbno = be32_to_cpu(agi->agi_root);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
		args.alignment = igeo->cluster_align;
		if ((error = xfs_alloc_vextent(&args)))
			return error;
@@ -764,7 +760,7 @@ xfs_ialloc_ag_alloc(
sparse_alloc:
		args.type = XFS_ALLOCTYPE_NEAR_BNO;
		args.agbno = be32_to_cpu(agi->agi_root);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
		args.fsbno = XFS_AGB_TO_FSB(args.mp, pag->pag_agno, args.agbno);
		args.alignment = args.mp->m_sb.sb_spino_align;
		args.prod = 1;

@@ -809,7 +805,7 @@ xfs_ialloc_ag_alloc(
	 * rather than a linear progression to prevent the next generation
	 * number from being easily guessable.
	 */
	error = xfs_ialloc_inode_init(args.mp, tp, NULL, newlen, agno,
	error = xfs_ialloc_inode_init(args.mp, tp, NULL, newlen, pag->pag_agno,
			args.agbno, args.len, prandom_u32());

	if (error)
@@ -836,12 +832,12 @@ xfs_ialloc_ag_alloc(
		 * if necessary. If a merge does occur, rec is updated to the
		 * merged record.
		 */
		error = xfs_inobt_insert_sprec(args.mp, tp, agbp, XFS_BTNUM_INO,
					       &rec, true);
		error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag,
				XFS_BTNUM_INO, &rec, true);
		if (error == -EFSCORRUPTED) {
			xfs_alert(args.mp,
	"invalid sparse inode record: ino 0x%llx holemask 0x%x count %u",
				  XFS_AGINO_TO_INO(args.mp, agno,
				  XFS_AGINO_TO_INO(args.mp, pag->pag_agno,
						   rec.ir_startino),
				  rec.ir_holemask, rec.ir_count);
			xfs_force_shutdown(args.mp, SHUTDOWN_CORRUPT_INCORE);
@@ -861,21 +857,20 @@ xfs_ialloc_ag_alloc(
		 * existing record with this one.
		 */
		if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
			error = xfs_inobt_insert_sprec(args.mp, tp, agbp,
						       XFS_BTNUM_FINO, &rec,
						       false);
			error = xfs_inobt_insert_sprec(args.mp, tp, agbp, pag,
				       XFS_BTNUM_FINO, &rec, false);
			if (error)
				return error;
		}
	} else {
		/* full chunk - insert new records to both btrees */
		error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen,
		error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino, newlen,
					 XFS_BTNUM_INO);
		if (error)
			return error;

		if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
			error = xfs_inobt_insert(args.mp, tp, agbp, newino,
			error = xfs_inobt_insert(args.mp, tp, agbp, pag, newino,
						 newlen, XFS_BTNUM_FINO);
			if (error)
				return error;
@@ -887,7 +882,6 @@ xfs_ialloc_ag_alloc(
	 */
	be32_add_cpu(&agi->agi_count, newlen);
	be32_add_cpu(&agi->agi_freecount, newlen);
	pag = agbp->b_pag;
	pag->pagi_freecount += newlen;
	pag->pagi_count += newlen;
	agi->agi_newino = cpu_to_be32(newino);
@@ -1123,15 +1117,14 @@ STATIC int
xfs_dialloc_ag_inobt(
	struct xfs_trans	*tp,
	struct xfs_buf		*agbp,
	struct xfs_perag	*pag,
	xfs_ino_t		parent,
	xfs_ino_t		*inop)
{
	struct xfs_mount	*mp = tp->t_mountp;
	struct xfs_agi		*agi = agbp->b_addr;
	xfs_agnumber_t		agno = be32_to_cpu(agi->agi_seqno);
	xfs_agnumber_t		pagno = XFS_INO_TO_AGNO(mp, parent);
	xfs_agino_t		pagino = XFS_INO_TO_AGINO(mp, parent);
	struct xfs_perag	*pag = agbp->b_pag;
	struct xfs_btree_cur	*cur, *tcur;
	struct xfs_inobt_rec_incore rec, trec;
	xfs_ino_t		ino;
@@ -1145,7 +1138,7 @@ xfs_dialloc_ag_inobt(
	ASSERT(pag->pagi_freecount > 0);

 restart_pagno:
	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, XFS_BTNUM_INO);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO);
	/*
	 * If pagino is 0 (this is the root inode allocation) use newino.
	 * This must work because we've just allocated some.
@@ -1160,7 +1153,7 @@ xfs_dialloc_ag_inobt(
	/*
	 * If in the same AG as the parent, try to get near the parent.
	 */
	if (pagno == agno) {
	if (pagno == pag->pag_agno) {
		int		doneleft;	/* done, to the left */
		int		doneright;	/* done, to the right */

@@ -1363,7 +1356,7 @@ xfs_dialloc_ag_inobt(
	ASSERT(offset < XFS_INODES_PER_CHUNK);
	ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
				   XFS_INODES_PER_CHUNK) == 0);
	ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
	ino = XFS_AGINO_TO_INO(mp, pag->pag_agno, rec.ir_startino + offset);
	rec.ir_free &= ~XFS_INOBT_MASK(offset);
	rec.ir_freecount--;
	error = xfs_inobt_update(cur, &rec);
@@ -1577,7 +1570,6 @@ xfs_dialloc_ag(
{
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_agi			*agi = agbp->b_addr;
	xfs_agnumber_t			agno = be32_to_cpu(agi->agi_seqno);
	xfs_agnumber_t			pagno = XFS_INO_TO_AGNO(mp, parent);
	xfs_agino_t			pagino = XFS_INO_TO_AGINO(mp, parent);
	struct xfs_btree_cur		*cur;	/* finobt cursor */
@@ -1587,9 +1579,10 @@ xfs_dialloc_ag(
	int				error;
	int				offset;
	int				i;
	struct xfs_perag		*pag = agbp->b_pag;

	if (!xfs_sb_version_hasfinobt(&mp->m_sb))
		return xfs_dialloc_ag_inobt(tp, agbp, parent, inop);
		return xfs_dialloc_ag_inobt(tp, agbp, pag, parent, inop);

	/*
	 * If pagino is 0 (this is the root inode allocation) use newino.
@@ -1598,7 +1591,7 @@ xfs_dialloc_ag(
	if (!pagino)
		pagino = be32_to_cpu(agi->agi_newino);

	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, XFS_BTNUM_FINO);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_FINO);

	error = xfs_check_agi_freecount(cur, agi);
	if (error)
@@ -1609,7 +1602,7 @@ xfs_dialloc_ag(
	 * parent. If so, find the closest available inode to the parent. If
	 * not, consider the agi hint or find the first free inode in the AG.
	 */
	if (agno == pagno)
	if (pag->pag_agno == pagno)
		error = xfs_dialloc_ag_finobt_near(pagino, &cur, &rec);
	else
		error = xfs_dialloc_ag_finobt_newino(agi, cur, &rec);
@@ -1621,7 +1614,7 @@ xfs_dialloc_ag(
	ASSERT(offset < XFS_INODES_PER_CHUNK);
	ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
				   XFS_INODES_PER_CHUNK) == 0);
	ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
	ino = XFS_AGINO_TO_INO(mp, pag->pag_agno, rec.ir_startino + offset);

	/*
	 * Modify or remove the finobt record.
@@ -1641,7 +1634,7 @@ xfs_dialloc_ag(
	 * the original freecount. If all is well, make the equivalent update to
	 * the inobt using the finobt record and offset information.
	 */
	icur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, XFS_BTNUM_INO);
	icur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO);

	error = xfs_check_agi_freecount(icur, agi);
	if (error)
@@ -1657,7 +1650,7 @@ xfs_dialloc_ag(
	 */
	be32_add_cpu(&agi->agi_freecount, -1);
	xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
	agbp->b_pag->pagi_freecount--;
	pag->pagi_freecount--;

	xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);

@@ -1809,7 +1802,7 @@ xfs_dialloc_select_ag(
		if (!okalloc)
			goto nextag_relse_buffer;

		error = xfs_ialloc_ag_alloc(*tpp, agbp);
		error = xfs_ialloc_ag_alloc(*tpp, agbp, pag);
		if (error < 0) {
			xfs_trans_brelse(*tpp, agbp);

@@ -1935,12 +1928,12 @@ xfs_difree_inobt(
	struct xfs_mount		*mp,
	struct xfs_trans		*tp,
	struct xfs_buf			*agbp,
	struct xfs_perag		*pag,
	xfs_agino_t			agino,
	struct xfs_icluster		*xic,
	struct xfs_inobt_rec_incore	*orec)
{
	struct xfs_agi			*agi = agbp->b_addr;
	xfs_agnumber_t			agno = be32_to_cpu(agi->agi_seqno);
	struct xfs_btree_cur		*cur;
	struct xfs_inobt_rec_incore	rec;
	int				ilen;
@@ -1954,7 +1947,7 @@ xfs_difree_inobt(
	/*
	 * Initialize the cursor.
	 */
	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, XFS_BTNUM_INO);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO);

	error = xfs_check_agi_freecount(cur, agi);
	if (error)
@@ -2005,7 +1998,8 @@ xfs_difree_inobt(
		struct xfs_perag	*pag = agbp->b_pag;

		xic->deleted = true;
		xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
		xic->first_ino = XFS_AGINO_TO_INO(mp, pag->pag_agno,
				rec.ir_startino);
		xic->alloc = xfs_inobt_irec_to_allocmask(&rec);

		/*
@@ -2028,7 +2022,7 @@ xfs_difree_inobt(
			goto error0;
		}

		xfs_difree_inode_chunk(tp, agno, &rec);
		xfs_difree_inode_chunk(tp, pag->pag_agno, &rec);
	} else {
		xic->deleted = false;

@@ -2044,7 +2038,7 @@ xfs_difree_inobt(
		 */
		be32_add_cpu(&agi->agi_freecount, 1);
		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
		agbp->b_pag->pagi_freecount++;
		pag->pagi_freecount++;
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
	}

@@ -2069,18 +2063,18 @@ xfs_difree_finobt(
	struct xfs_mount		*mp,
	struct xfs_trans		*tp,
	struct xfs_buf			*agbp,
	struct xfs_perag		*pag,
	xfs_agino_t			agino,
	struct xfs_inobt_rec_incore	*ibtrec) /* inobt record */
{
	struct xfs_agi			*agi = agbp->b_addr;
	xfs_agnumber_t			agno = be32_to_cpu(agi->agi_seqno);
	struct xfs_btree_cur		*cur;
	struct xfs_inobt_rec_incore	rec;
	int				offset = agino - ibtrec->ir_startino;
	int				error;
	int				i;

	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, XFS_BTNUM_FINO);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_FINO);

	error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i);
	if (error)
@@ -2188,10 +2182,9 @@ xfs_difree(
	xfs_agino_t		agino;	/* allocation group inode number */
	xfs_agnumber_t		agno;	/* allocation group number */
	int			error;	/* error return value */
	struct xfs_mount	*mp;	/* mount structure for filesystem */
	struct xfs_mount	*mp = tp->t_mountp;
	struct xfs_inobt_rec_incore rec;/* btree record */

	mp = tp->t_mountp;
	struct xfs_perag	*pag;

	/*
	 * Break up inode number into its components.
@@ -2231,7 +2224,8 @@ xfs_difree(
	/*
	 * Fix up the inode allocation btree.
	 */
	error = xfs_difree_inobt(mp, tp, agbp, agino, xic, &rec);
	pag = agbp->b_pag;
	error = xfs_difree_inobt(mp, tp, agbp, pag, agino, xic, &rec);
	if (error)
		goto error0;

@@ -2239,7 +2233,7 @@ xfs_difree(
	 * Fix up the free inode btree.
	 */
	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
		error = xfs_difree_finobt(mp, tp, agbp, agino, &rec);
		error = xfs_difree_finobt(mp, tp, agbp, pag, agino, &rec);
		if (error)
			goto error0;
	}
@@ -2254,7 +2248,7 @@ STATIC int
xfs_imap_lookup(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	xfs_agnumber_t		agno,
	struct xfs_perag	*pag,
	xfs_agino_t		agino,
	xfs_agblock_t		agbno,
	xfs_agblock_t		*chunk_agbno,
@@ -2267,11 +2261,11 @@ xfs_imap_lookup(
	int			error;
	int			i;

	error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
	error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, &agbp);
	if (error) {
		xfs_alert(mp,
			"%s: xfs_ialloc_read_agi() returned error %d, agno %d",
			__func__, error, agno);
			__func__, error, pag->pag_agno);
		return error;
	}

@@ -2281,7 +2275,7 @@ xfs_imap_lookup(
	 * we have a record, we need to ensure it contains the inode number
	 * we are looking up.
	 */
	cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, NULL, XFS_BTNUM_INO);
	cur = xfs_inobt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_INO);
	error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
	if (!error) {
		if (i)
@@ -2315,42 +2309,44 @@ xfs_imap_lookup(
 */
int
xfs_imap(
	xfs_mount_t	 *mp,	/* file system mount structure */
	xfs_trans_t	 *tp,	/* transaction pointer */
	struct xfs_mount	 *mp,	/* file system mount structure */
	struct xfs_trans	 *tp,	/* transaction pointer */
	xfs_ino_t		ino,	/* inode to locate */
	struct xfs_imap		*imap,	/* location map structure */
	uint			flags)	/* flags for inode btree lookup */
{
	xfs_agblock_t		agbno;	/* block number of inode in the alloc group */
	xfs_agino_t		agino;	/* inode number within alloc group */
	xfs_agnumber_t	agno;	/* allocation group number */
	xfs_agblock_t		chunk_agbno;	/* first block in inode chunk */
	xfs_agblock_t		cluster_agbno;	/* first block in inode cluster */
	int			error;	/* error code */
	int			offset;	/* index of inode in its buffer */
	xfs_agblock_t		offset_agbno;	/* blks from chunk start to inode */
	struct xfs_perag	*pag;

	ASSERT(ino != NULLFSINO);

	/*
	 * Split up the inode number into its parts.
	 */
	agno = XFS_INO_TO_AGNO(mp, ino);
	pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));
	agino = XFS_INO_TO_AGINO(mp, ino);
	agbno = XFS_AGINO_TO_AGBNO(mp, agino);
	if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
	    ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
	if (!pag || agbno >= mp->m_sb.sb_agblocks ||
	    ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) {
		error = -EINVAL;
#ifdef DEBUG
		/*
		 * Don't output diagnostic information for untrusted inodes
		 * as they can be invalid without implying corruption.
		 */
		if (flags & XFS_IGET_UNTRUSTED)
			return -EINVAL;
		if (agno >= mp->m_sb.sb_agcount) {
			goto out_drop;
		if (!pag) {
			xfs_alert(mp,
				"%s: agno (%d) >= mp->m_sb.sb_agcount (%d)",
				__func__, agno, mp->m_sb.sb_agcount);
				__func__, XFS_INO_TO_AGNO(mp, ino),
				mp->m_sb.sb_agcount);
		}
		if (agbno >= mp->m_sb.sb_agblocks) {
			xfs_alert(mp,
@@ -2358,15 +2354,15 @@ xfs_imap(
				__func__, (unsigned long long)agbno,
				(unsigned long)mp->m_sb.sb_agblocks);
		}
		if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
		if (pag && ino != XFS_AGINO_TO_INO(mp, pag->pag_agno, agino)) {
			xfs_alert(mp,
		"%s: ino (0x%llx) != XFS_AGINO_TO_INO() (0x%llx)",
				__func__, ino,
				XFS_AGINO_TO_INO(mp, agno, agino));
				XFS_AGINO_TO_INO(mp, pag->pag_agno, agino));
		}
		xfs_stack_trace();
#endif /* DEBUG */
		return -EINVAL;
		goto out_drop;
	}

	/*
@@ -2377,10 +2373,10 @@ xfs_imap(
	 * in all cases where an untrusted inode number is passed.
	 */
	if (flags & XFS_IGET_UNTRUSTED) {
		error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
		error = xfs_imap_lookup(mp, tp, pag, agino, agbno,
					&chunk_agbno, &offset_agbno, flags);
		if (error)
			return error;
			goto out_drop;
		goto out_map;
	}

@@ -2392,11 +2388,12 @@ xfs_imap(
		offset = XFS_INO_TO_OFFSET(mp, ino);
		ASSERT(offset < mp->m_sb.sb_inopblock);

		imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno);
		imap->im_blkno = XFS_AGB_TO_DADDR(mp, pag->pag_agno, agbno);
		imap->im_len = XFS_FSB_TO_BB(mp, 1);
		imap->im_boffset = (unsigned short)(offset <<
							mp->m_sb.sb_inodelog);
		return 0;
		error = 0;
		goto out_drop;
	}

	/*
@@ -2408,10 +2405,10 @@ xfs_imap(
		offset_agbno = agbno & M_IGEO(mp)->inoalign_mask;
		chunk_agbno = agbno - offset_agbno;
	} else {
		error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
		error = xfs_imap_lookup(mp, tp, pag, agino, agbno,
					&chunk_agbno, &offset_agbno, flags);
		if (error)
			return error;
			goto out_drop;
	}

out_map:
@@ -2422,7 +2419,7 @@ xfs_imap(
	offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
		XFS_INO_TO_OFFSET(mp, ino);

	imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno);
	imap->im_blkno = XFS_AGB_TO_DADDR(mp, pag->pag_agno, cluster_agbno);
	imap->im_len = XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster);
	imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog);

@@ -2439,9 +2436,13 @@ xfs_imap(
			__func__, (unsigned long long) imap->im_blkno,
			(unsigned long long) imap->im_len,
			XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
		return -EINVAL;
		error = -EINVAL;
		goto out_drop;
	}
	return 0;
	error = 0;
out_drop:
	xfs_perag_put(pag);
	return error;
}

/*
+11 −16
Original line number Diff line number Diff line
@@ -35,8 +35,7 @@ xfs_inobt_dup_cursor(
	struct xfs_btree_cur	*cur)
{
	return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp,
			cur->bc_ag.agbp, cur->bc_ag.agno,
			cur->bc_ag.pag, cur->bc_btnum);
			cur->bc_ag.agbp, cur->bc_ag.pag, cur->bc_btnum);
}

STATIC void
@@ -428,7 +427,6 @@ static struct xfs_btree_cur *
xfs_inobt_init_common(
	struct xfs_mount	*mp,		/* file system mount point */
	struct xfs_trans	*tp,		/* transaction pointer */
	xfs_agnumber_t		agno,		/* allocation group number */
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)		/* ialloc or free ino btree */
{
@@ -451,12 +449,10 @@ xfs_inobt_init_common(
	if (xfs_sb_version_hascrc(&mp->m_sb))
		cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;

	cur->bc_ag.agno = agno;
	if (pag) {
	/* take a reference for the cursor */
	atomic_inc(&pag->pag_ref);
	}
	cur->bc_ag.pag = pag;
	cur->bc_ag.agno = pag->pag_agno;
	return cur;
}

@@ -466,14 +462,13 @@ xfs_inobt_init_cursor(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct xfs_buf		*agbp,
	xfs_agnumber_t		agno,
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)
{
	struct xfs_btree_cur	*cur;
	struct xfs_agi		*agi = agbp->b_addr;

	cur = xfs_inobt_init_common(mp, tp, agno, pag, btnum);
	cur = xfs_inobt_init_common(mp, tp, pag, btnum);
	if (btnum == XFS_BTNUM_INO)
		cur->bc_nlevels = be32_to_cpu(agi->agi_level);
	else
@@ -487,12 +482,12 @@ struct xfs_btree_cur *
xfs_inobt_stage_cursor(
	struct xfs_mount	*mp,
	struct xbtree_afakeroot	*afake,
	xfs_agnumber_t		agno,
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)
{
	struct xfs_btree_cur	*cur;

	cur = xfs_inobt_init_common(mp, NULL, agno, NULL, btnum);
	cur = xfs_inobt_init_common(mp, NULL, pag, btnum);
	xfs_btree_stage_afakeroot(cur, afake);
	return cur;
}
@@ -664,7 +659,7 @@ int
xfs_inobt_cur(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	xfs_agnumber_t		agno,
	struct xfs_perag	*pag,
	xfs_btnum_t		which,
	struct xfs_btree_cur	**curpp,
	struct xfs_buf		**agi_bpp)
@@ -675,11 +670,11 @@ xfs_inobt_cur(
	ASSERT(*agi_bpp == NULL);
	ASSERT(*curpp == NULL);

	error = xfs_ialloc_read_agi(mp, tp, agno, agi_bpp);
	error = xfs_ialloc_read_agi(mp, tp, pag->pag_agno, agi_bpp);
	if (error)
		return error;

	cur = xfs_inobt_init_cursor(mp, tp, *agi_bpp, agno, NULL, which);
	cur = xfs_inobt_init_cursor(mp, tp, *agi_bpp, pag, which);
	*curpp = cur;
	return 0;
}
@@ -696,7 +691,7 @@ xfs_inobt_count_blocks(
	struct xfs_btree_cur	*cur = NULL;
	int			error;

	error = xfs_inobt_cur(mp, tp, pag->pag_agno, btnum, &cur, &agbp);
	error = xfs_inobt_cur(mp, tp, pag, btnum, &cur, &agbp);
	if (error)
		return error;

+3 −3
Original line number Diff line number Diff line
@@ -47,10 +47,10 @@ struct xfs_perag;
		 ((index) - 1) * sizeof(xfs_inobt_ptr_t)))

extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *mp,
		struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno,
		struct xfs_trans *tp, struct xfs_buf *agbp,
		struct xfs_perag *pag, xfs_btnum_t btnum);
struct xfs_btree_cur *xfs_inobt_stage_cursor(struct xfs_mount *mp,
		struct xbtree_afakeroot *afake, xfs_agnumber_t agno,
		struct xbtree_afakeroot *afake, struct xfs_perag *pag,
		xfs_btnum_t btnum);
extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int);

@@ -69,7 +69,7 @@ int xfs_finobt_calc_reserves(struct xfs_mount *mp, struct xfs_trans *tp,
extern xfs_extlen_t xfs_iallocbt_calc_size(struct xfs_mount *mp,
		unsigned long long len);
int xfs_inobt_cur(struct xfs_mount *mp, struct xfs_trans *tp,
		xfs_agnumber_t agno, xfs_btnum_t btnum,
		struct xfs_perag *pag, xfs_btnum_t btnum,
		struct xfs_btree_cur **curpp, struct xfs_buf **agi_bpp);

void xfs_inobt_commit_staged_btree(struct xfs_btree_cur *cur,
+2 −2
Original line number Diff line number Diff line
@@ -806,7 +806,7 @@ xrep_agi_calc_from_btrees(
	xfs_agino_t		freecount;
	int			error;

	cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno,
	cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp,
			sc->sa.pag, XFS_BTNUM_INO);
	error = xfs_ialloc_count_inodes(cur, &count, &freecount);
	if (error)
@@ -828,7 +828,7 @@ xrep_agi_calc_from_btrees(
	    xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
		xfs_agblock_t	blocks;

		cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno,
		cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp,
				sc->sa.pag, XFS_BTNUM_FINO);
		error = xfs_btree_count_blocks(cur, &blocks);
		if (error)
+2 −3
Original line number Diff line number Diff line
@@ -458,7 +458,6 @@ xchk_ag_btcur_init(
	struct xchk_ag		*sa)
{
	struct xfs_mount	*mp = sc->mp;
	xfs_agnumber_t		agno = sa->agno;

	xchk_perag_get(sc->mp, sa);
	if (sa->agf_bp &&
@@ -479,14 +478,14 @@ xchk_ag_btcur_init(
	if (sa->agi_bp &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_INO)) {
		sa->ino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
				agno, sa->pag, XFS_BTNUM_INO);
				sa->pag, XFS_BTNUM_INO);
	}

	/* Set up a finobt cursor for cross-referencing. */
	if (sa->agi_bp && xfs_sb_version_hasfinobt(&mp->m_sb) &&
	    xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_FINO)) {
		sa->fino_cur = xfs_inobt_init_cursor(mp, sc->tp, sa->agi_bp,
				agno, sa->pag, XFS_BTNUM_FINO);
				sa->pag, XFS_BTNUM_FINO);
	}

	/* Set up a rmapbt cursor for cross-referencing. */
Loading