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: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
Dave Chinner 2011-09-18 20:40:51 +00:00 committed by Alex Elder
parent 7e47a4efde
commit b447fe5a05
1 changed files with 70 additions and 37 deletions

View File

@ -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 */