fs/nfs/blocklayout/extent_tree.c

Source file repositories/reference/linux-study-clean/fs/nfs/blocklayout/extent_tree.c

File Facts

System
Linux kernel
Corpus path
fs/nfs/blocklayout/extent_tree.c
Extension
.c
Size
17470 bytes
Lines
727
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 (new->be_f_offset < be->be_f_offset) {
			if (merge_ok && ext_can_merge(new, be)) {
				be->be_f_offset = new->be_f_offset;
				if (be->be_state != PNFS_BLOCK_NONE_DATA)
					be->be_v_offset = new->be_v_offset;
				be->be_length += new->be_length;
				be = ext_try_to_merge_left(root, be);
				goto free_new;
			}
			p = &(*p)->rb_left;
		} else if (new->be_f_offset >= ext_f_end(be)) {
			if (merge_ok && ext_can_merge(be, new)) {
				be->be_length += new->be_length;
				be = ext_try_to_merge_right(root, be);
				goto free_new;
			}
			p = &(*p)->rb_right;
		} else {
			BUG();
		}
	}

	rb_link_node(&new->be_node, parent, p);
	rb_insert_color(&new->be_node, root);
	return;
free_new:
	nfs4_put_deviceid_node(new->be_device);
	kfree(new);
}

static int
__ext_tree_remove(struct rb_root *root,
		sector_t start, sector_t end, struct list_head *tmp)
{
	struct pnfs_block_extent *be;
	sector_t len1 = 0, len2 = 0;
	sector_t orig_v_offset;
	sector_t orig_len;

	be = __ext_tree_search(root, start);
	if (!be)
		return 0;
	if (be->be_f_offset >= end)
		return 0;

	orig_v_offset = be->be_v_offset;
	orig_len = be->be_length;

	if (start > be->be_f_offset)
		len1 = start - be->be_f_offset;
	if (ext_f_end(be) > end)
		len2 = ext_f_end(be) - end;

	if (len2 > 0) {
		if (len1 > 0) {
			struct pnfs_block_extent *new;

			new = kzalloc_obj(*new, GFP_ATOMIC);
			if (!new)
				return -ENOMEM;

			be->be_length = len1;

			new->be_f_offset = end;
			if (be->be_state != PNFS_BLOCK_NONE_DATA) {
				new->be_v_offset =
					orig_v_offset + orig_len - len2;
			}
			new->be_length = len2;
			new->be_state = be->be_state;
			new->be_tag = be->be_tag;
			new->be_device = nfs4_get_deviceid(be->be_device);

			__ext_tree_insert(root, new, true);
		} else {
			be->be_f_offset = end;
			if (be->be_state != PNFS_BLOCK_NONE_DATA) {
				be->be_v_offset =
					orig_v_offset + orig_len - len2;
			}
			be->be_length = len2;
		}
	} else {
		if (len1 > 0) {
			be->be_length = len1;
			be = ext_tree_next(be);
		}

		while (be && ext_f_end(be) <= end) {
			struct pnfs_block_extent *next = ext_tree_next(be);

Annotation

Implementation Notes