fs/ntfs/reparse.c

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

File Facts

System
Linux kernel
Corpus path
fs/ntfs/reparse.c
Extension
.c
Size
23965 bytes
Lines
965
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

struct wsl_link_reparse_data {
	__le32	type;
	char	link[];
};

static bool reparse_name_is_valid(size_t size, size_t name_off, u16 len)
{
	if ((name_off | len) & 1)
		return false;

	return name_off + len <= size;
}

/*
 * Windows-native reparse payloads store pathnames as UTF-16 strings with '\\'
 * separators. Convert the on-disk UTF-16 target into the mount's NLS and
 * normalize path separators.
 */
static int ntfs_reparse_target_to_nls(struct ntfs_volume *vol,
				      const __le16 *uname, u16 ulen,
				      char **target)
{
	int err, i;

	*target = NULL;
	ulen >>= 1;
	if (!ulen)
		return -EINVAL;

	if (!uname[ulen - 1])
		ulen--;

	err = ntfs_ucstonls(vol, uname, ulen, (unsigned char **)target, 0);
	if (err < 0) {
		ntfs_attr_name_free((unsigned char **)target);
		return err;
	}

	for (i = 0; i < err; i++) {
		if ((*target)[i] == '\\')
			(*target)[i] = '/';
	}

	return 0;
}

/* Index entry in $Extend/$Reparse */
struct reparse_index {
	struct index_entry_header header;
	struct reparse_index_key key;
	__le32 filling;
};

__le16 reparse_index_name[] = {cpu_to_le16('$'), cpu_to_le16('R'), 0};


/*
 * Check if the reparse point attribute buffer is valid.
 * Returns true if valid, false otherwise.
 */
static bool valid_reparse_buffer(struct ntfs_inode *ni,
				 const struct reparse_point *reparse_attr,
				 size_t size,
				 size_t payload_min_len)
{
	size_t expected;

	if (!ni || !reparse_attr)
		return false;

	/* Minimum size must cover reparse_point header */
	if (size < sizeof(struct reparse_point))
		return false;

	/* The payload must contain the fixed fields for the current tag. */
	if (payload_min_len &&
	    le16_to_cpu(reparse_attr->reparse_data_length) < payload_min_len)
		return false;

	/* Reserved zero tag is invalid */
	if (reparse_attr->reparse_tag == IO_REPARSE_TAG_RESERVED_ZERO)
		return false;

	/* Calculate expected total size */
	expected = sizeof(struct reparse_point) +
		le16_to_cpu(reparse_attr->reparse_data_length);

	/* Add GUID size for non-Microsoft tags */
	if (!(reparse_attr->reparse_tag & IO_REPARSE_TAG_IS_MICROSOFT))
		expected += sizeof(struct guid);

Annotation

Implementation Notes