fs/nilfs2/btree.c

Source file repositories/reference/linux-study-clean/fs/nilfs2/btree.c

File Facts

System
Linux kernel
Corpus path
fs/nilfs2/btree.c
Extension
.c
Size
65539 bytes
Lines
2448
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

struct nilfs_btree_readahead_info {
	struct nilfs_btree_node *node;	/* parent node */
	int max_ra_blocks;		/* max nof blocks to read ahead */
	int index;			/* current index on the parent node */
	int ncmax;			/* nof children in the parent node */
};

static int __nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
				   struct buffer_head **bhp,
				   const struct nilfs_btree_readahead_info *ra)
{
	struct inode *btnc_inode = NILFS_BMAP_I(btree)->i_assoc_inode;
	struct address_space *btnc = btnc_inode->i_mapping;
	struct buffer_head *bh, *ra_bh;
	sector_t submit_ptr = 0;
	int ret;

	ret = nilfs_btnode_submit_block(btnc, ptr, 0, REQ_OP_READ, &bh,
					&submit_ptr);
	if (ret) {
		if (likely(ret == -EEXIST))
			goto out_check;
		if (ret == -ENOENT) {
			/*
			 * Block address translation failed due to invalid
			 * value of 'ptr'.  In this case, return internal code
			 * -EINVAL (broken bmap) to notify bmap layer of fatal
			 * metadata corruption.
			 */
			ret = -EINVAL;
		}
		return ret;
	}

	if (ra) {
		int i, n;
		__u64 ptr2;

		/* read ahead sibling nodes */
		for (n = ra->max_ra_blocks, i = ra->index + 1;
		     n > 0 && i < ra->ncmax; n--, i++) {
			ptr2 = nilfs_btree_node_get_ptr(ra->node, i, ra->ncmax);

			ret = nilfs_btnode_submit_block(btnc, ptr2, 0,
						REQ_OP_READ | REQ_RAHEAD,
						&ra_bh, &submit_ptr);
			if (likely(!ret || ret == -EEXIST))
				brelse(ra_bh);
			else if (ret != -EBUSY)
				break;
			if (!buffer_locked(bh))
				goto out_no_wait;
		}
	}

	wait_on_buffer(bh);

 out_no_wait:
	if (!buffer_uptodate(bh)) {
		nilfs_err(btree->b_inode->i_sb,
			  "I/O error reading b-tree node block (ino=%llu, blocknr=%llu)",
			  btree->b_inode->i_ino, (unsigned long long)ptr);
		brelse(bh);
		return -EIO;
	}

 out_check:
	if (nilfs_btree_broken_node_block(bh)) {
		clear_buffer_uptodate(bh);
		brelse(bh);
		return -EINVAL;
	}

	*bhp = bh;
	return 0;
}

static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
				   struct buffer_head **bhp)
{
	return __nilfs_btree_get_block(btree, ptr, bhp, NULL);
}

static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
				 struct nilfs_btree_path *path,
				 __u64 key, __u64 *ptrp, int minlevel,
				 int readahead)
{
	struct nilfs_btree_node *node;
	struct nilfs_btree_readahead_info p, *ra;

Annotation

Implementation Notes