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

Commit 44b56e0a authored by Dave Chinner's avatar Dave Chinner Committed by Alex Elder
Browse files

xfs: convert remaining direct references to m_perag



Convert the remaining direct lookups of the per ag structures to use
get/put accesses. Ensure that the loops across AGs and prior users
of the interface balance gets and puts correctly.

Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
parent 4196ac08
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -2630,11 +2630,12 @@ xfs_bmap_btalloc(
			startag = ag = 0;
			startag = ag = 0;
		notinit = 0;
		notinit = 0;
		down_read(&mp->m_peraglock);
		down_read(&mp->m_peraglock);
		pag = xfs_perag_get(mp, ag);
		while (blen < ap->alen) {
		while (blen < ap->alen) {
			pag = &mp->m_perag[ag];
			if (!pag->pagf_init &&
			if (!pag->pagf_init &&
			    (error = xfs_alloc_pagf_init(mp, args.tp,
			    (error = xfs_alloc_pagf_init(mp, args.tp,
				    ag, XFS_ALLOC_FLAG_TRYLOCK))) {
				    ag, XFS_ALLOC_FLAG_TRYLOCK))) {
				xfs_perag_put(pag);
				up_read(&mp->m_peraglock);
				up_read(&mp->m_peraglock);
				return error;
				return error;
			}
			}
@@ -2667,6 +2668,7 @@ xfs_bmap_btalloc(
						break;
						break;


					error = xfs_filestream_new_ag(ap, &ag);
					error = xfs_filestream_new_ag(ap, &ag);
					xfs_perag_put(pag);
					if (error) {
					if (error) {
						up_read(&mp->m_peraglock);
						up_read(&mp->m_peraglock);
						return error;
						return error;
@@ -2674,6 +2676,7 @@ xfs_bmap_btalloc(


					/* loop again to set 'blen'*/
					/* loop again to set 'blen'*/
					startag = NULLAGNUMBER;
					startag = NULLAGNUMBER;
					pag = xfs_perag_get(mp, ag);
					continue;
					continue;
				}
				}
			}
			}
@@ -2681,7 +2684,10 @@ xfs_bmap_btalloc(
				ag = 0;
				ag = 0;
			if (ag == startag)
			if (ag == startag)
				break;
				break;
			xfs_perag_put(pag);
			pag = xfs_perag_get(mp, ag);
		}
		}
		xfs_perag_put(pag);
		up_read(&mp->m_peraglock);
		up_read(&mp->m_peraglock);
		/*
		/*
		 * Since the above loop did a BUF_TRYLOCK, it is
		 * Since the above loop did a BUF_TRYLOCK, it is
+25 −10
Original line number Original line Diff line number Diff line
@@ -253,6 +253,7 @@ xfs_ialloc_ag_alloc(
	xfs_agino_t	thisino;	/* current inode number, for loop */
	xfs_agino_t	thisino;	/* current inode number, for loop */
	int		isaligned = 0;	/* inode allocation at stripe unit */
	int		isaligned = 0;	/* inode allocation at stripe unit */
					/* boundary */
					/* boundary */
	struct xfs_perag *pag;


	args.tp = tp;
	args.tp = tp;
	args.mp = tp->t_mountp;
	args.mp = tp->t_mountp;
@@ -383,7 +384,9 @@ xfs_ialloc_ag_alloc(
	be32_add_cpu(&agi->agi_count, newlen);
	be32_add_cpu(&agi->agi_count, newlen);
	be32_add_cpu(&agi->agi_freecount, newlen);
	be32_add_cpu(&agi->agi_freecount, newlen);
	down_read(&args.mp->m_peraglock);
	down_read(&args.mp->m_peraglock);
	args.mp->m_perag[agno].pagi_freecount += newlen;
	pag = xfs_perag_get(args.mp, agno);
	pag->pagi_freecount += newlen;
	xfs_perag_put(pag);
	up_read(&args.mp->m_peraglock);
	up_read(&args.mp->m_peraglock);
	agi->agi_newino = cpu_to_be32(newino);
	agi->agi_newino = cpu_to_be32(newino);


@@ -488,7 +491,7 @@ xfs_ialloc_ag_select(
	flags = XFS_ALLOC_FLAG_TRYLOCK;
	flags = XFS_ALLOC_FLAG_TRYLOCK;
	down_read(&mp->m_peraglock);
	down_read(&mp->m_peraglock);
	for (;;) {
	for (;;) {
		pag = &mp->m_perag[agno];
		pag = xfs_perag_get(mp, agno);
		if (!pag->pagi_init) {
		if (!pag->pagi_init) {
			if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
			if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
				agbp = NULL;
				agbp = NULL;
@@ -527,6 +530,7 @@ xfs_ialloc_ag_select(
					agbp = NULL;
					agbp = NULL;
					goto nextag;
					goto nextag;
				}
				}
				xfs_perag_put(pag);
				up_read(&mp->m_peraglock);
				up_read(&mp->m_peraglock);
				return agbp;
				return agbp;
			}
			}
@@ -535,6 +539,7 @@ unlock_nextag:
		if (agbp)
		if (agbp)
			xfs_trans_brelse(tp, agbp);
			xfs_trans_brelse(tp, agbp);
nextag:
nextag:
		xfs_perag_put(pag);
		/*
		/*
		 * No point in iterating over the rest, if we're shutting
		 * No point in iterating over the rest, if we're shutting
		 * down.
		 * down.
@@ -672,6 +677,7 @@ xfs_dialloc(
	xfs_agnumber_t	tagno;		/* testing allocation group number */
	xfs_agnumber_t	tagno;		/* testing allocation group number */
	xfs_btree_cur_t	*tcur;		/* temp cursor */
	xfs_btree_cur_t	*tcur;		/* temp cursor */
	xfs_inobt_rec_incore_t trec;	/* temp inode allocation record */
	xfs_inobt_rec_incore_t trec;	/* temp inode allocation record */
	struct xfs_perag *pag;




	if (*IO_agbp == NULL) {
	if (*IO_agbp == NULL) {
@@ -772,11 +778,14 @@ nextag:
			return noroom ? ENOSPC : 0;
			return noroom ? ENOSPC : 0;
		}
		}
		down_read(&mp->m_peraglock);
		down_read(&mp->m_peraglock);
		if (mp->m_perag[tagno].pagi_inodeok == 0) {
		pag = xfs_perag_get(mp, tagno);
		if (pag->pagi_inodeok == 0) {
			xfs_perag_put(pag);
			up_read(&mp->m_peraglock);
			up_read(&mp->m_peraglock);
			goto nextag;
			goto nextag;
		}
		}
		error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);
		error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);
		xfs_perag_put(pag);
		up_read(&mp->m_peraglock);
		up_read(&mp->m_peraglock);
		if (error)
		if (error)
			goto nextag;
			goto nextag;
@@ -790,6 +799,7 @@ nextag:
	 */
	 */
	agno = tagno;
	agno = tagno;
	*IO_agbp = NULL;
	*IO_agbp = NULL;
	pag = xfs_perag_get(mp, agno);


 restart_pagno:
 restart_pagno:
	cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
	cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
@@ -808,7 +818,6 @@ nextag:
	 * If in the same AG as the parent, try to get near the parent.
	 * If in the same AG as the parent, try to get near the parent.
	 */
	 */
	if (pagno == agno) {
	if (pagno == agno) {
		xfs_perag_t	*pag = &mp->m_perag[agno];
		int		doneleft;	/* done, to the left */
		int		doneleft;	/* done, to the left */
		int		doneright;	/* done, to the right */
		int		doneright;	/* done, to the right */
		int		searchdistance = 10;
		int		searchdistance = 10;
@@ -1007,7 +1016,7 @@ alloc_inode:
	be32_add_cpu(&agi->agi_freecount, -1);
	be32_add_cpu(&agi->agi_freecount, -1);
	xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
	xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
	down_read(&mp->m_peraglock);
	down_read(&mp->m_peraglock);
	mp->m_perag[tagno].pagi_freecount--;
	pag->pagi_freecount--;
	up_read(&mp->m_peraglock);
	up_read(&mp->m_peraglock);


	error = xfs_check_agi_freecount(cur, agi);
	error = xfs_check_agi_freecount(cur, agi);
@@ -1016,12 +1025,14 @@ alloc_inode:


	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
	xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
	xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
	xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
	xfs_perag_put(pag);
	*inop = ino;
	*inop = ino;
	return 0;
	return 0;
error1:
error1:
	xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
	xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
error0:
error0:
	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
	xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
	xfs_perag_put(pag);
	return error;
	return error;
}
}


@@ -1052,6 +1063,7 @@ xfs_difree(
	xfs_mount_t	*mp;	/* mount structure for filesystem */
	xfs_mount_t	*mp;	/* mount structure for filesystem */
	int		off;	/* offset of inode in inode chunk */
	int		off;	/* offset of inode in inode chunk */
	xfs_inobt_rec_incore_t rec;	/* btree record */
	xfs_inobt_rec_incore_t rec;	/* btree record */
	struct xfs_perag *pag;


	mp = tp->t_mountp;
	mp = tp->t_mountp;


@@ -1158,7 +1170,9 @@ xfs_difree(
		be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
		be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
		down_read(&mp->m_peraglock);
		down_read(&mp->m_peraglock);
		mp->m_perag[agno].pagi_freecount -= ilen - 1;
		pag = xfs_perag_get(mp, agno);
		pag->pagi_freecount -= ilen - 1;
		xfs_perag_put(pag);
		up_read(&mp->m_peraglock);
		up_read(&mp->m_peraglock);
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
@@ -1189,7 +1203,9 @@ xfs_difree(
		be32_add_cpu(&agi->agi_freecount, 1);
		be32_add_cpu(&agi->agi_freecount, 1);
		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
		xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
		down_read(&mp->m_peraglock);
		down_read(&mp->m_peraglock);
		mp->m_perag[agno].pagi_freecount++;
		pag = xfs_perag_get(mp, agno);
		pag->pagi_freecount++;
		xfs_perag_put(pag);
		up_read(&mp->m_peraglock);
		up_read(&mp->m_peraglock);
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
		xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
	}
	}
@@ -1379,7 +1395,6 @@ xfs_imap(
			XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
			XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
		return XFS_ERROR(EINVAL);
		return XFS_ERROR(EINVAL);
	}
	}

	return 0;
	return 0;
}
}


@@ -1523,8 +1538,7 @@ xfs_ialloc_read_agi(
		return error;
		return error;


	agi = XFS_BUF_TO_AGI(*bpp);
	agi = XFS_BUF_TO_AGI(*bpp);
	pag = &mp->m_perag[agno];
	pag = xfs_perag_get(mp, agno);

	if (!pag->pagi_init) {
	if (!pag->pagi_init) {
		pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
		pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
		pag->pagi_count = be32_to_cpu(agi->agi_count);
		pag->pagi_count = be32_to_cpu(agi->agi_count);
@@ -1537,6 +1551,7 @@ xfs_ialloc_read_agi(
	 */
	 */
	ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
	ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
		XFS_FORCED_SHUTDOWN(mp));
		XFS_FORCED_SHUTDOWN(mp));
	xfs_perag_put(pag);
	return 0;
	return 0;
}
}


+4 −1
Original line number Original line Diff line number Diff line
@@ -2695,7 +2695,7 @@ xfs_iflush_cluster(
	ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
	ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
	ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
	ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
	if (!ilist)
	if (!ilist)
		return 0;
		goto out_put;


	mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
	mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
	first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask;
	first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask;
@@ -2764,6 +2764,8 @@ xfs_iflush_cluster(
out_free:
out_free:
	read_unlock(&pag->pag_ici_lock);
	read_unlock(&pag->pag_ici_lock);
	kmem_free(ilist);
	kmem_free(ilist);
out_put:
	xfs_perag_put(pag);
	return 0;
	return 0;




@@ -2807,6 +2809,7 @@ cluster_corrupt_out:
	 */
	 */
	xfs_iflush_abort(iq);
	xfs_iflush_abort(iq);
	kmem_free(ilist);
	kmem_free(ilist);
	xfs_perag_put(pag);
	return XFS_ERROR(EFSCORRUPTED);
	return XFS_ERROR(EFSCORRUPTED);
}
}


+6 −3
Original line number Original line Diff line number Diff line
@@ -438,18 +438,20 @@ xfs_initialize_perag(
			}
			}


			/* This ag is preferred for inodes */
			/* This ag is preferred for inodes */
			pag = &mp->m_perag[index];
			pag = xfs_perag_get(mp, index);
			pag->pagi_inodeok = 1;
			pag->pagi_inodeok = 1;
			if (index < max_metadata)
			if (index < max_metadata)
				pag->pagf_metadata = 1;
				pag->pagf_metadata = 1;
			xfs_initialize_perag_icache(pag);
			xfs_initialize_perag_icache(pag);
			xfs_perag_put(pag);
		}
		}
	} else {
	} else {
		/* Setup default behavior for smaller filesystems */
		/* Setup default behavior for smaller filesystems */
		for (index = 0; index < agcount; index++) {
		for (index = 0; index < agcount; index++) {
			pag = &mp->m_perag[index];
			pag = xfs_perag_get(mp, index);
			pag->pagi_inodeok = 1;
			pag->pagi_inodeok = 1;
			xfs_initialize_perag_icache(pag);
			xfs_initialize_perag_icache(pag);
			xfs_perag_put(pag);
		}
		}
	}
	}
	return index;
	return index;
@@ -731,12 +733,13 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
		error = xfs_ialloc_pagi_init(mp, NULL, index);
		error = xfs_ialloc_pagi_init(mp, NULL, index);
		if (error)
		if (error)
			return error;
			return error;
		pag = &mp->m_perag[index];
		pag = xfs_perag_get(mp, index);
		ifree += pag->pagi_freecount;
		ifree += pag->pagi_freecount;
		ialloc += pag->pagi_count;
		ialloc += pag->pagi_count;
		bfree += pag->pagf_freeblks;
		bfree += pag->pagf_freeblks;
		bfreelst += pag->pagf_flcount;
		bfreelst += pag->pagf_flcount;
		btree += pag->pagf_btreeblks;
		btree += pag->pagf_btreeblks;
		xfs_perag_put(pag);
	}
	}
	/*
	/*
	 * Overwrite incore superblock counters with just-read data
	 * Overwrite incore superblock counters with just-read data