fs/ntfs3/xattr.c

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

File Facts

System
Linux kernel
Corpus path
fs/ntfs3/xattr.c
Extension
.c
Size
22428 bytes
Lines
1060
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 (ef->size) {
			ea_size = le32_to_cpu(ef->size);
			if (ea_size > bytes)
				goto out1;
			continue;
		}

		/* Check if we can use fields ef->name_len and ef->elength. */
		if (bytes < offsetof(struct EA_FULL, name))
			goto out1;

		ea_size = ALIGN(struct_size(ef, name,
					    1 + ef->name_len +
						    le16_to_cpu(ef->elength)),
				4);
		if (ea_size > bytes)
			goto out1;
	}

	*ea = ea_p;
	return 0;

out1:
	kfree(ea_p);
out:
	ntfs_set_state(sbi, NTFS_DIRTY_DIRTY);
	return err;
}

/*
 * ntfs_list_ea
 *
 * Copy a list of xattrs names into the buffer
 * provided, or compute the buffer size required.
 *
 * Return:
 * * Number of bytes used / required on
 * * -ERRNO - on failure
 */
static ssize_t ntfs_list_ea(struct ntfs_inode *ni, char *buffer,
			    size_t bytes_per_buffer)
{
	const struct EA_INFO *info;
	struct EA_FULL *ea_all = NULL;
	u32 off, size;
	int err;
	size_t ret;

	err = ntfs_read_ea(ni, &ea_all, 0, &info);
	if (err)
		return err;

	if (!info || !ea_all)
		return 0;

	size = le32_to_cpu(info->size);

	/* Enumerate all xattrs. */
	ret = 0;
	off = 0;
	while (off + sizeof(struct EA_FULL) < size) {
		const struct EA_FULL *ea = Add2Ptr(ea_all, off);
		int ea_size = unpacked_ea_size(ea);
		u8 name_len = ea->name_len;

		if (!name_len)
			break;

		if (name_len > ea_size) {
			ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_ERROR);
			err = -EINVAL; /* corrupted fs. */
			break;
		}

		if (buffer) {
			/* Check if we can use field ea->name */
			if (off + ea_size > size)
				break;

			if (ret + name_len + 1 > bytes_per_buffer) {
				err = -ERANGE;
				goto out;
			}

			memcpy(buffer + ret, ea->name, name_len);
			buffer[ret + name_len] = 0;
		}

		ret += name_len + 1;
		off += ea_size;

Annotation

Implementation Notes