summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c31
-rw-r--r--fs/xfs/libxfs/xfs_bmap.h2
-rw-r--r--fs/xfs/libxfs/xfs_inode_fork.c3
3 files changed, 34 insertions, 2 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index 0b4fb3979bdc..5e66807737c5 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -1083,6 +1083,34 @@ struct xfs_iread_state {
xfs_extnum_t loaded;
};
+int
+xfs_bmap_complain_bad_rec(
+ struct xfs_inode *ip,
+ int whichfork,
+ xfs_failaddr_t fa,
+ const struct xfs_bmbt_irec *irec)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ const char *forkname;
+
+ switch (whichfork) {
+ case XFS_DATA_FORK: forkname = "data"; break;
+ case XFS_ATTR_FORK: forkname = "attr"; break;
+ case XFS_COW_FORK: forkname = "CoW"; break;
+ default: forkname = "???"; break;
+ }
+
+ xfs_warn(mp,
+ "Bmap BTree record corruption in inode 0x%llx %s fork detected at %pS!",
+ ip->i_ino, forkname, fa);
+ xfs_warn(mp,
+ "Offset 0x%llx, start block 0x%llx, block count 0x%llx state 0x%x",
+ irec->br_startoff, irec->br_startblock, irec->br_blockcount,
+ irec->br_state);
+
+ return -EFSCORRUPTED;
+}
+
/* Stuff every bmbt record from this block into the incore extent map. */
static int
xfs_iread_bmbt_block(
@@ -1125,7 +1153,8 @@ xfs_iread_bmbt_block(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iread_extents(2)", frp,
sizeof(*frp), fa);
- return -EFSCORRUPTED;
+ return xfs_bmap_complain_bad_rec(ip, whichfork, fa,
+ &new);
}
xfs_iext_insert(ip, &ir->icur, &new,
xfs_bmap_fork_to_state(whichfork));
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index e5a492027aea..9ff030d12981 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -265,6 +265,8 @@ static inline uint32_t xfs_bmap_fork_to_state(int whichfork)
xfs_failaddr_t xfs_bmap_validate_extent(struct xfs_inode *ip, int whichfork,
struct xfs_bmbt_irec *irec);
+int xfs_bmap_complain_bad_rec(struct xfs_inode *ip, int whichfork,
+ xfs_failaddr_t fa, const struct xfs_bmbt_irec *irec);
int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip,
xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock,
diff --git a/fs/xfs/libxfs/xfs_inode_fork.c b/fs/xfs/libxfs/xfs_inode_fork.c
index 6b21760184d9..ff37eecec4b0 100644
--- a/fs/xfs/libxfs/xfs_inode_fork.c
+++ b/fs/xfs/libxfs/xfs_inode_fork.c
@@ -140,7 +140,8 @@ xfs_iformat_extents(
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_extents(2)",
dp, sizeof(*dp), fa);
- return -EFSCORRUPTED;
+ return xfs_bmap_complain_bad_rec(ip, whichfork,
+ fa, &new);
}
xfs_iext_insert(ip, &icur, &new, state);