fs/hfsplus/xattr.c

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

File Facts

System
Linux kernel
Corpus path
fs/hfsplus/xattr.c
Extension
.c
Size
27804 bytes
Lines
1037
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 (unlikely(err)) {
			pr_err("failed to extend attributes file\n");
			goto end_attr_file_creation;
		}
		hip->phys_size = attr_file->i_size =
			(loff_t)hip->alloc_blocks << sbi->alloc_blksz_shift;
		hip->fs_blocks = hip->alloc_blocks << sbi->fs_shift;
		inode_set_bytes(attr_file, attr_file->i_size);
	}

	buf = kzalloc(node_size, GFP_NOFS);
	if (!buf) {
		err = -ENOMEM;
		goto end_attr_file_creation;
	}

	map_nodes = hfsplus_init_header_node(attr_file, clump_size, buf, node_size);

	desc = (struct hfs_bnode_desc *)buf;
	next_node = be32_to_cpu(desc->next);

	index = 0;

	err = hfsplus_write_attributes_file_node(attr_file, buf,
						 node_size, &index);
	if (unlikely(err))
		goto failed_header_node_init;

	for (map_node_idx = 0; map_node_idx < map_nodes; map_node_idx++) {
		if (next_node >= map_nodes)
			next_node = 0;

		hfsplus_init_map_node(buf, node_size, next_node);

		err = hfsplus_write_attributes_file_node(attr_file, buf,
							 node_size, &index);
		if (unlikely(err))
			goto failed_header_node_init;

		next_node++;
	}

	hfsplus_mark_inode_dirty(attr_file, HFSPLUS_I_ATTR_DIRTY);

	sbi->attr_tree = hfs_btree_open(sb, HFSPLUS_ATTR_CNID);
	if (!sbi->attr_tree)
		pr_err("failed to load attributes file\n");

failed_header_node_init:
	kfree(buf);

end_attr_file_creation:
	iput(attr_file);

	if (!err)
		atomic_set(&sbi->attr_tree_state, HFSPLUS_VALID_ATTR_TREE);
	else if (err == -ENOSPC)
		atomic_set(&sbi->attr_tree_state, HFSPLUS_EMPTY_ATTR_TREE);
	else
		atomic_set(&sbi->attr_tree_state, HFSPLUS_FAILED_ATTR_TREE);

	return err;
}

static inline
bool is_xattr_operation_supported(struct inode *inode)
{
	if (HFSPLUS_IS_RSRC(inode))
		return false;

	return true;
}

int __hfsplus_setxattr(struct inode *inode, const char *name,
			const void *value, size_t size, int flags)
{
	int err;
	struct hfs_find_data cat_fd;
	hfsplus_cat_entry entry;
	u16 cat_entry_flags, cat_entry_type;
	u16 folder_finderinfo_len = sizeof(DInfo) + sizeof(DXInfo);
	u16 file_finderinfo_len = sizeof(FInfo) + sizeof(FXInfo);

	hfs_dbg("ino %llu, name %s, value %p, size %zu\n",
		inode->i_ino, name ? name : NULL,
		value, size);

	if (!is_xattr_operation_supported(inode))
		return -EOPNOTSUPP;

Annotation

Implementation Notes