aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_ialloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r--fs/xfs/xfs_ialloc.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index cb907ba69c4c..884ee1367f46 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -253,6 +253,7 @@ xfs_ialloc_ag_alloc(
253 xfs_agino_t thisino; /* current inode number, for loop */ 253 xfs_agino_t thisino; /* current inode number, for loop */
254 int isaligned = 0; /* inode allocation at stripe unit */ 254 int isaligned = 0; /* inode allocation at stripe unit */
255 /* boundary */ 255 /* boundary */
256 struct xfs_perag *pag;
256 257
257 args.tp = tp; 258 args.tp = tp;
258 args.mp = tp->t_mountp; 259 args.mp = tp->t_mountp;
@@ -383,7 +384,9 @@ xfs_ialloc_ag_alloc(
383 be32_add_cpu(&agi->agi_count, newlen); 384 be32_add_cpu(&agi->agi_count, newlen);
384 be32_add_cpu(&agi->agi_freecount, newlen); 385 be32_add_cpu(&agi->agi_freecount, newlen);
385 down_read(&args.mp->m_peraglock); 386 down_read(&args.mp->m_peraglock);
386 args.mp->m_perag[agno].pagi_freecount += newlen; 387 pag = xfs_perag_get(args.mp, agno);
388 pag->pagi_freecount += newlen;
389 xfs_perag_put(pag);
387 up_read(&args.mp->m_peraglock); 390 up_read(&args.mp->m_peraglock);
388 agi->agi_newino = cpu_to_be32(newino); 391 agi->agi_newino = cpu_to_be32(newino);
389 392
@@ -488,7 +491,7 @@ xfs_ialloc_ag_select(
488 flags = XFS_ALLOC_FLAG_TRYLOCK; 491 flags = XFS_ALLOC_FLAG_TRYLOCK;
489 down_read(&mp->m_peraglock); 492 down_read(&mp->m_peraglock);
490 for (;;) { 493 for (;;) {
491 pag = &mp->m_perag[agno]; 494 pag = xfs_perag_get(mp, agno);
492 if (!pag->pagi_init) { 495 if (!pag->pagi_init) {
493 if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { 496 if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
494 agbp = NULL; 497 agbp = NULL;
@@ -527,6 +530,7 @@ xfs_ialloc_ag_select(
527 agbp = NULL; 530 agbp = NULL;
528 goto nextag; 531 goto nextag;
529 } 532 }
533 xfs_perag_put(pag);
530 up_read(&mp->m_peraglock); 534 up_read(&mp->m_peraglock);
531 return agbp; 535 return agbp;
532 } 536 }
@@ -535,6 +539,7 @@ unlock_nextag:
535 if (agbp) 539 if (agbp)
536 xfs_trans_brelse(tp, agbp); 540 xfs_trans_brelse(tp, agbp);
537nextag: 541nextag:
542 xfs_perag_put(pag);
538 /* 543 /*
539 * No point in iterating over the rest, if we're shutting 544 * No point in iterating over the rest, if we're shutting
540 * down. 545 * down.
@@ -672,6 +677,7 @@ xfs_dialloc(
672 xfs_agnumber_t tagno; /* testing allocation group number */ 677 xfs_agnumber_t tagno; /* testing allocation group number */
673 xfs_btree_cur_t *tcur; /* temp cursor */ 678 xfs_btree_cur_t *tcur; /* temp cursor */
674 xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ 679 xfs_inobt_rec_incore_t trec; /* temp inode allocation record */
680 struct xfs_perag *pag;
675 681
676 682
677 if (*IO_agbp == NULL) { 683 if (*IO_agbp == NULL) {
@@ -772,11 +778,14 @@ nextag:
772 return noroom ? ENOSPC : 0; 778 return noroom ? ENOSPC : 0;
773 } 779 }
774 down_read(&mp->m_peraglock); 780 down_read(&mp->m_peraglock);
775 if (mp->m_perag[tagno].pagi_inodeok == 0) { 781 pag = xfs_perag_get(mp, tagno);
782 if (pag->pagi_inodeok == 0) {
783 xfs_perag_put(pag);
776 up_read(&mp->m_peraglock); 784 up_read(&mp->m_peraglock);
777 goto nextag; 785 goto nextag;
778 } 786 }
779 error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp); 787 error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);
788 xfs_perag_put(pag);
780 up_read(&mp->m_peraglock); 789 up_read(&mp->m_peraglock);
781 if (error) 790 if (error)
782 goto nextag; 791 goto nextag;
@@ -790,6 +799,7 @@ nextag:
790 */ 799 */
791 agno = tagno; 800 agno = tagno;
792 *IO_agbp = NULL; 801 *IO_agbp = NULL;
802 pag = xfs_perag_get(mp, agno);
793 803
794 restart_pagno: 804 restart_pagno:
795 cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); 805 cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
@@ -808,7 +818,6 @@ nextag:
808 * If in the same AG as the parent, try to get near the parent. 818 * If in the same AG as the parent, try to get near the parent.
809 */ 819 */
810 if (pagno == agno) { 820 if (pagno == agno) {
811 xfs_perag_t *pag = &mp->m_perag[agno];
812 int doneleft; /* done, to the left */ 821 int doneleft; /* done, to the left */
813 int doneright; /* done, to the right */ 822 int doneright; /* done, to the right */
814 int searchdistance = 10; 823 int searchdistance = 10;
@@ -1007,7 +1016,7 @@ alloc_inode:
1007 be32_add_cpu(&agi->agi_freecount, -1); 1016 be32_add_cpu(&agi->agi_freecount, -1);
1008 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); 1017 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1009 down_read(&mp->m_peraglock); 1018 down_read(&mp->m_peraglock);
1010 mp->m_perag[tagno].pagi_freecount--; 1019 pag->pagi_freecount--;
1011 up_read(&mp->m_peraglock); 1020 up_read(&mp->m_peraglock);
1012 1021
1013 error = xfs_check_agi_freecount(cur, agi); 1022 error = xfs_check_agi_freecount(cur, agi);
@@ -1016,12 +1025,14 @@ alloc_inode:
1016 1025
1017 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1026 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1018 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); 1027 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
1028 xfs_perag_put(pag);
1019 *inop = ino; 1029 *inop = ino;
1020 return 0; 1030 return 0;
1021error1: 1031error1:
1022 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); 1032 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
1023error0: 1033error0:
1024 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); 1034 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1035 xfs_perag_put(pag);
1025 return error; 1036 return error;
1026} 1037}
1027 1038
@@ -1052,6 +1063,7 @@ xfs_difree(
1052 xfs_mount_t *mp; /* mount structure for filesystem */ 1063 xfs_mount_t *mp; /* mount structure for filesystem */
1053 int off; /* offset of inode in inode chunk */ 1064 int off; /* offset of inode in inode chunk */
1054 xfs_inobt_rec_incore_t rec; /* btree record */ 1065 xfs_inobt_rec_incore_t rec; /* btree record */
1066 struct xfs_perag *pag;
1055 1067
1056 mp = tp->t_mountp; 1068 mp = tp->t_mountp;
1057 1069
@@ -1158,7 +1170,9 @@ xfs_difree(
1158 be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); 1170 be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
1159 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); 1171 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
1160 down_read(&mp->m_peraglock); 1172 down_read(&mp->m_peraglock);
1161 mp->m_perag[agno].pagi_freecount -= ilen - 1; 1173 pag = xfs_perag_get(mp, agno);
1174 pag->pagi_freecount -= ilen - 1;
1175 xfs_perag_put(pag);
1162 up_read(&mp->m_peraglock); 1176 up_read(&mp->m_peraglock);
1163 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen); 1177 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
1164 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1)); 1178 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
@@ -1189,7 +1203,9 @@ xfs_difree(
1189 be32_add_cpu(&agi->agi_freecount, 1); 1203 be32_add_cpu(&agi->agi_freecount, 1);
1190 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); 1204 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1191 down_read(&mp->m_peraglock); 1205 down_read(&mp->m_peraglock);
1192 mp->m_perag[agno].pagi_freecount++; 1206 pag = xfs_perag_get(mp, agno);
1207 pag->pagi_freecount++;
1208 xfs_perag_put(pag);
1193 up_read(&mp->m_peraglock); 1209 up_read(&mp->m_peraglock);
1194 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1); 1210 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
1195 } 1211 }
@@ -1379,7 +1395,6 @@ xfs_imap(
1379 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); 1395 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
1380 return XFS_ERROR(EINVAL); 1396 return XFS_ERROR(EINVAL);
1381 } 1397 }
1382
1383 return 0; 1398 return 0;
1384} 1399}
1385 1400
@@ -1523,8 +1538,7 @@ xfs_ialloc_read_agi(
1523 return error; 1538 return error;
1524 1539
1525 agi = XFS_BUF_TO_AGI(*bpp); 1540 agi = XFS_BUF_TO_AGI(*bpp);
1526 pag = &mp->m_perag[agno]; 1541 pag = xfs_perag_get(mp, agno);
1527
1528 if (!pag->pagi_init) { 1542 if (!pag->pagi_init) {
1529 pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); 1543 pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
1530 pag->pagi_count = be32_to_cpu(agi->agi_count); 1544 pag->pagi_count = be32_to_cpu(agi->agi_count);
@@ -1537,6 +1551,7 @@ xfs_ialloc_read_agi(
1537 */ 1551 */
1538 ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || 1552 ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
1539 XFS_FORCED_SHUTDOWN(mp)); 1553 XFS_FORCED_SHUTDOWN(mp));
1554 xfs_perag_put(pag);
1540 return 0; 1555 return 0;
1541} 1556}
1542 1557