fs/hfsplus/catalog.c

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

File Facts

System
Linux kernel
Corpus path
fs/hfsplus/catalog.c
Extension
.c
Size
14324 bytes
Lines
542
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 (cnid == inode->i_ino) {
			hfsplus_cat_set_perms(inode, &file->permissions);
			if (S_ISLNK(inode->i_mode)) {
				file->user_info.fdType =
					cpu_to_be32(HFSP_SYMLINK_TYPE);
				file->user_info.fdCreator =
					cpu_to_be32(HFSP_SYMLINK_CREATOR);
			} else {
				file->user_info.fdType =
					cpu_to_be32(sbi->type);
				file->user_info.fdCreator =
					cpu_to_be32(sbi->creator);
			}
			if (HFSPLUS_FLG_IMMUTABLE &
					(file->permissions.rootflags |
					file->permissions.userflags))
				file->flags |=
					cpu_to_be16(HFSPLUS_FILE_LOCKED);
		} else {
			file->user_info.fdType =
				cpu_to_be32(HFSP_HARDLINK_TYPE);
			file->user_info.fdCreator =
				cpu_to_be32(HFSP_HFSPLUS_CREATOR);
			file->user_info.fdFlags =
				cpu_to_be16(0x100);
			file->create_date =
				HFSPLUS_I(sbi->hidden_dir)->create_date;
			file->permissions.dev =
				cpu_to_be32(HFSPLUS_I(inode)->linkid);
		}
		return sizeof(*file);
	}
}

static int hfsplus_fill_cat_thread(struct super_block *sb,
				   hfsplus_cat_entry *entry, int type,
				   u32 parentid, const struct qstr *str)
{
	int err;

	entry->type = cpu_to_be16(type);
	entry->thread.reserved = 0;
	entry->thread.parentID = cpu_to_be32(parentid);
	err = hfsplus_asc2uni(sb, &entry->thread.nodeName, HFSPLUS_MAX_STRLEN,
				str->name, str->len, HFS_REGULAR_NAME);
	if (unlikely(err < 0))
		return err;

	return 10 + be16_to_cpu(entry->thread.nodeName.length) * 2;
}

/* Try to get a catalog entry for given catalog id */
int hfsplus_find_cat(struct super_block *sb, u32 cnid,
		     struct hfs_find_data *fd)
{
	hfsplus_cat_entry tmp = {0};
	int err;
	u16 type;

	hfsplus_cat_build_key_with_cnid(sb, fd->search_key, cnid);
	err = hfsplus_brec_read_cat(fd, &tmp);
	if (err)
		return err;

	type = be16_to_cpu(tmp.type);
	if (type != HFSPLUS_FOLDER_THREAD && type != HFSPLUS_FILE_THREAD) {
		pr_err("found bad thread record in catalog\n");
		return -EIO;
	}

	if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
		pr_err("catalog name length corrupted\n");
		return -EIO;
	}

	hfsplus_cat_build_key_uni(fd->search_key,
		be32_to_cpu(tmp.thread.parentID),
		&tmp.thread.nodeName);
	return hfs_brec_find(fd, hfs_find_rec_by_key);
}

static void hfsplus_subfolders_inc(struct inode *dir)
{
	struct hfsplus_sb_info *sbi = HFSPLUS_SB(dir->i_sb);

	if (test_bit(HFSPLUS_SB_HFSX, &sbi->flags)) {
		/*
		 * Increment subfolder count. Note, the value is only meaningful
		 * for folders with HFSPLUS_HAS_FOLDER_COUNT flag set.
		 */

Annotation

Implementation Notes