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

Commit b447fe5a authored by Dave Chinner's avatar Dave Chinner Committed by Alex Elder
Browse files

xfs: factor unwritten extent map manipulations out of xfs_bmapi



To further improve the readability of xfs_bmapi(), factor the
unwritten extent conversion out into a separate function. This
removes large block of logic from the xfs_bmapi() code loop and
makes it easier to see the operational logic flow for xfs_bmapi().

Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
parent 7e47a4ef
Loading
Loading
Loading
Loading
+70 −37
Original line number Diff line number Diff line
@@ -4089,7 +4089,6 @@ xfs_bmap_read_extents(
		xfs_extnum_t	num_recs;
		xfs_extnum_t	start;


		num_recs = xfs_btree_get_numrecs(block);
		if (unlikely(i + num_recs > room)) {
			ASSERT(i + num_recs <= room);
@@ -4746,6 +4745,69 @@ xfs_bmapi_allocate(
	return 0;
}

STATIC int
xfs_bmapi_convert_unwritten(
	struct xfs_bmalloca	*bma,
	struct xfs_bmbt_irec	*mval,
	xfs_filblks_t		len,
	xfs_extnum_t		*lastx,
	struct xfs_btree_cur	**cur,
	xfs_fsblock_t		*firstblock,
	struct xfs_bmap_free	*flist,
	int			flags,
	int			*logflags)
{
	int			whichfork = (flags & XFS_BMAPI_ATTRFORK) ?
						XFS_ATTR_FORK : XFS_DATA_FORK;
	struct xfs_ifork	*ifp = XFS_IFORK_PTR(bma->ip, whichfork);
	int			error;

	*logflags = 0;

	/* check if we need to do unwritten->real conversion */
	if (mval->br_state == XFS_EXT_UNWRITTEN &&
	    (flags & XFS_BMAPI_PREALLOC))
		return 0;

	/* check if we need to do real->unwritten conversion */
	if (mval->br_state == XFS_EXT_NORM &&
	    (flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT)) !=
			(XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT))
		return 0;

	/*
	 * Modify (by adding) the state flag, if writing.
	 */
	ASSERT(mval->br_blockcount <= len);
	if ((ifp->if_flags & XFS_IFBROOT) && !*cur) {
		*cur = xfs_bmbt_init_cursor(bma->ip->i_mount, bma->tp,
					bma->ip, whichfork);
		(*cur)->bc_private.b.firstblock = *firstblock;
		(*cur)->bc_private.b.flist = flist;
	}
	mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
				? XFS_EXT_NORM : XFS_EXT_UNWRITTEN;

	error = xfs_bmap_add_extent(bma->tp, bma->ip, lastx, cur, mval,
				firstblock, flist, logflags, whichfork);
	if (error)
		return error;

	/*
	 * Update our extent pointer, given that xfs_bmap_add_extent  might
	 * have merged it into one of the neighbouring ones.
	 */
	xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), bma->gotp);

	/*
	 * We may have combined previously unwritten space with written space,
	 * so generate another request.
	 */
	if (mval->br_blockcount < len)
		return EAGAIN;
	return 0;
}

/*
 * Map file blocks to filesystem blocks.
 * File range is given by the bno/len pair.
@@ -4932,45 +4994,16 @@ xfs_bmapi(
		/* Deal with the allocated space we found.  */
		xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);

		/*
		 * Check if writing previously allocated but
		 * unwritten extents.
		 */
		if (wr &&
		    ((mval->br_state == XFS_EXT_UNWRITTEN &&
		      ((flags & XFS_BMAPI_PREALLOC) == 0)) ||
		     (mval->br_state == XFS_EXT_NORM &&
		      ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) ==
				(XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) {
			/*
			 * Modify (by adding) the state flag, if writing.
			 */
			ASSERT(mval->br_blockcount <= len);
			if ((ifp->if_flags & XFS_IFBROOT) && !cur) {
				cur = xfs_bmbt_init_cursor(mp,
					tp, ip, whichfork);
				cur->bc_private.b.firstblock =
					*firstblock;
				cur->bc_private.b.flist = flist;
			}
			mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN)
						? XFS_EXT_NORM
						: XFS_EXT_UNWRITTEN;
			error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, mval,
				firstblock, flist, &tmp_logflags,
				whichfork);
		/* Execute unwritten extent conversion if necessary */
		if (wr) {
			error = xfs_bmapi_convert_unwritten(&bma, mval, len,
						&lastx, &cur, firstblock, flist, flags,
						&tmp_logflags);
			logflags |= tmp_logflags;
			if (error == EAGAIN)
				continue;
			if (error)
				goto error0;
			ep = xfs_iext_get_ext(ifp, lastx);
			xfs_bmbt_get_all(ep, &got);
			/*
			 * We may have combined previously unwritten
			 * space with written space, so generate
			 * another request.
			 */
			if (mval->br_blockcount < len)
				continue;
		}

		/* update the extent map to return */