fs/hfs/btree.c

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

File Facts

System
Linux kernel
Corpus path
fs/hfs/btree.c
Extension
.c
Size
9953 bytes
Lines
419
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

HFS_I(tree->inode)->first_blocks) {
			pr_err("invalid btree extent records\n");
			unlock_new_inode(tree->inode);
			goto free_inode;
		}

		tree->inode->i_mapping->a_ops = &hfs_btree_aops;
		break;
	case HFS_CAT_CNID:
		hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize,
				    mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz));

		if (!HFS_I(tree->inode)->first_blocks) {
			pr_err("invalid btree extent records (0 size)\n");
			unlock_new_inode(tree->inode);
			goto free_inode;
		}

		tree->inode->i_mapping->a_ops = &hfs_btree_aops;
		break;
	default:
		BUG();
	}
	}
	unlock_new_inode(tree->inode);

	mapping = tree->inode->i_mapping;
	folio = filemap_grab_folio(mapping, 0);
	if (IS_ERR(folio))
		goto free_inode;

	folio_zero_range(folio, 0, folio_size(folio));

	dblock = hfs_ext_find_block(HFS_I(tree->inode)->first_extents, 0);
	start_block = HFS_SB(sb)->fs_start + (dblock * HFS_SB(sb)->fs_div);

	size = folio_size(folio);
	offset = 0;
	while (size > 0) {
		size_t len;

		bh = sb_bread(sb, start_block);
		if (!bh) {
			pr_err("unable to read tree header\n");
			goto put_folio;
		}

		len = min_t(size_t, folio_size(folio), sb->s_blocksize);
		memcpy_to_folio(folio, offset, bh->b_data, sb->s_blocksize);

		brelse(bh);

		start_block++;
		offset += len;
		size -= len;
	}

	folio_mark_uptodate(folio);

	/* Load the header */
	head = (struct hfs_btree_header_rec *)(kmap_local_folio(folio, 0) +
					       sizeof(struct hfs_bnode_desc));
	tree->root = be32_to_cpu(head->root);
	tree->leaf_count = be32_to_cpu(head->leaf_count);
	tree->leaf_head = be32_to_cpu(head->leaf_head);
	tree->leaf_tail = be32_to_cpu(head->leaf_tail);
	tree->node_count = be32_to_cpu(head->node_count);
	tree->free_nodes = be32_to_cpu(head->free_nodes);
	tree->attributes = be32_to_cpu(head->attributes);
	tree->node_size = be16_to_cpu(head->node_size);
	tree->max_key_len = be16_to_cpu(head->max_key_len);
	tree->depth = be16_to_cpu(head->depth);

	size = tree->node_size;
	if (!is_power_of_2(size))
		goto fail_folio;
	if (!tree->node_count)
		goto fail_folio;
	switch (id) {
	case HFS_EXT_CNID:
		if (tree->max_key_len != HFS_MAX_EXT_KEYLEN) {
			pr_err("invalid extent max_key_len %d\n",
			       tree->max_key_len);
			goto fail_folio;
		}
		break;
	case HFS_CAT_CNID:
		if (tree->max_key_len != HFS_MAX_CAT_KEYLEN) {
			pr_err("invalid catalog max_key_len %d\n",
			       tree->max_key_len);

Annotation

Implementation Notes