fs/xfs/xfs_inode_item.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_inode_item.c
Extension
.c
Size
36647 bytes
Lines
1248
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

xfs_has_bigtime(mp) && !xfs_inode_has_bigtime(ip)) {
		ip->i_diflags2 |= XFS_DIFLAG2_BIGTIME;
		flags |= XFS_ILOG_CORE;
	}

	/*
	 * Inode verifiers do not check that the extent size hints are an
	 * integer multiple of the rt extent size on a directory with
	 * rtinherit flags set.  If we're logging a directory that is
	 * misconfigured in this way, clear the bad hints.
	 */
	if (ip->i_diflags & XFS_DIFLAG_RTINHERIT) {
		if ((ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) &&
		    xfs_extlen_to_rtxmod(mp, ip->i_extsize) > 0) {
			ip->i_diflags &= ~(XFS_DIFLAG_EXTSIZE |
					   XFS_DIFLAG_EXTSZINHERIT);
			ip->i_extsize = 0;
			flags |= XFS_ILOG_CORE;
		}
		if ((ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE) &&
		    xfs_extlen_to_rtxmod(mp, ip->i_cowextsize) > 0) {
			ip->i_diflags2 &= ~XFS_DIFLAG2_COWEXTSIZE;
			ip->i_cowextsize = 0;
			flags |= XFS_ILOG_CORE;
		}
	}

	spin_lock(&iip->ili_lock);
	if (!iip->ili_item.li_buf) {
		struct xfs_perag *pag;
		struct xfs_buf	*bp;
		int		error;

		/*
		 * We hold the ILOCK here, so this inode is not going to be
		 * flushed while we are here. Further, because there is no
		 * buffer attached to the item, we know that there is no IO in
		 * progress, so nothing will clear the ili_fields while we read
		 * in the buffer. Hence we can safely drop the spin lock and
		 * read the buffer knowing that the state will not change from
		 * here.
		 */
		spin_unlock(&iip->ili_lock);
		pag = xfs_perag_get(mp, XFS_INODE_TO_AGNO(ip));
		error = xfs_read_icluster(pag, tp, ip->i_imap.im_agbno, &bp);
		xfs_perag_put(pag);
		if (error)
			return error;

		/*
		 * We need an explicit buffer reference for the log item but
		 * don't want the buffer to remain attached to the transaction.
		 * Hold the buffer but release the transaction reference once
		 * we've attached the inode log item to the buffer log item
		 * list.
		 */
		xfs_buf_hold(bp);
		spin_lock(&iip->ili_lock);
		iip->ili_item.li_buf = bp;
		bp->b_iodone = xfs_buf_inode_iodone;
		list_add_tail(&iip->ili_item.li_bio_list, &bp->b_li_list);
		xfs_trans_brelse(tp, bp);
	}

	/*
	 * Store the dirty flags back into the inode item as this state is used
	 * later on in xfs_inode_item_committing() to determine whether the
	 * transaction is relevant to fsync state or not.
	 */
	iip->ili_dirty_flags = flags;

	/*
	 * Convert the flags on-disk fields that have been modified in the
	 * transaction so that ili_fields tracks the changes correctly.
	 */
	if (flags & XFS_ILOG_IVERSION)
		flags = ((flags & ~XFS_ILOG_IVERSION) | XFS_ILOG_CORE);

	/*
	 * Always OR in the bits from the ili_last_fields field.  This is to
	 * coordinate with the xfs_iflush() and xfs_buf_inode_iodone() routines
	 * in the eventual clearing of the ili_fields bits.  See the big comment
	 * in xfs_iflush() for an explanation of this coordination mechanism.
	 */
	iip->ili_fields |= (flags | iip->ili_last_fields);
	spin_unlock(&iip->ili_lock);

	xfs_inode_item_precommit_check(ip);
	return 0;
}

Annotation

Implementation Notes