1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_inode.h"
15 #include "xfs_trans.h"
16 #include "xfs_alloc.h"
17 #include "xfs_btree.h"
18 #include "xfs_btree_staging.h"
19 #include "xfs_bmap_btree.h"
21 #include "xfs_error.h"
22 #include "xfs_quota.h"
23 #include "xfs_trace.h"
27 static struct kmem_cache
*xfs_bmbt_cur_cache
;
32 struct xfs_btree_block
*buf
,
38 xfs_btree_init_buf(ip
->i_mount
, bp
, &xfs_bmbt_ops
, level
,
41 xfs_btree_init_block(ip
->i_mount
, buf
, &xfs_bmbt_ops
, level
,
46 * Convert on-disk form of btree root to in-memory form.
51 xfs_bmdr_block_t
*dblock
,
53 struct xfs_btree_block
*rblock
,
56 struct xfs_mount
*mp
= ip
->i_mount
;
63 xfs_bmbt_init_block(ip
, rblock
, NULL
, 0, 0);
64 rblock
->bb_level
= dblock
->bb_level
;
65 ASSERT(be16_to_cpu(rblock
->bb_level
) > 0);
66 rblock
->bb_numrecs
= dblock
->bb_numrecs
;
67 dmxr
= xfs_bmdr_maxrecs(dblocklen
, 0);
68 fkp
= xfs_bmdr_key_addr(dblock
, 1);
69 tkp
= xfs_bmbt_key_addr(mp
, rblock
, 1);
70 fpp
= xfs_bmdr_ptr_addr(dblock
, 1, dmxr
);
71 tpp
= xfs_bmap_broot_ptr_addr(mp
, rblock
, 1, rblocklen
);
72 dmxr
= be16_to_cpu(dblock
->bb_numrecs
);
73 memcpy(tkp
, fkp
, sizeof(*fkp
) * dmxr
);
74 memcpy(tpp
, fpp
, sizeof(*fpp
) * dmxr
);
78 xfs_bmbt_disk_get_all(
79 const struct xfs_bmbt_rec
*rec
,
80 struct xfs_bmbt_irec
*irec
)
82 uint64_t l0
= get_unaligned_be64(&rec
->l0
);
83 uint64_t l1
= get_unaligned_be64(&rec
->l1
);
85 irec
->br_startoff
= (l0
& xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN
)) >> 9;
86 irec
->br_startblock
= ((l0
& xfs_mask64lo(9)) << 43) | (l1
>> 21);
87 irec
->br_blockcount
= l1
& xfs_mask64lo(21);
88 if (l0
>> (64 - BMBT_EXNTFLAG_BITLEN
))
89 irec
->br_state
= XFS_EXT_UNWRITTEN
;
91 irec
->br_state
= XFS_EXT_NORM
;
95 * Extract the blockcount field from an on disk bmap extent record.
98 xfs_bmbt_disk_get_blockcount(
99 const struct xfs_bmbt_rec
*r
)
101 return (xfs_filblks_t
)(be64_to_cpu(r
->l1
) & xfs_mask64lo(21));
105 * Extract the startoff field from a disk format bmap extent record.
108 xfs_bmbt_disk_get_startoff(
109 const struct xfs_bmbt_rec
*r
)
111 return ((xfs_fileoff_t
)be64_to_cpu(r
->l0
) &
112 xfs_mask64lo(64 - BMBT_EXNTFLAG_BITLEN
)) >> 9;
116 * Set all the fields in a bmap extent record from the uncompressed form.
119 xfs_bmbt_disk_set_all(
120 struct xfs_bmbt_rec
*r
,
121 struct xfs_bmbt_irec
*s
)
123 int extent_flag
= (s
->br_state
!= XFS_EXT_NORM
);
125 ASSERT(s
->br_state
== XFS_EXT_NORM
|| s
->br_state
== XFS_EXT_UNWRITTEN
);
126 ASSERT(!(s
->br_startoff
& xfs_mask64hi(64-BMBT_STARTOFF_BITLEN
)));
127 ASSERT(!(s
->br_blockcount
& xfs_mask64hi(64-BMBT_BLOCKCOUNT_BITLEN
)));
128 ASSERT(!(s
->br_startblock
& xfs_mask64hi(64-BMBT_STARTBLOCK_BITLEN
)));
131 ((xfs_bmbt_rec_base_t
)extent_flag
<< 63) |
132 ((xfs_bmbt_rec_base_t
)s
->br_startoff
<< 9) |
133 ((xfs_bmbt_rec_base_t
)s
->br_startblock
>> 43), &r
->l0
);
135 ((xfs_bmbt_rec_base_t
)s
->br_startblock
<< 21) |
136 ((xfs_bmbt_rec_base_t
)s
->br_blockcount
&
137 (xfs_bmbt_rec_base_t
)xfs_mask64lo(21)), &r
->l1
);
141 * Convert in-memory form of btree root to on-disk form.
145 struct xfs_mount
*mp
,
146 struct xfs_btree_block
*rblock
,
148 xfs_bmdr_block_t
*dblock
,
157 if (xfs_has_crc(mp
)) {
158 ASSERT(rblock
->bb_magic
== cpu_to_be32(XFS_BMAP_CRC_MAGIC
));
159 ASSERT(uuid_equal(&rblock
->bb_u
.l
.bb_uuid
,
160 &mp
->m_sb
.sb_meta_uuid
));
161 ASSERT(rblock
->bb_u
.l
.bb_blkno
==
162 cpu_to_be64(XFS_BUF_DADDR_NULL
));
164 ASSERT(rblock
->bb_magic
== cpu_to_be32(XFS_BMAP_MAGIC
));
165 ASSERT(rblock
->bb_u
.l
.bb_leftsib
== cpu_to_be64(NULLFSBLOCK
));
166 ASSERT(rblock
->bb_u
.l
.bb_rightsib
== cpu_to_be64(NULLFSBLOCK
));
167 ASSERT(rblock
->bb_level
!= 0);
168 dblock
->bb_level
= rblock
->bb_level
;
169 dblock
->bb_numrecs
= rblock
->bb_numrecs
;
170 dmxr
= xfs_bmdr_maxrecs(dblocklen
, 0);
171 fkp
= xfs_bmbt_key_addr(mp
, rblock
, 1);
172 tkp
= xfs_bmdr_key_addr(dblock
, 1);
173 fpp
= xfs_bmap_broot_ptr_addr(mp
, rblock
, 1, rblocklen
);
174 tpp
= xfs_bmdr_ptr_addr(dblock
, 1, dmxr
);
175 dmxr
= be16_to_cpu(dblock
->bb_numrecs
);
176 memcpy(tkp
, fkp
, sizeof(*fkp
) * dmxr
);
177 memcpy(tpp
, fpp
, sizeof(*fpp
) * dmxr
);
180 STATIC
struct xfs_btree_cur
*
182 struct xfs_btree_cur
*cur
)
184 struct xfs_btree_cur
*new;
186 new = xfs_bmbt_init_cursor(cur
->bc_mp
, cur
->bc_tp
,
187 cur
->bc_ino
.ip
, cur
->bc_ino
.whichfork
);
188 new->bc_flags
|= (cur
->bc_flags
&
189 (XFS_BTREE_BMBT_INVALID_OWNER
| XFS_BTREE_BMBT_WASDEL
));
194 xfs_bmbt_update_cursor(
195 struct xfs_btree_cur
*src
,
196 struct xfs_btree_cur
*dst
)
198 ASSERT((dst
->bc_tp
->t_highest_agno
!= NULLAGNUMBER
) ||
199 (dst
->bc_ino
.ip
->i_diflags
& XFS_DIFLAG_REALTIME
));
201 dst
->bc_bmap
.allocated
+= src
->bc_bmap
.allocated
;
202 dst
->bc_tp
->t_highest_agno
= src
->bc_tp
->t_highest_agno
;
204 src
->bc_bmap
.allocated
= 0;
208 xfs_bmbt_alloc_block(
209 struct xfs_btree_cur
*cur
,
210 const union xfs_btree_ptr
*start
,
211 union xfs_btree_ptr
*new,
214 struct xfs_alloc_arg args
;
217 memset(&args
, 0, sizeof(args
));
218 args
.tp
= cur
->bc_tp
;
219 args
.mp
= cur
->bc_mp
;
220 xfs_rmap_ino_bmbt_owner(&args
.oinfo
, cur
->bc_ino
.ip
->i_ino
,
221 cur
->bc_ino
.whichfork
);
222 args
.minlen
= args
.maxlen
= args
.prod
= 1;
223 args
.wasdel
= cur
->bc_flags
& XFS_BTREE_BMBT_WASDEL
;
224 if (!args
.wasdel
&& args
.tp
->t_blk_res
== 0)
228 * If we are coming here from something like unwritten extent
229 * conversion, there has been no data extent allocation already done, so
230 * we have to ensure that we attempt to locate the entire set of bmbt
231 * allocations in the same AG, as xfs_bmapi_write() would have reserved.
233 if (cur
->bc_tp
->t_highest_agno
== NULLAGNUMBER
)
234 args
.minleft
= xfs_bmapi_minleft(cur
->bc_tp
, cur
->bc_ino
.ip
,
235 cur
->bc_ino
.whichfork
);
237 error
= xfs_alloc_vextent_start_ag(&args
, be64_to_cpu(start
->l
));
241 if (args
.fsbno
== NULLFSBLOCK
&& args
.minleft
) {
243 * Could not find an AG with enough free space to satisfy
244 * a full btree split. Try again and if
245 * successful activate the lowspace algorithm.
248 error
= xfs_alloc_vextent_start_ag(&args
, 0);
251 cur
->bc_tp
->t_flags
|= XFS_TRANS_LOWMODE
;
253 if (WARN_ON_ONCE(args
.fsbno
== NULLFSBLOCK
)) {
258 ASSERT(args
.len
== 1);
259 cur
->bc_bmap
.allocated
++;
260 cur
->bc_ino
.ip
->i_nblocks
++;
261 xfs_trans_log_inode(args
.tp
, cur
->bc_ino
.ip
, XFS_ILOG_CORE
);
262 xfs_trans_mod_dquot_byino(args
.tp
, cur
->bc_ino
.ip
,
263 XFS_TRANS_DQ_BCOUNT
, 1L);
265 new->l
= cpu_to_be64(args
.fsbno
);
273 struct xfs_btree_cur
*cur
,
276 struct xfs_mount
*mp
= cur
->bc_mp
;
277 struct xfs_inode
*ip
= cur
->bc_ino
.ip
;
278 struct xfs_trans
*tp
= cur
->bc_tp
;
279 xfs_fsblock_t fsbno
= XFS_DADDR_TO_FSB(mp
, xfs_buf_daddr(bp
));
280 struct xfs_owner_info oinfo
;
283 xfs_rmap_ino_bmbt_owner(&oinfo
, ip
->i_ino
, cur
->bc_ino
.whichfork
);
284 error
= xfs_free_extent_later(cur
->bc_tp
, fsbno
, 1, &oinfo
,
285 XFS_AG_RESV_NONE
, 0);
290 xfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
291 xfs_trans_mod_dquot_byino(tp
, ip
, XFS_TRANS_DQ_BCOUNT
, -1L);
296 xfs_bmbt_get_minrecs(
297 struct xfs_btree_cur
*cur
,
300 if (level
== cur
->bc_nlevels
- 1) {
301 struct xfs_ifork
*ifp
= xfs_btree_ifork_ptr(cur
);
303 return xfs_bmbt_maxrecs(cur
->bc_mp
,
304 ifp
->if_broot_bytes
, level
== 0) / 2;
307 return cur
->bc_mp
->m_bmap_dmnr
[level
!= 0];
311 xfs_bmbt_get_maxrecs(
312 struct xfs_btree_cur
*cur
,
315 if (level
== cur
->bc_nlevels
- 1) {
316 struct xfs_ifork
*ifp
= xfs_btree_ifork_ptr(cur
);
318 return xfs_bmbt_maxrecs(cur
->bc_mp
,
319 ifp
->if_broot_bytes
, level
== 0);
322 return cur
->bc_mp
->m_bmap_dmxr
[level
!= 0];
327 * Get the maximum records we could store in the on-disk format.
329 * For non-root nodes this is equivalent to xfs_bmbt_get_maxrecs, but
330 * for the root node this checks the available space in the dinode fork
331 * so that we can resize the in-memory buffer to match it. After a
332 * resize to the maximum size this function returns the same value
333 * as xfs_bmbt_get_maxrecs for the root node, too.
336 xfs_bmbt_get_dmaxrecs(
337 struct xfs_btree_cur
*cur
,
340 if (level
!= cur
->bc_nlevels
- 1)
341 return cur
->bc_mp
->m_bmap_dmxr
[level
!= 0];
342 return xfs_bmdr_maxrecs(cur
->bc_ino
.forksize
, level
== 0);
346 xfs_bmbt_init_key_from_rec(
347 union xfs_btree_key
*key
,
348 const union xfs_btree_rec
*rec
)
350 key
->bmbt
.br_startoff
=
351 cpu_to_be64(xfs_bmbt_disk_get_startoff(&rec
->bmbt
));
355 xfs_bmbt_init_high_key_from_rec(
356 union xfs_btree_key
*key
,
357 const union xfs_btree_rec
*rec
)
359 key
->bmbt
.br_startoff
= cpu_to_be64(
360 xfs_bmbt_disk_get_startoff(&rec
->bmbt
) +
361 xfs_bmbt_disk_get_blockcount(&rec
->bmbt
) - 1);
365 xfs_bmbt_init_rec_from_cur(
366 struct xfs_btree_cur
*cur
,
367 union xfs_btree_rec
*rec
)
369 xfs_bmbt_disk_set_all(&rec
->bmbt
, &cur
->bc_rec
.b
);
374 struct xfs_btree_cur
*cur
,
375 const union xfs_btree_key
*key
)
377 return (int64_t)be64_to_cpu(key
->bmbt
.br_startoff
) -
378 cur
->bc_rec
.b
.br_startoff
;
382 xfs_bmbt_diff_two_keys(
383 struct xfs_btree_cur
*cur
,
384 const union xfs_btree_key
*k1
,
385 const union xfs_btree_key
*k2
,
386 const union xfs_btree_key
*mask
)
388 uint64_t a
= be64_to_cpu(k1
->bmbt
.br_startoff
);
389 uint64_t b
= be64_to_cpu(k2
->bmbt
.br_startoff
);
391 ASSERT(!mask
|| mask
->bmbt
.br_startoff
);
394 * Note: This routine previously casted a and b to int64 and subtracted
395 * them to generate a result. This lead to problems if b was the
396 * "maximum" key value (all ones) being signed incorrectly, hence this
397 * somewhat less efficient version.
406 static xfs_failaddr_t
410 struct xfs_mount
*mp
= bp
->b_mount
;
411 struct xfs_btree_block
*block
= XFS_BUF_TO_BLOCK(bp
);
415 if (!xfs_verify_magic(bp
, block
->bb_magic
))
416 return __this_address
;
418 if (xfs_has_crc(mp
)) {
420 * XXX: need a better way of verifying the owner here. Right now
421 * just make sure there has been one set.
423 fa
= xfs_btree_fsblock_v5hdr_verify(bp
, XFS_RMAP_OWN_UNKNOWN
);
429 * numrecs and level verification.
431 * We don't know what fork we belong to, so just verify that the level
432 * is less than the maximum of the two. Later checks will be more
435 level
= be16_to_cpu(block
->bb_level
);
436 if (level
> max(mp
->m_bm_maxlevels
[0], mp
->m_bm_maxlevels
[1]))
437 return __this_address
;
439 return xfs_btree_fsblock_verify(bp
, mp
->m_bmap_dmxr
[level
!= 0]);
443 xfs_bmbt_read_verify(
448 if (!xfs_btree_fsblock_verify_crc(bp
))
449 xfs_verifier_error(bp
, -EFSBADCRC
, __this_address
);
451 fa
= xfs_bmbt_verify(bp
);
453 xfs_verifier_error(bp
, -EFSCORRUPTED
, fa
);
457 trace_xfs_btree_corrupt(bp
, _RET_IP_
);
461 xfs_bmbt_write_verify(
466 fa
= xfs_bmbt_verify(bp
);
468 trace_xfs_btree_corrupt(bp
, _RET_IP_
);
469 xfs_verifier_error(bp
, -EFSCORRUPTED
, fa
);
472 xfs_btree_fsblock_calc_crc(bp
);
475 const struct xfs_buf_ops xfs_bmbt_buf_ops
= {
477 .magic
= { cpu_to_be32(XFS_BMAP_MAGIC
),
478 cpu_to_be32(XFS_BMAP_CRC_MAGIC
) },
479 .verify_read
= xfs_bmbt_read_verify
,
480 .verify_write
= xfs_bmbt_write_verify
,
481 .verify_struct
= xfs_bmbt_verify
,
486 xfs_bmbt_keys_inorder(
487 struct xfs_btree_cur
*cur
,
488 const union xfs_btree_key
*k1
,
489 const union xfs_btree_key
*k2
)
491 return be64_to_cpu(k1
->bmbt
.br_startoff
) <
492 be64_to_cpu(k2
->bmbt
.br_startoff
);
496 xfs_bmbt_recs_inorder(
497 struct xfs_btree_cur
*cur
,
498 const union xfs_btree_rec
*r1
,
499 const union xfs_btree_rec
*r2
)
501 return xfs_bmbt_disk_get_startoff(&r1
->bmbt
) +
502 xfs_bmbt_disk_get_blockcount(&r1
->bmbt
) <=
503 xfs_bmbt_disk_get_startoff(&r2
->bmbt
);
506 STATIC
enum xbtree_key_contig
507 xfs_bmbt_keys_contiguous(
508 struct xfs_btree_cur
*cur
,
509 const union xfs_btree_key
*key1
,
510 const union xfs_btree_key
*key2
,
511 const union xfs_btree_key
*mask
)
513 ASSERT(!mask
|| mask
->bmbt
.br_startoff
);
515 return xbtree_key_contig(be64_to_cpu(key1
->bmbt
.br_startoff
),
516 be64_to_cpu(key2
->bmbt
.br_startoff
));
519 const struct xfs_btree_ops xfs_bmbt_ops
= {
521 .type
= XFS_BTREE_TYPE_INODE
,
523 .rec_len
= sizeof(xfs_bmbt_rec_t
),
524 .key_len
= sizeof(xfs_bmbt_key_t
),
525 .ptr_len
= XFS_BTREE_LONG_PTR_LEN
,
527 .lru_refs
= XFS_BMAP_BTREE_REF
,
528 .statoff
= XFS_STATS_CALC_INDEX(xs_bmbt_2
),
530 .dup_cursor
= xfs_bmbt_dup_cursor
,
531 .update_cursor
= xfs_bmbt_update_cursor
,
532 .alloc_block
= xfs_bmbt_alloc_block
,
533 .free_block
= xfs_bmbt_free_block
,
534 .get_maxrecs
= xfs_bmbt_get_maxrecs
,
535 .get_minrecs
= xfs_bmbt_get_minrecs
,
536 .get_dmaxrecs
= xfs_bmbt_get_dmaxrecs
,
537 .init_key_from_rec
= xfs_bmbt_init_key_from_rec
,
538 .init_high_key_from_rec
= xfs_bmbt_init_high_key_from_rec
,
539 .init_rec_from_cur
= xfs_bmbt_init_rec_from_cur
,
540 .key_diff
= xfs_bmbt_key_diff
,
541 .diff_two_keys
= xfs_bmbt_diff_two_keys
,
542 .buf_ops
= &xfs_bmbt_buf_ops
,
543 .keys_inorder
= xfs_bmbt_keys_inorder
,
544 .recs_inorder
= xfs_bmbt_recs_inorder
,
545 .keys_contiguous
= xfs_bmbt_keys_contiguous
,
549 * Create a new bmap btree cursor.
551 * For staging cursors -1 in passed in whichfork.
553 struct xfs_btree_cur
*
554 xfs_bmbt_init_cursor(
555 struct xfs_mount
*mp
,
556 struct xfs_trans
*tp
,
557 struct xfs_inode
*ip
,
560 struct xfs_btree_cur
*cur
;
561 unsigned int maxlevels
;
563 ASSERT(whichfork
!= XFS_COW_FORK
);
566 * The Data fork always has larger maxlevel, so use that for staging
570 case XFS_STAGING_FORK
:
571 maxlevels
= mp
->m_bm_maxlevels
[XFS_DATA_FORK
];
574 maxlevels
= mp
->m_bm_maxlevels
[whichfork
];
577 cur
= xfs_btree_alloc_cursor(mp
, tp
, &xfs_bmbt_ops
, maxlevels
,
580 cur
->bc_ino
.whichfork
= whichfork
;
581 cur
->bc_bmap
.allocated
= 0;
582 if (whichfork
!= XFS_STAGING_FORK
) {
583 struct xfs_ifork
*ifp
= xfs_ifork_ptr(ip
, whichfork
);
585 cur
->bc_nlevels
= be16_to_cpu(ifp
->if_broot
->bb_level
) + 1;
586 cur
->bc_ino
.forksize
= xfs_inode_fork_size(ip
, whichfork
);
591 /* Calculate number of records in a block mapping btree block. */
592 static inline unsigned int
593 xfs_bmbt_block_maxrecs(
594 unsigned int blocklen
,
598 return blocklen
/ sizeof(xfs_bmbt_rec_t
);
599 return blocklen
/ (sizeof(xfs_bmbt_key_t
) + sizeof(xfs_bmbt_ptr_t
));
603 * Swap in the new inode fork root. Once we pass this point the newly rebuilt
604 * mappings are in place and we have to kill off any old btree blocks.
607 xfs_bmbt_commit_staged_btree(
608 struct xfs_btree_cur
*cur
,
609 struct xfs_trans
*tp
,
612 struct xbtree_ifakeroot
*ifake
= cur
->bc_ino
.ifake
;
613 struct xfs_ifork
*ifp
;
614 static const short brootflag
[2] = {XFS_ILOG_DBROOT
, XFS_ILOG_ABROOT
};
615 static const short extflag
[2] = {XFS_ILOG_DEXT
, XFS_ILOG_AEXT
};
616 int flags
= XFS_ILOG_CORE
;
618 ASSERT(cur
->bc_flags
& XFS_BTREE_STAGING
);
619 ASSERT(whichfork
!= XFS_COW_FORK
);
622 * Free any resources hanging off the real fork, then shallow-copy the
623 * staging fork's contents into the real fork to transfer everything
626 ifp
= xfs_ifork_ptr(cur
->bc_ino
.ip
, whichfork
);
627 xfs_idestroy_fork(ifp
);
628 memcpy(ifp
, ifake
->if_fork
, sizeof(struct xfs_ifork
));
630 switch (ifp
->if_format
) {
631 case XFS_DINODE_FMT_EXTENTS
:
632 flags
|= extflag
[whichfork
];
634 case XFS_DINODE_FMT_BTREE
:
635 flags
|= brootflag
[whichfork
];
641 xfs_trans_log_inode(tp
, cur
->bc_ino
.ip
, flags
);
642 xfs_btree_commit_ifakeroot(cur
, tp
, whichfork
);
646 * Calculate number of records in a bmap btree block.
650 struct xfs_mount
*mp
,
651 unsigned int blocklen
,
654 blocklen
-= xfs_bmbt_block_len(mp
);
655 return xfs_bmbt_block_maxrecs(blocklen
, leaf
);
659 * Calculate the maximum possible height of the btree that the on-disk format
660 * supports. This is used for sizing structures large enough to support every
661 * possible configuration of a filesystem that might get mounted.
664 xfs_bmbt_maxlevels_ondisk(void)
666 unsigned int minrecs
[2];
667 unsigned int blocklen
;
669 blocklen
= min(XFS_MIN_BLOCKSIZE
- XFS_BTREE_SBLOCK_LEN
,
670 XFS_MIN_CRC_BLOCKSIZE
- XFS_BTREE_SBLOCK_CRC_LEN
);
672 minrecs
[0] = xfs_bmbt_block_maxrecs(blocklen
, true) / 2;
673 minrecs
[1] = xfs_bmbt_block_maxrecs(blocklen
, false) / 2;
675 /* One extra level for the inode root. */
676 return xfs_btree_compute_maxlevels(minrecs
,
677 XFS_MAX_EXTCNT_DATA_FORK_LARGE
) + 1;
681 * Calculate number of records in a bmap btree inode root.
688 blocklen
-= sizeof(xfs_bmdr_block_t
);
691 return blocklen
/ sizeof(xfs_bmdr_rec_t
);
692 return blocklen
/ (sizeof(xfs_bmdr_key_t
) + sizeof(xfs_bmdr_ptr_t
));
696 * Change the owner of a btree format fork fo the inode passed in. Change it to
697 * the owner of that is passed in so that we can change owners before or after
698 * we switch forks between inodes. The operation that the caller is doing will
699 * determine whether is needs to change owner before or after the switch.
701 * For demand paged transactional modification, the fork switch should be done
702 * after reading in all the blocks, modifying them and pinning them in the
703 * transaction. For modification when the buffers are already pinned in memory,
704 * the fork switch can be done before changing the owner as we won't need to
705 * validate the owner until the btree buffers are unpinned and writes can occur
708 * For recovery based ownership change, there is no transactional context and
709 * so a buffer list must be supplied so that we can record the buffers that we
710 * modified for the caller to issue IO on.
713 xfs_bmbt_change_owner(
714 struct xfs_trans
*tp
,
715 struct xfs_inode
*ip
,
718 struct list_head
*buffer_list
)
720 struct xfs_btree_cur
*cur
;
723 ASSERT(tp
|| buffer_list
);
724 ASSERT(!(tp
&& buffer_list
));
725 ASSERT(xfs_ifork_ptr(ip
, whichfork
)->if_format
== XFS_DINODE_FMT_BTREE
);
727 cur
= xfs_bmbt_init_cursor(ip
->i_mount
, tp
, ip
, whichfork
);
728 cur
->bc_flags
|= XFS_BTREE_BMBT_INVALID_OWNER
;
730 error
= xfs_btree_change_owner(cur
, new_owner
, buffer_list
);
731 xfs_btree_del_cursor(cur
, error
);
735 /* Calculate the bmap btree size for some records. */
738 struct xfs_mount
*mp
,
739 unsigned long long len
)
741 return xfs_btree_calc_size(mp
->m_bmap_dmnr
, len
);
745 xfs_bmbt_init_cur_cache(void)
747 xfs_bmbt_cur_cache
= kmem_cache_create("xfs_bmbt_cur",
748 xfs_btree_cur_sizeof(xfs_bmbt_maxlevels_ondisk()),
751 if (!xfs_bmbt_cur_cache
)
757 xfs_bmbt_destroy_cur_cache(void)
759 kmem_cache_destroy(xfs_bmbt_cur_cache
);
760 xfs_bmbt_cur_cache
= NULL
;