fs/xfs/scrub/inode.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/scrub/inode.c
Extension
.c
Size
22906 bytes
Lines
842
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 (xfs_dinode_is_metadir(dip)) {
			if (be16_to_cpu(dip->di_metatype) >= XFS_METAFILE_MAX)
				xchk_ino_set_corrupt(sc, ino);
		} else {
			if (dip->di_metatype != 0)
				xchk_ino_set_corrupt(sc, ino);
		}

		if (dip->di_mode == 0 && sc->ip)
			xchk_ino_set_corrupt(sc, ino);

		if (dip->di_projid_hi != 0 &&
		    !xfs_has_projid32(mp))
			xchk_ino_set_corrupt(sc, ino);

		prid = be16_to_cpu(dip->di_projid_lo);
		break;
	default:
		xchk_ino_set_corrupt(sc, ino);
		return;
	}

	if (xfs_has_projid32(mp))
		prid |= (prid_t)be16_to_cpu(dip->di_projid_hi) << 16;

	/*
	 * di_uid/di_gid -- -1 isn't invalid, but there's no way that
	 * userspace could have created that.
	 */
	if (dip->di_uid == cpu_to_be32(-1U) ||
	    dip->di_gid == cpu_to_be32(-1U))
		xchk_ino_set_warning(sc, ino);

	/*
	 * project id of -1 isn't supposed to be valid, but the kernel didn't
	 * always validate that.
	 */
	if (prid == -1U)
		xchk_ino_set_warning(sc, ino);

	/* di_format */
	switch (dip->di_format) {
	case XFS_DINODE_FMT_DEV:
		if (!S_ISCHR(mode) && !S_ISBLK(mode) &&
		    !S_ISFIFO(mode) && !S_ISSOCK(mode))
			xchk_ino_set_corrupt(sc, ino);
		break;
	case XFS_DINODE_FMT_LOCAL:
		if (!S_ISDIR(mode) && !S_ISLNK(mode))
			xchk_ino_set_corrupt(sc, ino);
		break;
	case XFS_DINODE_FMT_EXTENTS:
		if (!S_ISREG(mode) && !S_ISDIR(mode) && !S_ISLNK(mode))
			xchk_ino_set_corrupt(sc, ino);
		break;
	case XFS_DINODE_FMT_BTREE:
		if (!S_ISREG(mode) && !S_ISDIR(mode))
			xchk_ino_set_corrupt(sc, ino);
		break;
	case XFS_DINODE_FMT_META_BTREE:
		if (!S_ISREG(mode))
			xchk_ino_set_corrupt(sc, ino);
		break;
	case XFS_DINODE_FMT_UUID:
	default:
		xchk_ino_set_corrupt(sc, ino);
		break;
	}

	/* di_[amc]time.nsec */
	xchk_dinode_nsec(sc, ino, dip, dip->di_atime);
	xchk_dinode_nsec(sc, ino, dip, dip->di_mtime);
	xchk_dinode_nsec(sc, ino, dip, dip->di_ctime);

	/*
	 * di_size.  xfs_dinode_verify checks for things that screw up
	 * the VFS such as the upper bit being set and zero-length
	 * symlinks/directories, but we can do more here.
	 */
	isize = be64_to_cpu(dip->di_size);
	if (isize & (1ULL << 63))
		xchk_ino_set_corrupt(sc, ino);

	/* Devices, fifos, and sockets must have zero size */
	if (!S_ISDIR(mode) && !S_ISREG(mode) && !S_ISLNK(mode) && isize != 0)
		xchk_ino_set_corrupt(sc, ino);

	/* Directories can't be larger than the data section size (32G) */
	if (S_ISDIR(mode) && (isize == 0 || isize >= XFS_DIR2_SPACE_SIZE))
		xchk_ino_set_corrupt(sc, ino);

Annotation

Implementation Notes