| .. | .. |
|---|
| 1 | | -// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. |
|---|
| 4 | 4 | * All Rights Reserved. |
|---|
| .. | .. |
|---|
| 10 | 10 | struct xfs_inode; |
|---|
| 11 | 11 | struct xfs_mount; |
|---|
| 12 | 12 | struct xfs_trans; |
|---|
| 13 | +struct xfs_ifork; |
|---|
| 13 | 14 | |
|---|
| 14 | 15 | extern kmem_zone_t *xfs_btree_cur_zone; |
|---|
| 15 | 16 | |
|---|
| .. | .. |
|---|
| 177 | 178 | struct xfs_refcount_irec rc; |
|---|
| 178 | 179 | }; |
|---|
| 179 | 180 | |
|---|
| 180 | | -/* Per-AG btree private information. */ |
|---|
| 181 | | -union xfs_btree_cur_private { |
|---|
| 182 | | - struct { |
|---|
| 183 | | - unsigned long nr_ops; /* # record updates */ |
|---|
| 184 | | - int shape_changes; /* # of extent splits */ |
|---|
| 185 | | - } refc; |
|---|
| 181 | +/* Per-AG btree information. */ |
|---|
| 182 | +struct xfs_btree_cur_ag { |
|---|
| 183 | + union { |
|---|
| 184 | + struct xfs_buf *agbp; |
|---|
| 185 | + struct xbtree_afakeroot *afake; /* for staging cursor */ |
|---|
| 186 | + }; |
|---|
| 187 | + xfs_agnumber_t agno; |
|---|
| 188 | + union { |
|---|
| 189 | + struct { |
|---|
| 190 | + unsigned long nr_ops; /* # record updates */ |
|---|
| 191 | + int shape_changes; /* # of extent splits */ |
|---|
| 192 | + } refc; |
|---|
| 193 | + struct { |
|---|
| 194 | + bool active; /* allocation cursor state */ |
|---|
| 195 | + } abt; |
|---|
| 196 | + }; |
|---|
| 197 | +}; |
|---|
| 198 | + |
|---|
| 199 | +/* Btree-in-inode cursor information */ |
|---|
| 200 | +struct xfs_btree_cur_ino { |
|---|
| 201 | + struct xfs_inode *ip; |
|---|
| 202 | + struct xbtree_ifakeroot *ifake; /* for staging cursor */ |
|---|
| 203 | + int allocated; |
|---|
| 204 | + short forksize; |
|---|
| 205 | + char whichfork; |
|---|
| 206 | + char flags; |
|---|
| 207 | +/* We are converting a delalloc reservation */ |
|---|
| 208 | +#define XFS_BTCUR_BMBT_WASDEL (1 << 0) |
|---|
| 209 | + |
|---|
| 210 | +/* For extent swap, ignore owner check in verifier */ |
|---|
| 211 | +#define XFS_BTCUR_BMBT_INVALID_OWNER (1 << 1) |
|---|
| 186 | 212 | }; |
|---|
| 187 | 213 | |
|---|
| 188 | 214 | /* |
|---|
| .. | .. |
|---|
| 206 | 232 | xfs_btnum_t bc_btnum; /* identifies which btree type */ |
|---|
| 207 | 233 | int bc_statoff; /* offset of btre stats array */ |
|---|
| 208 | 234 | union { |
|---|
| 209 | | - struct { /* needed for BNO, CNT, INO */ |
|---|
| 210 | | - struct xfs_buf *agbp; /* agf/agi buffer pointer */ |
|---|
| 211 | | - xfs_agnumber_t agno; /* ag number */ |
|---|
| 212 | | - union xfs_btree_cur_private priv; |
|---|
| 213 | | - } a; |
|---|
| 214 | | - struct { /* needed for BMAP */ |
|---|
| 215 | | - struct xfs_inode *ip; /* pointer to our inode */ |
|---|
| 216 | | - int allocated; /* count of alloced */ |
|---|
| 217 | | - short forksize; /* fork's inode space */ |
|---|
| 218 | | - char whichfork; /* data or attr fork */ |
|---|
| 219 | | - char flags; /* flags */ |
|---|
| 220 | | -#define XFS_BTCUR_BPRV_WASDEL (1<<0) /* was delayed */ |
|---|
| 221 | | -#define XFS_BTCUR_BPRV_INVALID_OWNER (1<<1) /* for ext swap */ |
|---|
| 222 | | - } b; |
|---|
| 223 | | - } bc_private; /* per-btree type data */ |
|---|
| 235 | + struct xfs_btree_cur_ag bc_ag; |
|---|
| 236 | + struct xfs_btree_cur_ino bc_ino; |
|---|
| 237 | + }; |
|---|
| 224 | 238 | } xfs_btree_cur_t; |
|---|
| 225 | 239 | |
|---|
| 226 | 240 | /* cursor flags */ |
|---|
| .. | .. |
|---|
| 229 | 243 | #define XFS_BTREE_LASTREC_UPDATE (1<<2) /* track last rec externally */ |
|---|
| 230 | 244 | #define XFS_BTREE_CRC_BLOCKS (1<<3) /* uses extended btree blocks */ |
|---|
| 231 | 245 | #define XFS_BTREE_OVERLAPPING (1<<4) /* overlapping intervals */ |
|---|
| 246 | +/* |
|---|
| 247 | + * The root of this btree is a fakeroot structure so that we can stage a btree |
|---|
| 248 | + * rebuild without leaving it accessible via primary metadata. The ops struct |
|---|
| 249 | + * is dynamically allocated and must be freed when the cursor is deleted. |
|---|
| 250 | + */ |
|---|
| 251 | +#define XFS_BTREE_STAGING (1<<5) |
|---|
| 232 | 252 | |
|---|
| 233 | 253 | |
|---|
| 234 | 254 | #define XFS_BTREE_NOERROR 0 |
|---|
| .. | .. |
|---|
| 294 | 314 | xfs_btree_cur_t **ncur);/* output cursor */ |
|---|
| 295 | 315 | |
|---|
| 296 | 316 | /* |
|---|
| 297 | | - * Get a buffer for the block, return it with no data read. |
|---|
| 298 | | - * Long-form addressing. |
|---|
| 299 | | - */ |
|---|
| 300 | | -struct xfs_buf * /* buffer for fsbno */ |
|---|
| 301 | | -xfs_btree_get_bufl( |
|---|
| 302 | | - struct xfs_mount *mp, /* file system mount point */ |
|---|
| 303 | | - struct xfs_trans *tp, /* transaction pointer */ |
|---|
| 304 | | - xfs_fsblock_t fsbno, /* file system block number */ |
|---|
| 305 | | - uint lock); /* lock flags for get_buf */ |
|---|
| 306 | | - |
|---|
| 307 | | -/* |
|---|
| 308 | | - * Get a buffer for the block, return it with no data read. |
|---|
| 309 | | - * Short-form addressing. |
|---|
| 310 | | - */ |
|---|
| 311 | | -struct xfs_buf * /* buffer for agno/agbno */ |
|---|
| 312 | | -xfs_btree_get_bufs( |
|---|
| 313 | | - struct xfs_mount *mp, /* file system mount point */ |
|---|
| 314 | | - struct xfs_trans *tp, /* transaction pointer */ |
|---|
| 315 | | - xfs_agnumber_t agno, /* allocation group number */ |
|---|
| 316 | | - xfs_agblock_t agbno, /* allocation group block number */ |
|---|
| 317 | | - uint lock); /* lock flags for get_buf */ |
|---|
| 318 | | - |
|---|
| 319 | | -/* |
|---|
| 320 | | - * Check for the cursor referring to the last block at the given level. |
|---|
| 321 | | - */ |
|---|
| 322 | | -int /* 1=is last block, 0=not last block */ |
|---|
| 323 | | -xfs_btree_islastblock( |
|---|
| 324 | | - xfs_btree_cur_t *cur, /* btree cursor */ |
|---|
| 325 | | - int level); /* level to check */ |
|---|
| 326 | | - |
|---|
| 327 | | -/* |
|---|
| 328 | 317 | * Compute first and last byte offsets for the fields given. |
|---|
| 329 | 318 | * Interprets the offsets table, which contains struct field offsets. |
|---|
| 330 | 319 | */ |
|---|
| .. | .. |
|---|
| 345 | 334 | struct xfs_mount *mp, /* file system mount point */ |
|---|
| 346 | 335 | struct xfs_trans *tp, /* transaction pointer */ |
|---|
| 347 | 336 | xfs_fsblock_t fsbno, /* file system block number */ |
|---|
| 348 | | - uint lock, /* lock flags for read_buf */ |
|---|
| 349 | 337 | struct xfs_buf **bpp, /* buffer for fsbno */ |
|---|
| 350 | 338 | int refval, /* ref count value for buffer */ |
|---|
| 351 | 339 | const struct xfs_buf_ops *ops); |
|---|
| .. | .. |
|---|
| 383 | 371 | xfs_btnum_t btnum, |
|---|
| 384 | 372 | __u16 level, |
|---|
| 385 | 373 | __u16 numrecs, |
|---|
| 386 | | - __u64 owner, |
|---|
| 387 | | - unsigned int flags); |
|---|
| 374 | + __u64 owner); |
|---|
| 388 | 375 | |
|---|
| 389 | 376 | void |
|---|
| 390 | 377 | xfs_btree_init_block_int( |
|---|
| .. | .. |
|---|
| 468 | 455 | uint xfs_btree_compute_maxlevels(uint *limits, unsigned long len); |
|---|
| 469 | 456 | unsigned long long xfs_btree_calc_size(uint *limits, unsigned long long len); |
|---|
| 470 | 457 | |
|---|
| 471 | | -/* return codes */ |
|---|
| 472 | | -#define XFS_BTREE_QUERY_RANGE_CONTINUE 0 /* keep iterating */ |
|---|
| 473 | | -#define XFS_BTREE_QUERY_RANGE_ABORT 1 /* stop iterating */ |
|---|
| 458 | +/* |
|---|
| 459 | + * Return codes for the query range iterator function are 0 to continue |
|---|
| 460 | + * iterating, and non-zero to stop iterating. Any non-zero value will be |
|---|
| 461 | + * passed up to the _query_range caller. The special value -ECANCELED can be |
|---|
| 462 | + * used to stop iteration, because _query_range never generates that error |
|---|
| 463 | + * code on its own. |
|---|
| 464 | + */ |
|---|
| 474 | 465 | typedef int (*xfs_btree_query_range_fn)(struct xfs_btree_cur *cur, |
|---|
| 475 | 466 | union xfs_btree_rec *rec, void *priv); |
|---|
| 476 | 467 | |
|---|
| .. | .. |
|---|
| 482 | 473 | |
|---|
| 483 | 474 | typedef int (*xfs_btree_visit_blocks_fn)(struct xfs_btree_cur *cur, int level, |
|---|
| 484 | 475 | void *data); |
|---|
| 476 | +/* Visit record blocks. */ |
|---|
| 477 | +#define XFS_BTREE_VISIT_RECORDS (1 << 0) |
|---|
| 478 | +/* Visit leaf blocks. */ |
|---|
| 479 | +#define XFS_BTREE_VISIT_LEAVES (1 << 1) |
|---|
| 480 | +/* Visit all blocks. */ |
|---|
| 481 | +#define XFS_BTREE_VISIT_ALL (XFS_BTREE_VISIT_RECORDS | \ |
|---|
| 482 | + XFS_BTREE_VISIT_LEAVES) |
|---|
| 485 | 483 | int xfs_btree_visit_blocks(struct xfs_btree_cur *cur, |
|---|
| 486 | | - xfs_btree_visit_blocks_fn fn, void *data); |
|---|
| 484 | + xfs_btree_visit_blocks_fn fn, unsigned int flags, void *data); |
|---|
| 487 | 485 | |
|---|
| 488 | 486 | int xfs_btree_count_blocks(struct xfs_btree_cur *cur, xfs_extlen_t *blocks); |
|---|
| 489 | 487 | |
|---|
| .. | .. |
|---|
| 513 | 511 | int xfs_btree_has_record(struct xfs_btree_cur *cur, union xfs_btree_irec *low, |
|---|
| 514 | 512 | union xfs_btree_irec *high, bool *exists); |
|---|
| 515 | 513 | bool xfs_btree_has_more_records(struct xfs_btree_cur *cur); |
|---|
| 514 | +struct xfs_ifork *xfs_btree_ifork_ptr(struct xfs_btree_cur *cur); |
|---|
| 515 | + |
|---|
| 516 | +/* Does this cursor point to the last block in the given level? */ |
|---|
| 517 | +static inline bool |
|---|
| 518 | +xfs_btree_islastblock( |
|---|
| 519 | + xfs_btree_cur_t *cur, |
|---|
| 520 | + int level) |
|---|
| 521 | +{ |
|---|
| 522 | + struct xfs_btree_block *block; |
|---|
| 523 | + struct xfs_buf *bp; |
|---|
| 524 | + |
|---|
| 525 | + block = xfs_btree_get_block(cur, level, &bp); |
|---|
| 526 | + ASSERT(block && xfs_btree_check_block(cur, block, level, bp) == 0); |
|---|
| 527 | + |
|---|
| 528 | + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) |
|---|
| 529 | + return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); |
|---|
| 530 | + return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); |
|---|
| 531 | +} |
|---|
| 532 | + |
|---|
| 533 | +void xfs_btree_set_ptr_null(struct xfs_btree_cur *cur, |
|---|
| 534 | + union xfs_btree_ptr *ptr); |
|---|
| 535 | +int xfs_btree_get_buf_block(struct xfs_btree_cur *cur, union xfs_btree_ptr *ptr, |
|---|
| 536 | + struct xfs_btree_block **block, struct xfs_buf **bpp); |
|---|
| 537 | +void xfs_btree_set_sibling(struct xfs_btree_cur *cur, |
|---|
| 538 | + struct xfs_btree_block *block, union xfs_btree_ptr *ptr, |
|---|
| 539 | + int lr); |
|---|
| 540 | +void xfs_btree_init_block_cur(struct xfs_btree_cur *cur, |
|---|
| 541 | + struct xfs_buf *bp, int level, int numrecs); |
|---|
| 542 | +void xfs_btree_copy_ptrs(struct xfs_btree_cur *cur, |
|---|
| 543 | + union xfs_btree_ptr *dst_ptr, |
|---|
| 544 | + const union xfs_btree_ptr *src_ptr, int numptrs); |
|---|
| 545 | +void xfs_btree_copy_keys(struct xfs_btree_cur *cur, |
|---|
| 546 | + union xfs_btree_key *dst_key, union xfs_btree_key *src_key, |
|---|
| 547 | + int numkeys); |
|---|
| 516 | 548 | |
|---|
| 517 | 549 | #endif /* __XFS_BTREE_H__ */ |
|---|