diff options
Diffstat (limited to 'fs/xfs/xfs_ialloc.c')
| -rw-r--r-- | fs/xfs/xfs_ialloc.c | 62 |
1 files changed, 28 insertions, 34 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c index cb907ba69c4c..9d884c127bb9 100644 --- a/fs/xfs/xfs_ialloc.c +++ b/fs/xfs/xfs_ialloc.c | |||
| @@ -205,7 +205,7 @@ xfs_ialloc_inode_init( | |||
| 205 | d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); | 205 | d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster)); |
| 206 | fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, | 206 | fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, |
| 207 | mp->m_bsize * blks_per_cluster, | 207 | mp->m_bsize * blks_per_cluster, |
| 208 | XFS_BUF_LOCK); | 208 | XBF_LOCK); |
| 209 | ASSERT(fbuf); | 209 | ASSERT(fbuf); |
| 210 | ASSERT(!XFS_BUF_GETERROR(fbuf)); | 210 | ASSERT(!XFS_BUF_GETERROR(fbuf)); |
| 211 | 211 | ||
| @@ -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; |
| @@ -382,9 +383,9 @@ xfs_ialloc_ag_alloc( | |||
| 382 | newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); | 383 | newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0); |
| 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 | pag = xfs_perag_get(args.mp, agno); |
| 386 | args.mp->m_perag[agno].pagi_freecount += newlen; | 387 | pag->pagi_freecount += newlen; |
| 387 | up_read(&args.mp->m_peraglock); | 388 | xfs_perag_put(pag); |
| 388 | agi->agi_newino = cpu_to_be32(newino); | 389 | agi->agi_newino = cpu_to_be32(newino); |
| 389 | 390 | ||
| 390 | /* | 391 | /* |
| @@ -486,9 +487,8 @@ xfs_ialloc_ag_select( | |||
| 486 | */ | 487 | */ |
| 487 | agno = pagno; | 488 | agno = pagno; |
| 488 | flags = XFS_ALLOC_FLAG_TRYLOCK; | 489 | flags = XFS_ALLOC_FLAG_TRYLOCK; |
| 489 | down_read(&mp->m_peraglock); | ||
| 490 | for (;;) { | 490 | for (;;) { |
| 491 | pag = &mp->m_perag[agno]; | 491 | pag = xfs_perag_get(mp, agno); |
| 492 | if (!pag->pagi_init) { | 492 | if (!pag->pagi_init) { |
| 493 | if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | 493 | if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { |
| 494 | agbp = NULL; | 494 | agbp = NULL; |
| @@ -527,7 +527,7 @@ xfs_ialloc_ag_select( | |||
| 527 | agbp = NULL; | 527 | agbp = NULL; |
| 528 | goto nextag; | 528 | goto nextag; |
| 529 | } | 529 | } |
| 530 | up_read(&mp->m_peraglock); | 530 | xfs_perag_put(pag); |
| 531 | return agbp; | 531 | return agbp; |
| 532 | } | 532 | } |
| 533 | } | 533 | } |
| @@ -535,22 +535,19 @@ unlock_nextag: | |||
| 535 | if (agbp) | 535 | if (agbp) |
| 536 | xfs_trans_brelse(tp, agbp); | 536 | xfs_trans_brelse(tp, agbp); |
| 537 | nextag: | 537 | nextag: |
| 538 | xfs_perag_put(pag); | ||
| 538 | /* | 539 | /* |
| 539 | * No point in iterating over the rest, if we're shutting | 540 | * No point in iterating over the rest, if we're shutting |
| 540 | * down. | 541 | * down. |
| 541 | */ | 542 | */ |
| 542 | if (XFS_FORCED_SHUTDOWN(mp)) { | 543 | if (XFS_FORCED_SHUTDOWN(mp)) |
| 543 | up_read(&mp->m_peraglock); | ||
| 544 | return NULL; | 544 | return NULL; |
| 545 | } | ||
| 546 | agno++; | 545 | agno++; |
| 547 | if (agno >= agcount) | 546 | if (agno >= agcount) |
| 548 | agno = 0; | 547 | agno = 0; |
| 549 | if (agno == pagno) { | 548 | if (agno == pagno) { |
| 550 | if (flags == 0) { | 549 | if (flags == 0) |
| 551 | up_read(&mp->m_peraglock); | ||
| 552 | return NULL; | 550 | return NULL; |
| 553 | } | ||
| 554 | flags = 0; | 551 | flags = 0; |
| 555 | } | 552 | } |
| 556 | } | 553 | } |
| @@ -672,6 +669,7 @@ xfs_dialloc( | |||
| 672 | xfs_agnumber_t tagno; /* testing allocation group number */ | 669 | xfs_agnumber_t tagno; /* testing allocation group number */ |
| 673 | xfs_btree_cur_t *tcur; /* temp cursor */ | 670 | xfs_btree_cur_t *tcur; /* temp cursor */ |
| 674 | xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ | 671 | xfs_inobt_rec_incore_t trec; /* temp inode allocation record */ |
| 672 | struct xfs_perag *pag; | ||
| 675 | 673 | ||
| 676 | 674 | ||
| 677 | if (*IO_agbp == NULL) { | 675 | if (*IO_agbp == NULL) { |
| @@ -771,13 +769,13 @@ nextag: | |||
| 771 | *inop = NULLFSINO; | 769 | *inop = NULLFSINO; |
| 772 | return noroom ? ENOSPC : 0; | 770 | return noroom ? ENOSPC : 0; |
| 773 | } | 771 | } |
| 774 | down_read(&mp->m_peraglock); | 772 | pag = xfs_perag_get(mp, tagno); |
| 775 | if (mp->m_perag[tagno].pagi_inodeok == 0) { | 773 | if (pag->pagi_inodeok == 0) { |
| 776 | up_read(&mp->m_peraglock); | 774 | xfs_perag_put(pag); |
| 777 | goto nextag; | 775 | goto nextag; |
| 778 | } | 776 | } |
| 779 | error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp); | 777 | error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp); |
| 780 | up_read(&mp->m_peraglock); | 778 | xfs_perag_put(pag); |
| 781 | if (error) | 779 | if (error) |
| 782 | goto nextag; | 780 | goto nextag; |
| 783 | agi = XFS_BUF_TO_AGI(agbp); | 781 | agi = XFS_BUF_TO_AGI(agbp); |
| @@ -790,6 +788,7 @@ nextag: | |||
| 790 | */ | 788 | */ |
| 791 | agno = tagno; | 789 | agno = tagno; |
| 792 | *IO_agbp = NULL; | 790 | *IO_agbp = NULL; |
| 791 | pag = xfs_perag_get(mp, agno); | ||
| 793 | 792 | ||
| 794 | restart_pagno: | 793 | restart_pagno: |
| 795 | cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); | 794 | cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno)); |
| @@ -808,7 +807,6 @@ nextag: | |||
| 808 | * If in the same AG as the parent, try to get near the parent. | 807 | * If in the same AG as the parent, try to get near the parent. |
| 809 | */ | 808 | */ |
| 810 | if (pagno == agno) { | 809 | if (pagno == agno) { |
| 811 | xfs_perag_t *pag = &mp->m_perag[agno]; | ||
| 812 | int doneleft; /* done, to the left */ | 810 | int doneleft; /* done, to the left */ |
| 813 | int doneright; /* done, to the right */ | 811 | int doneright; /* done, to the right */ |
| 814 | int searchdistance = 10; | 812 | int searchdistance = 10; |
| @@ -1006,9 +1004,7 @@ alloc_inode: | |||
| 1006 | goto error0; | 1004 | goto error0; |
| 1007 | be32_add_cpu(&agi->agi_freecount, -1); | 1005 | be32_add_cpu(&agi->agi_freecount, -1); |
| 1008 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); | 1006 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); |
| 1009 | down_read(&mp->m_peraglock); | 1007 | pag->pagi_freecount--; |
| 1010 | mp->m_perag[tagno].pagi_freecount--; | ||
| 1011 | up_read(&mp->m_peraglock); | ||
| 1012 | 1008 | ||
| 1013 | error = xfs_check_agi_freecount(cur, agi); | 1009 | error = xfs_check_agi_freecount(cur, agi); |
| 1014 | if (error) | 1010 | if (error) |
| @@ -1016,12 +1012,14 @@ alloc_inode: | |||
| 1016 | 1012 | ||
| 1017 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); | 1013 | xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); |
| 1018 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); | 1014 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1); |
| 1015 | xfs_perag_put(pag); | ||
| 1019 | *inop = ino; | 1016 | *inop = ino; |
| 1020 | return 0; | 1017 | return 0; |
| 1021 | error1: | 1018 | error1: |
| 1022 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); | 1019 | xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR); |
| 1023 | error0: | 1020 | error0: |
| 1024 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 1021 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
| 1022 | xfs_perag_put(pag); | ||
| 1025 | return error; | 1023 | return error; |
| 1026 | } | 1024 | } |
| 1027 | 1025 | ||
| @@ -1052,6 +1050,7 @@ xfs_difree( | |||
| 1052 | xfs_mount_t *mp; /* mount structure for filesystem */ | 1050 | xfs_mount_t *mp; /* mount structure for filesystem */ |
| 1053 | int off; /* offset of inode in inode chunk */ | 1051 | int off; /* offset of inode in inode chunk */ |
| 1054 | xfs_inobt_rec_incore_t rec; /* btree record */ | 1052 | xfs_inobt_rec_incore_t rec; /* btree record */ |
| 1053 | struct xfs_perag *pag; | ||
| 1055 | 1054 | ||
| 1056 | mp = tp->t_mountp; | 1055 | mp = tp->t_mountp; |
| 1057 | 1056 | ||
| @@ -1088,9 +1087,7 @@ xfs_difree( | |||
| 1088 | /* | 1087 | /* |
| 1089 | * Get the allocation group header. | 1088 | * Get the allocation group header. |
| 1090 | */ | 1089 | */ |
| 1091 | down_read(&mp->m_peraglock); | ||
| 1092 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); | 1090 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); |
| 1093 | up_read(&mp->m_peraglock); | ||
| 1094 | if (error) { | 1091 | if (error) { |
| 1095 | cmn_err(CE_WARN, | 1092 | cmn_err(CE_WARN, |
| 1096 | "xfs_difree: xfs_ialloc_read_agi() returned an error %d on %s. Returning error.", | 1093 | "xfs_difree: xfs_ialloc_read_agi() returned an error %d on %s. Returning error.", |
| @@ -1157,9 +1154,9 @@ xfs_difree( | |||
| 1157 | be32_add_cpu(&agi->agi_count, -ilen); | 1154 | be32_add_cpu(&agi->agi_count, -ilen); |
| 1158 | be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); | 1155 | be32_add_cpu(&agi->agi_freecount, -(ilen - 1)); |
| 1159 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); | 1156 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT); |
| 1160 | down_read(&mp->m_peraglock); | 1157 | pag = xfs_perag_get(mp, agno); |
| 1161 | mp->m_perag[agno].pagi_freecount -= ilen - 1; | 1158 | pag->pagi_freecount -= ilen - 1; |
| 1162 | up_read(&mp->m_peraglock); | 1159 | xfs_perag_put(pag); |
| 1163 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen); | 1160 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen); |
| 1164 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1)); | 1161 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1)); |
| 1165 | 1162 | ||
| @@ -1188,9 +1185,9 @@ xfs_difree( | |||
| 1188 | */ | 1185 | */ |
| 1189 | be32_add_cpu(&agi->agi_freecount, 1); | 1186 | be32_add_cpu(&agi->agi_freecount, 1); |
| 1190 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); | 1187 | xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT); |
| 1191 | down_read(&mp->m_peraglock); | 1188 | pag = xfs_perag_get(mp, agno); |
| 1192 | mp->m_perag[agno].pagi_freecount++; | 1189 | pag->pagi_freecount++; |
| 1193 | up_read(&mp->m_peraglock); | 1190 | xfs_perag_put(pag); |
| 1194 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1); | 1191 | xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1); |
| 1195 | } | 1192 | } |
| 1196 | 1193 | ||
| @@ -1312,9 +1309,7 @@ xfs_imap( | |||
| 1312 | xfs_buf_t *agbp; /* agi buffer */ | 1309 | xfs_buf_t *agbp; /* agi buffer */ |
| 1313 | int i; /* temp state */ | 1310 | int i; /* temp state */ |
| 1314 | 1311 | ||
| 1315 | down_read(&mp->m_peraglock); | ||
| 1316 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); | 1312 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); |
| 1317 | up_read(&mp->m_peraglock); | ||
| 1318 | if (error) { | 1313 | if (error) { |
| 1319 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " | 1314 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " |
| 1320 | "xfs_ialloc_read_agi() returned " | 1315 | "xfs_ialloc_read_agi() returned " |
| @@ -1379,7 +1374,6 @@ xfs_imap( | |||
| 1379 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); | 1374 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); |
| 1380 | return XFS_ERROR(EINVAL); | 1375 | return XFS_ERROR(EINVAL); |
| 1381 | } | 1376 | } |
| 1382 | |||
| 1383 | return 0; | 1377 | return 0; |
| 1384 | } | 1378 | } |
| 1385 | 1379 | ||
| @@ -1523,8 +1517,7 @@ xfs_ialloc_read_agi( | |||
| 1523 | return error; | 1517 | return error; |
| 1524 | 1518 | ||
| 1525 | agi = XFS_BUF_TO_AGI(*bpp); | 1519 | agi = XFS_BUF_TO_AGI(*bpp); |
| 1526 | pag = &mp->m_perag[agno]; | 1520 | pag = xfs_perag_get(mp, agno); |
| 1527 | |||
| 1528 | if (!pag->pagi_init) { | 1521 | if (!pag->pagi_init) { |
| 1529 | pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); | 1522 | pag->pagi_freecount = be32_to_cpu(agi->agi_freecount); |
| 1530 | pag->pagi_count = be32_to_cpu(agi->agi_count); | 1523 | pag->pagi_count = be32_to_cpu(agi->agi_count); |
| @@ -1537,6 +1530,7 @@ xfs_ialloc_read_agi( | |||
| 1537 | */ | 1530 | */ |
| 1538 | ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || | 1531 | ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) || |
| 1539 | XFS_FORCED_SHUTDOWN(mp)); | 1532 | XFS_FORCED_SHUTDOWN(mp)); |
| 1533 | xfs_perag_put(pag); | ||
| 1540 | return 0; | 1534 | return 0; |
| 1541 | } | 1535 | } |
| 1542 | 1536 | ||
