|
@@ -249,7 +249,27 @@ xfs_bmbt_lookup_ge(
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
-* Update the record referred to by cur to the value given
|
|
|
|
|
|
+ * Check if the inode needs to be converted to btree format.
|
|
|
|
+ */
|
|
|
|
+static inline bool xfs_bmap_needs_btree(struct xfs_inode *ip, int whichfork)
|
|
|
|
+{
|
|
|
|
+ return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
+ XFS_IFORK_NEXTENTS(ip, whichfork) >
|
|
|
|
+ XFS_IFORK_MAXEXT(ip, whichfork);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Check if the inode should be converted to extent format.
|
|
|
|
+ */
|
|
|
|
+static inline bool xfs_bmap_wants_extents(struct xfs_inode *ip, int whichfork)
|
|
|
|
+{
|
|
|
|
+ return XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
|
|
|
|
+ XFS_IFORK_NEXTENTS(ip, whichfork) <=
|
|
|
|
+ XFS_IFORK_MAXEXT(ip, whichfork);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Update the record referred to by cur to the value given
|
|
* by [off, bno, len, state].
|
|
* by [off, bno, len, state].
|
|
* This either works (return 0) or gets an EFSCORRUPTED error.
|
|
* This either works (return 0) or gets an EFSCORRUPTED error.
|
|
*/
|
|
*/
|
|
@@ -683,8 +703,8 @@ xfs_bmap_add_extent_delay_real(
|
|
goto done;
|
|
goto done;
|
|
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
|
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
|
}
|
|
}
|
|
- if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
- bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) {
|
|
|
|
|
|
+
|
|
|
|
+ if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
|
|
error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
|
|
error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
|
|
bma->firstblock, bma->flist,
|
|
bma->firstblock, bma->flist,
|
|
&bma->cur, 1, &tmp_rval, XFS_DATA_FORK);
|
|
&bma->cur, 1, &tmp_rval, XFS_DATA_FORK);
|
|
@@ -767,8 +787,8 @@ xfs_bmap_add_extent_delay_real(
|
|
goto done;
|
|
goto done;
|
|
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
|
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
|
}
|
|
}
|
|
- if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
- bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) {
|
|
|
|
|
|
+
|
|
|
|
+ if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
|
|
error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
|
|
error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
|
|
bma->firstblock, bma->flist, &bma->cur, 1,
|
|
bma->firstblock, bma->flist, &bma->cur, 1,
|
|
&tmp_rval, XFS_DATA_FORK);
|
|
&tmp_rval, XFS_DATA_FORK);
|
|
@@ -836,8 +856,8 @@ xfs_bmap_add_extent_delay_real(
|
|
goto done;
|
|
goto done;
|
|
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
|
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
|
|
}
|
|
}
|
|
- if (bma->ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
- bma->ip->i_d.di_nextents > bma->ip->i_df.if_ext_max) {
|
|
|
|
|
|
+
|
|
|
|
+ if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
|
|
error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
|
|
error = xfs_bmap_extents_to_btree(bma->tp, bma->ip,
|
|
bma->firstblock, bma->flist, &bma->cur,
|
|
bma->firstblock, bma->flist, &bma->cur,
|
|
1, &tmp_rval, XFS_DATA_FORK);
|
|
1, &tmp_rval, XFS_DATA_FORK);
|
|
@@ -884,8 +904,7 @@ xfs_bmap_add_extent_delay_real(
|
|
}
|
|
}
|
|
|
|
|
|
/* convert to a btree if necessary */
|
|
/* convert to a btree if necessary */
|
|
- if (XFS_IFORK_FORMAT(bma->ip, XFS_DATA_FORK) == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
- XFS_IFORK_NEXTENTS(bma->ip, XFS_DATA_FORK) > ifp->if_ext_max) {
|
|
|
|
|
|
+ if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) {
|
|
int tmp_logflags; /* partial log flag return val */
|
|
int tmp_logflags; /* partial log flag return val */
|
|
|
|
|
|
ASSERT(bma->cur == NULL);
|
|
ASSERT(bma->cur == NULL);
|
|
@@ -1421,8 +1440,7 @@ xfs_bmap_add_extent_unwritten_real(
|
|
}
|
|
}
|
|
|
|
|
|
/* convert to a btree if necessary */
|
|
/* 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) {
|
|
|
|
|
|
+ if (xfs_bmap_needs_btree(ip, XFS_DATA_FORK)) {
|
|
int tmp_logflags; /* partial log flag return val */
|
|
int tmp_logflags; /* partial log flag return val */
|
|
|
|
|
|
ASSERT(cur == NULL);
|
|
ASSERT(cur == NULL);
|
|
@@ -1812,8 +1830,7 @@ xfs_bmap_add_extent_hole_real(
|
|
}
|
|
}
|
|
|
|
|
|
/* convert to a btree if necessary */
|
|
/* convert to a btree if necessary */
|
|
- if (XFS_IFORK_FORMAT(bma->ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
|
|
|
- XFS_IFORK_NEXTENTS(bma->ip, whichfork) > ifp->if_ext_max) {
|
|
|
|
|
|
+ if (xfs_bmap_needs_btree(bma->ip, whichfork)) {
|
|
int tmp_logflags; /* partial log flag return val */
|
|
int tmp_logflags; /* partial log flag return val */
|
|
|
|
|
|
ASSERT(bma->cur == NULL);
|
|
ASSERT(bma->cur == NULL);
|
|
@@ -3037,8 +3054,7 @@ xfs_bmap_extents_to_btree(
|
|
|
|
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS);
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Make space in the inode incore.
|
|
* Make space in the inode incore.
|
|
*/
|
|
*/
|
|
@@ -3184,13 +3200,8 @@ xfs_bmap_forkoff_reset(
|
|
ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
|
|
ip->i_d.di_format != XFS_DINODE_FMT_BTREE) {
|
|
uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
|
|
uint dfl_forkoff = xfs_default_attroffset(ip) >> 3;
|
|
|
|
|
|
- if (dfl_forkoff > ip->i_d.di_forkoff) {
|
|
|
|
|
|
+ if (dfl_forkoff > ip->i_d.di_forkoff)
|
|
ip->i_d.di_forkoff = dfl_forkoff;
|
|
ip->i_d.di_forkoff = dfl_forkoff;
|
|
- ip->i_df.if_ext_max =
|
|
|
|
- XFS_IFORK_DSIZE(ip) / sizeof(xfs_bmbt_rec_t);
|
|
|
|
- ip->i_afp->if_ext_max =
|
|
|
|
- XFS_IFORK_ASIZE(ip) / sizeof(xfs_bmbt_rec_t);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3430,8 +3441,6 @@ xfs_bmap_add_attrfork(
|
|
int error; /* error return value */
|
|
int error; /* error return value */
|
|
|
|
|
|
ASSERT(XFS_IFORK_Q(ip) == 0);
|
|
ASSERT(XFS_IFORK_Q(ip) == 0);
|
|
- ASSERT(ip->i_df.if_ext_max ==
|
|
|
|
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
|
|
mp = ip->i_mount;
|
|
mp = ip->i_mount;
|
|
ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
|
|
ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
|
|
@@ -3486,12 +3495,9 @@ xfs_bmap_add_attrfork(
|
|
error = XFS_ERROR(EINVAL);
|
|
error = XFS_ERROR(EINVAL);
|
|
goto error1;
|
|
goto error1;
|
|
}
|
|
}
|
|
- ip->i_df.if_ext_max =
|
|
|
|
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
|
|
|
|
|
|
+
|
|
ASSERT(ip->i_afp == NULL);
|
|
ASSERT(ip->i_afp == NULL);
|
|
ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
|
|
ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP);
|
|
- ip->i_afp->if_ext_max =
|
|
|
|
- XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t);
|
|
|
|
ip->i_afp->if_flags = XFS_IFEXTENTS;
|
|
ip->i_afp->if_flags = XFS_IFEXTENTS;
|
|
logflags = 0;
|
|
logflags = 0;
|
|
xfs_bmap_init(&flist, &firstblock);
|
|
xfs_bmap_init(&flist, &firstblock);
|
|
@@ -3535,20 +3541,17 @@ xfs_bmap_add_attrfork(
|
|
} else
|
|
} else
|
|
spin_unlock(&mp->m_sb_lock);
|
|
spin_unlock(&mp->m_sb_lock);
|
|
}
|
|
}
|
|
- if ((error = xfs_bmap_finish(&tp, &flist, &committed)))
|
|
|
|
|
|
+
|
|
|
|
+ error = xfs_bmap_finish(&tp, &flist, &committed);
|
|
|
|
+ if (error)
|
|
goto error2;
|
|
goto error2;
|
|
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
|
|
|
- ASSERT(ip->i_df.if_ext_max ==
|
|
|
|
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
- return error;
|
|
|
|
|
|
+ return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
|
error2:
|
|
error2:
|
|
xfs_bmap_cancel(&flist);
|
|
xfs_bmap_cancel(&flist);
|
|
error1:
|
|
error1:
|
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
|
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
|
error0:
|
|
error0:
|
|
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
|
|
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
|
|
- ASSERT(ip->i_df.if_ext_max ==
|
|
|
|
- XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4379,8 +4382,6 @@ xfs_bmapi_read(
|
|
XFS_STATS_INC(xs_blk_mapr);
|
|
XFS_STATS_INC(xs_blk_mapr);
|
|
|
|
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
|
|
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
|
|
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
|
|
error = xfs_iread_extents(NULL, ip, whichfork);
|
|
error = xfs_iread_extents(NULL, ip, whichfork);
|
|
@@ -4871,8 +4872,6 @@ xfs_bmapi_write(
|
|
return XFS_ERROR(EIO);
|
|
return XFS_ERROR(EIO);
|
|
|
|
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
|
|
XFS_STATS_INC(xs_blk_mapw);
|
|
XFS_STATS_INC(xs_blk_mapw);
|
|
|
|
|
|
@@ -4981,8 +4980,7 @@ xfs_bmapi_write(
|
|
/*
|
|
/*
|
|
* Transform from btree to extents, give it cur.
|
|
* Transform from btree to extents, give it cur.
|
|
*/
|
|
*/
|
|
- if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
|
|
|
|
- XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
|
|
|
|
|
|
+ if (xfs_bmap_wants_extents(ip, whichfork)) {
|
|
int tmp_logflags = 0;
|
|
int tmp_logflags = 0;
|
|
|
|
|
|
ASSERT(bma.cur);
|
|
ASSERT(bma.cur);
|
|
@@ -4992,10 +4990,10 @@ xfs_bmapi_write(
|
|
if (error)
|
|
if (error)
|
|
goto error0;
|
|
goto error0;
|
|
}
|
|
}
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
+
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
|
|
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
|
|
- XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
|
|
|
|
|
|
+ XFS_IFORK_NEXTENTS(ip, whichfork) >
|
|
|
|
+ XFS_IFORK_MAXEXT(ip, whichfork));
|
|
error = 0;
|
|
error = 0;
|
|
error0:
|
|
error0:
|
|
/*
|
|
/*
|
|
@@ -5095,8 +5093,7 @@ xfs_bunmapi(
|
|
|
|
|
|
ASSERT(len > 0);
|
|
ASSERT(len > 0);
|
|
ASSERT(nexts >= 0);
|
|
ASSERT(nexts >= 0);
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
+
|
|
if (!(ifp->if_flags & XFS_IFEXTENTS) &&
|
|
if (!(ifp->if_flags & XFS_IFEXTENTS) &&
|
|
(error = xfs_iread_extents(tp, ip, whichfork)))
|
|
(error = xfs_iread_extents(tp, ip, whichfork)))
|
|
return error;
|
|
return error;
|
|
@@ -5322,7 +5319,8 @@ xfs_bunmapi(
|
|
*/
|
|
*/
|
|
if (!wasdel && xfs_trans_get_block_res(tp) == 0 &&
|
|
if (!wasdel && xfs_trans_get_block_res(tp) == 0 &&
|
|
XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
|
XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS &&
|
|
- XFS_IFORK_NEXTENTS(ip, whichfork) >= ifp->if_ext_max &&
|
|
|
|
|
|
+ XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */
|
|
|
|
+ XFS_IFORK_MAXEXT(ip, whichfork) &&
|
|
del.br_startoff > got.br_startoff &&
|
|
del.br_startoff > got.br_startoff &&
|
|
del.br_startoff + del.br_blockcount <
|
|
del.br_startoff + del.br_blockcount <
|
|
got.br_startoff + got.br_blockcount) {
|
|
got.br_startoff + got.br_blockcount) {
|
|
@@ -5353,13 +5351,11 @@ nodelete:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
|
|
*done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0;
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Convert to a btree if necessary.
|
|
* 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) {
|
|
|
|
|
|
+ if (xfs_bmap_needs_btree(ip, whichfork)) {
|
|
ASSERT(cur == NULL);
|
|
ASSERT(cur == NULL);
|
|
error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist,
|
|
error = xfs_bmap_extents_to_btree(tp, ip, firstblock, flist,
|
|
&cur, 0, &tmp_logflags, whichfork);
|
|
&cur, 0, &tmp_logflags, whichfork);
|
|
@@ -5370,8 +5366,7 @@ nodelete:
|
|
/*
|
|
/*
|
|
* transform from btree to extents, give it cur
|
|
* transform from btree to extents, give it cur
|
|
*/
|
|
*/
|
|
- else if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE &&
|
|
|
|
- XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) {
|
|
|
|
|
|
+ else if (xfs_bmap_wants_extents(ip, whichfork)) {
|
|
ASSERT(cur != NULL);
|
|
ASSERT(cur != NULL);
|
|
error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
|
|
error = xfs_bmap_btree_to_extents(tp, ip, cur, &tmp_logflags,
|
|
whichfork);
|
|
whichfork);
|
|
@@ -5382,8 +5377,6 @@ nodelete:
|
|
/*
|
|
/*
|
|
* transform from extents to local?
|
|
* transform from extents to local?
|
|
*/
|
|
*/
|
|
- ASSERT(ifp->if_ext_max ==
|
|
|
|
- XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
|
error = 0;
|
|
error = 0;
|
|
error0:
|
|
error0:
|
|
/*
|
|
/*
|