1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 #ifndef __XFS_BTREE_H__ 7 #define __XFS_BTREE_H__ 8 9 struct xfs_buf; 10 struct xfs_inode; 11 struct xfs_mount; 12 struct xfs_trans; 13 struct xfs_ifork; 14 struct xfs_perag; 15 16 extern kmem_zone_t *xfs_btree_cur_zone; 17 18 /* 19 * Generic key, ptr and record wrapper structures. 20 * 21 * These are disk format structures, and are converted where necessary 22 * by the btree specific code that needs to interpret them. 23 */ 24 union xfs_btree_ptr { 25 __be32 s; /* short form ptr */ 26 __be64 l; /* long form ptr */ 27 }; 28 29 /* 30 * The in-core btree key. Overlapping btrees actually store two keys 31 * per pointer, so we reserve enough memory to hold both. The __*bigkey 32 * items should never be accessed directly. 33 */ 34 union xfs_btree_key { 35 struct xfs_bmbt_key bmbt; 36 xfs_bmdr_key_t bmbr; /* bmbt root block */ 37 xfs_alloc_key_t alloc; 38 struct xfs_inobt_key inobt; 39 struct xfs_rmap_key rmap; 40 struct xfs_rmap_key __rmap_bigkey[2]; 41 struct xfs_refcount_key refc; 42 }; 43 44 union xfs_btree_rec { 45 struct xfs_bmbt_rec bmbt; 46 xfs_bmdr_rec_t bmbr; /* bmbt root block */ 47 struct xfs_alloc_rec alloc; 48 struct xfs_inobt_rec inobt; 49 struct xfs_rmap_rec rmap; 50 struct xfs_refcount_rec refc; 51 }; 52 53 /* 54 * This nonsense is to make -wlint happy. 55 */ 56 #define XFS_LOOKUP_EQ ((xfs_lookup_t)XFS_LOOKUP_EQi) 57 #define XFS_LOOKUP_LE ((xfs_lookup_t)XFS_LOOKUP_LEi) 58 #define XFS_LOOKUP_GE ((xfs_lookup_t)XFS_LOOKUP_GEi) 59 60 #define XFS_BTNUM_BNO ((xfs_btnum_t)XFS_BTNUM_BNOi) 61 #define XFS_BTNUM_CNT ((xfs_btnum_t)XFS_BTNUM_CNTi) 62 #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) 63 #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) 64 #define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi) 65 #define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi) 66 #define XFS_BTNUM_REFC ((xfs_btnum_t)XFS_BTNUM_REFCi) 67 68 uint32_t xfs_btree_magic(int crc, xfs_btnum_t btnum); 69 70 /* 71 * For logging record fields. 72 */ 73 #define XFS_BB_MAGIC (1 << 0) 74 #define XFS_BB_LEVEL (1 << 1) 75 #define XFS_BB_NUMRECS (1 << 2) 76 #define XFS_BB_LEFTSIB (1 << 3) 77 #define XFS_BB_RIGHTSIB (1 << 4) 78 #define XFS_BB_BLKNO (1 << 5) 79 #define XFS_BB_LSN (1 << 6) 80 #define XFS_BB_UUID (1 << 7) 81 #define XFS_BB_OWNER (1 << 8) 82 #define XFS_BB_NUM_BITS 5 83 #define XFS_BB_ALL_BITS ((1 << XFS_BB_NUM_BITS) - 1) 84 #define XFS_BB_NUM_BITS_CRC 9 85 #define XFS_BB_ALL_BITS_CRC ((1 << XFS_BB_NUM_BITS_CRC) - 1) 86 87 /* 88 * Generic stats interface 89 */ 90 #define XFS_BTREE_STATS_INC(cur, stat) \ 91 XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat) 92 #define XFS_BTREE_STATS_ADD(cur, stat, val) \ 93 XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val) 94 95 /* 96 * The btree cursor zone hands out cursors that can handle up to this many 97 * levels. This is the known maximum for all btree types. 98 */ 99 #define XFS_BTREE_CUR_CACHE_MAXLEVELS (9) 100 101 struct xfs_btree_ops { 102 /* size of the key and record structures */ 103 size_t key_len; 104 size_t rec_len; 105 106 /* cursor operations */ 107 struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); 108 void (*update_cursor)(struct xfs_btree_cur *src, 109 struct xfs_btree_cur *dst); 110 111 /* update btree root pointer */ 112 void (*set_root)(struct xfs_btree_cur *cur, 113 const union xfs_btree_ptr *nptr, int level_change); 114 115 /* block allocation / freeing */ 116 int (*alloc_block)(struct xfs_btree_cur *cur, 117 const union xfs_btree_ptr *start_bno, 118 union xfs_btree_ptr *new_bno, 119 int *stat); 120 int (*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp); 121 122 /* update last record information */ 123 void (*update_lastrec)(struct xfs_btree_cur *cur, 124 const struct xfs_btree_block *block, 125 const union xfs_btree_rec *rec, 126 int ptr, int reason); 127 128 /* records in block/level */ 129 int (*get_minrecs)(struct xfs_btree_cur *cur, int level); 130 int (*get_maxrecs)(struct xfs_btree_cur *cur, int level); 131 132 /* records on disk. Matter for the root in inode case. */ 133 int (*get_dmaxrecs)(struct xfs_btree_cur *cur, int level); 134 135 /* init values of btree structures */ 136 void (*init_key_from_rec)(union xfs_btree_key *key, 137 const union xfs_btree_rec *rec); 138 void (*init_rec_from_cur)(struct xfs_btree_cur *cur, 139 union xfs_btree_rec *rec); 140 void (*init_ptr_from_cur)(struct xfs_btree_cur *cur, 141 union xfs_btree_ptr *ptr); 142 void (*init_high_key_from_rec)(union xfs_btree_key *key, 143 const union xfs_btree_rec *rec); 144 145 /* difference between key value and cursor value */ 146 int64_t (*key_diff)(struct xfs_btree_cur *cur, 147 const union xfs_btree_key *key); 148 149 /* 150 * Difference between key2 and key1 -- positive if key1 > key2, 151 * negative if key1 < key2, and zero if equal. 152 */ 153 int64_t (*diff_two_keys)(struct xfs_btree_cur *cur, 154 const union xfs_btree_key *key1, 155 const union xfs_btree_key *key2); 156 157 const struct xfs_buf_ops *buf_ops; 158 159 /* check that k1 is lower than k2 */ 160 int (*keys_inorder)(struct xfs_btree_cur *cur, 161 const union xfs_btree_key *k1, 162 const union xfs_btree_key *k2); 163 164 /* check that r1 is lower than r2 */ 165 int (*recs_inorder)(struct xfs_btree_cur *cur, 166 const union xfs_btree_rec *r1, 167 const union xfs_btree_rec *r2); 168 }; 169 170 /* 171 * Reasons for the update_lastrec method to be called. 172 */ 173 #define LASTREC_UPDATE 0 174 #define LASTREC_INSREC 1 175 #define LASTREC_DELREC 2 176 177 178 union xfs_btree_irec { 179 struct xfs_alloc_rec_incore a; 180 struct xfs_bmbt_irec b; 181 struct xfs_inobt_rec_incore i; 182 struct xfs_rmap_irec r; 183 struct xfs_refcount_irec rc; 184 }; 185 186 /* Per-AG btree information. */ 187 struct xfs_btree_cur_ag { 188 struct xfs_perag *pag; 189 union { 190 struct xfs_buf *agbp; 191 struct xbtree_afakeroot *afake; /* for staging cursor */ 192 }; 193 union { 194 struct { 195 unsigned int nr_ops; /* # record updates */ 196 unsigned int shape_changes; /* # of extent splits */ 197 } refc; 198 struct { 199 bool active; /* allocation cursor state */ 200 } abt; 201 }; 202 }; 203 204 /* Btree-in-inode cursor information */ 205 struct xfs_btree_cur_ino { 206 struct xfs_inode *ip; 207 struct xbtree_ifakeroot *ifake; /* for staging cursor */ 208 int allocated; 209 short forksize; 210 char whichfork; 211 char flags; 212 /* We are converting a delalloc reservation */ 213 #define XFS_BTCUR_BMBT_WASDEL (1 << 0) 214 215 /* For extent swap, ignore owner check in verifier */ 216 #define XFS_BTCUR_BMBT_INVALID_OWNER (1 << 1) 217 }; 218 219 struct xfs_btree_level { 220 /* buffer pointer */ 221 struct xfs_buf *bp; 222 223 /* key/record number */ 224 uint16_t ptr; 225 226 /* readahead info */ 227 #define XFS_BTCUR_LEFTRA (1 << 0) /* left sibling has been read-ahead */ 228 #define XFS_BTCUR_RIGHTRA (1 << 1) /* right sibling has been read-ahead */ 229 uint16_t ra; 230 }; 231 232 /* 233 * Btree cursor structure. 234 * This collects all information needed by the btree code in one place. 235 */ 236 struct xfs_btree_cur 237 { 238 struct xfs_trans *bc_tp; /* transaction we're in, if any */ 239 struct xfs_mount *bc_mp; /* file system mount struct */ 240 const struct xfs_btree_ops *bc_ops; 241 unsigned int bc_flags; /* btree features - below */ 242 xfs_btnum_t bc_btnum; /* identifies which btree type */ 243 union xfs_btree_irec bc_rec; /* current insert/search record value */ 244 uint8_t bc_nlevels; /* number of levels in the tree */ 245 uint8_t bc_maxlevels; /* maximum levels for this btree type */ 246 int bc_statoff; /* offset of btree stats array */ 247 248 /* 249 * Short btree pointers need an agno to be able to turn the pointers 250 * into physical addresses for IO, so the btree cursor switches between 251 * bc_ino and bc_ag based on whether XFS_BTREE_LONG_PTRS is set for the 252 * cursor. 253 */ 254 union { 255 struct xfs_btree_cur_ag bc_ag; 256 struct xfs_btree_cur_ino bc_ino; 257 }; 258 259 /* Must be at the end of the struct! */ 260 struct xfs_btree_level bc_levels[]; 261 }; 262 263 /* 264 * Compute the size of a btree cursor that can handle a btree of a given 265 * height. The bc_levels array handles node and leaf blocks, so its size 266 * is exactly nlevels. 267 */ 268 static inline size_t 269 xfs_btree_cur_sizeof(unsigned int nlevels) 270 { 271 return struct_size((struct xfs_btree_cur *)NULL, bc_levels, nlevels); 272 } 273 274 /* cursor flags */ 275 #define XFS_BTREE_LONG_PTRS (1<<0) /* pointers are 64bits long */ 276 #define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */ 277 #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ 278 #define XFS_BTREE_CRC_BLOCKS (1<<3) /* uses extended btree blocks */ 279 #define XFS_BTREE_OVERLAPPING (1<<4) /* overlapping intervals */ 280 /* 281 * The root of this btree is a fakeroot structure so that we can stage a btree 282 * rebuild without leaving it accessible via primary metadata. The ops struct 283 * is dynamically allocated and must be freed when the cursor is deleted. 284 */ 285 #define XFS_BTREE_STAGING (1<<5) 286 287 #define XFS_BTREE_NOERROR 0 288 #define XFS_BTREE_ERROR 1 289 290 /* 291 * Convert from buffer to btree block header. 292 */ 293 #define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr)) 294 295 /* 296 * Internal long and short btree block checks. They return NULL if the 297 * block is ok or the address of the failed check otherwise. 298 */ 299 xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur, 300 struct xfs_btree_block *block, int level, struct xfs_buf *bp); 301 xfs_failaddr_t __xfs_btree_check_sblock(struct xfs_btree_cur *cur, 302 struct xfs_btree_block *block, int level, struct xfs_buf *bp); 303 304 /* 305 * Check that block header is ok. 306 */ 307 int 308 xfs_btree_check_block( 309 struct xfs_btree_cur *cur, /* btree cursor */ 310 struct xfs_btree_block *block, /* generic btree block pointer */ 311 int level, /* level of the btree block */ 312 struct xfs_buf *bp); /* buffer containing block, if any */ 313 314 /* 315 * Check that (long) pointer is ok. 316 */ 317 bool /* error (0 or EFSCORRUPTED) */ 318 xfs_btree_check_lptr( 319 struct xfs_btree_cur *cur, /* btree cursor */ 320 xfs_fsblock_t fsbno, /* btree block disk address */ 321 int level); /* btree block level */ 322 323 /* 324 * Check that (short) pointer is ok. 325 */ 326 bool /* error (0 or EFSCORRUPTED) */ 327 xfs_btree_check_sptr( 328 struct xfs_btree_cur *cur, /* btree cursor */ 329 xfs_agblock_t agbno, /* btree block disk address */ 330 int level); /* btree block level */ 331 332 /* 333 * Delete the btree cursor. 334 */ 335 void 336 xfs_btree_del_cursor( 337 struct xfs_btree_cur *cur, /* btree cursor */ 338 int error); /* del because of error */ 339 340 /* 341 * Duplicate the btree cursor. 342 * Allocate a new one, copy the record, re-get the buffers. 343 */ 344 int /* error */ 345 xfs_btree_dup_cursor( 346 struct xfs_btree_cur *cur, /* input cursor */ 347 struct xfs_btree_cur **ncur);/* output cursor */ 348 349 /* 350 * Compute first and last byte offsets for the fields given. 351 * Interprets the offsets table, which contains struct field offsets. 352 */ 353 void 354 xfs_btree_offsets( 355 int64_t fields, /* bitmask of fields */ 356 const short *offsets,/* table of field offsets */ 357 int nbits, /* number of bits to inspect */ 358 int *first, /* output: first byte offset */ 359 int *last); /* output: last byte offset */ 360 361 /* 362 * Get a buffer for the block, return it read in. 363 * Long-form addressing. 364 */ 365 int /* error */ 366 xfs_btree_read_bufl( 367 struct xfs_mount *mp, /* file system mount point */ 368 struct xfs_trans *tp, /* transaction pointer */ 369 xfs_fsblock_t fsbno, /* file system block number */ 370 struct xfs_buf **bpp, /* buffer for fsbno */ 371 int refval, /* ref count value for buffer */ 372 const struct xfs_buf_ops *ops); 373 374 /* 375 * Read-ahead the block, don't wait for it, don't return a buffer. 376 * Long-form addressing. 377 */ 378 void /* error */ 379 xfs_btree_reada_bufl( 380 struct xfs_mount *mp, /* file system mount point */ 381 xfs_fsblock_t fsbno, /* file system block number */ 382 xfs_extlen_t count, /* count of filesystem blocks */ 383 const struct xfs_buf_ops *ops); 384 385 /* 386 * Read-ahead the block, don't wait for it, don't return a buffer. 387 * Short-form addressing. 388 */ 389 void /* error */ 390 xfs_btree_reada_bufs( 391 struct xfs_mount *mp, /* file system mount point */ 392 xfs_agnumber_t agno, /* allocation group number */ 393 xfs_agblock_t agbno, /* allocation group block number */ 394 xfs_extlen_t count, /* count of filesystem blocks */ 395 const struct xfs_buf_ops *ops); 396 397 /* 398 * Initialise a new btree block header 399 */ 400 void 401 xfs_btree_init_block( 402 struct xfs_mount *mp, 403 struct xfs_buf *bp, 404 xfs_btnum_t btnum, 405 __u16 level, 406 __u16 numrecs, 407 __u64 owner); 408 409 void 410 xfs_btree_init_block_int( 411 struct xfs_mount *mp, 412 struct xfs_btree_block *buf, 413 xfs_daddr_t blkno, 414 xfs_btnum_t btnum, 415 __u16 level, 416 __u16 numrecs, 417 __u64 owner, 418 unsigned int flags); 419 420 /* 421 * Common btree core entry points. 422 */ 423 int xfs_btree_increment(struct xfs_btree_cur *, int, int *); 424 int xfs_btree_decrement(struct xfs_btree_cur *, int, int *); 425 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *); 426 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *); 427 int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *); 428 int xfs_btree_insert(struct xfs_btree_cur *, int *); 429 int xfs_btree_delete(struct xfs_btree_cur *, int *); 430 int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *); 431 int xfs_btree_change_owner(struct xfs_btree_cur *cur, uint64_t new_owner, 432 struct list_head *buffer_list); 433 434 /* 435 * btree block CRC helpers 436 */ 437 void xfs_btree_lblock_calc_crc(struct xfs_buf *); 438 bool xfs_btree_lblock_verify_crc(struct xfs_buf *); 439 void xfs_btree_sblock_calc_crc(struct xfs_buf *); 440 bool xfs_btree_sblock_verify_crc(struct xfs_buf *); 441 442 /* 443 * Internal btree helpers also used by xfs_bmap.c. 444 */ 445 void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int); 446 void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int); 447 448 /* 449 * Helpers. 450 */ 451 static inline int xfs_btree_get_numrecs(const struct xfs_btree_block *block) 452 { 453 return be16_to_cpu(block->bb_numrecs); 454 } 455 456 static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block, 457 uint16_t numrecs) 458 { 459 block->bb_numrecs = cpu_to_be16(numrecs); 460 } 461 462 static inline int xfs_btree_get_level(const struct xfs_btree_block *block) 463 { 464 return be16_to_cpu(block->bb_level); 465 } 466 467 468 /* 469 * Min and max functions for extlen, agblock, fileoff, and filblks types. 470 */ 471 #define XFS_EXTLEN_MIN(a,b) min_t(xfs_extlen_t, (a), (b)) 472 #define XFS_EXTLEN_MAX(a,b) max_t(xfs_extlen_t, (a), (b)) 473 #define XFS_AGBLOCK_MIN(a,b) min_t(xfs_agblock_t, (a), (b)) 474 #define XFS_AGBLOCK_MAX(a,b) max_t(xfs_agblock_t, (a), (b)) 475 #define XFS_FILEOFF_MIN(a,b) min_t(xfs_fileoff_t, (a), (b)) 476 #define XFS_FILEOFF_MAX(a,b) max_t(xfs_fileoff_t, (a), (b)) 477 #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) 478 #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) 479 480 xfs_failaddr_t xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp); 481 xfs_failaddr_t xfs_btree_sblock_verify(struct xfs_buf *bp, 482 unsigned int max_recs); 483 xfs_failaddr_t xfs_btree_lblock_v5hdr_verify(struct xfs_buf *bp, 484 uint64_t owner); 485 xfs_failaddr_t xfs_btree_lblock_verify(struct xfs_buf *bp, 486 unsigned int max_recs); 487 488 unsigned int xfs_btree_compute_maxlevels(const unsigned int *limits, 489 unsigned long long records); 490 unsigned long long xfs_btree_calc_size(const unsigned int *limits, 491 unsigned long long records); 492 unsigned int xfs_btree_space_to_height(const unsigned int *limits, 493 unsigned long long blocks); 494 495 /* 496 * Return codes for the query range iterator function are 0 to continue 497 * iterating, and non-zero to stop iterating. Any non-zero value will be 498 * passed up to the _query_range caller. The special value -ECANCELED can be 499 * used to stop iteration, because _query_range never generates that error 500 * code on its own. 501 */ 502 typedef int (*xfs_btree_query_range_fn)(struct xfs_btree_cur *cur, 503 const union xfs_btree_rec *rec, void *priv); 504 505 int xfs_btree_query_range(struct xfs_btree_cur *cur, 506 const union xfs_btree_irec *low_rec, 507 const union xfs_btree_irec *high_rec, 508 xfs_btree_query_range_fn fn, void *priv); 509 int xfs_btree_query_all(struct xfs_btree_cur *cur, xfs_btree_query_range_fn fn, 510 void *priv); 511 512 typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level, 513 void *data); 514 /* Visit record blocks. */ 515 #define XFS_BTREE_VISIT_RECORDS (1 << 0) 516 /* Visit leaf blocks. */ 517 #define XFS_BTREE_VISIT_LEAVES (1 << 1) 518 /* Visit all blocks. */ 519 #define XFS_BTREE_VISIT_ALL (XFS_BTREE_VISIT_RECORDS | \ 520 XFS_BTREE_VISIT_LEAVES) 521 int xfs_btree_visit_blocks(struct xfs_btree_cur *cur, 522 xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data); 523 524 int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks); 525 526 union xfs_btree_rec *xfs_btree_rec_addr(struct xfs_btree_cur *cur, int n, 527 struct xfs_btree_block *block); 528 union xfs_btree_key *xfs_btree_key_addr(struct xfs_btree_cur *cur, int n, 529 struct xfs_btree_block *block); 530 union xfs_btree_key *xfs_btree_high_key_addr(struct xfs_btree_cur *cur, int n, 531 struct xfs_btree_block *block); 532 union xfs_btree_ptr *xfs_btree_ptr_addr(struct xfs_btree_cur *cur, int n, 533 struct xfs_btree_block *block); 534 int xfs_btree_lookup_get_block(struct xfs_btree_cur *cur, int level, 535 const union xfs_btree_ptr *pp, struct xfs_btree_block **blkp); 536 struct xfs_btree_block *xfs_btree_get_block(struct xfs_btree_cur *cur, 537 int level, struct xfs_buf **bpp); 538 bool xfs_btree_ptr_is_null(struct xfs_btree_cur *cur, 539 const union xfs_btree_ptr *ptr); 540 int64_t xfs_btree_diff_two_ptrs(struct xfs_btree_cur *cur, 541 const union xfs_btree_ptr *a, 542 const union xfs_btree_ptr *b); 543 void xfs_btree_get_sibling(struct xfs_btree_cur *cur, 544 struct xfs_btree_block *block, 545 union xfs_btree_ptr *ptr, int lr); 546 void xfs_btree_get_keys(struct xfs_btree_cur *cur, 547 struct xfs_btree_block *block, union xfs_btree_key *key); 548 union xfs_btree_key *xfs_btree_high_key_from_key(struct xfs_btree_cur *cur, 549 union xfs_btree_key *key); 550 int xfs_btree_has_record(struct xfs_btree_cur *cur, 551 const union xfs_btree_irec *low, 552 const union xfs_btree_irec *high, bool *exists); 553 bool xfs_btree_has_more_records(struct xfs_btree_cur *cur); 554 struct xfs_ifork *xfs_btree_ifork_ptr(struct xfs_btree_cur *cur); 555 556 /* Does this cursor point to the last block in the given level? */ 557 static inline bool 558 xfs_btree_islastblock( 559 struct xfs_btree_cur *cur, 560 int level) 561 { 562 struct xfs_btree_block *block; 563 struct xfs_buf *bp; 564 565 block = xfs_btree_get_block(cur, level, &bp); 566 ASSERT(block && xfs_btree_check_block(cur, block, level, bp) == 0); 567 568 if (cur->bc_flags & XFS_BTREE_LONG_PTRS) 569 return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); 570 return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); 571 } 572 573 void xfs_btree_set_ptr_null(struct xfs_btree_cur *cur, 574 union xfs_btree_ptr *ptr); 575 int xfs_btree_get_buf_block(struct xfs_btree_cur *cur, 576 const union xfs_btree_ptr *ptr, struct xfs_btree_block **block, 577 struct xfs_buf **bpp); 578 void xfs_btree_set_sibling(struct xfs_btree_cur *cur, 579 struct xfs_btree_block *block, const union xfs_btree_ptr *ptr, 580 int lr); 581 void xfs_btree_init_block_cur(struct xfs_btree_cur *cur, 582 struct xfs_buf *bp, int level, int numrecs); 583 void xfs_btree_copy_ptrs(struct xfs_btree_cur *cur, 584 union xfs_btree_ptr *dst_ptr, 585 const union xfs_btree_ptr *src_ptr, int numptrs); 586 void xfs_btree_copy_keys(struct xfs_btree_cur *cur, 587 union xfs_btree_key *dst_key, 588 const union xfs_btree_key *src_key, int numkeys); 589 590 static inline struct xfs_btree_cur * 591 xfs_btree_alloc_cursor( 592 struct xfs_mount *mp, 593 struct xfs_trans *tp, 594 xfs_btnum_t btnum, 595 uint8_t maxlevels) 596 { 597 struct xfs_btree_cur *cur; 598 599 ASSERT(maxlevels <= XFS_BTREE_CUR_CACHE_MAXLEVELS); 600 601 cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); 602 cur->bc_tp = tp; 603 cur->bc_mp = mp; 604 cur->bc_btnum = btnum; 605 cur->bc_maxlevels = maxlevels; 606 607 return cur; 608 } 609 610 #endif /* __XFS_BTREE_H__ */ 611