]> git.itanic.dy.fi Git - linux-stable/commitdiff
xfs: always log corruption errors
authorDarrick J. Wong <darrick.wong@oracle.com>
Sat, 24 Sep 2022 12:56:48 +0000 (18:26 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 28 Sep 2022 09:04:10 +0000 (11:04 +0200)
commit a5155b870d687de1a5f07e774b49b1e8ef0f6f50 upstream.

Make sure we log something to dmesg whenever we return -EFSCORRUPTED up
the call stack.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25 files changed:
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_da_btree.c
fs/xfs/libxfs/xfs_dir2.c
fs/xfs/libxfs/xfs_dir2_leaf.c
fs/xfs/libxfs/xfs_dir2_node.c
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_refcount.c
fs/xfs/libxfs/xfs_rtbitmap.c
fs/xfs/xfs_acl.c
fs/xfs/xfs_attr_inactive.c
fs/xfs/xfs_attr_list.c
fs/xfs/xfs_bmap_item.c
fs/xfs/xfs_error.c
fs/xfs/xfs_error.h
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_iops.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_qm.c
fs/xfs/xfs_refcount_item.c
fs/xfs/xfs_rmap_item.c

index 436f686a98918eea224a80eadf9fa34eafba46c0..f1cdf5fbaa71608cc07952971433647416dce6de 100644 (file)
@@ -684,8 +684,10 @@ xfs_alloc_update_counters(
 
        xfs_trans_agblocks_delta(tp, len);
        if (unlikely(be32_to_cpu(agf->agf_freeblks) >
-                    be32_to_cpu(agf->agf_length)))
+                    be32_to_cpu(agf->agf_length))) {
+               xfs_buf_corruption_error(agbp);
                return -EFSCORRUPTED;
+       }
 
        xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
        return 0;
@@ -751,6 +753,7 @@ xfs_alloc_ag_vextent_small(
 
                bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno);
                if (!bp) {
+                       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->mp);
                        error = -EFSCORRUPTED;
                        goto error;
                }
@@ -2087,8 +2090,10 @@ xfs_free_agfl_block(
                return error;
 
        bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno);
-       if (!bp)
+       if (!bp) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp);
                return -EFSCORRUPTED;
+       }
        xfs_trans_binval(tp, bp);
 
        return 0;
index de33efc9b4f94e4ea984213873aa6fefaf8ae734..0c23127347acac0de8ad44de519b5e51d8dcf570 100644 (file)
@@ -2287,8 +2287,10 @@ xfs_attr3_leaf_lookup_int(
        leaf = bp->b_addr;
        xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
        entries = xfs_attr3_leaf_entryp(leaf);
-       if (ichdr.count >= args->geo->blksize / 8)
+       if (ichdr.count >= args->geo->blksize / 8) {
+               xfs_buf_corruption_error(bp);
                return -EFSCORRUPTED;
+       }
 
        /*
         * Binary search.  (note: small blocks will skip this loop)
@@ -2304,10 +2306,14 @@ xfs_attr3_leaf_lookup_int(
                else
                        break;
        }
-       if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count)))
+       if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
+               xfs_buf_corruption_error(bp);
                return -EFSCORRUPTED;
-       if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval))
+       }
+       if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
+               xfs_buf_corruption_error(bp);
                return -EFSCORRUPTED;
+       }
 
        /*
         * Since we may have duplicate hashval's, find the first matching
index de4e71725b2cb197c9c228dc519687a692a09b9b..e7fa611887adfcff38e5dae678c675bf76c48a1f 100644 (file)
@@ -729,6 +729,7 @@ xfs_bmap_extents_to_btree(
        xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
        abp = xfs_btree_get_bufl(mp, tp, args.fsbno);
        if (!abp) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                error = -EFSCORRUPTED;
                goto out_unreserve_dquot;
        }
@@ -1084,6 +1085,7 @@ xfs_bmap_add_attrfork(
        if (XFS_IFORK_Q(ip))
                goto trans_cancel;
        if (ip->i_d.di_anextents != 0) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                error = -EFSCORRUPTED;
                goto trans_cancel;
        }
@@ -1374,6 +1376,7 @@ xfs_bmap_last_before(
        case XFS_DINODE_FMT_EXTENTS:
                break;
        default:
+               ASSERT(0);
                return -EFSCORRUPTED;
        }
 
@@ -1474,8 +1477,10 @@ xfs_bmap_last_offset(
                return 0;
 
        if (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE &&
-           XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS)
+           XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS) {
+               ASSERT(0);
                return -EFSCORRUPTED;
+       }
 
        error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
        if (error || is_empty)
@@ -5872,6 +5877,7 @@ xfs_bmap_insert_extents(
                                del_cursor);
 
        if (stop_fsb >= got.br_startoff + got.br_blockcount) {
+               ASSERT(0);
                error = -EFSCORRUPTED;
                goto del_cursor;
        }
index 71de937f9e64d2cef3bc0591bb33a884a9f08cf0..a13a25e922ec656c931ad1412b98610ea2cb3217 100644 (file)
@@ -1820,6 +1820,7 @@ xfs_btree_lookup_get_block(
 
 out_bad:
        *blkp = NULL;
+       xfs_buf_corruption_error(bp);
        xfs_trans_brelse(cur->bc_tp, bp);
        return -EFSCORRUPTED;
 }
@@ -1867,8 +1868,10 @@ xfs_btree_lookup(
        XFS_BTREE_STATS_INC(cur, lookup);
 
        /* No such thing as a zero-level tree. */
-       if (cur->bc_nlevels == 0)
+       if (cur->bc_nlevels == 0) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp);
                return -EFSCORRUPTED;
+       }
 
        block = NULL;
        keyno = 0;
index 4fd1223c1bd5defb5e5fa32fdc354a443f6cf3c4..1e2dc65adeb85fe3318d6db04c642fbe3fac9b7e 100644 (file)
@@ -504,6 +504,7 @@ xfs_da3_split(
        node = oldblk->bp->b_addr;
        if (node->hdr.info.forw) {
                if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
+                       xfs_buf_corruption_error(oldblk->bp);
                        error = -EFSCORRUPTED;
                        goto out;
                }
@@ -516,6 +517,7 @@ xfs_da3_split(
        node = oldblk->bp->b_addr;
        if (node->hdr.info.back) {
                if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
+                       xfs_buf_corruption_error(oldblk->bp);
                        error = -EFSCORRUPTED;
                        goto out;
                }
@@ -1541,8 +1543,10 @@ xfs_da3_node_lookup_int(
                        break;
                }
 
-               if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC)
+               if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {
+                       xfs_buf_corruption_error(blk->bp);
                        return -EFSCORRUPTED;
+               }
 
                blk->magic = XFS_DA_NODE_MAGIC;
 
@@ -1554,15 +1558,18 @@ xfs_da3_node_lookup_int(
                btree = dp->d_ops->node_tree_p(node);
 
                /* Tree taller than we can handle; bail out! */
-               if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH)
+               if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
+                       xfs_buf_corruption_error(blk->bp);
                        return -EFSCORRUPTED;
+               }
 
                /* Check the level from the root. */
                if (blkno == args->geo->leafblk)
                        expected_level = nodehdr.level - 1;
-               else if (expected_level != nodehdr.level)
+               else if (expected_level != nodehdr.level) {
+                       xfs_buf_corruption_error(blk->bp);
                        return -EFSCORRUPTED;
-               else
+               else
                        expected_level--;
 
                max = nodehdr.count;
@@ -1612,12 +1619,17 @@ xfs_da3_node_lookup_int(
                }
 
                /* We can't point back to the root. */
-               if (blkno == args->geo->leafblk)
+               if (blkno == args->geo->leafblk) {
+                       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
+                                       dp->i_mount);
                        return -EFSCORRUPTED;
+               }
        }
 
-       if (expected_level != 0)
+       if (expected_level != 0) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, dp->i_mount);
                return -EFSCORRUPTED;
+       }
 
        /*
         * A leaf block that ends in the hashval that we are interested in
index 867c5dee07518ed44f38488daa69cb02d6224ef2..452d04ae10ceb3d101e3bea15b8784eae9d32195 100644 (file)
@@ -600,8 +600,10 @@ xfs_dir2_isblock(
        if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
                return rval;
        rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
-       if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize)
+       if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount);
                return -EFSCORRUPTED;
+       }
        *vp = rval;
        return 0;
 }
index a53e4585a2f3ab6a88a5782a82820a62b971bffb..388b5da12228706926a91e66534ced7fdf0ae3df 100644 (file)
@@ -1343,8 +1343,10 @@ xfs_dir2_leaf_removename(
        oldbest = be16_to_cpu(bf[0].length);
        ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
        bestsp = xfs_dir2_leaf_bests_p(ltp);
-       if (be16_to_cpu(bestsp[db]) != oldbest)
+       if (be16_to_cpu(bestsp[db]) != oldbest) {
+               xfs_buf_corruption_error(lbp);
                return -EFSCORRUPTED;
+       }
        /*
         * Mark the former data entry unused.
         */
index 99d5b2ed67f2ea684959fcaac69c95b8d14678b7..35e698fa85fd77974e1b4efd2b031c04d7260cc3 100644 (file)
@@ -374,8 +374,10 @@ xfs_dir2_leaf_to_node(
        leaf = lbp->b_addr;
        ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
        if (be32_to_cpu(ltp->bestcount) >
-                               (uint)dp->i_d.di_size / args->geo->blksize)
+                               (uint)dp->i_d.di_size / args->geo->blksize) {
+               xfs_buf_corruption_error(lbp);
                return -EFSCORRUPTED;
+       }
 
        /*
         * Copy freespace entries from the leaf block to the new block.
@@ -446,8 +448,10 @@ xfs_dir2_leafn_add(
         * Quick check just to make sure we are not going to index
         * into other peoples memory
         */
-       if (index < 0)
+       if (index < 0) {
+               xfs_buf_corruption_error(bp);
                return -EFSCORRUPTED;
+       }
 
        /*
         * If there are already the maximum number of leaf entries in
@@ -740,8 +744,10 @@ xfs_dir2_leafn_lookup_for_entry(
        ents = dp->d_ops->leaf_ents_p(leaf);
 
        xfs_dir3_leaf_check(dp, bp);
-       if (leafhdr.count <= 0)
+       if (leafhdr.count <= 0) {
+               xfs_buf_corruption_error(bp);
                return -EFSCORRUPTED;
+       }
 
        /*
         * Look up the hash value in the leaf entries.
index 8fdd0424070e02b0fc45952aaa3adfb6508899fe..15d6f947620ffdba5c015d948d5a10431f6d499a 100644 (file)
@@ -75,11 +75,15 @@ xfs_iformat_fork(
                        error = xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
                        break;
                default:
+                       xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
+                                       dip, sizeof(*dip), __this_address);
                        return -EFSCORRUPTED;
                }
                break;
 
        default:
+               xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
+                               sizeof(*dip), __this_address);
                return -EFSCORRUPTED;
        }
        if (error)
@@ -110,6 +114,8 @@ xfs_iformat_fork(
                error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
                break;
        default:
+               xfs_inode_verifier_error(ip, error, __func__, dip,
+                               sizeof(*dip), __this_address);
                error = -EFSCORRUPTED;
                break;
        }
index 9a7fadb1361cbdb4b78a5556bd0f8f03f5a85e76..78236bd6c64f0c24cd405fce04abed9536a8efbf 100644 (file)
@@ -1591,8 +1591,10 @@ xfs_refcount_recover_extent(
        struct list_head                *debris = priv;
        struct xfs_refcount_recovery    *rr;
 
-       if (be32_to_cpu(rec->refc.rc_refcount) != 1)
+       if (be32_to_cpu(rec->refc.rc_refcount) != 1) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, cur->bc_mp);
                return -EFSCORRUPTED;
+       }
 
        rr = kmem_alloc(sizeof(struct xfs_refcount_recovery), 0);
        xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec);
index 42085e70c01ac9695b3bc2f3ee2601703fc40ab3..85f123b3dfcc14c526b91ca81c5b29ca008bf54d 100644 (file)
@@ -15,7 +15,7 @@
 #include "xfs_bmap.h"
 #include "xfs_trans.h"
 #include "xfs_rtalloc.h"
-
+#include "xfs_error.h"
 
 /*
  * Realtime allocator bitmap functions shared with userspace.
@@ -70,8 +70,10 @@ xfs_rtbuf_get(
        if (error)
                return error;
 
-       if (nmap == 0 || !xfs_bmap_is_real_extent(&map))
+       if (nmap == 0 || !xfs_bmap_is_real_extent(&map)) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                return -EFSCORRUPTED;
+       }
 
        ASSERT(map.br_startblock != NULLFSBLOCK);
        error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
index 96d7071cfa4689435aeaf2ed34a7d58bb3e7bc2c..3f2292c7835ca88da22a52674db3aaf5f2f2bb89 100644 (file)
@@ -12,6 +12,7 @@
 #include "xfs_inode.h"
 #include "xfs_attr.h"
 #include "xfs_trace.h"
+#include "xfs_error.h"
 #include <linux/posix_acl_xattr.h>
 
 
@@ -23,6 +24,7 @@
 
 STATIC struct posix_acl *
 xfs_acl_from_disk(
+       struct xfs_mount        *mp,
        const struct xfs_acl    *aclp,
        int                     len,
        int                     max_entries)
@@ -32,11 +34,18 @@ xfs_acl_from_disk(
        const struct xfs_acl_entry *ace;
        unsigned int count, i;
 
-       if (len < sizeof(*aclp))
+       if (len < sizeof(*aclp)) {
+               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp,
+                               len);
                return ERR_PTR(-EFSCORRUPTED);
+       }
+
        count = be32_to_cpu(aclp->acl_cnt);
-       if (count > max_entries || XFS_ACL_SIZE(count) != len)
+       if (count > max_entries || XFS_ACL_SIZE(count) != len) {
+               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, aclp,
+                               len);
                return ERR_PTR(-EFSCORRUPTED);
+       }
 
        acl = posix_acl_alloc(count, GFP_KERNEL);
        if (!acl)
@@ -145,7 +154,7 @@ xfs_get_acl(struct inode *inode, int type)
                if (error != -ENOATTR)
                        acl = ERR_PTR(error);
        } else  {
-               acl = xfs_acl_from_disk(xfs_acl, len,
+               acl = xfs_acl_from_disk(ip->i_mount, xfs_acl, len,
                                        XFS_ACL_MAX_ENTRIES(ip->i_mount));
                kmem_free(xfs_acl);
        }
index f83f11d929e49969aae65c223bb0d9af439172b0..43ae392992e7c4c2fd9ddbab5a9d0b9873ce4100 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_attr_leaf.h"
 #include "xfs_quota.h"
 #include "xfs_dir2.h"
+#include "xfs_error.h"
 
 /*
  * Look at all the extents for this logical region,
@@ -209,6 +210,7 @@ xfs_attr3_node_inactive(
         */
        if (level > XFS_DA_NODE_MAXDEPTH) {
                xfs_trans_brelse(*trans, bp);   /* no locks for later trans */
+               xfs_buf_corruption_error(bp);
                return -EFSCORRUPTED;
        }
 
@@ -258,8 +260,9 @@ xfs_attr3_node_inactive(
                        error = xfs_attr3_leaf_inactive(trans, dp, child_bp);
                        break;
                default:
-                       error = -EFSCORRUPTED;
+                       xfs_buf_corruption_error(child_bp);
                        xfs_trans_brelse(*trans, child_bp);
+                       error = -EFSCORRUPTED;
                        break;
                }
                if (error)
@@ -342,6 +345,7 @@ xfs_attr3_root_inactive(
                break;
        default:
                error = -EFSCORRUPTED;
+               xfs_buf_corruption_error(bp);
                xfs_trans_brelse(*trans, bp);
                break;
        }
index 00758fdc2fecf58eac5795a781023a8837452dc5..8b9b500e75e81155f41e05e0f15b13b495b63c19 100644 (file)
@@ -258,8 +258,10 @@ xfs_attr_node_list_lookup(
                        return 0;
 
                /* We can't point back to the root. */
-               if (cursor->blkno == 0)
+               if (cursor->blkno == 0) {
+                       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                        return -EFSCORRUPTED;
+               }
        }
 
        if (expected_level != 0)
@@ -269,6 +271,7 @@ xfs_attr_node_list_lookup(
        return 0;
 
 out_corruptbuf:
+       xfs_buf_corruption_error(bp);
        xfs_trans_brelse(tp, bp);
        return -EFSCORRUPTED;
 }
index d84339c91466cdab5270f145c104a656a9cb7dcc..243e5e0f82a3094cc1f4adf386be0a0afd6b3e9c 100644 (file)
@@ -21,7 +21,7 @@
 #include "xfs_icache.h"
 #include "xfs_bmap_btree.h"
 #include "xfs_trans_space.h"
-
+#include "xfs_error.h"
 
 kmem_zone_t    *xfs_bui_zone;
 kmem_zone_t    *xfs_bud_zone;
@@ -525,6 +525,7 @@ xfs_bui_recover(
                type = bui_type;
                break;
        default:
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                error = -EFSCORRUPTED;
                goto err_inode;
        }
index 0b156cc881083faf950d48a13b4fab6c41629698..d8cdb27fe6ed33d773c3c1c898f16f3a2360a8fe 100644 (file)
@@ -341,6 +341,27 @@ xfs_corruption_error(
        xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
 }
 
+/*
+ * Complain about the kinds of metadata corruption that we can't detect from a
+ * verifier, such as incorrect inter-block relationship data.  Does not set
+ * bp->b_error.
+ */
+void
+xfs_buf_corruption_error(
+       struct xfs_buf          *bp)
+{
+       struct xfs_mount        *mp = bp->b_mount;
+
+       xfs_alert_tag(mp, XFS_PTAG_VERIFIER_ERROR,
+                 "Metadata corruption detected at %pS, %s block 0x%llx",
+                 __return_address, bp->b_ops->name, bp->b_bn);
+
+       xfs_alert(mp, "Unmount and run xfs_repair");
+
+       if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
+               xfs_stack_trace();
+}
+
 /*
  * Warnings specifically for verifier errors.  Differentiate CRC vs. invalid
  * values, and omit the stack trace unless the error level is tuned high.
index e6a22cfb542fb3d0ede498f69d5da03bec664537..c319379f7d1a393e447dee8f254ae525901b9e11 100644 (file)
@@ -15,6 +15,7 @@ extern void xfs_corruption_error(const char *tag, int level,
                        struct xfs_mount *mp, const void *buf, size_t bufsize,
                        const char *filename, int linenum,
                        xfs_failaddr_t failaddr);
+void xfs_buf_corruption_error(struct xfs_buf *bp);
 extern void xfs_buf_verifier_error(struct xfs_buf *bp, int error,
                        const char *name, const void *buf, size_t bufsz,
                        xfs_failaddr_t failaddr);
index 1b3ade30ef658fb8a014a9260eb0f507ef0a1d24..a05a1074e8f81e50823536537886c114964b6e39 100644 (file)
@@ -21,7 +21,7 @@
 #include "xfs_alloc.h"
 #include "xfs_bmap.h"
 #include "xfs_trace.h"
-
+#include "xfs_error.h"
 
 kmem_zone_t    *xfs_efi_zone;
 kmem_zone_t    *xfs_efd_zone;
@@ -228,6 +228,7 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
                }
                return 0;
        }
+       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
        return -EFSCORRUPTED;
 }
 
index 8990be13a16c4758157d0c8f257922509959d8f5..70c5050463a6d2c7848cbb086738d7df3ea3347c 100644 (file)
@@ -2149,8 +2149,10 @@ xfs_iunlink_update_bucket(
         * passed in because either we're adding or removing ourselves from the
         * head of the list.
         */
-       if (old_value == new_agino)
+       if (old_value == new_agino) {
+               xfs_buf_corruption_error(agibp);
                return -EFSCORRUPTED;
+       }
 
        agi->agi_unlinked[bucket_index] = cpu_to_be32(new_agino);
        offset = offsetof(struct xfs_agi, agi_unlinked) +
@@ -2213,6 +2215,8 @@ xfs_iunlink_update_inode(
        /* Make sure the old pointer isn't garbage. */
        old_value = be32_to_cpu(dip->di_next_unlinked);
        if (!xfs_verify_agino_or_null(mp, agno, old_value)) {
+               xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
+                               sizeof(*dip), __this_address);
                error = -EFSCORRUPTED;
                goto out;
        }
@@ -2224,8 +2228,11 @@ xfs_iunlink_update_inode(
         */
        *old_next_agino = old_value;
        if (old_value == next_agino) {
-               if (next_agino != NULLAGINO)
+               if (next_agino != NULLAGINO) {
+                       xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
+                                       dip, sizeof(*dip), __this_address);
                        error = -EFSCORRUPTED;
+               }
                goto out;
        }
 
@@ -2276,8 +2283,10 @@ xfs_iunlink(
         */
        next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]);
        if (next_agino == agino ||
-           !xfs_verify_agino_or_null(mp, agno, next_agino))
+           !xfs_verify_agino_or_null(mp, agno, next_agino)) {
+               xfs_buf_corruption_error(agibp);
                return -EFSCORRUPTED;
+       }
 
        if (next_agino != NULLAGINO) {
                struct xfs_perag        *pag;
index bb8f076805b9ea5f97f4ec82ee9ee77eab42fa06..726aa3bfd6e84b4bf2c4e7947b958509d6548946 100644 (file)
@@ -17,6 +17,7 @@
 #include "xfs_trans_priv.h"
 #include "xfs_buf_item.h"
 #include "xfs_log.h"
+#include "xfs_error.h"
 
 #include <linux/iversion.h>
 
@@ -828,8 +829,10 @@ xfs_inode_item_format_convert(
 {
        struct xfs_inode_log_format_32  *in_f32 = buf->i_addr;
 
-       if (buf->i_len != sizeof(*in_f32))
+       if (buf->i_len != sizeof(*in_f32)) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
                return -EFSCORRUPTED;
+       }
 
        in_f->ilf_type = in_f32->ilf_type;
        in_f->ilf_size = in_f32->ilf_size;
index ca8c763902b969fdfe5caf46ce2dd108e2b78efa..80dd05f8f1afc5d87e59e40b1c28d69cad719417 100644 (file)
@@ -20,6 +20,7 @@
 #include "xfs_symlink.h"
 #include "xfs_dir2.h"
 #include "xfs_iomap.h"
+#include "xfs_error.h"
 
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
@@ -470,17 +471,20 @@ xfs_vn_get_link_inline(
        struct inode            *inode,
        struct delayed_call     *done)
 {
+       struct xfs_inode        *ip = XFS_I(inode);
        char                    *link;
 
-       ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE);
+       ASSERT(ip->i_df.if_flags & XFS_IFINLINE);
 
        /*
         * The VFS crashes on a NULL pointer, so return -EFSCORRUPTED if
         * if_data is junk.
         */
-       link = XFS_I(inode)->i_df.if_u1.if_data;
-       if (!link)
+       link = ip->i_df.if_u1.if_data;
+       if (!link) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, ip->i_mount);
                return ERR_PTR(-EFSCORRUPTED);
+       }
        return link;
 }
 
index 796bbc9dd8b0c13367ff034e7e076e041cd1ab67..02f2147952b37d590a4ea101459a4ef497597fb5 100644 (file)
@@ -3537,6 +3537,7 @@ xfs_cui_copy_format(
                memcpy(dst_cui_fmt, src_cui_fmt, len);
                return 0;
        }
+       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
        return -EFSCORRUPTED;
 }
 
@@ -3601,8 +3602,10 @@ xlog_recover_cud_pass2(
        struct xfs_ail                  *ailp = log->l_ailp;
 
        cud_formatp = item->ri_buf[0].i_addr;
-       if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format))
+       if (item->ri_buf[0].i_len != sizeof(struct xfs_cud_log_format)) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
                return -EFSCORRUPTED;
+       }
        cui_id = cud_formatp->cud_cui_id;
 
        /*
@@ -3654,6 +3657,7 @@ xfs_bui_copy_format(
                memcpy(dst_bui_fmt, src_bui_fmt, len);
                return 0;
        }
+       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
        return -EFSCORRUPTED;
 }
 
@@ -3677,8 +3681,10 @@ xlog_recover_bui_pass2(
 
        bui_formatp = item->ri_buf[0].i_addr;
 
-       if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS)
+       if (bui_formatp->bui_nextents != XFS_BUI_MAX_FAST_EXTENTS) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
                return -EFSCORRUPTED;
+       }
        buip = xfs_bui_init(mp);
        error = xfs_bui_copy_format(&item->ri_buf[0], &buip->bui_format);
        if (error) {
@@ -3720,8 +3726,10 @@ xlog_recover_bud_pass2(
        struct xfs_ail                  *ailp = log->l_ailp;
 
        bud_formatp = item->ri_buf[0].i_addr;
-       if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format))
+       if (item->ri_buf[0].i_len != sizeof(struct xfs_bud_log_format)) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
                return -EFSCORRUPTED;
+       }
        bui_id = bud_formatp->bud_bui_id;
 
        /*
@@ -5181,8 +5189,10 @@ xlog_recover_process(
                 * If the filesystem is CRC enabled, this mismatch becomes a
                 * fatal log corruption failure.
                 */
-               if (xfs_sb_version_hascrc(&log->l_mp->m_sb))
+               if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
+                       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, log->l_mp);
                        return -EFSCORRUPTED;
+               }
        }
 
        xlog_unpack_data(rhead, dp, log);
@@ -5305,8 +5315,11 @@ xlog_do_recovery_pass(
                "invalid iclog size (%d bytes), using lsunit (%d bytes)",
                                         h_size, log->l_mp->m_logbsize);
                                h_size = log->l_mp->m_logbsize;
-                       } else
+                       } else {
+                               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
+                                               log->l_mp);
                                return -EFSCORRUPTED;
+                       }
                }
 
                if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) &&
index ecd8ce152ab1f0040330f1bbe4f62511f4dd9253..66ea8e4fca86c5b56a1eb543344a1b1ead429b67 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_qm.h"
 #include "xfs_trace.h"
 #include "xfs_icache.h"
+#include "xfs_error.h"
 
 /*
  * The global quota manager. There is only one of these for the entire
@@ -754,11 +755,19 @@ xfs_qm_qino_alloc(
                if ((flags & XFS_QMOPT_PQUOTA) &&
                             (mp->m_sb.sb_gquotino != NULLFSINO)) {
                        ino = mp->m_sb.sb_gquotino;
-                       ASSERT(mp->m_sb.sb_pquotino == NULLFSINO);
+                       if (mp->m_sb.sb_pquotino != NULLFSINO) {
+                               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
+                                               mp);
+                               return -EFSCORRUPTED;
+                       }
                } else if ((flags & XFS_QMOPT_GQUOTA) &&
                             (mp->m_sb.sb_pquotino != NULLFSINO)) {
                        ino = mp->m_sb.sb_pquotino;
-                       ASSERT(mp->m_sb.sb_gquotino == NULLFSINO);
+                       if (mp->m_sb.sb_gquotino != NULLFSINO) {
+                               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW,
+                                               mp);
+                               return -EFSCORRUPTED;
+                       }
                }
                if (ino != NULLFSINO) {
                        error = xfs_iget(mp, NULL, ino, 0, 0, ip);
index e22ac9cdb97168ee4ea7590041b95b4918963749..d5708d40ad877248b69670b36753d587b0fce1be 100644 (file)
@@ -17,7 +17,7 @@
 #include "xfs_refcount_item.h"
 #include "xfs_log.h"
 #include "xfs_refcount.h"
-
+#include "xfs_error.h"
 
 kmem_zone_t    *xfs_cui_zone;
 kmem_zone_t    *xfs_cud_zone;
@@ -536,6 +536,7 @@ xfs_cui_recover(
                        type = refc_type;
                        break;
                default:
+                       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, mp);
                        error = -EFSCORRUPTED;
                        goto abort_error;
                }
index af83e2b2a42959c2a68915aac7413ceea454da10..02f84d9a511c3712b764ad67a94103eb288380ac 100644 (file)
@@ -17,7 +17,7 @@
 #include "xfs_rmap_item.h"
 #include "xfs_log.h"
 #include "xfs_rmap.h"
-
+#include "xfs_error.h"
 
 kmem_zone_t    *xfs_rui_zone;
 kmem_zone_t    *xfs_rud_zone;
@@ -171,8 +171,10 @@ xfs_rui_copy_format(
        src_rui_fmt = buf->i_addr;
        len = xfs_rui_log_format_sizeof(src_rui_fmt->rui_nextents);
 
-       if (buf->i_len != len)
+       if (buf->i_len != len) {
+               XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
                return -EFSCORRUPTED;
+       }
 
        memcpy(dst_rui_fmt, src_rui_fmt, len);
        return 0;
@@ -581,6 +583,7 @@ xfs_rui_recover(
                        type = XFS_RMAP_FREE;
                        break;
                default:
+                       XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, NULL);
                        error = -EFSCORRUPTED;
                        goto abort_error;
                }