|
@@ -42,35 +42,6 @@ STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int);
|
|
|
STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
|
|
|
STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int);
|
|
|
|
|
|
-#ifdef DEBUG
|
|
|
-/*
|
|
|
- * Make sure that the extents in the given memory buffer
|
|
|
- * are valid.
|
|
|
- */
|
|
|
-void
|
|
|
-xfs_validate_extents(
|
|
|
- xfs_ifork_t *ifp,
|
|
|
- int nrecs,
|
|
|
- xfs_exntfmt_t fmt)
|
|
|
-{
|
|
|
- xfs_bmbt_irec_t irec;
|
|
|
- xfs_bmbt_rec_host_t rec;
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; i < nrecs; i++) {
|
|
|
- xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
|
|
|
- rec.l0 = get_unaligned(&ep->l0);
|
|
|
- rec.l1 = get_unaligned(&ep->l1);
|
|
|
- xfs_bmbt_get_all(&rec, &irec);
|
|
|
- if (fmt == XFS_EXTFMT_NOSTATE)
|
|
|
- ASSERT(irec.br_state == XFS_EXT_NORM);
|
|
|
- }
|
|
|
-}
|
|
|
-#else /* DEBUG */
|
|
|
-#define xfs_validate_extents(ifp, nrecs, fmt)
|
|
|
-#endif /* DEBUG */
|
|
|
-
|
|
|
-
|
|
|
/*
|
|
|
* Move inode type and inode format specific information from the
|
|
|
* on-disk inode to the in-core inode. For fifos, devs, and sockets
|
|
@@ -352,40 +323,33 @@ xfs_iformat_local(
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * The file consists of a set of extents all
|
|
|
- * of which fit into the on-disk inode.
|
|
|
- * If there are few enough extents to fit into
|
|
|
- * the if_inline_ext, then copy them there.
|
|
|
- * Otherwise allocate a buffer for them and copy
|
|
|
- * them into it. Either way, set if_extents
|
|
|
- * to point at the extents.
|
|
|
+ * The file consists of a set of extents all of which fit into the on-disk
|
|
|
+ * inode. If there are few enough extents to fit into the if_inline_ext, then
|
|
|
+ * copy them there. Otherwise allocate a buffer for them and copy them into it.
|
|
|
+ * Either way, set if_extents to point at the extents.
|
|
|
*/
|
|
|
STATIC int
|
|
|
xfs_iformat_extents(
|
|
|
- xfs_inode_t *ip,
|
|
|
- xfs_dinode_t *dip,
|
|
|
- int whichfork)
|
|
|
+ struct xfs_inode *ip,
|
|
|
+ struct xfs_dinode *dip,
|
|
|
+ int whichfork)
|
|
|
{
|
|
|
- xfs_bmbt_rec_t *dp;
|
|
|
- xfs_ifork_t *ifp;
|
|
|
- int nex;
|
|
|
- int size;
|
|
|
- int i;
|
|
|
-
|
|
|
- ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
- nex = XFS_DFORK_NEXTENTS(dip, whichfork);
|
|
|
- size = nex * (uint)sizeof(xfs_bmbt_rec_t);
|
|
|
+ struct xfs_mount *mp = ip->i_mount;
|
|
|
+ struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
|
|
|
+ int nex = XFS_DFORK_NEXTENTS(dip, whichfork);
|
|
|
+ int size = nex * sizeof(xfs_bmbt_rec_t);
|
|
|
+ struct xfs_bmbt_rec *dp;
|
|
|
+ int i;
|
|
|
|
|
|
/*
|
|
|
- * If the number of extents is unreasonable, then something
|
|
|
- * is wrong and we just bail out rather than crash in
|
|
|
- * kmem_alloc() or memcpy() below.
|
|
|
+ * If the number of extents is unreasonable, then something is wrong and
|
|
|
+ * we just bail out rather than crash in kmem_alloc() or memcpy() below.
|
|
|
*/
|
|
|
- if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
|
|
|
+ if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
|
|
|
xfs_warn(ip->i_mount, "corrupt inode %Lu ((a)extents = %d).",
|
|
|
(unsigned long long) ip->i_ino, nex);
|
|
|
XFS_CORRUPTION_ERROR("xfs_iformat_extents(1)", XFS_ERRLEVEL_LOW,
|
|
|
- ip->i_mount, dip);
|
|
|
+ mp, dip);
|
|
|
return -EFSCORRUPTED;
|
|
|
}
|
|
|
|
|
@@ -400,22 +364,17 @@ xfs_iformat_extents(
|
|
|
ifp->if_bytes = size;
|
|
|
if (size) {
|
|
|
dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
|
|
|
- xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip));
|
|
|
for (i = 0; i < nex; i++, dp++) {
|
|
|
xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
|
|
|
ep->l0 = get_unaligned_be64(&dp->l0);
|
|
|
ep->l1 = get_unaligned_be64(&dp->l1);
|
|
|
+ if (!xfs_bmbt_validate_extent(mp, whichfork, ep)) {
|
|
|
+ XFS_ERROR_REPORT("xfs_iformat_extents(2)",
|
|
|
+ XFS_ERRLEVEL_LOW, mp);
|
|
|
+ return -EFSCORRUPTED;
|
|
|
+ }
|
|
|
}
|
|
|
XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork);
|
|
|
- if (whichfork != XFS_DATA_FORK ||
|
|
|
- XFS_EXTFMT_INODE(ip) == XFS_EXTFMT_NOSTATE)
|
|
|
- if (unlikely(xfs_check_nostate_extents(
|
|
|
- ifp, 0, nex))) {
|
|
|
- XFS_ERROR_REPORT("xfs_iformat_extents(2)",
|
|
|
- XFS_ERRLEVEL_LOW,
|
|
|
- ip->i_mount);
|
|
|
- return -EFSCORRUPTED;
|
|
|
- }
|
|
|
}
|
|
|
ifp->if_flags |= XFS_IFEXTENTS;
|
|
|
return 0;
|
|
@@ -518,7 +477,6 @@ xfs_iread_extents(
|
|
|
xfs_iext_destroy(ifp);
|
|
|
return error;
|
|
|
}
|
|
|
- xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
|
|
|
ifp->if_flags |= XFS_IFEXTENTS;
|
|
|
return 0;
|
|
|
}
|
|
@@ -837,6 +795,9 @@ xfs_iextents_copy(
|
|
|
copied = 0;
|
|
|
for (i = 0; i < nrecs; i++) {
|
|
|
xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i);
|
|
|
+
|
|
|
+ ASSERT(xfs_bmbt_validate_extent(ip->i_mount, whichfork, ep));
|
|
|
+
|
|
|
start_block = xfs_bmbt_get_startblock(ep);
|
|
|
if (isnullstartblock(start_block)) {
|
|
|
/*
|
|
@@ -852,7 +813,6 @@ xfs_iextents_copy(
|
|
|
copied++;
|
|
|
}
|
|
|
ASSERT(copied != 0);
|
|
|
- xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip));
|
|
|
|
|
|
return (copied * (uint)sizeof(xfs_bmbt_rec_t));
|
|
|
}
|