diff options
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
-rw-r--r-- | fs/xfs/xfs_alloc.c | 264 |
1 files changed, 189 insertions, 75 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 1956f83489f1..028e44e58ea9 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -90,6 +90,92 @@ STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, | |||
90 | */ | 90 | */ |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * Lookup the record equal to [bno, len] in the btree given by cur. | ||
94 | */ | ||
95 | STATIC int /* error */ | ||
96 | xfs_alloc_lookup_eq( | ||
97 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
98 | xfs_agblock_t bno, /* starting block of extent */ | ||
99 | xfs_extlen_t len, /* length of extent */ | ||
100 | int *stat) /* success/failure */ | ||
101 | { | ||
102 | cur->bc_rec.a.ar_startblock = bno; | ||
103 | cur->bc_rec.a.ar_blockcount = len; | ||
104 | return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Lookup the first record greater than or equal to [bno, len] | ||
109 | * in the btree given by cur. | ||
110 | */ | ||
111 | STATIC int /* error */ | ||
112 | xfs_alloc_lookup_ge( | ||
113 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
114 | xfs_agblock_t bno, /* starting block of extent */ | ||
115 | xfs_extlen_t len, /* length of extent */ | ||
116 | int *stat) /* success/failure */ | ||
117 | { | ||
118 | cur->bc_rec.a.ar_startblock = bno; | ||
119 | cur->bc_rec.a.ar_blockcount = len; | ||
120 | return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Lookup the first record less than or equal to [bno, len] | ||
125 | * in the btree given by cur. | ||
126 | */ | ||
127 | STATIC int /* error */ | ||
128 | xfs_alloc_lookup_le( | ||
129 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
130 | xfs_agblock_t bno, /* starting block of extent */ | ||
131 | xfs_extlen_t len, /* length of extent */ | ||
132 | int *stat) /* success/failure */ | ||
133 | { | ||
134 | cur->bc_rec.a.ar_startblock = bno; | ||
135 | cur->bc_rec.a.ar_blockcount = len; | ||
136 | return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Update the record referred to by cur to the value given | ||
141 | * by [bno, len]. | ||
142 | * This either works (return 0) or gets an EFSCORRUPTED error. | ||
143 | */ | ||
144 | STATIC int /* error */ | ||
145 | xfs_alloc_update( | ||
146 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
147 | xfs_agblock_t bno, /* starting block of extent */ | ||
148 | xfs_extlen_t len) /* length of extent */ | ||
149 | { | ||
150 | union xfs_btree_rec rec; | ||
151 | |||
152 | rec.alloc.ar_startblock = cpu_to_be32(bno); | ||
153 | rec.alloc.ar_blockcount = cpu_to_be32(len); | ||
154 | return xfs_btree_update(cur, &rec); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Get the data from the pointed-to record. | ||
159 | */ | ||
160 | STATIC int /* error */ | ||
161 | xfs_alloc_get_rec( | ||
162 | struct xfs_btree_cur *cur, /* btree cursor */ | ||
163 | xfs_agblock_t *bno, /* output: starting block of extent */ | ||
164 | xfs_extlen_t *len, /* output: length of extent */ | ||
165 | int *stat) /* output: success/failure */ | ||
166 | { | ||
167 | union xfs_btree_rec *rec; | ||
168 | int error; | ||
169 | |||
170 | error = xfs_btree_get_rec(cur, &rec, stat); | ||
171 | if (!error && *stat == 1) { | ||
172 | *bno = be32_to_cpu(rec->alloc.ar_startblock); | ||
173 | *len = be32_to_cpu(rec->alloc.ar_blockcount); | ||
174 | } | ||
175 | return error; | ||
176 | } | ||
177 | |||
178 | /* | ||
93 | * Compute aligned version of the found extent. | 179 | * Compute aligned version of the found extent. |
94 | * Takes alignment and min length into account. | 180 | * Takes alignment and min length into account. |
95 | */ | 181 | */ |
@@ -294,21 +380,20 @@ xfs_alloc_fixup_trees( | |||
294 | return error; | 380 | return error; |
295 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 381 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
296 | } | 382 | } |
383 | |||
297 | #ifdef DEBUG | 384 | #ifdef DEBUG |
298 | { | 385 | if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) { |
299 | xfs_alloc_block_t *bnoblock; | 386 | struct xfs_btree_block *bnoblock; |
300 | xfs_alloc_block_t *cntblock; | 387 | struct xfs_btree_block *cntblock; |
301 | 388 | ||
302 | if (bno_cur->bc_nlevels == 1 && | 389 | bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); |
303 | cnt_cur->bc_nlevels == 1) { | 390 | cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); |
304 | bnoblock = XFS_BUF_TO_ALLOC_BLOCK(bno_cur->bc_bufs[0]); | 391 | |
305 | cntblock = XFS_BUF_TO_ALLOC_BLOCK(cnt_cur->bc_bufs[0]); | 392 | XFS_WANT_CORRUPTED_RETURN( |
306 | XFS_WANT_CORRUPTED_RETURN( | 393 | bnoblock->bb_numrecs == cntblock->bb_numrecs); |
307 | be16_to_cpu(bnoblock->bb_numrecs) == | ||
308 | be16_to_cpu(cntblock->bb_numrecs)); | ||
309 | } | ||
310 | } | 394 | } |
311 | #endif | 395 | #endif |
396 | |||
312 | /* | 397 | /* |
313 | * Deal with all four cases: the allocated record is contained | 398 | * Deal with all four cases: the allocated record is contained |
314 | * within the freespace record, so we can have new freespace | 399 | * within the freespace record, so we can have new freespace |
@@ -333,7 +418,7 @@ xfs_alloc_fixup_trees( | |||
333 | /* | 418 | /* |
334 | * Delete the entry from the by-size btree. | 419 | * Delete the entry from the by-size btree. |
335 | */ | 420 | */ |
336 | if ((error = xfs_alloc_delete(cnt_cur, &i))) | 421 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
337 | return error; | 422 | return error; |
338 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 423 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
339 | /* | 424 | /* |
@@ -343,7 +428,7 @@ xfs_alloc_fixup_trees( | |||
343 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) | 428 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) |
344 | return error; | 429 | return error; |
345 | XFS_WANT_CORRUPTED_RETURN(i == 0); | 430 | XFS_WANT_CORRUPTED_RETURN(i == 0); |
346 | if ((error = xfs_alloc_insert(cnt_cur, &i))) | 431 | if ((error = xfs_btree_insert(cnt_cur, &i))) |
347 | return error; | 432 | return error; |
348 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 433 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
349 | } | 434 | } |
@@ -351,7 +436,7 @@ xfs_alloc_fixup_trees( | |||
351 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) | 436 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) |
352 | return error; | 437 | return error; |
353 | XFS_WANT_CORRUPTED_RETURN(i == 0); | 438 | XFS_WANT_CORRUPTED_RETURN(i == 0); |
354 | if ((error = xfs_alloc_insert(cnt_cur, &i))) | 439 | if ((error = xfs_btree_insert(cnt_cur, &i))) |
355 | return error; | 440 | return error; |
356 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 441 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
357 | } | 442 | } |
@@ -362,7 +447,7 @@ xfs_alloc_fixup_trees( | |||
362 | /* | 447 | /* |
363 | * No remaining freespace, just delete the by-block tree entry. | 448 | * No remaining freespace, just delete the by-block tree entry. |
364 | */ | 449 | */ |
365 | if ((error = xfs_alloc_delete(bno_cur, &i))) | 450 | if ((error = xfs_btree_delete(bno_cur, &i))) |
366 | return error; | 451 | return error; |
367 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 452 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
368 | } else { | 453 | } else { |
@@ -379,7 +464,7 @@ xfs_alloc_fixup_trees( | |||
379 | if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) | 464 | if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) |
380 | return error; | 465 | return error; |
381 | XFS_WANT_CORRUPTED_RETURN(i == 0); | 466 | XFS_WANT_CORRUPTED_RETURN(i == 0); |
382 | if ((error = xfs_alloc_insert(bno_cur, &i))) | 467 | if ((error = xfs_btree_insert(bno_cur, &i))) |
383 | return error; | 468 | return error; |
384 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 469 | XFS_WANT_CORRUPTED_RETURN(i == 1); |
385 | } | 470 | } |
@@ -640,8 +725,8 @@ xfs_alloc_ag_vextent_exact( | |||
640 | /* | 725 | /* |
641 | * Allocate/initialize a cursor for the by-number freespace btree. | 726 | * Allocate/initialize a cursor for the by-number freespace btree. |
642 | */ | 727 | */ |
643 | bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 728 | bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
644 | args->agno, XFS_BTNUM_BNO, NULL, 0); | 729 | args->agno, XFS_BTNUM_BNO); |
645 | /* | 730 | /* |
646 | * Lookup bno and minlen in the btree (minlen is irrelevant, really). | 731 | * Lookup bno and minlen in the btree (minlen is irrelevant, really). |
647 | * Look for the closest free block <= bno, it must contain bno | 732 | * Look for the closest free block <= bno, it must contain bno |
@@ -696,8 +781,8 @@ xfs_alloc_ag_vextent_exact( | |||
696 | * We are allocating agbno for rlen [agbno .. end] | 781 | * We are allocating agbno for rlen [agbno .. end] |
697 | * Allocate/initialize a cursor for the by-size btree. | 782 | * Allocate/initialize a cursor for the by-size btree. |
698 | */ | 783 | */ |
699 | cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 784 | cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
700 | args->agno, XFS_BTNUM_CNT, NULL, 0); | 785 | args->agno, XFS_BTNUM_CNT); |
701 | ASSERT(args->agbno + args->len <= | 786 | ASSERT(args->agbno + args->len <= |
702 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); | 787 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); |
703 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, | 788 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, |
@@ -759,8 +844,8 @@ xfs_alloc_ag_vextent_near( | |||
759 | /* | 844 | /* |
760 | * Get a cursor for the by-size btree. | 845 | * Get a cursor for the by-size btree. |
761 | */ | 846 | */ |
762 | cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 847 | cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
763 | args->agno, XFS_BTNUM_CNT, NULL, 0); | 848 | args->agno, XFS_BTNUM_CNT); |
764 | ltlen = 0; | 849 | ltlen = 0; |
765 | bno_cur_lt = bno_cur_gt = NULL; | 850 | bno_cur_lt = bno_cur_gt = NULL; |
766 | /* | 851 | /* |
@@ -818,7 +903,7 @@ xfs_alloc_ag_vextent_near( | |||
818 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 903 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
819 | if (ltlen >= args->minlen) | 904 | if (ltlen >= args->minlen) |
820 | break; | 905 | break; |
821 | if ((error = xfs_alloc_increment(cnt_cur, 0, &i))) | 906 | if ((error = xfs_btree_increment(cnt_cur, 0, &i))) |
822 | goto error0; | 907 | goto error0; |
823 | } while (i); | 908 | } while (i); |
824 | ASSERT(ltlen >= args->minlen); | 909 | ASSERT(ltlen >= args->minlen); |
@@ -828,7 +913,7 @@ xfs_alloc_ag_vextent_near( | |||
828 | i = cnt_cur->bc_ptrs[0]; | 913 | i = cnt_cur->bc_ptrs[0]; |
829 | for (j = 1, blen = 0, bdiff = 0; | 914 | for (j = 1, blen = 0, bdiff = 0; |
830 | !error && j && (blen < args->maxlen || bdiff > 0); | 915 | !error && j && (blen < args->maxlen || bdiff > 0); |
831 | error = xfs_alloc_increment(cnt_cur, 0, &j)) { | 916 | error = xfs_btree_increment(cnt_cur, 0, &j)) { |
832 | /* | 917 | /* |
833 | * For each entry, decide if it's better than | 918 | * For each entry, decide if it's better than |
834 | * the previous best entry. | 919 | * the previous best entry. |
@@ -886,8 +971,8 @@ xfs_alloc_ag_vextent_near( | |||
886 | /* | 971 | /* |
887 | * Set up a cursor for the by-bno tree. | 972 | * Set up a cursor for the by-bno tree. |
888 | */ | 973 | */ |
889 | bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, | 974 | bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, |
890 | args->agbp, args->agno, XFS_BTNUM_BNO, NULL, 0); | 975 | args->agbp, args->agno, XFS_BTNUM_BNO); |
891 | /* | 976 | /* |
892 | * Fix up the btree entries. | 977 | * Fix up the btree entries. |
893 | */ | 978 | */ |
@@ -914,8 +999,8 @@ xfs_alloc_ag_vextent_near( | |||
914 | /* | 999 | /* |
915 | * Allocate and initialize the cursor for the leftward search. | 1000 | * Allocate and initialize the cursor for the leftward search. |
916 | */ | 1001 | */ |
917 | bno_cur_lt = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 1002 | bno_cur_lt = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
918 | args->agno, XFS_BTNUM_BNO, NULL, 0); | 1003 | args->agno, XFS_BTNUM_BNO); |
919 | /* | 1004 | /* |
920 | * Lookup <= bno to find the leftward search's starting point. | 1005 | * Lookup <= bno to find the leftward search's starting point. |
921 | */ | 1006 | */ |
@@ -938,7 +1023,7 @@ xfs_alloc_ag_vextent_near( | |||
938 | * Increment the cursor, so we will point at the entry just right | 1023 | * Increment the cursor, so we will point at the entry just right |
939 | * of the leftward entry if any, or to the leftmost entry. | 1024 | * of the leftward entry if any, or to the leftmost entry. |
940 | */ | 1025 | */ |
941 | if ((error = xfs_alloc_increment(bno_cur_gt, 0, &i))) | 1026 | if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) |
942 | goto error0; | 1027 | goto error0; |
943 | if (!i) { | 1028 | if (!i) { |
944 | /* | 1029 | /* |
@@ -961,7 +1046,7 @@ xfs_alloc_ag_vextent_near( | |||
961 | args->minlen, <bnoa, <lena); | 1046 | args->minlen, <bnoa, <lena); |
962 | if (ltlena >= args->minlen) | 1047 | if (ltlena >= args->minlen) |
963 | break; | 1048 | break; |
964 | if ((error = xfs_alloc_decrement(bno_cur_lt, 0, &i))) | 1049 | if ((error = xfs_btree_decrement(bno_cur_lt, 0, &i))) |
965 | goto error0; | 1050 | goto error0; |
966 | if (!i) { | 1051 | if (!i) { |
967 | xfs_btree_del_cursor(bno_cur_lt, | 1052 | xfs_btree_del_cursor(bno_cur_lt, |
@@ -977,7 +1062,7 @@ xfs_alloc_ag_vextent_near( | |||
977 | args->minlen, >bnoa, >lena); | 1062 | args->minlen, >bnoa, >lena); |
978 | if (gtlena >= args->minlen) | 1063 | if (gtlena >= args->minlen) |
979 | break; | 1064 | break; |
980 | if ((error = xfs_alloc_increment(bno_cur_gt, 0, &i))) | 1065 | if ((error = xfs_btree_increment(bno_cur_gt, 0, &i))) |
981 | goto error0; | 1066 | goto error0; |
982 | if (!i) { | 1067 | if (!i) { |
983 | xfs_btree_del_cursor(bno_cur_gt, | 1068 | xfs_btree_del_cursor(bno_cur_gt, |
@@ -1066,7 +1151,7 @@ xfs_alloc_ag_vextent_near( | |||
1066 | /* | 1151 | /* |
1067 | * Fell off the right end. | 1152 | * Fell off the right end. |
1068 | */ | 1153 | */ |
1069 | if ((error = xfs_alloc_increment( | 1154 | if ((error = xfs_btree_increment( |
1070 | bno_cur_gt, 0, &i))) | 1155 | bno_cur_gt, 0, &i))) |
1071 | goto error0; | 1156 | goto error0; |
1072 | if (!i) { | 1157 | if (!i) { |
@@ -1162,7 +1247,7 @@ xfs_alloc_ag_vextent_near( | |||
1162 | /* | 1247 | /* |
1163 | * Fell off the left end. | 1248 | * Fell off the left end. |
1164 | */ | 1249 | */ |
1165 | if ((error = xfs_alloc_decrement( | 1250 | if ((error = xfs_btree_decrement( |
1166 | bno_cur_lt, 0, &i))) | 1251 | bno_cur_lt, 0, &i))) |
1167 | goto error0; | 1252 | goto error0; |
1168 | if (!i) { | 1253 | if (!i) { |
@@ -1267,8 +1352,8 @@ xfs_alloc_ag_vextent_size( | |||
1267 | /* | 1352 | /* |
1268 | * Allocate and initialize a cursor for the by-size btree. | 1353 | * Allocate and initialize a cursor for the by-size btree. |
1269 | */ | 1354 | */ |
1270 | cnt_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 1355 | cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
1271 | args->agno, XFS_BTNUM_CNT, NULL, 0); | 1356 | args->agno, XFS_BTNUM_CNT); |
1272 | bno_cur = NULL; | 1357 | bno_cur = NULL; |
1273 | /* | 1358 | /* |
1274 | * Look for an entry >= maxlen+alignment-1 blocks. | 1359 | * Look for an entry >= maxlen+alignment-1 blocks. |
@@ -1321,7 +1406,7 @@ xfs_alloc_ag_vextent_size( | |||
1321 | bestflen = flen; | 1406 | bestflen = flen; |
1322 | bestfbno = fbno; | 1407 | bestfbno = fbno; |
1323 | for (;;) { | 1408 | for (;;) { |
1324 | if ((error = xfs_alloc_decrement(cnt_cur, 0, &i))) | 1409 | if ((error = xfs_btree_decrement(cnt_cur, 0, &i))) |
1325 | goto error0; | 1410 | goto error0; |
1326 | if (i == 0) | 1411 | if (i == 0) |
1327 | break; | 1412 | break; |
@@ -1372,8 +1457,8 @@ xfs_alloc_ag_vextent_size( | |||
1372 | /* | 1457 | /* |
1373 | * Allocate and initialize a cursor for the by-block tree. | 1458 | * Allocate and initialize a cursor for the by-block tree. |
1374 | */ | 1459 | */ |
1375 | bno_cur = xfs_btree_init_cursor(args->mp, args->tp, args->agbp, | 1460 | bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, |
1376 | args->agno, XFS_BTNUM_BNO, NULL, 0); | 1461 | args->agno, XFS_BTNUM_BNO); |
1377 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, | 1462 | if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, |
1378 | rbno, rlen, XFSA_FIXUP_CNT_OK))) | 1463 | rbno, rlen, XFSA_FIXUP_CNT_OK))) |
1379 | goto error0; | 1464 | goto error0; |
@@ -1416,7 +1501,7 @@ xfs_alloc_ag_vextent_small( | |||
1416 | xfs_extlen_t flen; | 1501 | xfs_extlen_t flen; |
1417 | int i; | 1502 | int i; |
1418 | 1503 | ||
1419 | if ((error = xfs_alloc_decrement(ccur, 0, &i))) | 1504 | if ((error = xfs_btree_decrement(ccur, 0, &i))) |
1420 | goto error0; | 1505 | goto error0; |
1421 | if (i) { | 1506 | if (i) { |
1422 | if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) | 1507 | if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) |
@@ -1515,8 +1600,7 @@ xfs_free_ag_extent( | |||
1515 | /* | 1600 | /* |
1516 | * Allocate and initialize a cursor for the by-block btree. | 1601 | * Allocate and initialize a cursor for the by-block btree. |
1517 | */ | 1602 | */ |
1518 | bno_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO, NULL, | 1603 | bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO); |
1519 | 0); | ||
1520 | cnt_cur = NULL; | 1604 | cnt_cur = NULL; |
1521 | /* | 1605 | /* |
1522 | * Look for a neighboring block on the left (lower block numbers) | 1606 | * Look for a neighboring block on the left (lower block numbers) |
@@ -1549,7 +1633,7 @@ xfs_free_ag_extent( | |||
1549 | * Look for a neighboring block on the right (higher block numbers) | 1633 | * Look for a neighboring block on the right (higher block numbers) |
1550 | * that is contiguous with this space. | 1634 | * that is contiguous with this space. |
1551 | */ | 1635 | */ |
1552 | if ((error = xfs_alloc_increment(bno_cur, 0, &haveright))) | 1636 | if ((error = xfs_btree_increment(bno_cur, 0, &haveright))) |
1553 | goto error0; | 1637 | goto error0; |
1554 | if (haveright) { | 1638 | if (haveright) { |
1555 | /* | 1639 | /* |
@@ -1575,8 +1659,7 @@ xfs_free_ag_extent( | |||
1575 | /* | 1659 | /* |
1576 | * Now allocate and initialize a cursor for the by-size tree. | 1660 | * Now allocate and initialize a cursor for the by-size tree. |
1577 | */ | 1661 | */ |
1578 | cnt_cur = xfs_btree_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT, NULL, | 1662 | cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT); |
1579 | 0); | ||
1580 | /* | 1663 | /* |
1581 | * Have both left and right contiguous neighbors. | 1664 | * Have both left and right contiguous neighbors. |
1582 | * Merge all three into a single free block. | 1665 | * Merge all three into a single free block. |
@@ -1588,7 +1671,7 @@ xfs_free_ag_extent( | |||
1588 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) | 1671 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) |
1589 | goto error0; | 1672 | goto error0; |
1590 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1673 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1591 | if ((error = xfs_alloc_delete(cnt_cur, &i))) | 1674 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
1592 | goto error0; | 1675 | goto error0; |
1593 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1676 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1594 | /* | 1677 | /* |
@@ -1597,19 +1680,19 @@ xfs_free_ag_extent( | |||
1597 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) | 1680 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) |
1598 | goto error0; | 1681 | goto error0; |
1599 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1682 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1600 | if ((error = xfs_alloc_delete(cnt_cur, &i))) | 1683 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
1601 | goto error0; | 1684 | goto error0; |
1602 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1685 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1603 | /* | 1686 | /* |
1604 | * Delete the old by-block entry for the right block. | 1687 | * Delete the old by-block entry for the right block. |
1605 | */ | 1688 | */ |
1606 | if ((error = xfs_alloc_delete(bno_cur, &i))) | 1689 | if ((error = xfs_btree_delete(bno_cur, &i))) |
1607 | goto error0; | 1690 | goto error0; |
1608 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1691 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1609 | /* | 1692 | /* |
1610 | * Move the by-block cursor back to the left neighbor. | 1693 | * Move the by-block cursor back to the left neighbor. |
1611 | */ | 1694 | */ |
1612 | if ((error = xfs_alloc_decrement(bno_cur, 0, &i))) | 1695 | if ((error = xfs_btree_decrement(bno_cur, 0, &i))) |
1613 | goto error0; | 1696 | goto error0; |
1614 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1697 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1615 | #ifdef DEBUG | 1698 | #ifdef DEBUG |
@@ -1648,14 +1731,14 @@ xfs_free_ag_extent( | |||
1648 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) | 1731 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) |
1649 | goto error0; | 1732 | goto error0; |
1650 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1733 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1651 | if ((error = xfs_alloc_delete(cnt_cur, &i))) | 1734 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
1652 | goto error0; | 1735 | goto error0; |
1653 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1736 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1654 | /* | 1737 | /* |
1655 | * Back up the by-block cursor to the left neighbor, and | 1738 | * Back up the by-block cursor to the left neighbor, and |
1656 | * update its length. | 1739 | * update its length. |
1657 | */ | 1740 | */ |
1658 | if ((error = xfs_alloc_decrement(bno_cur, 0, &i))) | 1741 | if ((error = xfs_btree_decrement(bno_cur, 0, &i))) |
1659 | goto error0; | 1742 | goto error0; |
1660 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1743 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1661 | nbno = ltbno; | 1744 | nbno = ltbno; |
@@ -1674,7 +1757,7 @@ xfs_free_ag_extent( | |||
1674 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) | 1757 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) |
1675 | goto error0; | 1758 | goto error0; |
1676 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1759 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1677 | if ((error = xfs_alloc_delete(cnt_cur, &i))) | 1760 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
1678 | goto error0; | 1761 | goto error0; |
1679 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1762 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1680 | /* | 1763 | /* |
@@ -1693,7 +1776,7 @@ xfs_free_ag_extent( | |||
1693 | else { | 1776 | else { |
1694 | nbno = bno; | 1777 | nbno = bno; |
1695 | nlen = len; | 1778 | nlen = len; |
1696 | if ((error = xfs_alloc_insert(bno_cur, &i))) | 1779 | if ((error = xfs_btree_insert(bno_cur, &i))) |
1697 | goto error0; | 1780 | goto error0; |
1698 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1781 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1699 | } | 1782 | } |
@@ -1705,7 +1788,7 @@ xfs_free_ag_extent( | |||
1705 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) | 1788 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) |
1706 | goto error0; | 1789 | goto error0; |
1707 | XFS_WANT_CORRUPTED_GOTO(i == 0, error0); | 1790 | XFS_WANT_CORRUPTED_GOTO(i == 0, error0); |
1708 | if ((error = xfs_alloc_insert(cnt_cur, &i))) | 1791 | if ((error = xfs_btree_insert(cnt_cur, &i))) |
1709 | goto error0; | 1792 | goto error0; |
1710 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1793 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); |
1711 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 1794 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
@@ -2150,51 +2233,83 @@ xfs_alloc_put_freelist( | |||
2150 | * Read in the allocation group header (free/alloc section). | 2233 | * Read in the allocation group header (free/alloc section). |
2151 | */ | 2234 | */ |
2152 | int /* error */ | 2235 | int /* error */ |
2153 | xfs_alloc_read_agf( | 2236 | xfs_read_agf( |
2154 | xfs_mount_t *mp, /* mount point structure */ | 2237 | struct xfs_mount *mp, /* mount point structure */ |
2155 | xfs_trans_t *tp, /* transaction pointer */ | 2238 | struct xfs_trans *tp, /* transaction pointer */ |
2156 | xfs_agnumber_t agno, /* allocation group number */ | 2239 | xfs_agnumber_t agno, /* allocation group number */ |
2157 | int flags, /* XFS_ALLOC_FLAG_... */ | 2240 | int flags, /* XFS_BUF_ */ |
2158 | xfs_buf_t **bpp) /* buffer for the ag freelist header */ | 2241 | struct xfs_buf **bpp) /* buffer for the ag freelist header */ |
2159 | { | 2242 | { |
2160 | xfs_agf_t *agf; /* ag freelist header */ | 2243 | struct xfs_agf *agf; /* ag freelist header */ |
2161 | int agf_ok; /* set if agf is consistent */ | 2244 | int agf_ok; /* set if agf is consistent */ |
2162 | xfs_buf_t *bp; /* return value */ | ||
2163 | xfs_perag_t *pag; /* per allocation group data */ | ||
2164 | int error; | 2245 | int error; |
2165 | 2246 | ||
2166 | ASSERT(agno != NULLAGNUMBER); | 2247 | ASSERT(agno != NULLAGNUMBER); |
2167 | error = xfs_trans_read_buf( | 2248 | error = xfs_trans_read_buf( |
2168 | mp, tp, mp->m_ddev_targp, | 2249 | mp, tp, mp->m_ddev_targp, |
2169 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), | 2250 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), |
2170 | XFS_FSS_TO_BB(mp, 1), | 2251 | XFS_FSS_TO_BB(mp, 1), flags, bpp); |
2171 | (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0U, | ||
2172 | &bp); | ||
2173 | if (error) | 2252 | if (error) |
2174 | return error; | 2253 | return error; |
2175 | ASSERT(!bp || !XFS_BUF_GETERROR(bp)); | 2254 | if (!*bpp) |
2176 | if (!bp) { | ||
2177 | *bpp = NULL; | ||
2178 | return 0; | 2255 | return 0; |
2179 | } | 2256 | |
2257 | ASSERT(!XFS_BUF_GETERROR(*bpp)); | ||
2258 | agf = XFS_BUF_TO_AGF(*bpp); | ||
2259 | |||
2180 | /* | 2260 | /* |
2181 | * Validate the magic number of the agf block. | 2261 | * Validate the magic number of the agf block. |
2182 | */ | 2262 | */ |
2183 | agf = XFS_BUF_TO_AGF(bp); | ||
2184 | agf_ok = | 2263 | agf_ok = |
2185 | be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && | 2264 | be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && |
2186 | XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && | 2265 | XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && |
2187 | be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && | 2266 | be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && |
2188 | be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && | 2267 | be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && |
2189 | be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && | 2268 | be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && |
2190 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp); | 2269 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp) && |
2270 | be32_to_cpu(agf->agf_seqno) == agno; | ||
2271 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) | ||
2272 | agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <= | ||
2273 | be32_to_cpu(agf->agf_length); | ||
2191 | if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF, | 2274 | if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF, |
2192 | XFS_RANDOM_ALLOC_READ_AGF))) { | 2275 | XFS_RANDOM_ALLOC_READ_AGF))) { |
2193 | XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", | 2276 | XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", |
2194 | XFS_ERRLEVEL_LOW, mp, agf); | 2277 | XFS_ERRLEVEL_LOW, mp, agf); |
2195 | xfs_trans_brelse(tp, bp); | 2278 | xfs_trans_brelse(tp, *bpp); |
2196 | return XFS_ERROR(EFSCORRUPTED); | 2279 | return XFS_ERROR(EFSCORRUPTED); |
2197 | } | 2280 | } |
2281 | |||
2282 | XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); | ||
2283 | return 0; | ||
2284 | } | ||
2285 | |||
2286 | /* | ||
2287 | * Read in the allocation group header (free/alloc section). | ||
2288 | */ | ||
2289 | int /* error */ | ||
2290 | xfs_alloc_read_agf( | ||
2291 | struct xfs_mount *mp, /* mount point structure */ | ||
2292 | struct xfs_trans *tp, /* transaction pointer */ | ||
2293 | xfs_agnumber_t agno, /* allocation group number */ | ||
2294 | int flags, /* XFS_ALLOC_FLAG_... */ | ||
2295 | struct xfs_buf **bpp) /* buffer for the ag freelist header */ | ||
2296 | { | ||
2297 | struct xfs_agf *agf; /* ag freelist header */ | ||
2298 | struct xfs_perag *pag; /* per allocation group data */ | ||
2299 | int error; | ||
2300 | |||
2301 | ASSERT(agno != NULLAGNUMBER); | ||
2302 | |||
2303 | error = xfs_read_agf(mp, tp, agno, | ||
2304 | (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0, | ||
2305 | bpp); | ||
2306 | if (error) | ||
2307 | return error; | ||
2308 | if (!*bpp) | ||
2309 | return 0; | ||
2310 | ASSERT(!XFS_BUF_GETERROR(*bpp)); | ||
2311 | |||
2312 | agf = XFS_BUF_TO_AGF(*bpp); | ||
2198 | pag = &mp->m_perag[agno]; | 2313 | pag = &mp->m_perag[agno]; |
2199 | if (!pag->pagf_init) { | 2314 | if (!pag->pagf_init) { |
2200 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); | 2315 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); |
@@ -2213,6 +2328,7 @@ xfs_alloc_read_agf( | |||
2213 | #ifdef DEBUG | 2328 | #ifdef DEBUG |
2214 | else if (!XFS_FORCED_SHUTDOWN(mp)) { | 2329 | else if (!XFS_FORCED_SHUTDOWN(mp)) { |
2215 | ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks)); | 2330 | ASSERT(pag->pagf_freeblks == be32_to_cpu(agf->agf_freeblks)); |
2331 | ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks)); | ||
2216 | ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount)); | 2332 | ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount)); |
2217 | ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest)); | 2333 | ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest)); |
2218 | ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] == | 2334 | ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] == |
@@ -2221,8 +2337,6 @@ xfs_alloc_read_agf( | |||
2221 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); | 2337 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); |
2222 | } | 2338 | } |
2223 | #endif | 2339 | #endif |
2224 | XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGF, XFS_AGF_REF); | ||
2225 | *bpp = bp; | ||
2226 | return 0; | 2340 | return 0; |
2227 | } | 2341 | } |
2228 | 2342 | ||