xfs: remove xfs_bmap_add_extent
There is no real need to the xfs_bmap_add_extent, as the callers know what kind of extents they need to it. Removing it means duplicating the extents to btree conversion logic in three places, but overall it's still much simpler code and quite a bit less code. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
parent
27a3f8f2de
commit
a5bd606ba6
|
@ -50,17 +50,22 @@
|
|||
#include "xfs_trace.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
STATIC void
|
||||
xfs_bmap_check_leaf_extents(xfs_btree_cur_t *cur, xfs_inode_t *ip, int whichfork);
|
||||
#endif
|
||||
|
||||
kmem_zone_t *xfs_bmap_free_item_zone;
|
||||
|
||||
/*
|
||||
* Prototypes for internal bmap routines.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
STATIC void
|
||||
xfs_bmap_check_leaf_extents(
|
||||
struct xfs_btree_cur *cur,
|
||||
struct xfs_inode *ip,
|
||||
int whichfork);
|
||||
#else
|
||||
#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Called from xfs_bmap_add_attrfork to handle extents format files.
|
||||
|
@ -84,47 +89,6 @@ xfs_bmap_add_attrfork_local(
|
|||
xfs_bmap_free_t *flist, /* blocks to free at commit */
|
||||
int *flags); /* inode logging flags */
|
||||
|
||||
/*
|
||||
* Called by xfs_bmap_add_extent to handle cases converting a delayed
|
||||
* allocation to a real allocation.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent_delay_real(
|
||||
struct xfs_trans *tp, /* transaction pointer */
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
|
||||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp); /* inode logging flags */
|
||||
|
||||
/*
|
||||
* Called by xfs_bmap_add_extent to handle cases converting a hole
|
||||
* to a real allocation.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent_hole_real(
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
int whichfork); /* data or attr fork */
|
||||
|
||||
/*
|
||||
* Called by xfs_bmap_add_extent to handle cases converting an unwritten
|
||||
* allocation to a real allocation or vice versa.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent_unwritten_real(
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
int *logflagsp); /* inode logging flags */
|
||||
|
||||
/*
|
||||
* xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
|
||||
* It figures out where to ask the underlying allocator to put the new extent.
|
||||
|
@ -407,147 +371,7 @@ xfs_bmap_add_attrfork_local(
|
|||
}
|
||||
|
||||
/*
|
||||
* Update file extent records and the btree after allocating space.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent(
|
||||
struct xfs_trans *tp, /* transaction pointer */
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
int whichfork) /* data or attr fork */
|
||||
{
|
||||
xfs_btree_cur_t *cur; /* btree cursor or null */
|
||||
xfs_filblks_t da_new; /* new count del alloc blocks used */
|
||||
xfs_filblks_t da_old; /* old count del alloc blocks used */
|
||||
int error; /* error return value */
|
||||
xfs_ifork_t *ifp; /* inode fork ptr */
|
||||
int logflags; /* returned value */
|
||||
xfs_extnum_t nextents; /* number of extents in file now */
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
|
||||
cur = *curp;
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t);
|
||||
da_old = da_new = 0;
|
||||
error = 0;
|
||||
|
||||
ASSERT(*idx >= 0);
|
||||
ASSERT(*idx <= nextents);
|
||||
ASSERT(!isnullstartblock(new->br_startblock));
|
||||
|
||||
/*
|
||||
* Real allocation off the end of the file.
|
||||
*/
|
||||
if (*idx == nextents) {
|
||||
if (cur)
|
||||
ASSERT((cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL) == 0);
|
||||
error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
|
||||
&logflags, whichfork);
|
||||
} else {
|
||||
xfs_bmbt_irec_t prev; /* old extent at offset idx */
|
||||
|
||||
/*
|
||||
* Get the record referred to by idx.
|
||||
*/
|
||||
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *idx), &prev);
|
||||
/*
|
||||
* If it's a real allocation record, and the new allocation ends
|
||||
* after the start of the referred to record, then we're filling
|
||||
* in a delayed or unwritten allocation with a real one, or
|
||||
* converting real back to unwritten.
|
||||
*/
|
||||
if (!isnullstartblock(new->br_startblock) &&
|
||||
new->br_startoff + new->br_blockcount > prev.br_startoff) {
|
||||
if (prev.br_state != XFS_EXT_UNWRITTEN &&
|
||||
isnullstartblock(prev.br_startblock)) {
|
||||
da_old = startblockval(prev.br_startblock);
|
||||
if (cur)
|
||||
ASSERT(cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL);
|
||||
error = xfs_bmap_add_extent_delay_real(tp, ip,
|
||||
idx, &cur, new, &da_new,
|
||||
first, flist, &logflags);
|
||||
} else {
|
||||
ASSERT(new->br_state == XFS_EXT_NORM ||
|
||||
new->br_state == XFS_EXT_UNWRITTEN);
|
||||
|
||||
error = xfs_bmap_add_extent_unwritten_real(ip,
|
||||
idx, &cur, new, &logflags);
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Otherwise we're filling in a hole with an allocation.
|
||||
*/
|
||||
else {
|
||||
if (cur)
|
||||
ASSERT((cur->bc_private.b.flags &
|
||||
XFS_BTCUR_BPRV_WASDEL) == 0);
|
||||
error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
|
||||
new, &logflags, whichfork);
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
goto done;
|
||||
ASSERT(*curp == cur || *curp == NULL);
|
||||
|
||||
/*
|
||||
* Convert to a btree if necessary.
|
||||
*/
|
||||
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
||||
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) {
|
||||
int tmp_logflags; /* partial log flag return val */
|
||||
|
||||
ASSERT(cur == NULL);
|
||||
error = xfs_bmap_extents_to_btree(tp, ip, first,
|
||||
flist, &cur, da_old > 0, &tmp_logflags, whichfork);
|
||||
logflags |= tmp_logflags;
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* Adjust for changes in reserved delayed indirect blocks.
|
||||
* Nothing to do for disk quotas here.
|
||||
*/
|
||||
if (da_old || da_new) {
|
||||
xfs_filblks_t nblks;
|
||||
|
||||
nblks = da_new;
|
||||
if (cur)
|
||||
nblks += cur->bc_private.b.allocated;
|
||||
ASSERT(nblks <= da_old);
|
||||
if (nblks < da_old)
|
||||
xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS,
|
||||
(int64_t)(da_old - nblks), 0);
|
||||
}
|
||||
/*
|
||||
* Clear out the allocated field, done with it now in any case.
|
||||
*/
|
||||
if (cur) {
|
||||
cur->bc_private.b.allocated = 0;
|
||||
*curp = cur;
|
||||
}
|
||||
done:
|
||||
#ifdef DEBUG
|
||||
if (!error)
|
||||
xfs_bmap_check_leaf_extents(*curp, ip, whichfork);
|
||||
#endif
|
||||
*logflagsp = logflags;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by xfs_bmap_add_extent to handle cases converting a delayed
|
||||
* allocation to a real allocation.
|
||||
* Convert a delayed allocation to a real allocation.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent_delay_real(
|
||||
|
@ -556,7 +380,6 @@ xfs_bmap_add_extent_delay_real(
|
|||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
xfs_filblks_t *dnew, /* new delayed-alloc indirect blocks */
|
||||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp) /* inode logging flags */
|
||||
|
@ -572,10 +395,24 @@ xfs_bmap_add_extent_delay_real(
|
|||
/* left is 0, right is 1, prev is 2 */
|
||||
int rval=0; /* return value (logging flags) */
|
||||
int state = 0;/* state bits, accessed thru macros */
|
||||
xfs_filblks_t temp=0; /* value for dnew calculations */
|
||||
xfs_filblks_t temp2=0;/* value for dnew calculations */
|
||||
xfs_filblks_t da_new; /* new count del alloc blocks used */
|
||||
xfs_filblks_t da_old; /* old count del alloc blocks used */
|
||||
xfs_filblks_t temp=0; /* value for da_new calculations */
|
||||
xfs_filblks_t temp2=0;/* value for da_new calculations */
|
||||
int tmp_rval; /* partial logging flags */
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
|
||||
cur = *curp;
|
||||
|
||||
ASSERT(*idx >= 0);
|
||||
ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
|
||||
ASSERT(!isnullstartblock(new->br_startblock));
|
||||
ASSERT(!cur || (cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
|
||||
*logflagsp = 0;
|
||||
|
||||
#define LEFT r[0]
|
||||
#define RIGHT r[1]
|
||||
#define PREV r[2]
|
||||
|
@ -583,14 +420,15 @@ xfs_bmap_add_extent_delay_real(
|
|||
/*
|
||||
* Set up a bunch of variables to make the tests simpler.
|
||||
*/
|
||||
cur = *curp;
|
||||
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
|
||||
ep = xfs_iext_get_ext(ifp, *idx);
|
||||
xfs_bmbt_get_all(ep, &PREV);
|
||||
new_endoff = new->br_startoff + new->br_blockcount;
|
||||
ASSERT(PREV.br_startoff <= new->br_startoff);
|
||||
ASSERT(PREV.br_startoff + PREV.br_blockcount >= new_endoff);
|
||||
|
||||
da_old = startblockval(PREV.br_startblock);
|
||||
da_new = 0;
|
||||
|
||||
/*
|
||||
* Set flags determining what part of the previous delayed allocation
|
||||
* extent is being replaced by a real allocation.
|
||||
|
@ -688,7 +526,6 @@ xfs_bmap_add_extent_delay_real(
|
|||
RIGHT.br_blockcount, LEFT.br_state)))
|
||||
goto done;
|
||||
}
|
||||
*dnew = 0;
|
||||
break;
|
||||
|
||||
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
|
||||
|
@ -719,7 +556,6 @@ xfs_bmap_add_extent_delay_real(
|
|||
PREV.br_blockcount, LEFT.br_state)))
|
||||
goto done;
|
||||
}
|
||||
*dnew = 0;
|
||||
break;
|
||||
|
||||
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
|
||||
|
@ -749,8 +585,6 @@ xfs_bmap_add_extent_delay_real(
|
|||
RIGHT.br_blockcount, PREV.br_state)))
|
||||
goto done;
|
||||
}
|
||||
|
||||
*dnew = 0;
|
||||
break;
|
||||
|
||||
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
|
||||
|
@ -778,8 +612,6 @@ xfs_bmap_add_extent_delay_real(
|
|||
goto done;
|
||||
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
||||
}
|
||||
|
||||
*dnew = 0;
|
||||
break;
|
||||
|
||||
case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
|
||||
|
@ -813,13 +645,12 @@ xfs_bmap_add_extent_delay_real(
|
|||
LEFT.br_state)))
|
||||
goto done;
|
||||
}
|
||||
temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
startblockval(PREV.br_startblock));
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
|
||||
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
||||
|
||||
--*idx;
|
||||
*dnew = temp;
|
||||
break;
|
||||
|
||||
case BMAP_LEFT_FILLING:
|
||||
|
@ -856,14 +687,12 @@ xfs_bmap_add_extent_delay_real(
|
|||
if (error)
|
||||
goto done;
|
||||
}
|
||||
temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
startblockval(PREV.br_startblock) -
|
||||
(cur ? cur->bc_private.b.allocated : 0));
|
||||
ep = xfs_iext_get_ext(ifp, *idx + 1);
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
|
||||
trace_xfs_bmap_post_update(ip, *idx + 1, state, _THIS_IP_);
|
||||
|
||||
*dnew = temp;
|
||||
break;
|
||||
|
||||
case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
|
||||
|
@ -896,14 +725,13 @@ xfs_bmap_add_extent_delay_real(
|
|||
goto done;
|
||||
}
|
||||
|
||||
temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
startblockval(PREV.br_startblock));
|
||||
trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
|
||||
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
||||
|
||||
++*idx;
|
||||
*dnew = temp;
|
||||
break;
|
||||
|
||||
case BMAP_RIGHT_FILLING:
|
||||
|
@ -939,15 +767,14 @@ xfs_bmap_add_extent_delay_real(
|
|||
if (error)
|
||||
goto done;
|
||||
}
|
||||
temp = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip, temp),
|
||||
startblockval(PREV.br_startblock) -
|
||||
(cur ? cur->bc_private.b.allocated : 0));
|
||||
ep = xfs_iext_get_ext(ifp, *idx);
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
|
||||
xfs_bmbt_set_startblock(ep, nullstartblock(da_new));
|
||||
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
||||
|
||||
++*idx;
|
||||
*dnew = temp;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
|
@ -1029,7 +856,7 @@ xfs_bmap_add_extent_delay_real(
|
|||
trace_xfs_bmap_post_update(ip, *idx + 2, state, _THIS_IP_);
|
||||
|
||||
++*idx;
|
||||
*dnew = temp + temp2;
|
||||
da_new = temp + temp2;
|
||||
break;
|
||||
|
||||
case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
|
||||
|
@ -1044,9 +871,39 @@ xfs_bmap_add_extent_delay_real(
|
|||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
*curp = cur;
|
||||
|
||||
/* convert to a btree if necessary */
|
||||
if (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS &&
|
||||
XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > ifp->if_ext_max) {
|
||||
int tmp_logflags; /* partial log flag return val */
|
||||
|
||||
ASSERT(cur == NULL);
|
||||
error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur,
|
||||
da_old > 0, &tmp_logflags, XFS_DATA_FORK);
|
||||
*logflagsp |= tmp_logflags;
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* adjust for changes in reserved delayed indirect blocks */
|
||||
if (da_old || da_new) {
|
||||
temp = da_new;
|
||||
if (cur)
|
||||
temp += cur->bc_private.b.allocated;
|
||||
ASSERT(temp <= da_old);
|
||||
if (temp < da_old)
|
||||
xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS,
|
||||
(int64_t)(da_old - temp), 0);
|
||||
}
|
||||
|
||||
/* clear out the allocated field, done with it now in any case. */
|
||||
if (cur) {
|
||||
cur->bc_private.b.allocated = 0;
|
||||
*curp = cur;
|
||||
}
|
||||
xfs_bmap_check_leaf_extents(cur, ip, XFS_DATA_FORK);
|
||||
done:
|
||||
*logflagsp = rval;
|
||||
*logflagsp |= rval;
|
||||
return error;
|
||||
#undef LEFT
|
||||
#undef RIGHT
|
||||
|
@ -1054,15 +911,17 @@ done:
|
|||
}
|
||||
|
||||
/*
|
||||
* Called by xfs_bmap_add_extent to handle cases converting an unwritten
|
||||
* allocation to a real allocation or vice versa.
|
||||
* Convert an unwritten allocation to a real allocation or vice versa.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent_unwritten_real(
|
||||
struct xfs_trans *tp,
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp) /* inode logging flags */
|
||||
{
|
||||
xfs_btree_cur_t *cur; /* btree cursor */
|
||||
|
@ -1078,15 +937,25 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
int rval=0; /* return value (logging flags) */
|
||||
int state = 0;/* state bits, accessed thru macros */
|
||||
|
||||
*logflagsp = 0;
|
||||
|
||||
cur = *curp;
|
||||
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
|
||||
|
||||
ASSERT(*idx >= 0);
|
||||
ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
|
||||
ASSERT(!isnullstartblock(new->br_startblock));
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
|
||||
#define LEFT r[0]
|
||||
#define RIGHT r[1]
|
||||
#define PREV r[2]
|
||||
|
||||
/*
|
||||
* Set up a bunch of variables to make the tests simpler.
|
||||
*/
|
||||
error = 0;
|
||||
cur = *curp;
|
||||
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
|
||||
ep = xfs_iext_get_ext(ifp, *idx);
|
||||
xfs_bmbt_get_all(ep, &PREV);
|
||||
newext = new->br_state;
|
||||
|
@ -1537,9 +1406,29 @@ xfs_bmap_add_extent_unwritten_real(
|
|||
*/
|
||||
ASSERT(0);
|
||||
}
|
||||
*curp = cur;
|
||||
|
||||
/* convert to a btree if necessary */
|
||||
if (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS &&
|
||||
XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK) > ifp->if_ext_max) {
|
||||
int tmp_logflags; /* partial log flag return val */
|
||||
|
||||
ASSERT(cur == NULL);
|
||||
error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur,
|
||||
0, &tmp_logflags, XFS_DATA_FORK);
|
||||
*logflagsp |= tmp_logflags;
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* clear out the allocated field, done with it now in any case. */
|
||||
if (cur) {
|
||||
cur->bc_private.b.allocated = 0;
|
||||
*curp = cur;
|
||||
}
|
||||
|
||||
xfs_bmap_check_leaf_extents(*curp, ip, XFS_DATA_FORK);
|
||||
done:
|
||||
*logflagsp = rval;
|
||||
*logflagsp |= rval;
|
||||
return error;
|
||||
#undef LEFT
|
||||
#undef RIGHT
|
||||
|
@ -1691,30 +1580,42 @@ xfs_bmap_add_extent_hole_delay(
|
|||
}
|
||||
|
||||
/*
|
||||
* Called by xfs_bmap_add_extent to handle cases converting a hole
|
||||
* to a real allocation.
|
||||
* Convert a hole to a real allocation.
|
||||
*/
|
||||
STATIC int /* error */
|
||||
xfs_bmap_add_extent_hole_real(
|
||||
struct xfs_trans *tp,
|
||||
xfs_inode_t *ip, /* incore inode pointer */
|
||||
xfs_extnum_t *idx, /* extent number to update/insert */
|
||||
xfs_btree_cur_t *cur, /* if null, not a btree */
|
||||
xfs_btree_cur_t **curp, /* if null, not a btree */
|
||||
xfs_bmbt_irec_t *new, /* new data to add to file extents */
|
||||
xfs_fsblock_t *first, /* pointer to firstblock variable */
|
||||
xfs_bmap_free_t *flist, /* list of extents to be freed */
|
||||
int *logflagsp, /* inode logging flags */
|
||||
int whichfork) /* data or attr fork */
|
||||
{
|
||||
int error; /* error return value */
|
||||
int i; /* temp state */
|
||||
xfs_btree_cur_t *cur; /* if null, not a btree */
|
||||
xfs_ifork_t *ifp; /* inode fork pointer */
|
||||
xfs_bmbt_irec_t left; /* left neighbor extent entry */
|
||||
xfs_bmbt_irec_t right; /* right neighbor extent entry */
|
||||
int rval=0; /* return value (logging flags) */
|
||||
int state; /* state bits, accessed thru macros */
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
ASSERT(*idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
|
||||
state = 0;
|
||||
*logflagsp = 0;
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
cur = *curp;
|
||||
|
||||
ASSERT(*idx >= 0);
|
||||
ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec));
|
||||
ASSERT(!isnullstartblock(new->br_startblock));
|
||||
ASSERT(!cur || !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL));
|
||||
|
||||
XFS_STATS_INC(xs_add_exlist);
|
||||
|
||||
state = 0;
|
||||
if (whichfork == XFS_ATTR_FORK)
|
||||
state |= BMAP_ATTRFORK;
|
||||
|
||||
|
@ -1897,8 +1798,28 @@ xfs_bmap_add_extent_hole_real(
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* convert to a btree if necessary */
|
||||
if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
||||
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max) {
|
||||
int tmp_logflags; /* partial log flag return val */
|
||||
|
||||
ASSERT(cur == NULL);
|
||||
error = xfs_bmap_extents_to_btree(tp, ip, first,
|
||||
flist, &cur, 0, &tmp_logflags, whichfork);
|
||||
*logflagsp |= tmp_logflags;
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* clear out the allocated field, done with it now in any case. */
|
||||
if (cur) {
|
||||
cur->bc_private.b.allocated = 0;
|
||||
*curp = cur;
|
||||
}
|
||||
xfs_bmap_check_leaf_extents(cur, ip, whichfork);
|
||||
done:
|
||||
*logflagsp = rval;
|
||||
*logflagsp |= rval;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -4792,14 +4713,22 @@ xfs_bmapi_allocate(
|
|||
xfs_sb_version_hasextflgbit(&mp->m_sb))
|
||||
bma->gotp->br_state = XFS_EXT_UNWRITTEN;
|
||||
|
||||
error = xfs_bmap_add_extent(bma->tp, bma->ip, lastx, cur, bma->gotp,
|
||||
firstblock, flist, logflags, whichfork);
|
||||
if (bma->wasdel) {
|
||||
error = xfs_bmap_add_extent_delay_real(bma->tp, bma->ip, lastx,
|
||||
cur, bma->gotp, firstblock, flist, logflags);
|
||||
} else {
|
||||
error = xfs_bmap_add_extent_hole_real(bma->tp, bma->ip, lastx,
|
||||
cur, bma->gotp, 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.
|
||||
* Update our extent pointer, given that xfs_bmap_add_extent_delay_real
|
||||
* or xfs_bmap_add_extent_hole_real might have merged it into one of
|
||||
* the neighbouring ones.
|
||||
*/
|
||||
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), bma->gotp);
|
||||
|
||||
|
@ -4854,14 +4783,15 @@ xfs_bmapi_convert_unwritten(
|
|||
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);
|
||||
error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, lastx,
|
||||
cur, mval, firstblock, flist, logflags);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/*
|
||||
* Update our extent pointer, given that xfs_bmap_add_extent might
|
||||
* have merged it into one of the neighbouring ones.
|
||||
* Update our extent pointer, given that
|
||||
* xfs_bmap_add_extent_unwritten_real might have merged it into one
|
||||
* of the neighbouring ones.
|
||||
*/
|
||||
xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), bma->gotp);
|
||||
|
||||
|
@ -5287,9 +5217,9 @@ xfs_bunmapi(
|
|||
del.br_blockcount = mod;
|
||||
}
|
||||
del.br_state = XFS_EXT_UNWRITTEN;
|
||||
error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &del,
|
||||
firstblock, flist, &logflags,
|
||||
XFS_DATA_FORK);
|
||||
error = xfs_bmap_add_extent_unwritten_real(tp, ip,
|
||||
&lastx, &cur, &del, firstblock, flist,
|
||||
&logflags);
|
||||
if (error)
|
||||
goto error0;
|
||||
goto nodelete;
|
||||
|
@ -5345,18 +5275,18 @@ xfs_bunmapi(
|
|||
}
|
||||
prev.br_state = XFS_EXT_UNWRITTEN;
|
||||
lastx--;
|
||||
error = xfs_bmap_add_extent(tp, ip, &lastx,
|
||||
&cur, &prev, firstblock, flist,
|
||||
&logflags, XFS_DATA_FORK);
|
||||
error = xfs_bmap_add_extent_unwritten_real(tp,
|
||||
ip, &lastx, &cur, &prev,
|
||||
firstblock, flist, &logflags);
|
||||
if (error)
|
||||
goto error0;
|
||||
goto nodelete;
|
||||
} else {
|
||||
ASSERT(del.br_state == XFS_EXT_NORM);
|
||||
del.br_state = XFS_EXT_UNWRITTEN;
|
||||
error = xfs_bmap_add_extent(tp, ip, &lastx,
|
||||
&cur, &del, firstblock, flist,
|
||||
&logflags, XFS_DATA_FORK);
|
||||
error = xfs_bmap_add_extent_unwritten_real(tp,
|
||||
ip, &lastx, &cur, &del,
|
||||
firstblock, flist, &logflags);
|
||||
if (error)
|
||||
goto error0;
|
||||
goto nodelete;
|
||||
|
|
Loading…
Reference in a new issue