Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56933848 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

xfs: factor out splitting of an iclog from xlog_sync



Split out a self-contained chunk of code from xlog_sync that calculates
the split offset for an iclog that wraps the log end and bumps the
cycles for the second half.

Use the chance to bring some sanity to the variables used to track the
split in xlog_sync by not changing the count variable, and instead use
split as the offset for the split and use those to calculate the
sizes and offsets for the two write buffers.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 94860a30
Loading
Loading
Loading
Loading
+33 −30
Original line number Diff line number Diff line
@@ -1765,6 +1765,32 @@ xlog_write_iclog(
	xfs_buf_submit(bp);
}

/*
 * We need to bump cycle number for the part of the iclog that is
 * written to the start of the log. Watch out for the header magic
 * number case, though.
 */
static unsigned int
xlog_split_iclog(
	struct xlog		*log,
	void			*data,
	uint64_t		bno,
	unsigned int		count)
{
	unsigned int		split_offset = BBTOB(log->l_logBBsize - bno);
	unsigned int		i;

	for (i = split_offset; i < count; i += BBSIZE) {
		uint32_t cycle = get_unaligned_be32(data + i);

		if (++cycle == XLOG_HEADER_MAGIC_NUM)
			cycle++;
		put_unaligned_be32(cycle, data + i);
	}

	return split_offset;
}

/*
 * Flush out the in-core log (iclog) to the on-disk log in an asynchronous 
 * fashion.  Previously, we should have moved the current iclog
@@ -1793,13 +1819,12 @@ xlog_sync(
	struct xlog		*log,
	struct xlog_in_core	*iclog)
{
	int		i;
	uint		count;		/* byte count of bwrite */
	uint		count_init;	/* initial count before roundup */
	int		roundoff;       /* roundoff to BB or stripe */
	int		split = 0;	/* split write into two regions */
	int		v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb);
	uint64_t	bno;
	unsigned int	split = 0;
	int		size;
	bool		need_flush = true;

@@ -1842,32 +1867,8 @@ xlog_sync(
	bno = BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn));

	/* Do we need to split this write into 2 parts? */
	if (bno + BTOBB(count) > log->l_logBBsize) {
		char		*dptr;

		split = count - (BBTOB(log->l_logBBsize - bno));
		count = BBTOB(log->l_logBBsize - bno);
		iclog->ic_bwritecnt = 2;

		/*
		 * Bump the cycle numbers at the start of each block in the
		 * part of the iclog that ends up in the buffer that gets
		 * written to the start of the log.
		 *
		 * Watch out for the header magic number case, though.
		 */
		dptr = (char *)&iclog->ic_header + count;
		for (i = 0; i < split; i += BBSIZE) {
			uint32_t cycle = be32_to_cpu(*(__be32 *)dptr);
			if (++cycle == XLOG_HEADER_MAGIC_NUM)
				cycle++;
			*(__be32 *)dptr = cpu_to_be32(cycle);

			dptr += BBSIZE;
		}
	} else {
		iclog->ic_bwritecnt = 1;
	}
	if (bno + BTOBB(count) > log->l_logBBsize)
		split = xlog_split_iclog(log, &iclog->ic_header, bno, count);

	/* calculcate the checksum */
	iclog->ic_header.h_crc = xlog_cksum(log, &iclog->ic_header,
@@ -1902,14 +1903,16 @@ xlog_sync(
		need_flush = false;
	}

	iclog->ic_bp->b_io_length = BTOBB(count);
	iclog->ic_bp->b_io_length = BTOBB(split ? split : count);
	iclog->ic_bwritecnt = split ? 2 : 1;

	xlog_verify_iclog(log, iclog, count, true);
	xlog_write_iclog(log, iclog, iclog->ic_bp, bno, need_flush);

	if (split) {
		xfs_buf_associate_memory(iclog->ic_log->l_xbuf,
				(char *)&iclog->ic_header + count, split);
				(char *)&iclog->ic_header + split,
				count - split);
		xlog_write_iclog(log, iclog, iclog->ic_log->l_xbuf, 0, false);
	}
}