fs/ntfs3/inode.c

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

File Facts

System
Linux kernel
Corpus path
fs/ntfs3/inode.c
Extension
.c
Size
52303 bytes
Lines
2127
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 (!run_add_entry(&ni->file.run, 0, t64, t32, true)) {
			err = -ENOMEM;
			goto out;
		}
	}

	err = mi_read(&ni->mi, ino == MFT_REC_MFT);

	if (err)
		goto out;

	rec = ni->mi.mrec;

	if (sbi->flags & NTFS_FLAGS_LOG_REPLAYING) {
		;
	} else if (ref->seq != rec->seq) {
		err = -EINVAL;
		ntfs_err(sb, "MFT: r=%lx, expect seq=%x instead of %x!", ino,
			 le16_to_cpu(ref->seq), le16_to_cpu(rec->seq));
		goto out;
	} else if (!is_rec_inuse(rec)) {
		err = -ESTALE;
		ntfs_err(sb, "Inode r=%x is not in use!", (u32)ino);
		goto out;
	}

	if (le32_to_cpu(rec->total) != sbi->record_size) {
		/* Bad inode? */
		err = -EINVAL;
		goto out;
	}

	if (!is_rec_base(rec)) {
		err = -EINVAL;
		goto out;
	}

	/* Record should contain $I30 root. */
	is_dir = rec->flags & RECORD_FLAG_DIR;

	/* MFT_REC_MFT is not a dir */
	if (is_dir && ino == MFT_REC_MFT) {
		err = -EINVAL;
		goto out;
	}

	inode->i_generation = le16_to_cpu(rec->seq);

	/* Enumerate all struct Attributes MFT. */
	le = NULL;
	attr = NULL;

	/*
	 * To reduce tab pressure use goto instead of
	 * while( (attr = ni_enum_attr_ex(ni, attr, &le, NULL) ))
	 */
next_attr:
	run = NULL;
	err = -EINVAL;
	attr = ni_enum_attr_ex(ni, attr, &le, NULL);
	if (!attr)
		goto end_enum;

	if (le && le->vcn) {
		/* This is non primary attribute segment. Ignore if not MFT. */
		if (ino != MFT_REC_MFT || attr->type != ATTR_DATA)
			goto next_attr;

		run = &ni->file.run;
		asize = le32_to_cpu(attr->size);
		goto attr_unpack_run;
	}

	roff = attr->non_res ? 0 : le16_to_cpu(attr->res.data_off);
	rsize = attr->non_res ? 0 : le32_to_cpu(attr->res.data_size);
	asize = le32_to_cpu(attr->size);

	/*
	 * Really this check was done in 'ni_enum_attr_ex' -> ... 'mi_enum_attr'.
	 * There not critical to check this case again
	 */
	if (attr->name_len &&
	    sizeof(short) * attr->name_len + le16_to_cpu(attr->name_off) >
		    asize)
		goto out;

	if (attr->non_res) {
		t64 = le64_to_cpu(attr->nres.alloc_size);
		if (le64_to_cpu(attr->nres.data_size) > t64 ||
		    le64_to_cpu(attr->nres.valid_size) > t64)

Annotation

Implementation Notes