diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-10-30 01:58:01 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 01:58:01 -0400 |
commit | 91cca5df9bc85efdabfa645f51d54259ed09f4bf (patch) | |
tree | 29032361e21d1210effb72f4018f2a202d6a9fb0 /fs/xfs/xfs_bmap_btree.c | |
parent | d4b3a4b7dd62f2e111d4d0afa9ef3f9b6cd955c0 (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.c | 525 |
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 | |||
52 | STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int); | ||
53 | STATIC 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 | */ | ||
91 | STATIC int /* error */ | ||
92 | xfs_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 | |||
452 | error0: | ||
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 | */ | ||
461 | STATIC void | ||
462 | xfs_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 | */ | ||
497 | STATIC void | ||
498 | xfs_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 | */ | ||
581 | int /* error */ | ||
582 | xfs_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 | */ | ||
671 | xfs_bmbt_block_t * | ||
672 | xfs_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 | */ |
695 | xfs_filblks_t | 179 | xfs_filblks_t |
@@ -1226,6 +710,14 @@ xfs_bmbt_free_block( | |||
1226 | } | 710 | } |
1227 | 711 | ||
1228 | STATIC int | 712 | STATIC int |
713 | xfs_bmbt_get_minrecs( | ||
714 | struct xfs_btree_cur *cur, | ||
715 | int level) | ||
716 | { | ||
717 | return XFS_BMAP_BLOCK_IMINRECS(level, cur); | ||
718 | } | ||
719 | |||
720 | STATIC int | ||
1229 | xfs_bmbt_get_maxrecs( | 721 | xfs_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, |