fs/xfs/xfs_inode_item_recover.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_inode_item_recover.c
Extension
.c
Size
17776 bytes
Lines
605
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 (ldip->di_version == 3 && ldip->di_v3_pad != 0) {
			XFS_CORRUPTION_ERROR(
				"Bad log dinode di_v3_pad",
				XFS_ERRLEVEL_LOW, mp, ldip, sizeof(*ldip));
			xfs_alert(mp,
				"Bad inode 0x%llx, di_v3_pad 0x%llx",
				ldip->di_ino, ldip->di_v3_pad);
			return -EFSCORRUPTED;
		}

		nextents = ldip->di_nextents;
		anextents = ldip->di_anextents;
	}

	if (unlikely(nextents + anextents > ldip->di_nblocks)) {
		XFS_CORRUPTION_ERROR("Bad log dinode extent counts",
				XFS_ERRLEVEL_LOW, mp, ldip, sizeof(*ldip));
		xfs_alert(mp,
			"Bad inode 0x%llx, large extent counts %d, nextents 0x%llx, anextents 0x%x, nblocks 0x%llx",
			ldip->di_ino, xfs_has_large_extent_counts(mp), nextents,
			anextents, ldip->di_nblocks);
		return -EFSCORRUPTED;
	}

	return 0;
}

static inline int
xlog_recover_inode_dbroot(
	struct xfs_mount	*mp,
	void			*src,
	unsigned int		len,
	struct xfs_dinode	*dip)
{
	void			*dfork = XFS_DFORK_DPTR(dip);
	unsigned int		dsize = XFS_DFORK_DSIZE(dip, mp);

	switch (dip->di_format) {
	case XFS_DINODE_FMT_BTREE:
		xfs_bmbt_to_bmdr(mp, src, len, dfork, dsize);
		break;
	case XFS_DINODE_FMT_META_BTREE:
		switch (be16_to_cpu(dip->di_metatype)) {
		case XFS_METAFILE_RTRMAP:
			xfs_rtrmapbt_to_disk(mp, src, len, dfork, dsize);
			return 0;
		case XFS_METAFILE_RTREFCOUNT:
			xfs_rtrefcountbt_to_disk(mp, src, len, dfork, dsize);
			return 0;
		default:
			ASSERT(0);
			return -EFSCORRUPTED;
		}
		break;
	default:
		ASSERT(0);
		return -EFSCORRUPTED;
	}

	return 0;
}

STATIC int
xlog_recover_inode_commit_pass2(
	struct xlog			*log,
	struct list_head		*buffer_list,
	struct xlog_recover_item	*item,
	xfs_lsn_t			current_lsn)
{
	struct xfs_inode_log_format	*in_f;
	struct xfs_mount		*mp = log->l_mp;
	struct xfs_buf			*bp;
	struct xfs_dinode		*dip;
	int				len;
	char				*src;
	char				*dest;
	int				error;
	int				attr_index;
	uint				fields;
	struct xfs_log_dinode		*ldip;
	uint				isize;
	int				need_free = 0;
	xfs_failaddr_t			fa;

	if (item->ri_buf[0].iov_len == sizeof(struct xfs_inode_log_format)) {
		in_f = item->ri_buf[0].iov_base;
	} else {
		in_f = kmalloc_obj(struct xfs_inode_log_format,
				   GFP_KERNEL | __GFP_NOFAIL);
		need_free = 1;

Annotation

Implementation Notes