fs/xfs/xfs_iomap.c

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

File Facts

System
Linux kernel
Corpus path
fs/xfs/xfs_iomap.c
Extension
.c
Size
67307 bytes
Lines
2392
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_iomap_inode_sequence(ip, iomap->flags)) {
		trace_xfs_iomap_invalid(ip, iomap);
		return false;
	}

	XFS_ERRORTAG_DELAY(ip->i_mount, XFS_ERRTAG_WRITE_DELAY_MS);
	return true;
}

const struct iomap_write_ops xfs_iomap_write_ops = {
	.iomap_valid		= xfs_iomap_valid,
};

int
xfs_bmbt_to_iomap(
	struct xfs_inode	*ip,
	struct iomap		*iomap,
	struct xfs_bmbt_irec	*imap,
	unsigned int		mapping_flags,
	u16			iomap_flags,
	u64			sequence_cookie)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_buftarg	*target = xfs_inode_buftarg(ip);

	if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) {
		xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
		return xfs_alert_fsblock_zero(ip, imap);
	}

	iomap->flags = iomap_flags;
	if (imap->br_startblock == HOLESTARTBLOCK) {
		iomap->addr = IOMAP_NULL_ADDR;
		iomap->type = IOMAP_HOLE;
	} else if (imap->br_startblock == DELAYSTARTBLOCK ||
		   isnullstartblock(imap->br_startblock)) {
		iomap->addr = IOMAP_NULL_ADDR;
		iomap->type = IOMAP_DELALLOC;
	} else {
		xfs_daddr_t	daddr = xfs_fsb_to_db(ip, imap->br_startblock);

		iomap->addr = BBTOB(daddr);
		if (mapping_flags & IOMAP_DAX)
			iomap->addr += target->bt_dax_part_off;

		if (imap->br_state == XFS_EXT_UNWRITTEN)
			iomap->type = IOMAP_UNWRITTEN;
		else
			iomap->type = IOMAP_MAPPED;

		/*
		 * Mark iomaps starting at the first sector of a RTG as merge
		 * boundary so that each I/O completions is contained to a
		 * single RTG.
		 */
		if (XFS_IS_REALTIME_INODE(ip) && xfs_has_rtgroups(mp) &&
		    xfs_rtbno_is_group_start(mp, imap->br_startblock))
			iomap->flags |= IOMAP_F_BOUNDARY;
	}
	iomap->offset = XFS_FSB_TO_B(mp, imap->br_startoff);
	iomap->length = XFS_FSB_TO_B(mp, imap->br_blockcount);
	if (mapping_flags & IOMAP_DAX) {
		iomap->dax_dev = target->bt_daxdev;
	} else {
		iomap->bdev = target->bt_bdev;
		if (bdev_has_integrity_csum(iomap->bdev))
			iomap->flags |= IOMAP_F_INTEGRITY;
	}

	/*
	 * If the inode is dirty for datasync purposes, let iomap know so it
	 * doesn't elide the IO completion journal flushes on O_DSYNC IO.
	 */
	if (ip->i_itemp) {
		struct xfs_inode_log_item *iip = ip->i_itemp;

		spin_lock(&iip->ili_lock);
		if (iip->ili_datasync_seq)
			iomap->flags |= IOMAP_F_DIRTY;
		spin_unlock(&iip->ili_lock);
	}

	iomap->validity_cookie = sequence_cookie;
	return 0;
}

static void
xfs_hole_to_iomap(
	struct xfs_inode	*ip,
	struct iomap		*iomap,

Annotation

Implementation Notes