fs/ntfs/ea.c

Source file repositories/reference/linux-study-clean/fs/ntfs/ea.c

File Facts

System
Linux kernel
Corpus path
fs/ntfs/ea.c
Extension
.c
Size
22672 bytes
Lines
958
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 (!buffer) {
			kvfree(ea_buf);
			return ea_value_len;
		}

		if (ea_value_len > size) {
			err = -ERANGE;
			goto free_ea_buf;
		}

		memcpy(buffer, &p_ea->ea_name[p_ea->ea_name_length + 1],
				ea_value_len);
		kvfree(ea_buf);
		return ea_value_len;
	}

	err = -ENODATA;
free_ea_buf:
	kvfree(ea_buf);
	return err;
}

static inline int ea_packed_size(const struct ea_attr *p_ea)
{
	/*
	 * 4 bytes for header (flags and lengths) + name length + 1 +
	 * value length.
	 */
	return 5 + p_ea->ea_name_length + le16_to_cpu(p_ea->ea_value_length);
}

/*
 * Set a new EA, and set EA_INFORMATION accordingly
 *
 * This is roughly the same as ZwSetEaFile() on Windows, however
 * the "offset to next" of the last EA should not be cleared.
 *
 * Consistency of the new EA is first checked.
 *
 * EA_INFORMATION is set first, and it is restored to its former
 * state if setting EA fails.
 */
static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
		const void *value, size_t val_size, int flags,
		__le16 *packed_ea_size)
{
	struct ntfs_inode *ni = NTFS_I(inode);
	struct ea_information *p_ea_info = NULL;
	int ea_packed, err = 0;
	struct ea_attr *p_ea;
	u32 ea_info_qsize = 0;
	char *ea_buf = NULL;
	size_t new_ea_size = ALIGN(struct_size(p_ea, ea_name, 1 + name_len + val_size), 4);
	s64 ea_off, ea_info_size, all_ea_size, ea_size;

	if (name_len > 255)
		return -ENAMETOOLONG;

	if (ntfs_attr_exist(ni, AT_EA_INFORMATION, AT_UNNAMED, 0)) {
		p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
						&ea_info_size);
		if (!p_ea_info || ea_info_size != sizeof(struct ea_information))
			goto out;

		ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
		if (!ea_buf) {
			ea_info_qsize = 0;
			kvfree(p_ea_info);
			goto create_ea_info;
		}

		ea_info_qsize = le32_to_cpu(p_ea_info->ea_query_length);
	} else {
create_ea_info:
		p_ea_info = kzalloc(sizeof(struct ea_information), GFP_NOFS);
		if (!p_ea_info)
			return -ENOMEM;

		ea_info_qsize = 0;
		err = ntfs_attr_add(ni, AT_EA_INFORMATION, AT_UNNAMED, 0,
				(char *)p_ea_info, sizeof(struct ea_information));
		if (err)
			goto out;

		if (ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
			err = ntfs_attr_remove(ni, AT_EA, AT_UNNAMED, 0);
			if (err)
				goto out;
		}

Annotation

Implementation Notes