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

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
...@@ -2630,11 +2630,12 @@ xfs_bmap_btalloc( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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
......
...@@ -253,6 +253,7 @@ xfs_ialloc_ag_alloc( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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 @@ xfs_ialloc_ag_select( ...@@ -535,6 +539,7 @@ xfs_ialloc_ag_select(
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( ...@@ -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 @@ xfs_dialloc( ...@@ -772,11 +778,14 @@ xfs_dialloc(
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 @@ xfs_dialloc( ...@@ -790,6 +799,7 @@ xfs_dialloc(
*/ */
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 @@ xfs_dialloc( ...@@ -808,7 +818,6 @@ xfs_dialloc(
* 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 @@ xfs_dialloc( ...@@ -1007,7 +1016,7 @@ xfs_dialloc(
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 @@ xfs_dialloc( ...@@ -1016,12 +1025,14 @@ xfs_dialloc(
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( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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( ...@@ -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;
} }
......
...@@ -2695,7 +2695,7 @@ xfs_iflush_cluster( ...@@ -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( ...@@ -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 @@ xfs_iflush_cluster( ...@@ -2807,6 +2809,7 @@ xfs_iflush_cluster(
*/ */
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);
} }
......
...@@ -438,18 +438,20 @@ xfs_initialize_perag( ...@@ -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) ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment