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

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
...@@ -4089,7 +4089,6 @@ xfs_bmap_read_extents( ...@@ -4089,7 +4089,6 @@ xfs_bmap_read_extents(
xfs_extnum_t num_recs; xfs_extnum_t num_recs;
xfs_extnum_t start; xfs_extnum_t start;
num_recs = xfs_btree_get_numrecs(block); num_recs = xfs_btree_get_numrecs(block);
if (unlikely(i + num_recs > room)) { if (unlikely(i + num_recs > room)) {
ASSERT(i + num_recs <= room); ASSERT(i + num_recs <= room);
...@@ -4746,6 +4745,69 @@ xfs_bmapi_allocate( ...@@ -4746,6 +4745,69 @@ xfs_bmapi_allocate(
return 0; 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. * Map file blocks to filesystem blocks.
* File range is given by the bno/len pair. * File range is given by the bno/len pair.
...@@ -4932,45 +4994,16 @@ xfs_bmapi( ...@@ -4932,45 +4994,16 @@ xfs_bmapi(
/* Deal with the allocated space we found. */ /* Deal with the allocated space we found. */
xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags);
/* /* Execute unwritten extent conversion if necessary */
* Check if writing previously allocated but if (wr) {
* unwritten extents. error = xfs_bmapi_convert_unwritten(&bma, mval, len,
*/ &lastx, &cur, firstblock, flist, flags,
if (wr && &tmp_logflags);
((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);
logflags |= tmp_logflags; logflags |= tmp_logflags;
if (error == EAGAIN)
continue;
if (error) if (error)
goto error0; 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 */ /* update the extent map to return */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment