fs/xfs/libxfs/xfs_btree_staging.c

Source file repositories/reference/linux-study-clean/fs/xfs/libxfs/xfs_btree_staging.c

File Facts

System
Linux kernel
Corpus path
fs/xfs/libxfs/xfs_btree_staging.c
Extension
.c
Size
24893 bytes
Lines
821
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ops->type == XFS_BTREE_TYPE_INODE) {
			/*
			 * If all the items we want to store at this level
			 * would fit in the inode root block, then we have our
			 * btree root and are done.
			 *
			 * Note that bmap btrees forbid records in the root.
			 */
			if ((level != 0 ||
			     (ops->geom_flags & XFS_BTGEO_IROOT_RECORDS)) &&
			    nr_this_level <= avg_per_block) {
				nr_blocks++;
				break;
			}

			/*
			 * Otherwise, we have to store all the items for this
			 * level in traditional btree blocks and therefore need
			 * another level of btree to point to those blocks.
			 *
			 * We have to re-compute the geometry for each level of
			 * an inode-rooted btree because the geometry differs
			 * between a btree root in an inode fork and a
			 * traditional btree block.
			 *
			 * This distinction is made in the btree code based on
			 * whether level == bc_nlevels - 1.  Based on the
			 * previous root block size check against the root
			 * block geometry, we know that we aren't yet ready to
			 * populate the root.  Increment bc_nevels and
			 * recalculate the geometry for a traditional
			 * block-based btree level.
			 */
			cur->bc_nlevels++;
			ASSERT(cur->bc_nlevels <= cur->bc_maxlevels);
			xfs_btree_bload_level_geometry(cur, bbl, level,
					nr_this_level, &avg_per_block,
					&level_blocks, &dontcare64);
		} else {
			/*
			 * If all the items we want to store at this level
			 * would fit in a single root block, we're done.
			 */
			if (nr_this_level <= avg_per_block) {
				nr_blocks++;
				break;
			}

			/* Otherwise, we need another level of btree. */
			cur->bc_nlevels++;
			ASSERT(cur->bc_nlevels <= cur->bc_maxlevels);
		}

		nr_blocks += level_blocks;
		nr_this_level = level_blocks;
	}

	if (cur->bc_nlevels > cur->bc_maxlevels)
		return -EOVERFLOW;

	bbl->btree_height = cur->bc_nlevels;
	if (ops->type == XFS_BTREE_TYPE_INODE)
		bbl->nr_blocks = nr_blocks - 1;
	else
		bbl->nr_blocks = nr_blocks;
	return 0;
}

/* Bulk load a btree given the parameters and geometry established in bbl. */
int
xfs_btree_bload(
	struct xfs_btree_cur		*cur,
	struct xfs_btree_bload		*bbl,
	void				*priv)
{
	struct list_head		buffers_list;
	union xfs_btree_ptr		child_ptr;
	union xfs_btree_ptr		ptr;
	struct xfs_buf			*bp = NULL;
	struct xfs_btree_block		*block = NULL;
	uint64_t			nr_this_level = bbl->nr_records;
	uint64_t			blocks;
	uint64_t			i;
	uint64_t			blocks_with_extra;
	uint64_t			total_blocks = 0;
	unsigned int			avg_per_block;
	unsigned int			level = 0;
	int				ret;

	ASSERT(cur->bc_flags & XFS_BTREE_STAGING);

Annotation

Implementation Notes