|
@@ -579,7 +579,7 @@ xfs_bmap_validate_ret(
|
|
|
|
|
|
#else
|
|
|
#define xfs_bmap_check_leaf_extents(cur, ip, whichfork) do { } while (0)
|
|
|
-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
|
|
|
+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do { } while (0)
|
|
|
#endif /* DEBUG */
|
|
|
|
|
|
/*
|
|
@@ -880,7 +880,7 @@ xfs_bmap_local_to_extents(
|
|
|
xfs_ifork_t *ifp; /* inode fork pointer */
|
|
|
xfs_alloc_arg_t args; /* allocation arguments */
|
|
|
xfs_buf_t *bp; /* buffer for extent block */
|
|
|
- xfs_bmbt_rec_host_t *ep; /* extent record pointer */
|
|
|
+ struct xfs_bmbt_irec rec;
|
|
|
|
|
|
/*
|
|
|
* We don't want to deal with the case of keeping inode data inline yet.
|
|
@@ -943,9 +943,12 @@ xfs_bmap_local_to_extents(
|
|
|
xfs_bmap_local_to_extents_empty(ip, whichfork);
|
|
|
flags |= XFS_ILOG_CORE;
|
|
|
|
|
|
- xfs_iext_add(ifp, 0, 1);
|
|
|
- ep = xfs_iext_get_ext(ifp, 0);
|
|
|
- xfs_bmbt_set_allf(ep, 0, args.fsbno, 1, XFS_EXT_NORM);
|
|
|
+ rec.br_startoff = 0;
|
|
|
+ rec.br_startblock = args.fsbno;
|
|
|
+ rec.br_blockcount = 1;
|
|
|
+ rec.br_state = XFS_EXT_NORM;
|
|
|
+ xfs_iext_insert(ip, 0, 1, &rec, 0);
|
|
|
+
|
|
|
trace_xfs_bmap_post_update(ip, 0,
|
|
|
whichfork == XFS_ATTR_FORK ? BMAP_ATTRFORK : 0,
|
|
|
_THIS_IP_);
|
|
@@ -1196,7 +1199,7 @@ xfs_bmap_add_attrfork(
|
|
|
xfs_log_sb(tp);
|
|
|
}
|
|
|
|
|
|
- error = xfs_defer_finish(&tp, &dfops, NULL);
|
|
|
+ error = xfs_defer_finish(&tp, &dfops);
|
|
|
if (error)
|
|
|
goto bmap_cancel;
|
|
|
error = xfs_trans_commit(tp);
|
|
@@ -1356,7 +1359,6 @@ xfs_bmap_first_unused(
|
|
|
xfs_fileoff_t lastaddr; /* last block number seen */
|
|
|
xfs_fileoff_t lowest; /* lowest useful block */
|
|
|
xfs_fileoff_t max; /* starting useful block */
|
|
|
- xfs_fileoff_t off; /* offset for this block */
|
|
|
xfs_extnum_t nextents; /* number of extent entries */
|
|
|
|
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE ||
|
|
@@ -1373,16 +1375,19 @@ xfs_bmap_first_unused(
|
|
|
lowest = *first_unused;
|
|
|
nextents = xfs_iext_count(ifp);
|
|
|
for (idx = 0, lastaddr = 0, max = lowest; idx < nextents; idx++) {
|
|
|
- xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, idx);
|
|
|
- off = xfs_bmbt_get_startoff(ep);
|
|
|
+ struct xfs_bmbt_irec got;
|
|
|
+
|
|
|
+ xfs_iext_get_extent(ifp, idx, &got);
|
|
|
+
|
|
|
/*
|
|
|
* See if the hole before this extent will work.
|
|
|
*/
|
|
|
- if (off >= lowest + len && off - max >= len) {
|
|
|
+ if (got.br_startoff >= lowest + len &&
|
|
|
+ got.br_startoff - max >= len) {
|
|
|
*first_unused = max;
|
|
|
return 0;
|
|
|
}
|
|
|
- lastaddr = off + xfs_bmbt_get_blockcount(ep);
|
|
|
+ lastaddr = got.br_startoff + got.br_blockcount;
|
|
|
max = XFS_FILEOFF_MAX(lastaddr, lowest);
|
|
|
}
|
|
|
*first_unused = max;
|
|
@@ -4918,7 +4923,7 @@ xfs_bmap_del_extent_delay(
|
|
|
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip,
|
|
|
got->br_blockcount), da_old);
|
|
|
got->br_startblock = nullstartblock((int)da_new);
|
|
|
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got);
|
|
|
+ xfs_iext_update_extent(ifp, *idx, got);
|
|
|
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
|
|
break;
|
|
|
case BMAP_RIGHT_CONTIG:
|
|
@@ -4930,7 +4935,7 @@ xfs_bmap_del_extent_delay(
|
|
|
da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(ip,
|
|
|
got->br_blockcount), da_old);
|
|
|
got->br_startblock = nullstartblock((int)da_new);
|
|
|
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got);
|
|
|
+ xfs_iext_update_extent(ifp, *idx, got);
|
|
|
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
|
|
break;
|
|
|
case 0:
|
|
@@ -4956,7 +4961,7 @@ xfs_bmap_del_extent_delay(
|
|
|
del->br_blockcount);
|
|
|
|
|
|
got->br_startblock = nullstartblock((int)got_indlen);
|
|
|
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got);
|
|
|
+ xfs_iext_update_extent(ifp, *idx, got);
|
|
|
trace_xfs_bmap_post_update(ip, *idx, 0, _THIS_IP_);
|
|
|
|
|
|
new.br_startoff = del_endoff;
|
|
@@ -5026,7 +5031,7 @@ xfs_bmap_del_extent_cow(
|
|
|
got->br_startoff = del_endoff;
|
|
|
got->br_blockcount -= del->br_blockcount;
|
|
|
got->br_startblock = del->br_startblock + del->br_blockcount;
|
|
|
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got);
|
|
|
+ xfs_iext_update_extent(ifp, *idx, got);
|
|
|
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
|
|
break;
|
|
|
case BMAP_RIGHT_CONTIG:
|
|
@@ -5035,7 +5040,7 @@ xfs_bmap_del_extent_cow(
|
|
|
*/
|
|
|
trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
|
|
|
got->br_blockcount -= del->br_blockcount;
|
|
|
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got);
|
|
|
+ xfs_iext_update_extent(ifp, *idx, got);
|
|
|
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
|
|
break;
|
|
|
case 0:
|
|
@@ -5044,7 +5049,7 @@ xfs_bmap_del_extent_cow(
|
|
|
*/
|
|
|
trace_xfs_bmap_pre_update(ip, *idx, state, _THIS_IP_);
|
|
|
got->br_blockcount = del->br_startoff - got->br_startoff;
|
|
|
- xfs_bmbt_set_all(xfs_iext_get_ext(ifp, *idx), got);
|
|
|
+ xfs_iext_update_extent(ifp, *idx, got);
|
|
|
trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_);
|
|
|
|
|
|
new.br_startoff = del_endoff;
|
|
@@ -5876,32 +5881,26 @@ xfs_bmse_merge(
|
|
|
int whichfork,
|
|
|
xfs_fileoff_t shift, /* shift fsb */
|
|
|
int current_ext, /* idx of gotp */
|
|
|
- struct xfs_bmbt_rec_host *gotp, /* extent to shift */
|
|
|
- struct xfs_bmbt_rec_host *leftp, /* preceding extent */
|
|
|
+ struct xfs_bmbt_irec *got, /* extent to shift */
|
|
|
+ struct xfs_bmbt_irec *left, /* preceding extent */
|
|
|
struct xfs_btree_cur *cur,
|
|
|
- int *logflags) /* output */
|
|
|
+ int *logflags, /* output */
|
|
|
+ struct xfs_defer_ops *dfops)
|
|
|
{
|
|
|
- struct xfs_bmbt_irec got;
|
|
|
- struct xfs_bmbt_irec left;
|
|
|
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
+ struct xfs_bmbt_irec new;
|
|
|
xfs_filblks_t blockcount;
|
|
|
int error, i;
|
|
|
struct xfs_mount *mp = ip->i_mount;
|
|
|
|
|
|
- xfs_bmbt_get_all(gotp, &got);
|
|
|
- xfs_bmbt_get_all(leftp, &left);
|
|
|
- blockcount = left.br_blockcount + got.br_blockcount;
|
|
|
+ blockcount = left->br_blockcount + got->br_blockcount;
|
|
|
|
|
|
ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
|
|
|
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
|
|
- ASSERT(xfs_bmse_can_merge(&left, &got, shift));
|
|
|
+ ASSERT(xfs_bmse_can_merge(left, got, shift));
|
|
|
|
|
|
- /*
|
|
|
- * Merge the in-core extents. Note that the host record pointers and
|
|
|
- * current_ext index are invalid once the extent has been removed via
|
|
|
- * xfs_iext_remove().
|
|
|
- */
|
|
|
- xfs_bmbt_set_blockcount(leftp, blockcount);
|
|
|
- xfs_iext_remove(ip, current_ext, 1, 0);
|
|
|
+ new = *left;
|
|
|
+ new.br_blockcount = blockcount;
|
|
|
|
|
|
/*
|
|
|
* Update the on-disk extent count, the btree if necessary and log the
|
|
@@ -5912,12 +5911,12 @@ xfs_bmse_merge(
|
|
|
*logflags |= XFS_ILOG_CORE;
|
|
|
if (!cur) {
|
|
|
*logflags |= XFS_ILOG_DEXT;
|
|
|
- return 0;
|
|
|
+ goto done;
|
|
|
}
|
|
|
|
|
|
/* lookup and remove the extent to merge */
|
|
|
- error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
|
|
|
- got.br_blockcount, &i);
|
|
|
+ error = xfs_bmbt_lookup_eq(cur, got->br_startoff, got->br_startblock,
|
|
|
+ got->br_blockcount, &i);
|
|
|
if (error)
|
|
|
return error;
|
|
|
XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
|
|
@@ -5928,16 +5927,28 @@ xfs_bmse_merge(
|
|
|
XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
|
|
|
|
|
|
/* lookup and update size of the previous extent */
|
|
|
- error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock,
|
|
|
- left.br_blockcount, &i);
|
|
|
+ error = xfs_bmbt_lookup_eq(cur, left->br_startoff, left->br_startblock,
|
|
|
+ left->br_blockcount, &i);
|
|
|
if (error)
|
|
|
return error;
|
|
|
XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
|
|
|
|
|
|
- left.br_blockcount = blockcount;
|
|
|
+ error = xfs_bmbt_update(cur, new.br_startoff, new.br_startblock,
|
|
|
+ new.br_blockcount, new.br_state);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+
|
|
|
+done:
|
|
|
+ xfs_iext_update_extent(ifp, current_ext - 1, &new);
|
|
|
+ xfs_iext_remove(ip, current_ext, 1, 0);
|
|
|
|
|
|
- return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
|
|
|
- left.br_blockcount, left.br_state);
|
|
|
+ /* update reverse mapping. rmap functions merge the rmaps for us */
|
|
|
+ error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ memcpy(&new, got, sizeof(new));
|
|
|
+ new.br_startoff = left->br_startoff + left->br_blockcount;
|
|
|
+ return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -5949,7 +5960,7 @@ xfs_bmse_shift_one(
|
|
|
int whichfork,
|
|
|
xfs_fileoff_t offset_shift_fsb,
|
|
|
int *current_ext,
|
|
|
- struct xfs_bmbt_rec_host *gotp,
|
|
|
+ struct xfs_bmbt_irec *got,
|
|
|
struct xfs_btree_cur *cur,
|
|
|
int *logflags,
|
|
|
enum shift_direction direction,
|
|
@@ -5958,9 +5969,7 @@ xfs_bmse_shift_one(
|
|
|
struct xfs_ifork *ifp;
|
|
|
struct xfs_mount *mp;
|
|
|
xfs_fileoff_t startoff;
|
|
|
- struct xfs_bmbt_rec_host *adj_irecp;
|
|
|
- struct xfs_bmbt_irec got;
|
|
|
- struct xfs_bmbt_irec adj_irec;
|
|
|
+ struct xfs_bmbt_irec adj_irec, new;
|
|
|
int error;
|
|
|
int i;
|
|
|
int total_extents;
|
|
@@ -5969,13 +5978,11 @@ xfs_bmse_shift_one(
|
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
total_extents = xfs_iext_count(ifp);
|
|
|
|
|
|
- xfs_bmbt_get_all(gotp, &got);
|
|
|
-
|
|
|
/* delalloc extents should be prevented by caller */
|
|
|
- XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock));
|
|
|
+ XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got->br_startblock));
|
|
|
|
|
|
if (direction == SHIFT_LEFT) {
|
|
|
- startoff = got.br_startoff - offset_shift_fsb;
|
|
|
+ startoff = got->br_startoff - offset_shift_fsb;
|
|
|
|
|
|
/*
|
|
|
* Check for merge if we've got an extent to the left,
|
|
@@ -5983,46 +5990,39 @@ xfs_bmse_shift_one(
|
|
|
* of the file for the shift.
|
|
|
*/
|
|
|
if (!*current_ext) {
|
|
|
- if (got.br_startoff < offset_shift_fsb)
|
|
|
+ if (got->br_startoff < offset_shift_fsb)
|
|
|
return -EINVAL;
|
|
|
goto update_current_ext;
|
|
|
}
|
|
|
+
|
|
|
/*
|
|
|
- * grab the left extent and check for a large
|
|
|
- * enough hole.
|
|
|
+ * grab the left extent and check for a large enough hole.
|
|
|
*/
|
|
|
- adj_irecp = xfs_iext_get_ext(ifp, *current_ext - 1);
|
|
|
- xfs_bmbt_get_all(adj_irecp, &adj_irec);
|
|
|
-
|
|
|
- if (startoff <
|
|
|
- adj_irec.br_startoff + adj_irec.br_blockcount)
|
|
|
+ xfs_iext_get_extent(ifp, *current_ext - 1, &adj_irec);
|
|
|
+ if (startoff < adj_irec.br_startoff + adj_irec.br_blockcount)
|
|
|
return -EINVAL;
|
|
|
|
|
|
/* check whether to merge the extent or shift it down */
|
|
|
- if (xfs_bmse_can_merge(&adj_irec, &got,
|
|
|
- offset_shift_fsb)) {
|
|
|
- error = xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
|
|
|
- *current_ext, gotp, adj_irecp,
|
|
|
- cur, logflags);
|
|
|
- if (error)
|
|
|
- return error;
|
|
|
- adj_irec = got;
|
|
|
- goto update_rmap;
|
|
|
+ if (xfs_bmse_can_merge(&adj_irec, got, offset_shift_fsb)) {
|
|
|
+ return xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
|
|
|
+ *current_ext, got, &adj_irec,
|
|
|
+ cur, logflags, dfops);
|
|
|
}
|
|
|
} else {
|
|
|
- startoff = got.br_startoff + offset_shift_fsb;
|
|
|
+ startoff = got->br_startoff + offset_shift_fsb;
|
|
|
/* nothing to move if this is the last extent */
|
|
|
if (*current_ext >= (total_extents - 1))
|
|
|
goto update_current_ext;
|
|
|
+
|
|
|
/*
|
|
|
* If this is not the last extent in the file, make sure there
|
|
|
* is enough room between current extent and next extent for
|
|
|
* accommodating the shift.
|
|
|
*/
|
|
|
- adj_irecp = xfs_iext_get_ext(ifp, *current_ext + 1);
|
|
|
- xfs_bmbt_get_all(adj_irecp, &adj_irec);
|
|
|
- if (startoff + got.br_blockcount > adj_irec.br_startoff)
|
|
|
+ xfs_iext_get_extent(ifp, *current_ext + 1, &adj_irec);
|
|
|
+ if (startoff + got->br_blockcount > adj_irec.br_startoff)
|
|
|
return -EINVAL;
|
|
|
+
|
|
|
/*
|
|
|
* Unlike a left shift (which involves a hole punch),
|
|
|
* a right shift does not modify extent neighbors
|
|
@@ -6030,45 +6030,48 @@ xfs_bmse_shift_one(
|
|
|
* in this scenario. Check anyways and warn if we
|
|
|
* encounter two extents that could be one.
|
|
|
*/
|
|
|
- if (xfs_bmse_can_merge(&got, &adj_irec, offset_shift_fsb))
|
|
|
+ if (xfs_bmse_can_merge(got, &adj_irec, offset_shift_fsb))
|
|
|
WARN_ON_ONCE(1);
|
|
|
}
|
|
|
+
|
|
|
/*
|
|
|
* Increment the extent index for the next iteration, update the start
|
|
|
* offset of the in-core extent and update the btree if applicable.
|
|
|
*/
|
|
|
update_current_ext:
|
|
|
- if (direction == SHIFT_LEFT)
|
|
|
- (*current_ext)++;
|
|
|
- else
|
|
|
- (*current_ext)--;
|
|
|
- xfs_bmbt_set_startoff(gotp, startoff);
|
|
|
*logflags |= XFS_ILOG_CORE;
|
|
|
- adj_irec = got;
|
|
|
- if (!cur) {
|
|
|
+
|
|
|
+ new = *got;
|
|
|
+ new.br_startoff = startoff;
|
|
|
+
|
|
|
+ if (cur) {
|
|
|
+ error = xfs_bmbt_lookup_eq(cur, got->br_startoff,
|
|
|
+ got->br_startblock, got->br_blockcount, &i);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
|
|
|
+
|
|
|
+ error = xfs_bmbt_update(cur, new.br_startoff,
|
|
|
+ new.br_startblock, new.br_blockcount,
|
|
|
+ new.br_state);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+ } else {
|
|
|
*logflags |= XFS_ILOG_DEXT;
|
|
|
- goto update_rmap;
|
|
|
}
|
|
|
|
|
|
- error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
|
|
|
- got.br_blockcount, &i);
|
|
|
- if (error)
|
|
|
- return error;
|
|
|
- XFS_WANT_CORRUPTED_RETURN(mp, i == 1);
|
|
|
+ xfs_iext_update_extent(ifp, *current_ext, &new);
|
|
|
|
|
|
- got.br_startoff = startoff;
|
|
|
- error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock,
|
|
|
- got.br_blockcount, got.br_state);
|
|
|
- if (error)
|
|
|
- return error;
|
|
|
+ if (direction == SHIFT_LEFT)
|
|
|
+ (*current_ext)++;
|
|
|
+ else
|
|
|
+ (*current_ext)--;
|
|
|
|
|
|
-update_rmap:
|
|
|
/* update reverse mapping */
|
|
|
- error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, &adj_irec);
|
|
|
+ error = xfs_rmap_unmap_extent(mp, dfops, ip, whichfork, got);
|
|
|
if (error)
|
|
|
return error;
|
|
|
- adj_irec.br_startoff = startoff;
|
|
|
- return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &adj_irec);
|
|
|
+ return xfs_rmap_map_extent(mp, dfops, ip, whichfork, &new);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -6095,7 +6098,6 @@ xfs_bmap_shift_extents(
|
|
|
int num_exts)
|
|
|
{
|
|
|
struct xfs_btree_cur *cur = NULL;
|
|
|
- struct xfs_bmbt_rec_host *gotp;
|
|
|
struct xfs_bmbt_irec got;
|
|
|
struct xfs_mount *mp = ip->i_mount;
|
|
|
struct xfs_ifork *ifp;
|
|
@@ -6122,7 +6124,6 @@ xfs_bmap_shift_extents(
|
|
|
ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
|
|
|
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
|
|
|
ASSERT(direction == SHIFT_LEFT || direction == SHIFT_RIGHT);
|
|
|
- ASSERT(*next_fsb != NULLFSBLOCK || direction == SHIFT_RIGHT);
|
|
|
|
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
|
|
@@ -6154,10 +6155,26 @@ xfs_bmap_shift_extents(
|
|
|
* In case of first right shift, we need to initialize next_fsb
|
|
|
*/
|
|
|
if (*next_fsb == NULLFSBLOCK) {
|
|
|
- gotp = xfs_iext_get_ext(ifp, total_extents - 1);
|
|
|
- xfs_bmbt_get_all(gotp, &got);
|
|
|
+ ASSERT(direction == SHIFT_RIGHT);
|
|
|
+
|
|
|
+ current_ext = total_extents - 1;
|
|
|
+ xfs_iext_get_extent(ifp, current_ext, &got);
|
|
|
+ if (stop_fsb > got.br_startoff) {
|
|
|
+ *done = 1;
|
|
|
+ goto del_cursor;
|
|
|
+ }
|
|
|
*next_fsb = got.br_startoff;
|
|
|
- if (stop_fsb > *next_fsb) {
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * Look up the extent index for the fsb where we start shifting. We can
|
|
|
+ * henceforth iterate with current_ext as extent list changes are locked
|
|
|
+ * out via ilock.
|
|
|
+ *
|
|
|
+ * If next_fsb lies in a hole beyond which there are no extents we are
|
|
|
+ * done.
|
|
|
+ */
|
|
|
+ if (!xfs_iext_lookup_extent(ip, ifp, *next_fsb, ¤t_ext,
|
|
|
+ &got)) {
|
|
|
*done = 1;
|
|
|
goto del_cursor;
|
|
|
}
|
|
@@ -6165,37 +6182,26 @@ xfs_bmap_shift_extents(
|
|
|
|
|
|
/* Lookup the extent index at which we have to stop */
|
|
|
if (direction == SHIFT_RIGHT) {
|
|
|
- gotp = xfs_iext_bno_to_ext(ifp, stop_fsb, &stop_extent);
|
|
|
+ struct xfs_bmbt_irec s;
|
|
|
+
|
|
|
+ xfs_iext_lookup_extent(ip, ifp, stop_fsb, &stop_extent, &s);
|
|
|
/* Make stop_extent exclusive of shift range */
|
|
|
stop_extent--;
|
|
|
- } else
|
|
|
+ if (current_ext <= stop_extent) {
|
|
|
+ error = -EIO;
|
|
|
+ goto del_cursor;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
stop_extent = total_extents;
|
|
|
-
|
|
|
- /*
|
|
|
- * Look up the extent index for the fsb where we start shifting. We can
|
|
|
- * henceforth iterate with current_ext as extent list changes are locked
|
|
|
- * out via ilock.
|
|
|
- *
|
|
|
- * gotp can be null in 2 cases: 1) if there are no extents or 2)
|
|
|
- * *next_fsb lies in a hole beyond which there are no extents. Either
|
|
|
- * way, we are done.
|
|
|
- */
|
|
|
- gotp = xfs_iext_bno_to_ext(ifp, *next_fsb, ¤t_ext);
|
|
|
- if (!gotp) {
|
|
|
- *done = 1;
|
|
|
- goto del_cursor;
|
|
|
- }
|
|
|
-
|
|
|
- /* some sanity checking before we finally start shifting extents */
|
|
|
- if ((direction == SHIFT_LEFT && current_ext >= stop_extent) ||
|
|
|
- (direction == SHIFT_RIGHT && current_ext <= stop_extent)) {
|
|
|
- error = -EIO;
|
|
|
- goto del_cursor;
|
|
|
+ if (current_ext >= stop_extent) {
|
|
|
+ error = -EIO;
|
|
|
+ goto del_cursor;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
while (nexts++ < num_exts) {
|
|
|
error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb,
|
|
|
- ¤t_ext, gotp, cur, &logflags,
|
|
|
+ ¤t_ext, &got, cur, &logflags,
|
|
|
direction, dfops);
|
|
|
if (error)
|
|
|
goto del_cursor;
|
|
@@ -6213,13 +6219,11 @@ xfs_bmap_shift_extents(
|
|
|
*next_fsb = NULLFSBLOCK;
|
|
|
break;
|
|
|
}
|
|
|
- gotp = xfs_iext_get_ext(ifp, current_ext);
|
|
|
+ xfs_iext_get_extent(ifp, current_ext, &got);
|
|
|
}
|
|
|
|
|
|
- if (!*done) {
|
|
|
- xfs_bmbt_get_all(gotp, &got);
|
|
|
+ if (!*done)
|
|
|
*next_fsb = got.br_startoff;
|
|
|
- }
|
|
|
|
|
|
del_cursor:
|
|
|
if (cur)
|
|
@@ -6248,7 +6252,6 @@ xfs_bmap_split_extent_at(
|
|
|
{
|
|
|
int whichfork = XFS_DATA_FORK;
|
|
|
struct xfs_btree_cur *cur = NULL;
|
|
|
- struct xfs_bmbt_rec_host *gotp;
|
|
|
struct xfs_bmbt_irec got;
|
|
|
struct xfs_bmbt_irec new; /* split extent */
|
|
|
struct xfs_mount *mp = ip->i_mount;
|
|
@@ -6280,21 +6283,10 @@ xfs_bmap_split_extent_at(
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * gotp can be null in 2 cases: 1) if there are no extents
|
|
|
- * or 2) split_fsb lies in a hole beyond which there are
|
|
|
- * no extents. Either way, we are done.
|
|
|
- */
|
|
|
- gotp = xfs_iext_bno_to_ext(ifp, split_fsb, ¤t_ext);
|
|
|
- if (!gotp)
|
|
|
- return 0;
|
|
|
-
|
|
|
- xfs_bmbt_get_all(gotp, &got);
|
|
|
-
|
|
|
- /*
|
|
|
- * Check split_fsb lies in a hole or the start boundary offset
|
|
|
- * of the extent.
|
|
|
+ * If there are not extents, or split_fsb lies in a hole we are done.
|
|
|
*/
|
|
|
- if (got.br_startoff >= split_fsb)
|
|
|
+ if (!xfs_iext_lookup_extent(ip, ifp, split_fsb, ¤t_ext, &got) ||
|
|
|
+ got.br_startoff >= split_fsb)
|
|
|
return 0;
|
|
|
|
|
|
gotblkcnt = split_fsb - got.br_startoff;
|
|
@@ -6317,8 +6309,8 @@ xfs_bmap_split_extent_at(
|
|
|
XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor);
|
|
|
}
|
|
|
|
|
|
- xfs_bmbt_set_blockcount(gotp, gotblkcnt);
|
|
|
got.br_blockcount = gotblkcnt;
|
|
|
+ xfs_iext_update_extent(ifp, current_ext, &got);
|
|
|
|
|
|
logflags = XFS_ILOG_CORE;
|
|
|
if (cur) {
|
|
@@ -6402,7 +6394,7 @@ xfs_bmap_split_extent(
|
|
|
if (error)
|
|
|
goto out;
|
|
|
|
|
|
- error = xfs_defer_finish(&tp, &dfops, NULL);
|
|
|
+ error = xfs_defer_finish(&tp, &dfops);
|
|
|
if (error)
|
|
|
goto out;
|
|
|
|
|
@@ -6452,7 +6444,7 @@ __xfs_bmap_add(
|
|
|
bi->bi_whichfork = whichfork;
|
|
|
bi->bi_bmap = *bmap;
|
|
|
|
|
|
- error = xfs_defer_join(dfops, bi->bi_owner);
|
|
|
+ error = xfs_defer_ijoin(dfops, bi->bi_owner);
|
|
|
if (error) {
|
|
|
kmem_free(bi);
|
|
|
return error;
|