.. | .. |
---|
11 | 11 | #include "xfs_trans_resv.h" |
---|
12 | 12 | #include "xfs_bit.h" |
---|
13 | 13 | #include "xfs_mount.h" |
---|
14 | | -#include "xfs_inode.h" |
---|
15 | 14 | #include "xfs_btree.h" |
---|
| 15 | +#include "xfs_btree_staging.h" |
---|
16 | 16 | #include "xfs_ialloc.h" |
---|
17 | 17 | #include "xfs_ialloc_btree.h" |
---|
18 | 18 | #include "xfs_alloc.h" |
---|
19 | 19 | #include "xfs_error.h" |
---|
20 | 20 | #include "xfs_trace.h" |
---|
21 | | -#include "xfs_cksum.h" |
---|
22 | 21 | #include "xfs_trans.h" |
---|
23 | 22 | #include "xfs_rmap.h" |
---|
24 | | - |
---|
25 | 23 | |
---|
26 | 24 | STATIC int |
---|
27 | 25 | xfs_inobt_get_minrecs( |
---|
28 | 26 | struct xfs_btree_cur *cur, |
---|
29 | 27 | int level) |
---|
30 | 28 | { |
---|
31 | | - return cur->bc_mp->m_inobt_mnr[level != 0]; |
---|
| 29 | + return M_IGEO(cur->bc_mp)->inobt_mnr[level != 0]; |
---|
32 | 30 | } |
---|
33 | 31 | |
---|
34 | 32 | STATIC struct xfs_btree_cur * |
---|
.. | .. |
---|
36 | 34 | struct xfs_btree_cur *cur) |
---|
37 | 35 | { |
---|
38 | 36 | return xfs_inobt_init_cursor(cur->bc_mp, cur->bc_tp, |
---|
39 | | - cur->bc_private.a.agbp, cur->bc_private.a.agno, |
---|
| 37 | + cur->bc_ag.agbp, cur->bc_ag.agno, |
---|
40 | 38 | cur->bc_btnum); |
---|
41 | 39 | } |
---|
42 | 40 | |
---|
.. | .. |
---|
46 | 44 | union xfs_btree_ptr *nptr, |
---|
47 | 45 | int inc) /* level change */ |
---|
48 | 46 | { |
---|
49 | | - struct xfs_buf *agbp = cur->bc_private.a.agbp; |
---|
50 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
---|
| 47 | + struct xfs_buf *agbp = cur->bc_ag.agbp; |
---|
| 48 | + struct xfs_agi *agi = agbp->b_addr; |
---|
51 | 49 | |
---|
52 | 50 | agi->agi_root = nptr->s; |
---|
53 | 51 | be32_add_cpu(&agi->agi_level, inc); |
---|
.. | .. |
---|
60 | 58 | union xfs_btree_ptr *nptr, |
---|
61 | 59 | int inc) /* level change */ |
---|
62 | 60 | { |
---|
63 | | - struct xfs_buf *agbp = cur->bc_private.a.agbp; |
---|
64 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
---|
| 61 | + struct xfs_buf *agbp = cur->bc_ag.agbp; |
---|
| 62 | + struct xfs_agi *agi = agbp->b_addr; |
---|
65 | 63 | |
---|
66 | 64 | agi->agi_free_root = nptr->s; |
---|
67 | 65 | be32_add_cpu(&agi->agi_free_level, inc); |
---|
68 | 66 | xfs_ialloc_log_agi(cur->bc_tp, agbp, |
---|
69 | 67 | XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL); |
---|
| 68 | +} |
---|
| 69 | + |
---|
| 70 | +/* Update the inode btree block counter for this btree. */ |
---|
| 71 | +static inline void |
---|
| 72 | +xfs_inobt_mod_blockcount( |
---|
| 73 | + struct xfs_btree_cur *cur, |
---|
| 74 | + int howmuch) |
---|
| 75 | +{ |
---|
| 76 | + struct xfs_buf *agbp = cur->bc_ag.agbp; |
---|
| 77 | + struct xfs_agi *agi = agbp->b_addr; |
---|
| 78 | + |
---|
| 79 | + if (!xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) |
---|
| 80 | + return; |
---|
| 81 | + |
---|
| 82 | + if (cur->bc_btnum == XFS_BTNUM_FINO) |
---|
| 83 | + be32_add_cpu(&agi->agi_fblocks, howmuch); |
---|
| 84 | + else if (cur->bc_btnum == XFS_BTNUM_INO) |
---|
| 85 | + be32_add_cpu(&agi->agi_iblocks, howmuch); |
---|
| 86 | + xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_IBLOCKS); |
---|
70 | 87 | } |
---|
71 | 88 | |
---|
72 | 89 | STATIC int |
---|
.. | .. |
---|
84 | 101 | memset(&args, 0, sizeof(args)); |
---|
85 | 102 | args.tp = cur->bc_tp; |
---|
86 | 103 | args.mp = cur->bc_mp; |
---|
87 | | - xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_INOBT); |
---|
88 | | - args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); |
---|
| 104 | + args.oinfo = XFS_RMAP_OINFO_INOBT; |
---|
| 105 | + args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_ag.agno, sbno); |
---|
89 | 106 | args.minlen = 1; |
---|
90 | 107 | args.maxlen = 1; |
---|
91 | 108 | args.prod = 1; |
---|
.. | .. |
---|
104 | 121 | |
---|
105 | 122 | new->s = cpu_to_be32(XFS_FSB_TO_AGBNO(args.mp, args.fsbno)); |
---|
106 | 123 | *stat = 1; |
---|
| 124 | + xfs_inobt_mod_blockcount(cur, 1); |
---|
107 | 125 | return 0; |
---|
108 | 126 | } |
---|
109 | 127 | |
---|
.. | .. |
---|
136 | 154 | struct xfs_buf *bp, |
---|
137 | 155 | enum xfs_ag_resv_type resv) |
---|
138 | 156 | { |
---|
139 | | - struct xfs_owner_info oinfo; |
---|
140 | | - |
---|
141 | | - xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INOBT); |
---|
| 157 | + xfs_inobt_mod_blockcount(cur, -1); |
---|
142 | 158 | return xfs_free_extent(cur->bc_tp, |
---|
143 | 159 | XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)), 1, |
---|
144 | | - &oinfo, resv); |
---|
| 160 | + &XFS_RMAP_OINFO_INOBT, resv); |
---|
145 | 161 | } |
---|
146 | 162 | |
---|
147 | 163 | STATIC int |
---|
.. | .. |
---|
167 | 183 | struct xfs_btree_cur *cur, |
---|
168 | 184 | int level) |
---|
169 | 185 | { |
---|
170 | | - return cur->bc_mp->m_inobt_mxr[level != 0]; |
---|
| 186 | + return M_IGEO(cur->bc_mp)->inobt_mxr[level != 0]; |
---|
171 | 187 | } |
---|
172 | 188 | |
---|
173 | 189 | STATIC void |
---|
.. | .. |
---|
217 | 233 | struct xfs_btree_cur *cur, |
---|
218 | 234 | union xfs_btree_ptr *ptr) |
---|
219 | 235 | { |
---|
220 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); |
---|
| 236 | + struct xfs_agi *agi = cur->bc_ag.agbp->b_addr; |
---|
221 | 237 | |
---|
222 | | - ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno)); |
---|
| 238 | + ASSERT(cur->bc_ag.agno == be32_to_cpu(agi->agi_seqno)); |
---|
223 | 239 | |
---|
224 | 240 | ptr->s = agi->agi_root; |
---|
225 | 241 | } |
---|
.. | .. |
---|
229 | 245 | struct xfs_btree_cur *cur, |
---|
230 | 246 | union xfs_btree_ptr *ptr) |
---|
231 | 247 | { |
---|
232 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); |
---|
| 248 | + struct xfs_agi *agi = cur->bc_ag.agbp->b_addr; |
---|
233 | 249 | |
---|
234 | | - ASSERT(cur->bc_private.a.agno == be32_to_cpu(agi->agi_seqno)); |
---|
| 250 | + ASSERT(cur->bc_ag.agno == be32_to_cpu(agi->agi_seqno)); |
---|
235 | 251 | ptr->s = agi->agi_free_root; |
---|
236 | 252 | } |
---|
237 | 253 | |
---|
.. | .. |
---|
258 | 274 | xfs_inobt_verify( |
---|
259 | 275 | struct xfs_buf *bp) |
---|
260 | 276 | { |
---|
261 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 277 | + struct xfs_mount *mp = bp->b_mount; |
---|
262 | 278 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); |
---|
263 | 279 | xfs_failaddr_t fa; |
---|
264 | 280 | unsigned int level; |
---|
| 281 | + |
---|
| 282 | + if (!xfs_verify_magic(bp, block->bb_magic)) |
---|
| 283 | + return __this_address; |
---|
265 | 284 | |
---|
266 | 285 | /* |
---|
267 | 286 | * During growfs operations, we can't verify the exact owner as the |
---|
.. | .. |
---|
273 | 292 | * but beware of the landmine (i.e. need to check pag->pagi_init) if we |
---|
274 | 293 | * ever do. |
---|
275 | 294 | */ |
---|
276 | | - switch (block->bb_magic) { |
---|
277 | | - case cpu_to_be32(XFS_IBT_CRC_MAGIC): |
---|
278 | | - case cpu_to_be32(XFS_FIBT_CRC_MAGIC): |
---|
| 295 | + if (xfs_sb_version_hascrc(&mp->m_sb)) { |
---|
279 | 296 | fa = xfs_btree_sblock_v5hdr_verify(bp); |
---|
280 | 297 | if (fa) |
---|
281 | 298 | return fa; |
---|
282 | | - /* fall through */ |
---|
283 | | - case cpu_to_be32(XFS_IBT_MAGIC): |
---|
284 | | - case cpu_to_be32(XFS_FIBT_MAGIC): |
---|
285 | | - break; |
---|
286 | | - default: |
---|
287 | | - return __this_address; |
---|
288 | 299 | } |
---|
289 | 300 | |
---|
290 | 301 | /* level verification */ |
---|
291 | 302 | level = be16_to_cpu(block->bb_level); |
---|
292 | | - if (level >= mp->m_in_maxlevels) |
---|
| 303 | + if (level >= M_IGEO(mp)->inobt_maxlevels) |
---|
293 | 304 | return __this_address; |
---|
294 | 305 | |
---|
295 | | - return xfs_btree_sblock_verify(bp, mp->m_inobt_mxr[level != 0]); |
---|
| 306 | + return xfs_btree_sblock_verify(bp, |
---|
| 307 | + M_IGEO(mp)->inobt_mxr[level != 0]); |
---|
296 | 308 | } |
---|
297 | 309 | |
---|
298 | 310 | static void |
---|
.. | .. |
---|
331 | 343 | |
---|
332 | 344 | const struct xfs_buf_ops xfs_inobt_buf_ops = { |
---|
333 | 345 | .name = "xfs_inobt", |
---|
| 346 | + .magic = { cpu_to_be32(XFS_IBT_MAGIC), cpu_to_be32(XFS_IBT_CRC_MAGIC) }, |
---|
| 347 | + .verify_read = xfs_inobt_read_verify, |
---|
| 348 | + .verify_write = xfs_inobt_write_verify, |
---|
| 349 | + .verify_struct = xfs_inobt_verify, |
---|
| 350 | +}; |
---|
| 351 | + |
---|
| 352 | +const struct xfs_buf_ops xfs_finobt_buf_ops = { |
---|
| 353 | + .name = "xfs_finobt", |
---|
| 354 | + .magic = { cpu_to_be32(XFS_FIBT_MAGIC), |
---|
| 355 | + cpu_to_be32(XFS_FIBT_CRC_MAGIC) }, |
---|
334 | 356 | .verify_read = xfs_inobt_read_verify, |
---|
335 | 357 | .verify_write = xfs_inobt_write_verify, |
---|
336 | 358 | .verify_struct = xfs_inobt_verify, |
---|
.. | .. |
---|
392 | 414 | .init_rec_from_cur = xfs_inobt_init_rec_from_cur, |
---|
393 | 415 | .init_ptr_from_cur = xfs_finobt_init_ptr_from_cur, |
---|
394 | 416 | .key_diff = xfs_inobt_key_diff, |
---|
395 | | - .buf_ops = &xfs_inobt_buf_ops, |
---|
| 417 | + .buf_ops = &xfs_finobt_buf_ops, |
---|
396 | 418 | .diff_two_keys = xfs_inobt_diff_two_keys, |
---|
397 | 419 | .keys_inorder = xfs_inobt_keys_inorder, |
---|
398 | 420 | .recs_inorder = xfs_inobt_recs_inorder, |
---|
399 | 421 | }; |
---|
400 | 422 | |
---|
401 | 423 | /* |
---|
402 | | - * Allocate a new inode btree cursor. |
---|
| 424 | + * Initialize a new inode btree cursor. |
---|
403 | 425 | */ |
---|
404 | | -struct xfs_btree_cur * /* new inode btree cursor */ |
---|
405 | | -xfs_inobt_init_cursor( |
---|
| 426 | +static struct xfs_btree_cur * |
---|
| 427 | +xfs_inobt_init_common( |
---|
406 | 428 | struct xfs_mount *mp, /* file system mount point */ |
---|
407 | 429 | struct xfs_trans *tp, /* transaction pointer */ |
---|
408 | | - struct xfs_buf *agbp, /* buffer for agi structure */ |
---|
409 | 430 | xfs_agnumber_t agno, /* allocation group number */ |
---|
410 | 431 | xfs_btnum_t btnum) /* ialloc or free ino btree */ |
---|
411 | 432 | { |
---|
412 | | - struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp); |
---|
413 | 433 | struct xfs_btree_cur *cur; |
---|
414 | 434 | |
---|
415 | | - cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_NOFS); |
---|
416 | | - |
---|
| 435 | + cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); |
---|
417 | 436 | cur->bc_tp = tp; |
---|
418 | 437 | cur->bc_mp = mp; |
---|
419 | 438 | cur->bc_btnum = btnum; |
---|
420 | 439 | if (btnum == XFS_BTNUM_INO) { |
---|
421 | | - cur->bc_nlevels = be32_to_cpu(agi->agi_level); |
---|
422 | | - cur->bc_ops = &xfs_inobt_ops; |
---|
423 | 440 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2); |
---|
| 441 | + cur->bc_ops = &xfs_inobt_ops; |
---|
424 | 442 | } else { |
---|
425 | | - cur->bc_nlevels = be32_to_cpu(agi->agi_free_level); |
---|
426 | | - cur->bc_ops = &xfs_finobt_ops; |
---|
427 | 443 | cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2); |
---|
| 444 | + cur->bc_ops = &xfs_finobt_ops; |
---|
428 | 445 | } |
---|
429 | 446 | |
---|
430 | 447 | cur->bc_blocklog = mp->m_sb.sb_blocklog; |
---|
.. | .. |
---|
432 | 449 | if (xfs_sb_version_hascrc(&mp->m_sb)) |
---|
433 | 450 | cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; |
---|
434 | 451 | |
---|
435 | | - cur->bc_private.a.agbp = agbp; |
---|
436 | | - cur->bc_private.a.agno = agno; |
---|
437 | | - |
---|
| 452 | + cur->bc_ag.agno = agno; |
---|
438 | 453 | return cur; |
---|
| 454 | +} |
---|
| 455 | + |
---|
| 456 | +/* Create an inode btree cursor. */ |
---|
| 457 | +struct xfs_btree_cur * |
---|
| 458 | +xfs_inobt_init_cursor( |
---|
| 459 | + struct xfs_mount *mp, |
---|
| 460 | + struct xfs_trans *tp, |
---|
| 461 | + struct xfs_buf *agbp, |
---|
| 462 | + xfs_agnumber_t agno, |
---|
| 463 | + xfs_btnum_t btnum) |
---|
| 464 | +{ |
---|
| 465 | + struct xfs_btree_cur *cur; |
---|
| 466 | + struct xfs_agi *agi = agbp->b_addr; |
---|
| 467 | + |
---|
| 468 | + cur = xfs_inobt_init_common(mp, tp, agno, btnum); |
---|
| 469 | + if (btnum == XFS_BTNUM_INO) |
---|
| 470 | + cur->bc_nlevels = be32_to_cpu(agi->agi_level); |
---|
| 471 | + else |
---|
| 472 | + cur->bc_nlevels = be32_to_cpu(agi->agi_free_level); |
---|
| 473 | + cur->bc_ag.agbp = agbp; |
---|
| 474 | + return cur; |
---|
| 475 | +} |
---|
| 476 | + |
---|
| 477 | +/* Create an inode btree cursor with a fake root for staging. */ |
---|
| 478 | +struct xfs_btree_cur * |
---|
| 479 | +xfs_inobt_stage_cursor( |
---|
| 480 | + struct xfs_mount *mp, |
---|
| 481 | + struct xbtree_afakeroot *afake, |
---|
| 482 | + xfs_agnumber_t agno, |
---|
| 483 | + xfs_btnum_t btnum) |
---|
| 484 | +{ |
---|
| 485 | + struct xfs_btree_cur *cur; |
---|
| 486 | + |
---|
| 487 | + cur = xfs_inobt_init_common(mp, NULL, agno, btnum); |
---|
| 488 | + xfs_btree_stage_afakeroot(cur, afake); |
---|
| 489 | + return cur; |
---|
| 490 | +} |
---|
| 491 | + |
---|
| 492 | +/* |
---|
| 493 | + * Install a new inobt btree root. Caller is responsible for invalidating |
---|
| 494 | + * and freeing the old btree blocks. |
---|
| 495 | + */ |
---|
| 496 | +void |
---|
| 497 | +xfs_inobt_commit_staged_btree( |
---|
| 498 | + struct xfs_btree_cur *cur, |
---|
| 499 | + struct xfs_trans *tp, |
---|
| 500 | + struct xfs_buf *agbp) |
---|
| 501 | +{ |
---|
| 502 | + struct xfs_agi *agi = agbp->b_addr; |
---|
| 503 | + struct xbtree_afakeroot *afake = cur->bc_ag.afake; |
---|
| 504 | + int fields; |
---|
| 505 | + |
---|
| 506 | + ASSERT(cur->bc_flags & XFS_BTREE_STAGING); |
---|
| 507 | + |
---|
| 508 | + if (cur->bc_btnum == XFS_BTNUM_INO) { |
---|
| 509 | + fields = XFS_AGI_ROOT | XFS_AGI_LEVEL; |
---|
| 510 | + agi->agi_root = cpu_to_be32(afake->af_root); |
---|
| 511 | + agi->agi_level = cpu_to_be32(afake->af_levels); |
---|
| 512 | + if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) { |
---|
| 513 | + agi->agi_iblocks = cpu_to_be32(afake->af_blocks); |
---|
| 514 | + fields |= XFS_AGI_IBLOCKS; |
---|
| 515 | + } |
---|
| 516 | + xfs_ialloc_log_agi(tp, agbp, fields); |
---|
| 517 | + xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_inobt_ops); |
---|
| 518 | + } else { |
---|
| 519 | + fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL; |
---|
| 520 | + agi->agi_free_root = cpu_to_be32(afake->af_root); |
---|
| 521 | + agi->agi_free_level = cpu_to_be32(afake->af_levels); |
---|
| 522 | + if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) { |
---|
| 523 | + agi->agi_fblocks = cpu_to_be32(afake->af_blocks); |
---|
| 524 | + fields |= XFS_AGI_IBLOCKS; |
---|
| 525 | + } |
---|
| 526 | + xfs_ialloc_log_agi(tp, agbp, fields); |
---|
| 527 | + xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_finobt_ops); |
---|
| 528 | + } |
---|
439 | 529 | } |
---|
440 | 530 | |
---|
441 | 531 | /* |
---|
.. | .. |
---|
538 | 628 | |
---|
539 | 629 | static xfs_extlen_t |
---|
540 | 630 | xfs_inobt_max_size( |
---|
541 | | - struct xfs_mount *mp) |
---|
| 631 | + struct xfs_mount *mp, |
---|
| 632 | + xfs_agnumber_t agno) |
---|
542 | 633 | { |
---|
| 634 | + xfs_agblock_t agblocks = xfs_ag_block_count(mp, agno); |
---|
| 635 | + |
---|
543 | 636 | /* Bail out if we're uninitialized, which can happen in mkfs. */ |
---|
544 | | - if (mp->m_inobt_mxr[0] == 0) |
---|
| 637 | + if (M_IGEO(mp)->inobt_mxr[0] == 0) |
---|
545 | 638 | return 0; |
---|
546 | 639 | |
---|
547 | | - return xfs_btree_calc_size(mp->m_inobt_mnr, |
---|
548 | | - (uint64_t)mp->m_sb.sb_agblocks * mp->m_sb.sb_inopblock / |
---|
549 | | - XFS_INODES_PER_CHUNK); |
---|
| 640 | + /* |
---|
| 641 | + * The log is permanently allocated, so the space it occupies will |
---|
| 642 | + * never be available for the kinds of things that would require btree |
---|
| 643 | + * expansion. We therefore can pretend the space isn't there. |
---|
| 644 | + */ |
---|
| 645 | + if (mp->m_sb.sb_logstart && |
---|
| 646 | + XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart) == agno) |
---|
| 647 | + agblocks -= mp->m_sb.sb_logblocks; |
---|
| 648 | + |
---|
| 649 | + return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, |
---|
| 650 | + (uint64_t)agblocks * mp->m_sb.sb_inopblock / |
---|
| 651 | + XFS_INODES_PER_CHUNK); |
---|
| 652 | +} |
---|
| 653 | + |
---|
| 654 | +/* Read AGI and create inobt cursor. */ |
---|
| 655 | +int |
---|
| 656 | +xfs_inobt_cur( |
---|
| 657 | + struct xfs_mount *mp, |
---|
| 658 | + struct xfs_trans *tp, |
---|
| 659 | + xfs_agnumber_t agno, |
---|
| 660 | + xfs_btnum_t which, |
---|
| 661 | + struct xfs_btree_cur **curpp, |
---|
| 662 | + struct xfs_buf **agi_bpp) |
---|
| 663 | +{ |
---|
| 664 | + struct xfs_btree_cur *cur; |
---|
| 665 | + int error; |
---|
| 666 | + |
---|
| 667 | + ASSERT(*agi_bpp == NULL); |
---|
| 668 | + ASSERT(*curpp == NULL); |
---|
| 669 | + |
---|
| 670 | + error = xfs_ialloc_read_agi(mp, tp, agno, agi_bpp); |
---|
| 671 | + if (error) |
---|
| 672 | + return error; |
---|
| 673 | + |
---|
| 674 | + cur = xfs_inobt_init_cursor(mp, tp, *agi_bpp, agno, which); |
---|
| 675 | + if (!cur) { |
---|
| 676 | + xfs_trans_brelse(tp, *agi_bpp); |
---|
| 677 | + *agi_bpp = NULL; |
---|
| 678 | + return -ENOMEM; |
---|
| 679 | + } |
---|
| 680 | + *curpp = cur; |
---|
| 681 | + return 0; |
---|
550 | 682 | } |
---|
551 | 683 | |
---|
552 | 684 | static int |
---|
.. | .. |
---|
557 | 689 | xfs_btnum_t btnum, |
---|
558 | 690 | xfs_extlen_t *tree_blocks) |
---|
559 | 691 | { |
---|
| 692 | + struct xfs_buf *agbp = NULL; |
---|
| 693 | + struct xfs_btree_cur *cur = NULL; |
---|
| 694 | + int error; |
---|
| 695 | + |
---|
| 696 | + error = xfs_inobt_cur(mp, tp, agno, btnum, &cur, &agbp); |
---|
| 697 | + if (error) |
---|
| 698 | + return error; |
---|
| 699 | + |
---|
| 700 | + error = xfs_btree_count_blocks(cur, tree_blocks); |
---|
| 701 | + xfs_btree_del_cursor(cur, error); |
---|
| 702 | + xfs_trans_brelse(tp, agbp); |
---|
| 703 | + |
---|
| 704 | + return error; |
---|
| 705 | +} |
---|
| 706 | + |
---|
| 707 | +/* Read finobt block count from AGI header. */ |
---|
| 708 | +static int |
---|
| 709 | +xfs_finobt_read_blocks( |
---|
| 710 | + struct xfs_mount *mp, |
---|
| 711 | + struct xfs_trans *tp, |
---|
| 712 | + xfs_agnumber_t agno, |
---|
| 713 | + xfs_extlen_t *tree_blocks) |
---|
| 714 | +{ |
---|
560 | 715 | struct xfs_buf *agbp; |
---|
561 | | - struct xfs_btree_cur *cur; |
---|
| 716 | + struct xfs_agi *agi; |
---|
562 | 717 | int error; |
---|
563 | 718 | |
---|
564 | 719 | error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); |
---|
565 | 720 | if (error) |
---|
566 | 721 | return error; |
---|
567 | 722 | |
---|
568 | | - cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum); |
---|
569 | | - error = xfs_btree_count_blocks(cur, tree_blocks); |
---|
570 | | - xfs_btree_del_cursor(cur, error); |
---|
| 723 | + agi = agbp->b_addr; |
---|
| 724 | + *tree_blocks = be32_to_cpu(agi->agi_fblocks); |
---|
571 | 725 | xfs_trans_brelse(tp, agbp); |
---|
572 | | - |
---|
573 | | - return error; |
---|
| 726 | + return 0; |
---|
574 | 727 | } |
---|
575 | 728 | |
---|
576 | 729 | /* |
---|
.. | .. |
---|
590 | 743 | if (!xfs_sb_version_hasfinobt(&mp->m_sb)) |
---|
591 | 744 | return 0; |
---|
592 | 745 | |
---|
593 | | - error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, &tree_len); |
---|
| 746 | + if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) |
---|
| 747 | + error = xfs_finobt_read_blocks(mp, tp, agno, &tree_len); |
---|
| 748 | + else |
---|
| 749 | + error = xfs_inobt_count_blocks(mp, tp, agno, XFS_BTNUM_FINO, |
---|
| 750 | + &tree_len); |
---|
594 | 751 | if (error) |
---|
595 | 752 | return error; |
---|
596 | 753 | |
---|
597 | | - *ask += xfs_inobt_max_size(mp); |
---|
| 754 | + *ask += xfs_inobt_max_size(mp, agno); |
---|
598 | 755 | *used += tree_len; |
---|
599 | 756 | return 0; |
---|
600 | 757 | } |
---|
.. | .. |
---|
605 | 762 | struct xfs_mount *mp, |
---|
606 | 763 | unsigned long long len) |
---|
607 | 764 | { |
---|
608 | | - return xfs_btree_calc_size(mp->m_inobt_mnr, len); |
---|
| 765 | + return xfs_btree_calc_size(M_IGEO(mp)->inobt_mnr, len); |
---|
609 | 766 | } |
---|