fs/hfs/catalog.c

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

File Facts

System
Linux kernel
Corpus path
fs/hfs/catalog.c
Extension
.c
Size
12421 bytes
Lines
498
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 (node_id != leaf_tail) {
			node = hfs_bnode_find(cat_tree, node_id);
			if (IS_ERR(node))
				return -ENOENT;
		}

		hfs_dbg("node %lld, leaf_tail %lld, leaf_head %lld\n",
			node_id, leaf_tail, leaf_head);

		hfs_bnode_dump(node);

		for (i = node->num_recs - 1; i >= 0; i--) {
			hfs_cat_rec rec;
			u16 off, len, keylen;
			int entryoffset;
			int entrylength;
			u32 found_cnid;

			len = hfs_brec_lenoff(node, i, &off);
			keylen = hfs_brec_keylen(node, i);
			if (keylen == 0) {
				pr_err("fail to get the keylen: "
					"node_id %lld, record index %d\n",
					node_id, i);
				return -EINVAL;
			}

			entryoffset = off + keylen;
			entrylength = len - keylen;

			if (entrylength > sizeof(rec)) {
				pr_err("unexpected record length: "
					"entrylength %d\n",
					entrylength);
				return -EINVAL;
			}

			hfs_bnode_read(node, &rec, entryoffset, entrylength);

			if (rec.type == HFS_CDR_DIR) {
				found_cnid = be32_to_cpu(rec.dir.DirID);
				hfs_dbg("found_cnid %u\n", found_cnid);
				hfs_set_next_unused_CNID(sb, cnid, found_cnid);
				hfs_bnode_put(node);
				return 0;
			} else if (rec.type == HFS_CDR_FIL) {
				found_cnid = be32_to_cpu(rec.file.FlNum);
				hfs_dbg("found_cnid %u\n", found_cnid);
				hfs_set_next_unused_CNID(sb, cnid, found_cnid);
				hfs_bnode_put(node);
				return 0;
			}
		}

		node_id = node->prev;
		hfs_bnode_put(node);

	} while (node_id >= leaf_head);

	return -ENOENT;
}

/*
 * hfs_cat_delete()
 *
 * Delete the indicated file or directory.
 * The associated thread is also removed unless ('with_thread'==0).
 */
int hfs_cat_delete(u32 cnid, struct inode *dir, const struct qstr *str)
{
	struct super_block *sb;
	struct hfs_find_data fd;
	int res, type;

	hfs_dbg("name %s, cnid %u\n", str ? str->name : NULL, cnid);
	sb = dir->i_sb;
	res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd);
	if (res)
		return res;

	hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str);
	res = hfs_brec_find(&fd);
	if (res)
		goto out;

	type = hfs_bnode_read_u8(fd.bnode, fd.entryoffset);
	if (type == HFS_CDR_FIL) {
		struct hfs_cat_file file;
		hfs_bnode_read(fd.bnode, &file, fd.entryoffset, sizeof(file));
		if (be32_to_cpu(file.FlNum) == cnid) {

Annotation

Implementation Notes