aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap_btree.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 01:58:01 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 01:58:01 -0400
commit91cca5df9bc85efdabfa645f51d54259ed09f4bf (patch)
tree29032361e21d1210effb72f4018f2a202d6a9fb0 /fs/xfs/xfs_bmap_btree.c
parentd4b3a4b7dd62f2e111d4d0afa9ef3f9b6cd955c0 (diff)
[XFS] implement generic xfs_btree_delete/delrec
Make the btree delete code generic. Based on a patch from David Chinner with lots of changes to follow the original btree implementations more closely. While this loses some of the generic helper routines for inserting/moving/removing records it also solves some of the one off bugs in the original code and makes it easier to verify. SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32205a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Bill O'Donnell <billodo@sgi.com> Signed-off-by: David Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs/xfs_bmap_btree.c')
-rw-r--r--fs/xfs/xfs_bmap_btree.c525
1 files changed, 9 insertions, 516 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 6b7774ebc26a..5b8030561d78 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -44,14 +44,6 @@
44#include "xfs_error.h" 44#include "xfs_error.h"
45#include "xfs_quota.h" 45#include "xfs_quota.h"
46 46
47/*
48 * Prototypes for internal btree functions.
49 */
50
51
52STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
53STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
54
55#undef EXIT 47#undef EXIT
56 48
57#define ENTRY XBT_ENTRY 49#define ENTRY XBT_ENTRY
@@ -80,453 +72,6 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
80#define XFS_BMBT_TRACE_CURSOR(c,s) \ 72#define XFS_BMBT_TRACE_CURSOR(c,s) \
81 XFS_BTREE_TRACE_CURSOR(c,s) 73 XFS_BTREE_TRACE_CURSOR(c,s)
82 74
83
84/*
85 * Internal functions.
86 */
87
88/*
89 * Delete record pointed to by cur/level.
90 */
91STATIC int /* error */
92xfs_bmbt_delrec(
93 xfs_btree_cur_t *cur,
94 int level,
95 int *stat) /* success/failure */
96{
97 xfs_bmbt_block_t *block; /* bmap btree block */
98 xfs_fsblock_t bno; /* fs-relative block number */
99 xfs_buf_t *bp; /* buffer for block */
100 int error; /* error return value */
101 int i; /* loop counter */
102 int j; /* temp state */
103 xfs_bmbt_key_t key; /* bmap btree key */
104 xfs_bmbt_key_t *kp=NULL; /* pointer to bmap btree key */
105 xfs_fsblock_t lbno; /* left sibling block number */
106 xfs_buf_t *lbp; /* left buffer pointer */
107 xfs_bmbt_block_t *left; /* left btree block */
108 xfs_bmbt_key_t *lkp; /* left btree key */
109 xfs_bmbt_ptr_t *lpp; /* left address pointer */
110 int lrecs=0; /* left record count */
111 xfs_bmbt_rec_t *lrp; /* left record pointer */
112 xfs_mount_t *mp; /* file system mount point */
113 xfs_bmbt_ptr_t *pp; /* pointer to bmap block addr */
114 int ptr; /* key/record index */
115 xfs_fsblock_t rbno; /* right sibling block number */
116 xfs_buf_t *rbp; /* right buffer pointer */
117 xfs_bmbt_block_t *right; /* right btree block */
118 xfs_bmbt_key_t *rkp; /* right btree key */
119 xfs_bmbt_rec_t *rp; /* pointer to bmap btree rec */
120 xfs_bmbt_ptr_t *rpp; /* right address pointer */
121 xfs_bmbt_block_t *rrblock; /* right-right btree block */
122 xfs_buf_t *rrbp; /* right-right buffer pointer */
123 int rrecs=0; /* right record count */
124 xfs_bmbt_rec_t *rrp; /* right record pointer */
125 xfs_btree_cur_t *tcur; /* temporary btree cursor */
126 int numrecs; /* temporary numrec count */
127 int numlrecs, numrrecs;
128
129 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
130 XFS_BMBT_TRACE_ARGI(cur, level);
131 ptr = cur->bc_ptrs[level];
132 tcur = NULL;
133 if (ptr == 0) {
134 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
135 *stat = 0;
136 return 0;
137 }
138 block = xfs_bmbt_get_block(cur, level, &bp);
139 numrecs = be16_to_cpu(block->bb_numrecs);
140#ifdef DEBUG
141 if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
142 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
143 goto error0;
144 }
145#endif
146 if (ptr > numrecs) {
147 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
148 *stat = 0;
149 return 0;
150 }
151 XFS_STATS_INC(xs_bmbt_delrec);
152 if (level > 0) {
153 kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
154 pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
155#ifdef DEBUG
156 for (i = ptr; i < numrecs; i++) {
157 if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
158 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
159 goto error0;
160 }
161 }
162#endif
163 if (ptr < numrecs) {
164 memmove(&kp[ptr - 1], &kp[ptr],
165 (numrecs - ptr) * sizeof(*kp));
166 memmove(&pp[ptr - 1], &pp[ptr],
167 (numrecs - ptr) * sizeof(*pp));
168 xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
169 xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
170 }
171 } else {
172 rp = XFS_BMAP_REC_IADDR(block, 1, cur);
173 if (ptr < numrecs) {
174 memmove(&rp[ptr - 1], &rp[ptr],
175 (numrecs - ptr) * sizeof(*rp));
176 xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
177 }
178 if (ptr == 1) {
179 key.br_startoff =
180 cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
181 kp = &key;
182 }
183 }
184 numrecs--;
185 block->bb_numrecs = cpu_to_be16(numrecs);
186 xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
187 /*
188 * We're at the root level.
189 * First, shrink the root block in-memory.
190 * Try to get rid of the next level down.
191 * If we can't then there's nothing left to do.
192 */
193 if (level == cur->bc_nlevels - 1) {
194 xfs_iroot_realloc(cur->bc_private.b.ip, -1,
195 cur->bc_private.b.whichfork);
196 if ((error = xfs_btree_kill_iroot(cur))) {
197 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
198 goto error0;
199 }
200 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
201 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
202 goto error0;
203 }
204 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
205 *stat = 1;
206 return 0;
207 }
208 if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1))) {
209 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
210 goto error0;
211 }
212 if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
213 if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
214 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
215 goto error0;
216 }
217 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
218 *stat = 1;
219 return 0;
220 }
221 rbno = be64_to_cpu(block->bb_rightsib);
222 lbno = be64_to_cpu(block->bb_leftsib);
223 /*
224 * One child of root, need to get a chance to copy its contents
225 * into the root and delete it. Can't go up to next level,
226 * there's nothing to delete there.
227 */
228 if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK &&
229 level == cur->bc_nlevels - 2) {
230 if ((error = xfs_btree_kill_iroot(cur))) {
231 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
232 goto error0;
233 }
234 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
235 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
236 goto error0;
237 }
238 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
239 *stat = 1;
240 return 0;
241 }
242 ASSERT(rbno != NULLFSBLOCK || lbno != NULLFSBLOCK);
243 if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
244 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
245 goto error0;
246 }
247 bno = NULLFSBLOCK;
248 if (rbno != NULLFSBLOCK) {
249 i = xfs_btree_lastrec(tcur, level);
250 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
251 if ((error = xfs_btree_increment(tcur, level, &i))) {
252 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
253 goto error0;
254 }
255 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
256 i = xfs_btree_lastrec(tcur, level);
257 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
258 rbp = tcur->bc_bufs[level];
259 right = XFS_BUF_TO_BMBT_BLOCK(rbp);
260#ifdef DEBUG
261 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
262 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
263 goto error0;
264 }
265#endif
266 bno = be64_to_cpu(right->bb_leftsib);
267 if (be16_to_cpu(right->bb_numrecs) - 1 >=
268 XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
269 if ((error = xfs_btree_lshift(tcur, level, &i))) {
270 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
271 goto error0;
272 }
273 if (i) {
274 ASSERT(be16_to_cpu(block->bb_numrecs) >=
275 XFS_BMAP_BLOCK_IMINRECS(level, tcur));
276 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
277 tcur = NULL;
278 if (level > 0) {
279 if ((error = xfs_btree_decrement(cur,
280 level, &i))) {
281 XFS_BMBT_TRACE_CURSOR(cur,
282 ERROR);
283 goto error0;
284 }
285 }
286 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
287 *stat = 1;
288 return 0;
289 }
290 }
291 rrecs = be16_to_cpu(right->bb_numrecs);
292 if (lbno != NULLFSBLOCK) {
293 i = xfs_btree_firstrec(tcur, level);
294 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
295 if ((error = xfs_btree_decrement(tcur, level, &i))) {
296 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
297 goto error0;
298 }
299 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
300 }
301 }
302 if (lbno != NULLFSBLOCK) {
303 i = xfs_btree_firstrec(tcur, level);
304 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
305 /*
306 * decrement to last in block
307 */
308 if ((error = xfs_btree_decrement(tcur, level, &i))) {
309 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
310 goto error0;
311 }
312 i = xfs_btree_firstrec(tcur, level);
313 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
314 lbp = tcur->bc_bufs[level];
315 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
316#ifdef DEBUG
317 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
318 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
319 goto error0;
320 }
321#endif
322 bno = be64_to_cpu(left->bb_rightsib);
323 if (be16_to_cpu(left->bb_numrecs) - 1 >=
324 XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
325 if ((error = xfs_btree_rshift(tcur, level, &i))) {
326 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
327 goto error0;
328 }
329 if (i) {
330 ASSERT(be16_to_cpu(block->bb_numrecs) >=
331 XFS_BMAP_BLOCK_IMINRECS(level, tcur));
332 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
333 tcur = NULL;
334 if (level == 0)
335 cur->bc_ptrs[0]++;
336 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
337 *stat = 1;
338 return 0;
339 }
340 }
341 lrecs = be16_to_cpu(left->bb_numrecs);
342 }
343 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
344 tcur = NULL;
345 mp = cur->bc_mp;
346 ASSERT(bno != NULLFSBLOCK);
347 if (lbno != NULLFSBLOCK &&
348 lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
349 rbno = bno;
350 right = block;
351 rbp = bp;
352 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, lbno, 0, &lbp,
353 XFS_BMAP_BTREE_REF))) {
354 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
355 goto error0;
356 }
357 left = XFS_BUF_TO_BMBT_BLOCK(lbp);
358 if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
359 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
360 goto error0;
361 }
362 } else if (rbno != NULLFSBLOCK &&
363 rrecs + be16_to_cpu(block->bb_numrecs) <=
364 XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
365 lbno = bno;
366 left = block;
367 lbp = bp;
368 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, rbno, 0, &rbp,
369 XFS_BMAP_BTREE_REF))) {
370 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
371 goto error0;
372 }
373 right = XFS_BUF_TO_BMBT_BLOCK(rbp);
374 if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
375 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
376 goto error0;
377 }
378 lrecs = be16_to_cpu(left->bb_numrecs);
379 } else {
380 if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
381 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
382 goto error0;
383 }
384 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
385 *stat = 1;
386 return 0;
387 }
388 numlrecs = be16_to_cpu(left->bb_numrecs);
389 numrrecs = be16_to_cpu(right->bb_numrecs);
390 if (level > 0) {
391 lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur);
392 lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur);
393 rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
394 rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
395#ifdef DEBUG
396 for (i = 0; i < numrrecs; i++) {
397 if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
398 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
399 goto error0;
400 }
401 }
402#endif
403 memcpy(lkp, rkp, numrrecs * sizeof(*lkp));
404 memcpy(lpp, rpp, numrrecs * sizeof(*lpp));
405 xfs_bmbt_log_keys(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
406 xfs_bmbt_log_ptrs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
407 } else {
408 lrp = XFS_BMAP_REC_IADDR(left, numlrecs + 1, cur);
409 rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
410 memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
411 xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
412 }
413 be16_add_cpu(&left->bb_numrecs, numrrecs);
414 left->bb_rightsib = right->bb_rightsib;
415 xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
416 if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
417 if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
418 be64_to_cpu(left->bb_rightsib),
419 0, &rrbp, XFS_BMAP_BTREE_REF))) {
420 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
421 goto error0;
422 }
423 rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
424 if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
425 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
426 goto error0;
427 }
428 rrblock->bb_leftsib = cpu_to_be64(lbno);
429 xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
430 }
431 xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
432 cur->bc_private.b.flist, mp);
433 cur->bc_private.b.ip->i_d.di_nblocks--;
434 xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
435 XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip,
436 XFS_TRANS_DQ_BCOUNT, -1L);
437 xfs_trans_binval(cur->bc_tp, rbp);
438 if (bp != lbp) {
439 cur->bc_bufs[level] = lbp;
440 cur->bc_ptrs[level] += lrecs;
441 cur->bc_ra[level] = 0;
442 } else if ((error = xfs_btree_increment(cur, level + 1, &i))) {
443 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
444 goto error0;
445 }
446 if (level > 0)
447 cur->bc_ptrs[level]--;
448 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
449 *stat = 2;
450 return 0;
451
452error0:
453 if (tcur)
454 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
455 return error;
456}
457
458/*
459 * Log key values from the btree block.
460 */
461STATIC void
462xfs_bmbt_log_keys(
463 xfs_btree_cur_t *cur,
464 xfs_buf_t *bp,
465 int kfirst,
466 int klast)
467{
468 xfs_trans_t *tp;
469
470 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
471 XFS_BMBT_TRACE_ARGBII(cur, bp, kfirst, klast);
472 tp = cur->bc_tp;
473 if (bp) {
474 xfs_bmbt_block_t *block;
475 int first;
476 xfs_bmbt_key_t *kp;
477 int last;
478
479 block = XFS_BUF_TO_BMBT_BLOCK(bp);
480 kp = XFS_BMAP_KEY_DADDR(block, 1, cur);
481 first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
482 last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
483 xfs_trans_log_buf(tp, bp, first, last);
484 } else {
485 xfs_inode_t *ip;
486
487 ip = cur->bc_private.b.ip;
488 xfs_trans_log_inode(tp, ip,
489 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
490 }
491 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
492}
493
494/*
495 * Log pointer values from the btree block.
496 */
497STATIC void
498xfs_bmbt_log_ptrs(
499 xfs_btree_cur_t *cur,
500 xfs_buf_t *bp,
501 int pfirst,
502 int plast)
503{
504 xfs_trans_t *tp;
505
506 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
507 XFS_BMBT_TRACE_ARGBII(cur, bp, pfirst, plast);
508 tp = cur->bc_tp;
509 if (bp) {
510 xfs_bmbt_block_t *block;
511 int first;
512 int last;
513 xfs_bmbt_ptr_t *pp;
514
515 block = XFS_BUF_TO_BMBT_BLOCK(bp);
516 pp = XFS_BMAP_PTR_DADDR(block, 1, cur);
517 first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
518 last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
519 xfs_trans_log_buf(tp, bp, first, last);
520 } else {
521 xfs_inode_t *ip;
522
523 ip = cur->bc_private.b.ip;
524 xfs_trans_log_inode(tp, ip,
525 XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
526 }
527 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
528}
529
530/* 75/*
531 * Determine the extent state. 76 * Determine the extent state.
532 */ 77 */
@@ -576,42 +121,6 @@ xfs_bmdr_to_bmbt(
576} 121}
577 122
578/* 123/*
579 * Delete the record pointed to by cur.
580 */
581int /* error */
582xfs_bmbt_delete(
583 xfs_btree_cur_t *cur,
584 int *stat) /* success/failure */
585{
586 int error; /* error return value */
587 int i;
588 int level;
589
590 XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
591 for (level = 0, i = 2; i == 2; level++) {
592 if ((error = xfs_bmbt_delrec(cur, level, &i))) {
593 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
594 return error;
595 }
596 }
597 if (i == 0) {
598 for (level = 1; level < cur->bc_nlevels; level++) {
599 if (cur->bc_ptrs[level] == 0) {
600 if ((error = xfs_btree_decrement(cur, level,
601 &i))) {
602 XFS_BMBT_TRACE_CURSOR(cur, ERROR);
603 return error;
604 }
605 break;
606 }
607 }
608 }
609 XFS_BMBT_TRACE_CURSOR(cur, EXIT);
610 *stat = i;
611 return 0;
612}
613
614/*
615 * Convert a compressed bmap extent record to an uncompressed form. 124 * Convert a compressed bmap extent record to an uncompressed form.
616 * This code must be in sync with the routines xfs_bmbt_get_startoff, 125 * This code must be in sync with the routines xfs_bmbt_get_startoff,
617 * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state. 126 * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
@@ -665,31 +174,6 @@ xfs_bmbt_get_all(
665} 174}
666 175
667/* 176/*
668 * Get the block pointer for the given level of the cursor.
669 * Fill in the buffer pointer, if applicable.
670 */
671xfs_bmbt_block_t *
672xfs_bmbt_get_block(
673 xfs_btree_cur_t *cur,
674 int level,
675 xfs_buf_t **bpp)
676{
677 xfs_ifork_t *ifp;
678 xfs_bmbt_block_t *rval;
679
680 if (level < cur->bc_nlevels - 1) {
681 *bpp = cur->bc_bufs[level];
682 rval = XFS_BUF_TO_BMBT_BLOCK(*bpp);
683 } else {
684 *bpp = NULL;
685 ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
686 cur->bc_private.b.whichfork);
687 rval = ifp->if_broot;
688 }
689 return rval;
690}
691
692/*
693 * Extract the blockcount field from an in memory bmap extent record. 177 * Extract the blockcount field from an in memory bmap extent record.
694 */ 178 */
695xfs_filblks_t 179xfs_filblks_t
@@ -1226,6 +710,14 @@ xfs_bmbt_free_block(
1226} 710}
1227 711
1228STATIC int 712STATIC int
713xfs_bmbt_get_minrecs(
714 struct xfs_btree_cur *cur,
715 int level)
716{
717 return XFS_BMAP_BLOCK_IMINRECS(level, cur);
718}
719
720STATIC int
1229xfs_bmbt_get_maxrecs( 721xfs_bmbt_get_maxrecs(
1230 struct xfs_btree_cur *cur, 722 struct xfs_btree_cur *cur,
1231 int level) 723 int level)
@@ -1389,6 +881,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = {
1389 .alloc_block = xfs_bmbt_alloc_block, 881 .alloc_block = xfs_bmbt_alloc_block,
1390 .free_block = xfs_bmbt_free_block, 882 .free_block = xfs_bmbt_free_block,
1391 .get_maxrecs = xfs_bmbt_get_maxrecs, 883 .get_maxrecs = xfs_bmbt_get_maxrecs,
884 .get_minrecs = xfs_bmbt_get_minrecs,
1392 .get_dmaxrecs = xfs_bmbt_get_dmaxrecs, 885 .get_dmaxrecs = xfs_bmbt_get_dmaxrecs,
1393 .init_key_from_rec = xfs_bmbt_init_key_from_rec, 886 .init_key_from_rec = xfs_bmbt_init_key_from_rec,
1394 .init_rec_from_key = xfs_bmbt_init_rec_from_key, 887 .init_rec_from_key = xfs_bmbt_init_rec_from_key,