Commit baf44fa5 authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: report inode corruption errors to the health system

Whenever we encounter corrupt inode records, we should report that to
the health monitoring system for later reporting.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent b280fb0c
...@@ -2999,6 +2999,7 @@ xfs_ialloc_check_shrink( ...@@ -2999,6 +2999,7 @@ xfs_ialloc_check_shrink(
goto out; goto out;
if (!has) { if (!has) {
xfs_ag_mark_sick(pag, XFS_SICK_AG_INOBT);
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
goto out; goto out;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_ialloc.h" #include "xfs_ialloc.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_health.h"
#include <linux/iversion.h> #include <linux/iversion.h>
...@@ -132,9 +133,14 @@ xfs_imap_to_bp( ...@@ -132,9 +133,14 @@ xfs_imap_to_bp(
struct xfs_imap *imap, struct xfs_imap *imap,
struct xfs_buf **bpp) struct xfs_buf **bpp)
{ {
return xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, int error;
imap->im_len, XBF_UNMAPPED, bpp,
&xfs_inode_buf_ops); error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
imap->im_len, XBF_UNMAPPED, bpp, &xfs_inode_buf_ops);
if (xfs_metadata_is_sick(error))
xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, imap->im_blkno),
XFS_SICK_AG_INOBT);
return error;
} }
static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts) static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "xfs_attr_leaf.h" #include "xfs_attr_leaf.h"
#include "xfs_types.h" #include "xfs_types.h"
#include "xfs_errortag.h" #include "xfs_errortag.h"
#include "xfs_health.h"
struct kmem_cache *xfs_ifork_cache; struct kmem_cache *xfs_ifork_cache;
...@@ -88,6 +89,7 @@ xfs_iformat_local( ...@@ -88,6 +89,7 @@ xfs_iformat_local(
xfs_inode_verifier_error(ip, -EFSCORRUPTED, xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_local", dip, sizeof(*dip), "xfs_iformat_local", dip, sizeof(*dip),
__this_address); __this_address);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
...@@ -125,6 +127,7 @@ xfs_iformat_extents( ...@@ -125,6 +127,7 @@ xfs_iformat_extents(
xfs_inode_verifier_error(ip, -EFSCORRUPTED, xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_extents(1)", dip, sizeof(*dip), "xfs_iformat_extents(1)", dip, sizeof(*dip),
__this_address); __this_address);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
...@@ -144,6 +147,7 @@ xfs_iformat_extents( ...@@ -144,6 +147,7 @@ xfs_iformat_extents(
xfs_inode_verifier_error(ip, -EFSCORRUPTED, xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_extents(2)", "xfs_iformat_extents(2)",
dp, sizeof(*dp), fa); dp, sizeof(*dp), fa);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return xfs_bmap_complain_bad_rec(ip, whichfork, return xfs_bmap_complain_bad_rec(ip, whichfork,
fa, &new); fa, &new);
} }
...@@ -202,6 +206,7 @@ xfs_iformat_btree( ...@@ -202,6 +206,7 @@ xfs_iformat_btree(
xfs_inode_verifier_error(ip, -EFSCORRUPTED, xfs_inode_verifier_error(ip, -EFSCORRUPTED,
"xfs_iformat_btree", dfp, size, "xfs_iformat_btree", dfp, size,
__this_address); __this_address);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
...@@ -267,12 +272,14 @@ xfs_iformat_data_fork( ...@@ -267,12 +272,14 @@ xfs_iformat_data_fork(
default: default:
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
dip, sizeof(*dip), __this_address); dip, sizeof(*dip), __this_address);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
break; break;
default: default:
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip, xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
sizeof(*dip), __this_address); sizeof(*dip), __this_address);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
} }
...@@ -344,6 +351,7 @@ xfs_iformat_attr_fork( ...@@ -344,6 +351,7 @@ xfs_iformat_attr_fork(
default: default:
xfs_inode_verifier_error(ip, error, __func__, dip, xfs_inode_verifier_error(ip, error, __func__, dip,
sizeof(*dip), __this_address); sizeof(*dip), __this_address);
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
break; break;
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "xfs_ialloc.h" #include "xfs_ialloc.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_log_priv.h" #include "xfs_log_priv.h"
#include "xfs_health.h"
#include <linux/iversion.h> #include <linux/iversion.h>
...@@ -415,6 +416,9 @@ xfs_iget_check_free_state( ...@@ -415,6 +416,9 @@ xfs_iget_check_free_state(
xfs_warn(ip->i_mount, xfs_warn(ip->i_mount,
"Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)", "Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)",
ip->i_ino, VFS_I(ip)->i_mode); ip->i_ino, VFS_I(ip)->i_mode);
xfs_agno_mark_sick(ip->i_mount,
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
XFS_SICK_AG_INOBT);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
...@@ -422,6 +426,9 @@ xfs_iget_check_free_state( ...@@ -422,6 +426,9 @@ xfs_iget_check_free_state(
xfs_warn(ip->i_mount, xfs_warn(ip->i_mount,
"Corruption detected! Free inode 0x%llx has blocks allocated!", "Corruption detected! Free inode 0x%llx has blocks allocated!",
ip->i_ino); ip->i_ino);
xfs_agno_mark_sick(ip->i_mount,
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
XFS_SICK_AG_INOBT);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
return 0; return 0;
...@@ -640,6 +647,8 @@ xfs_iget_cache_miss( ...@@ -640,6 +647,8 @@ xfs_iget_cache_miss(
xfs_buf_offset(bp, ip->i_imap.im_boffset)); xfs_buf_offset(bp, ip->i_imap.im_boffset));
if (!error) if (!error)
xfs_buf_set_ref(bp, XFS_INO_REF); xfs_buf_set_ref(bp, XFS_INO_REF);
else
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
xfs_trans_brelse(tp, bp); xfs_trans_brelse(tp, bp);
if (error) if (error)
......
...@@ -3422,6 +3422,8 @@ xfs_iflush( ...@@ -3422,6 +3422,8 @@ xfs_iflush(
/* generate the checksum. */ /* generate the checksum. */
xfs_dinode_calc_crc(mp, dip); xfs_dinode_calc_crc(mp, dip);
if (error)
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
return error; return error;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment