aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_bmap.c8
-rw-r--r--fs/xfs/xfs_ialloc.c35
-rw-r--r--fs/xfs/xfs_inode.c5
-rw-r--r--fs/xfs/xfs_mount.c9
4 files changed, 42 insertions, 15 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 98251cdc52aa..a9b95d9cf2ad 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2630,11 +2630,12 @@ xfs_bmap_btalloc(
2630 startag = ag = 0; 2630 startag = ag = 0;
2631 notinit = 0; 2631 notinit = 0;
2632 down_read(&mp->m_peraglock); 2632 down_read(&mp->m_peraglock);
2633 pag = xfs_perag_get(mp, ag);
2633 while (blen < ap->alen) { 2634 while (blen < ap->alen) {
2634 pag = &mp->m_perag[ag];
2635 if (!pag->pagf_init && 2635 if (!pag->pagf_init &&
2636 (error = xfs_alloc_pagf_init(mp, args.tp, 2636 (error = xfs_alloc_pagf_init(mp, args.tp,
2637 ag, XFS_ALLOC_FLAG_TRYLOCK))) { 2637 ag, XFS_ALLOC_FLAG_TRYLOCK))) {
2638 xfs_perag_put(pag);
2638 up_read(&mp->m_peraglock); 2639 up_read(&mp->m_peraglock);
2639 return error; 2640 return error;
2640 } 2641 }
@@ -2667,6 +2668,7 @@ xfs_bmap_btalloc(
2667 break; 2668 break;
2668 2669
2669 error = xfs_filestream_new_ag(ap, &ag); 2670 error = xfs_filestream_new_ag(ap, &ag);
2671 xfs_perag_put(pag);
2670 if (error) { 2672 if (error) {
2671 up_read(&mp->m_peraglock); 2673 up_read(&mp->m_peraglock);
2672 return error; 2674 return error;
@@ -2674,6 +2676,7 @@ xfs_bmap_btalloc(
2674 2676
2675 /* loop again to set 'blen'*/ 2677 /* loop again to set 'blen'*/
2676 startag = NULLAGNUMBER; 2678 startag = NULLAGNUMBER;
2679 pag = xfs_perag_get(mp, ag);
2677 continue; 2680 continue;
2678 } 2681 }
2679 } 2682 }
@@ -2681,7 +2684,10 @@ xfs_bmap_btalloc(
2681 ag = 0; 2684 ag = 0;
2682 if (ag == startag) 2685 if (ag == startag)
2683 break; 2686 break;
2687 xfs_perag_put(pag);
2688 pag = xfs_perag_get(mp, ag);
2684 } 2689 }
2690 xfs_perag_put(pag);
2685 up_read(&mp->m_peraglock); 2691 up_read(&mp->m_peraglock);
2686 /* 2692 /*
2687 * Since the above loop did a BUF_TRYLOCK, it is 2693 * Since the above loop did a BUF_TRYLOCK, it is
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
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index bd3d81636d51..0317b000ab44 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2695,7 +2695,7 @@ xfs_iflush_cluster(
2695 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); 2695 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
2696 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS); 2696 ilist = kmem_alloc(ilist_size, KM_MAYFAIL|KM_NOFS);
2697 if (!ilist) 2697 if (!ilist)
2698 return 0; 2698 goto out_put;
2699 2699
2700 mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); 2700 mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1);
2701 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask; 2701 first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask;
@@ -2764,6 +2764,8 @@ xfs_iflush_cluster(
2764out_free: 2764out_free:
2765 read_unlock(&pag->pag_ici_lock); 2765 read_unlock(&pag->pag_ici_lock);
2766 kmem_free(ilist); 2766 kmem_free(ilist);
2767out_put:
2768 xfs_perag_put(pag);
2767 return 0; 2769 return 0;
2768 2770
2769 2771
@@ -2807,6 +2809,7 @@ cluster_corrupt_out:
2807 */ 2809 */
2808 xfs_iflush_abort(iq); 2810 xfs_iflush_abort(iq);
2809 kmem_free(ilist); 2811 kmem_free(ilist);
2812 xfs_perag_put(pag);
2810 return XFS_ERROR(EFSCORRUPTED); 2813 return XFS_ERROR(EFSCORRUPTED);
2811} 2814}
2812 2815
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index eb403b40e120..9055b60730d0 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -438,18 +438,20 @@ xfs_initialize_perag(
438 } 438 }
439 439
440 /* This ag is preferred for inodes */ 440 /* This ag is preferred for inodes */
441 pag = &mp->m_perag[index]; 441 pag = xfs_perag_get(mp, index);
442 pag->pagi_inodeok = 1; 442 pag->pagi_inodeok = 1;
443 if (index < max_metadata) 443 if (index < max_metadata)
444 pag->pagf_metadata = 1; 444 pag->pagf_metadata = 1;
445 xfs_initialize_perag_icache(pag); 445 xfs_initialize_perag_icache(pag);
446 xfs_perag_put(pag);
446 } 447 }
447 } else { 448 } else {
448 /* Setup default behavior for smaller filesystems */ 449 /* Setup default behavior for smaller filesystems */
449 for (index = 0; index < agcount; index++) { 450 for (index = 0; index < agcount; index++) {
450 pag = &mp->m_perag[index]; 451 pag = xfs_perag_get(mp, index);
451 pag->pagi_inodeok = 1; 452 pag->pagi_inodeok = 1;
452 xfs_initialize_perag_icache(pag); 453 xfs_initialize_perag_icache(pag);
454 xfs_perag_put(pag);
453 } 455 }
454 } 456 }
455 return index; 457 return index;
@@ -731,12 +733,13 @@ xfs_initialize_perag_data(xfs_mount_t *mp, xfs_agnumber_t agcount)
731 error = xfs_ialloc_pagi_init(mp, NULL, index); 733 error = xfs_ialloc_pagi_init(mp, NULL, index);
732 if (error) 734 if (error)
733 return error; 735 return error;
734 pag = &mp->m_perag[index]; 736 pag = xfs_perag_get(mp, index);
735 ifree += pag->pagi_freecount; 737 ifree += pag->pagi_freecount;
736 ialloc += pag->pagi_count; 738 ialloc += pag->pagi_count;
737 bfree += pag->pagf_freeblks; 739 bfree += pag->pagf_freeblks;
738 bfreelst += pag->pagf_flcount; 740 bfreelst += pag->pagf_flcount;
739 btree += pag->pagf_btreeblks; 741 btree += pag->pagf_btreeblks;
742 xfs_perag_put(pag);
740 } 743 }
741 /* 744 /*
742 * Overwrite incore superblock counters with just-read data 745 * Overwrite incore superblock counters with just-read data