aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_ialloc.c81
-rw-r--r--fs/xfs/xfs_ialloc.h4
-rw-r--r--fs/xfs/xfs_itable.c84
3 files changed, 77 insertions, 92 deletions
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index ce9edf7f4cb4..72fa3bfc56eb 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -135,9 +135,7 @@ xfs_inobt_update(
135int /* error */ 135int /* error */
136xfs_inobt_get_rec( 136xfs_inobt_get_rec(
137 struct xfs_btree_cur *cur, /* btree cursor */ 137 struct xfs_btree_cur *cur, /* btree cursor */
138 xfs_agino_t *ino, /* output: starting inode of chunk */ 138 xfs_inobt_rec_incore_t *irec, /* btree record */
139 __int32_t *fcnt, /* output: number of free inodes */
140 xfs_inofree_t *free, /* output: free inode mask */
141 int *stat) /* output: success/failure */ 139 int *stat) /* output: success/failure */
142{ 140{
143 union xfs_btree_rec *rec; 141 union xfs_btree_rec *rec;
@@ -145,9 +143,9 @@ xfs_inobt_get_rec(
145 143
146 error = xfs_btree_get_rec(cur, &rec, stat); 144 error = xfs_btree_get_rec(cur, &rec, stat);
147 if (!error && *stat == 1) { 145 if (!error && *stat == 1) {
148 *ino = be32_to_cpu(rec->inobt.ir_startino); 146 irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);
149 *fcnt = be32_to_cpu(rec->inobt.ir_freecount); 147 irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount);
150 *free = be64_to_cpu(rec->inobt.ir_free); 148 irec->ir_free = be64_to_cpu(rec->inobt.ir_free);
151 } 149 }
152 return error; 150 return error;
153} 151}
@@ -746,8 +744,8 @@ nextag:
746 goto error0; 744 goto error0;
747 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 745 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
748 do { 746 do {
749 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, 747 error = xfs_inobt_get_rec(cur, &rec, &i);
750 &rec.ir_freecount, &rec.ir_free, &i))) 748 if (error)
751 goto error0; 749 goto error0;
752 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 750 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
753 freecount += rec.ir_freecount; 751 freecount += rec.ir_freecount;
@@ -766,8 +764,7 @@ nextag:
766 if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i))) 764 if ((error = xfs_inobt_lookup_le(cur, pagino, 0, 0, &i)))
767 goto error0; 765 goto error0;
768 if (i != 0 && 766 if (i != 0 &&
769 (error = xfs_inobt_get_rec(cur, &rec.ir_startino, 767 (error = xfs_inobt_get_rec(cur, &rec, &j)) == 0 &&
770 &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
771 j == 1 && 768 j == 1 &&
772 rec.ir_freecount > 0) { 769 rec.ir_freecount > 0) {
773 /* 770 /*
@@ -799,10 +796,8 @@ nextag:
799 goto error1; 796 goto error1;
800 doneleft = !i; 797 doneleft = !i;
801 if (!doneleft) { 798 if (!doneleft) {
802 if ((error = xfs_inobt_get_rec(tcur, 799 error = xfs_inobt_get_rec(tcur, &trec, &i);
803 &trec.ir_startino, 800 if (error)
804 &trec.ir_freecount,
805 &trec.ir_free, &i)))
806 goto error1; 801 goto error1;
807 XFS_WANT_CORRUPTED_GOTO(i == 1, error1); 802 XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
808 } 803 }
@@ -813,10 +808,8 @@ nextag:
813 goto error1; 808 goto error1;
814 doneright = !i; 809 doneright = !i;
815 if (!doneright) { 810 if (!doneright) {
816 if ((error = xfs_inobt_get_rec(cur, 811 error = xfs_inobt_get_rec(cur, &rec, &i);
817 &rec.ir_startino, 812 if (error)
818 &rec.ir_freecount,
819 &rec.ir_free, &i)))
820 goto error1; 813 goto error1;
821 XFS_WANT_CORRUPTED_GOTO(i == 1, error1); 814 XFS_WANT_CORRUPTED_GOTO(i == 1, error1);
822 } 815 }
@@ -876,11 +869,9 @@ nextag:
876 goto error1; 869 goto error1;
877 doneleft = !i; 870 doneleft = !i;
878 if (!doneleft) { 871 if (!doneleft) {
879 if ((error = xfs_inobt_get_rec( 872 error = xfs_inobt_get_rec(
880 tcur, 873 tcur, &trec, &i);
881 &trec.ir_startino, 874 if (error)
882 &trec.ir_freecount,
883 &trec.ir_free, &i)))
884 goto error1; 875 goto error1;
885 XFS_WANT_CORRUPTED_GOTO(i == 1, 876 XFS_WANT_CORRUPTED_GOTO(i == 1,
886 error1); 877 error1);
@@ -896,11 +887,9 @@ nextag:
896 goto error1; 887 goto error1;
897 doneright = !i; 888 doneright = !i;
898 if (!doneright) { 889 if (!doneright) {
899 if ((error = xfs_inobt_get_rec( 890 error = xfs_inobt_get_rec(
900 cur, 891 cur, &rec, &i);
901 &rec.ir_startino, 892 if (error)
902 &rec.ir_freecount,
903 &rec.ir_free, &i)))
904 goto error1; 893 goto error1;
905 XFS_WANT_CORRUPTED_GOTO(i == 1, 894 XFS_WANT_CORRUPTED_GOTO(i == 1,
906 error1); 895 error1);
@@ -919,8 +908,7 @@ nextag:
919 be32_to_cpu(agi->agi_newino), 0, 0, &i))) 908 be32_to_cpu(agi->agi_newino), 0, 0, &i)))
920 goto error0; 909 goto error0;
921 if (i == 1 && 910 if (i == 1 &&
922 (error = xfs_inobt_get_rec(cur, &rec.ir_startino, 911 (error = xfs_inobt_get_rec(cur, &rec, &j)) == 0 &&
923 &rec.ir_freecount, &rec.ir_free, &j)) == 0 &&
924 j == 1 && 912 j == 1 &&
925 rec.ir_freecount > 0) { 913 rec.ir_freecount > 0) {
926 /* 914 /*
@@ -938,10 +926,8 @@ nextag:
938 goto error0; 926 goto error0;
939 ASSERT(i == 1); 927 ASSERT(i == 1);
940 for (;;) { 928 for (;;) {
941 if ((error = xfs_inobt_get_rec(cur, 929 error = xfs_inobt_get_rec(cur, &rec, &i);
942 &rec.ir_startino, 930 if (error)
943 &rec.ir_freecount, &rec.ir_free,
944 &i)))
945 goto error0; 931 goto error0;
946 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 932 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
947 if (rec.ir_freecount > 0) 933 if (rec.ir_freecount > 0)
@@ -975,8 +961,8 @@ nextag:
975 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) 961 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
976 goto error0; 962 goto error0;
977 do { 963 do {
978 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, 964 error = xfs_inobt_get_rec(cur, &rec, &i);
979 &rec.ir_freecount, &rec.ir_free, &i))) 965 if (error)
980 goto error0; 966 goto error0;
981 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 967 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
982 freecount += rec.ir_freecount; 968 freecount += rec.ir_freecount;
@@ -1084,8 +1070,8 @@ xfs_difree(
1084 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) 1070 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
1085 goto error0; 1071 goto error0;
1086 do { 1072 do {
1087 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, 1073 error = xfs_inobt_get_rec(cur, &rec, &i);
1088 &rec.ir_freecount, &rec.ir_free, &i))) 1074 if (error)
1089 goto error0; 1075 goto error0;
1090 if (i) { 1076 if (i) {
1091 freecount += rec.ir_freecount; 1077 freecount += rec.ir_freecount;
@@ -1107,8 +1093,8 @@ xfs_difree(
1107 goto error0; 1093 goto error0;
1108 } 1094 }
1109 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1095 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1110 if ((error = xfs_inobt_get_rec(cur, &rec.ir_startino, &rec.ir_freecount, 1096 error = xfs_inobt_get_rec(cur, &rec, &i);
1111 &rec.ir_free, &i))) { 1097 if (error) {
1112 cmn_err(CE_WARN, 1098 cmn_err(CE_WARN,
1113 "xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error.", 1099 "xfs_difree: xfs_inobt_get_rec() returned an error %d on %s. Returning error.",
1114 error, mp->m_fsname); 1100 error, mp->m_fsname);
@@ -1187,10 +1173,8 @@ xfs_difree(
1187 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i))) 1173 if ((error = xfs_inobt_lookup_ge(cur, 0, 0, 0, &i)))
1188 goto error0; 1174 goto error0;
1189 do { 1175 do {
1190 if ((error = xfs_inobt_get_rec(cur, 1176 error = xfs_inobt_get_rec(cur, &rec, &i);
1191 &rec.ir_startino, 1177 if (error)
1192 &rec.ir_freecount,
1193 &rec.ir_free, &i)))
1194 goto error0; 1178 goto error0;
1195 if (i) { 1179 if (i) {
1196 freecount += rec.ir_freecount; 1180 freecount += rec.ir_freecount;
@@ -1312,9 +1296,7 @@ xfs_imap(
1312 chunk_agbno = agbno - offset_agbno; 1296 chunk_agbno = agbno - offset_agbno;
1313 } else { 1297 } else {
1314 xfs_btree_cur_t *cur; /* inode btree cursor */ 1298 xfs_btree_cur_t *cur; /* inode btree cursor */
1315 xfs_agino_t chunk_agino; /* first agino in inode chunk */ 1299 xfs_inobt_rec_incore_t chunk_rec;
1316 __int32_t chunk_cnt; /* count of free inodes in chunk */
1317 xfs_inofree_t chunk_free; /* mask of free inodes in chunk */
1318 xfs_buf_t *agbp; /* agi buffer */ 1300 xfs_buf_t *agbp; /* agi buffer */
1319 int i; /* temp state */ 1301 int i; /* temp state */
1320 1302
@@ -1337,8 +1319,7 @@ xfs_imap(
1337 goto error0; 1319 goto error0;
1338 } 1320 }
1339 1321
1340 error = xfs_inobt_get_rec(cur, &chunk_agino, &chunk_cnt, 1322 error = xfs_inobt_get_rec(cur, &chunk_rec, &i);
1341 &chunk_free, &i);
1342 if (error) { 1323 if (error) {
1343 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " 1324 xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: "
1344 "xfs_inobt_get_rec() failed"); 1325 "xfs_inobt_get_rec() failed");
@@ -1356,7 +1337,7 @@ xfs_imap(
1356 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 1337 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1357 if (error) 1338 if (error)
1358 return error; 1339 return error;
1359 chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_agino); 1340 chunk_agbno = XFS_AGINO_TO_AGBNO(mp, chunk_rec.ir_startino);
1360 offset_agbno = agbno - chunk_agbno; 1341 offset_agbno = agbno - chunk_agbno;
1361 } 1342 }
1362 1343
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index aeee8278f92c..52e72fe7e411 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -166,7 +166,7 @@ int xfs_inobt_lookup_le(struct xfs_btree_cur *cur, xfs_agino_t ino,
166/* 166/*
167 * Get the data from the pointed-to record. 167 * Get the data from the pointed-to record.
168 */ 168 */
169extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur, xfs_agino_t *ino, 169extern int xfs_inobt_get_rec(struct xfs_btree_cur *cur,
170 __int32_t *fcnt, xfs_inofree_t *free, int *stat); 170 xfs_inobt_rec_incore_t *rec, int *stat);
171 171
172#endif /* __XFS_IALLOC_H__ */ 172#endif /* __XFS_IALLOC_H__ */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index c471122d2234..3ec13e8a8c54 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -353,9 +353,6 @@ xfs_bulkstat(
353 int end_of_ag; /* set if we've seen the ag end */ 353 int end_of_ag; /* set if we've seen the ag end */
354 int error; /* error code */ 354 int error; /* error code */
355 int fmterror;/* bulkstat formatter result */ 355 int fmterror;/* bulkstat formatter result */
356 __int32_t gcnt; /* current btree rec's count */
357 xfs_inofree_t gfree; /* current btree rec's free mask */
358 xfs_agino_t gino; /* current btree rec's start inode */
359 int i; /* loop index */ 356 int i; /* loop index */
360 int icount; /* count of inodes good in irbuf */ 357 int icount; /* count of inodes good in irbuf */
361 size_t irbsize; /* size of irec buffer in bytes */ 358 size_t irbsize; /* size of irec buffer in bytes */
@@ -442,6 +439,8 @@ xfs_bulkstat(
442 * we need to get the remainder of the chunk we're in. 439 * we need to get the remainder of the chunk we're in.
443 */ 440 */
444 if (agino > 0) { 441 if (agino > 0) {
442 xfs_inobt_rec_incore_t r;
443
445 /* 444 /*
446 * Lookup the inode chunk that this inode lives in. 445 * Lookup the inode chunk that this inode lives in.
447 */ 446 */
@@ -449,33 +448,33 @@ xfs_bulkstat(
449 if (!error && /* no I/O error */ 448 if (!error && /* no I/O error */
450 tmp && /* lookup succeeded */ 449 tmp && /* lookup succeeded */
451 /* got the record, should always work */ 450 /* got the record, should always work */
452 !(error = xfs_inobt_get_rec(cur, &gino, &gcnt, 451 !(error = xfs_inobt_get_rec(cur, &r, &i)) &&
453 &gfree, &i)) &&
454 i == 1 && 452 i == 1 &&
455 /* this is the right chunk */ 453 /* this is the right chunk */
456 agino < gino + XFS_INODES_PER_CHUNK && 454 agino < r.ir_startino + XFS_INODES_PER_CHUNK &&
457 /* lastino was not last in chunk */ 455 /* lastino was not last in chunk */
458 (chunkidx = agino - gino + 1) < 456 (chunkidx = agino - r.ir_startino + 1) <
459 XFS_INODES_PER_CHUNK && 457 XFS_INODES_PER_CHUNK &&
460 /* there are some left allocated */ 458 /* there are some left allocated */
461 xfs_inobt_maskn(chunkidx, 459 xfs_inobt_maskn(chunkidx,
462 XFS_INODES_PER_CHUNK - chunkidx) & ~gfree) { 460 XFS_INODES_PER_CHUNK - chunkidx) &
461 ~r.ir_free) {
463 /* 462 /*
464 * Grab the chunk record. Mark all the 463 * Grab the chunk record. Mark all the
465 * uninteresting inodes (because they're 464 * uninteresting inodes (because they're
466 * before our start point) free. 465 * before our start point) free.
467 */ 466 */
468 for (i = 0; i < chunkidx; i++) { 467 for (i = 0; i < chunkidx; i++) {
469 if (XFS_INOBT_MASK(i) & ~gfree) 468 if (XFS_INOBT_MASK(i) & ~r.ir_free)
470 gcnt++; 469 r.ir_freecount++;
471 } 470 }
472 gfree |= xfs_inobt_maskn(0, chunkidx); 471 r.ir_free |= xfs_inobt_maskn(0, chunkidx);
473 irbp->ir_startino = gino; 472 irbp->ir_startino = r.ir_startino;
474 irbp->ir_freecount = gcnt; 473 irbp->ir_freecount = r.ir_freecount;
475 irbp->ir_free = gfree; 474 irbp->ir_free = r.ir_free;
476 irbp++; 475 irbp++;
477 agino = gino + XFS_INODES_PER_CHUNK; 476 agino = r.ir_startino + XFS_INODES_PER_CHUNK;
478 icount = XFS_INODES_PER_CHUNK - gcnt; 477 icount = XFS_INODES_PER_CHUNK - r.ir_freecount;
479 } else { 478 } else {
480 /* 479 /*
481 * If any of those tests failed, bump the 480 * If any of those tests failed, bump the
@@ -501,6 +500,8 @@ xfs_bulkstat(
501 * until we run out of inodes or space in the buffer. 500 * until we run out of inodes or space in the buffer.
502 */ 501 */
503 while (irbp < irbufend && icount < ubcount) { 502 while (irbp < irbufend && icount < ubcount) {
503 xfs_inobt_rec_incore_t r;
504
504 /* 505 /*
505 * Loop as long as we're unable to read the 506 * Loop as long as we're unable to read the
506 * inode btree. 507 * inode btree.
@@ -518,43 +519,47 @@ xfs_bulkstat(
518 * If ran off the end of the ag either with an error, 519 * If ran off the end of the ag either with an error,
519 * or the normal way, set end and stop collecting. 520 * or the normal way, set end and stop collecting.
520 */ 521 */
521 if (error || 522 if (error) {
522 (error = xfs_inobt_get_rec(cur, &gino, &gcnt, 523 end_of_ag = 1;
523 &gfree, &i)) || 524 break;
524 i == 0) { 525 }
526
527 error = xfs_inobt_get_rec(cur, &r, &i);
528 if (error || i == 0) {
525 end_of_ag = 1; 529 end_of_ag = 1;
526 break; 530 break;
527 } 531 }
532
528 /* 533 /*
529 * If this chunk has any allocated inodes, save it. 534 * If this chunk has any allocated inodes, save it.
530 * Also start read-ahead now for this chunk. 535 * Also start read-ahead now for this chunk.
531 */ 536 */
532 if (gcnt < XFS_INODES_PER_CHUNK) { 537 if (r.ir_freecount < XFS_INODES_PER_CHUNK) {
533 /* 538 /*
534 * Loop over all clusters in the next chunk. 539 * Loop over all clusters in the next chunk.
535 * Do a readahead if there are any allocated 540 * Do a readahead if there are any allocated
536 * inodes in that cluster. 541 * inodes in that cluster.
537 */ 542 */
538 for (agbno = XFS_AGINO_TO_AGBNO(mp, gino), 543 agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino);
539 chunkidx = 0; 544 for (chunkidx = 0;
540 chunkidx < XFS_INODES_PER_CHUNK; 545 chunkidx < XFS_INODES_PER_CHUNK;
541 chunkidx += nicluster, 546 chunkidx += nicluster,
542 agbno += nbcluster) { 547 agbno += nbcluster) {
543 if (xfs_inobt_maskn(chunkidx, 548 if (xfs_inobt_maskn(chunkidx, nicluster)
544 nicluster) & ~gfree) 549 & ~r.ir_free)
545 xfs_btree_reada_bufs(mp, agno, 550 xfs_btree_reada_bufs(mp, agno,
546 agbno, nbcluster); 551 agbno, nbcluster);
547 } 552 }
548 irbp->ir_startino = gino; 553 irbp->ir_startino = r.ir_startino;
549 irbp->ir_freecount = gcnt; 554 irbp->ir_freecount = r.ir_freecount;
550 irbp->ir_free = gfree; 555 irbp->ir_free = r.ir_free;
551 irbp++; 556 irbp++;
552 icount += XFS_INODES_PER_CHUNK - gcnt; 557 icount += XFS_INODES_PER_CHUNK - r.ir_freecount;
553 } 558 }
554 /* 559 /*
555 * Set agino to after this chunk and bump the cursor. 560 * Set agino to after this chunk and bump the cursor.
556 */ 561 */
557 agino = gino + XFS_INODES_PER_CHUNK; 562 agino = r.ir_startino + XFS_INODES_PER_CHUNK;
558 error = xfs_btree_increment(cur, 0, &tmp); 563 error = xfs_btree_increment(cur, 0, &tmp);
559 cond_resched(); 564 cond_resched();
560 } 565 }
@@ -820,9 +825,7 @@ xfs_inumbers(
820 int bufidx; 825 int bufidx;
821 xfs_btree_cur_t *cur; 826 xfs_btree_cur_t *cur;
822 int error; 827 int error;
823 __int32_t gcnt; 828 xfs_inobt_rec_incore_t r;
824 xfs_inofree_t gfree;
825 xfs_agino_t gino;
826 int i; 829 int i;
827 xfs_ino_t ino; 830 xfs_ino_t ino;
828 int left; 831 int left;
@@ -870,9 +873,8 @@ xfs_inumbers(
870 continue; 873 continue;
871 } 874 }
872 } 875 }
873 if ((error = xfs_inobt_get_rec(cur, &gino, &gcnt, &gfree, 876 error = xfs_inobt_get_rec(cur, &r, &i);
874 &i)) || 877 if (error || i == 0) {
875 i == 0) {
876 xfs_buf_relse(agbp); 878 xfs_buf_relse(agbp);
877 agbp = NULL; 879 agbp = NULL;
878 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); 880 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
@@ -881,10 +883,12 @@ xfs_inumbers(
881 agino = 0; 883 agino = 0;
882 continue; 884 continue;
883 } 885 }
884 agino = gino + XFS_INODES_PER_CHUNK - 1; 886 agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1;
885 buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, gino); 887 buffer[bufidx].xi_startino =
886 buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - gcnt; 888 XFS_AGINO_TO_INO(mp, agno, r.ir_startino);
887 buffer[bufidx].xi_allocmask = ~gfree; 889 buffer[bufidx].xi_alloccount =
890 XFS_INODES_PER_CHUNK - r.ir_freecount;
891 buffer[bufidx].xi_allocmask = ~r.ir_free;
888 bufidx++; 892 bufidx++;
889 left--; 893 left--;
890 if (bufidx == bcount) { 894 if (bufidx == bcount) {