diff options
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/xfs_ialloc.c | 35 |
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); |
537 | nextag: | 541 | nextag: |
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; |
1021 | error1: | 1031 | error1: |
1022 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); | 1032 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); |
1023 | error0: | 1033 | error0: |
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 | ||