Merge tag 'xfs-6.9-merge-8' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
[linux-block.git] / fs / xfs / xfs_attr_list.c
index e368ad671e261e42159351316fc77cd5596742e4..a6819a642cc078fe484ac050dddbe407c390c62b 100644 (file)
@@ -22,6 +22,7 @@
 #include "xfs_error.h"
 #include "xfs_trace.h"
 #include "xfs_dir2.h"
+#include "xfs_health.h"
 
 STATIC int
 xfs_attr_shortform_compare(const void *a, const void *b)
@@ -82,8 +83,10 @@ xfs_attr_shortform_list(
                for (i = 0, sfe = xfs_attr_sf_firstentry(sf); i < sf->count; i++) {
                        if (XFS_IS_CORRUPT(context->dp->i_mount,
                                           !xfs_attr_namecheck(sfe->nameval,
-                                                              sfe->namelen)))
+                                                              sfe->namelen))) {
+                               xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
                                return -EFSCORRUPTED;
+                       }
                        context->put_listent(context,
                                             sfe->flags,
                                             sfe->nameval,
@@ -109,7 +112,7 @@ xfs_attr_shortform_list(
         * It didn't all fit, so we have to sort everything on hashval.
         */
        sbsize = sf->count * sizeof(*sbuf);
-       sbp = sbuf = kmem_alloc(sbsize, KM_NOFS);
+       sbp = sbuf = kmalloc(sbsize, GFP_KERNEL | __GFP_NOFAIL);
 
        /*
         * Scan the attribute list for the rest of the entries, storing
@@ -124,7 +127,8 @@ xfs_attr_shortform_list(
                                             XFS_ERRLEVEL_LOW,
                                             context->dp->i_mount, sfe,
                                             sizeof(*sfe));
-                       kmem_free(sbuf);
+                       kfree(sbuf);
+                       xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
                        return -EFSCORRUPTED;
                }
 
@@ -175,6 +179,7 @@ xfs_attr_shortform_list(
                if (XFS_IS_CORRUPT(context->dp->i_mount,
                                   !xfs_attr_namecheck(sbp->name,
                                                       sbp->namelen))) {
+                       xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
                        error = -EFSCORRUPTED;
                        goto out;
                }
@@ -188,7 +193,7 @@ xfs_attr_shortform_list(
                cursor->offset++;
        }
 out:
-       kmem_free(sbuf);
+       kfree(sbuf);
        return error;
 }
 
@@ -262,8 +267,10 @@ xfs_attr_node_list_lookup(
                        return 0;
 
                /* We can't point back to the root. */
-               if (XFS_IS_CORRUPT(mp, cursor->blkno == 0))
+               if (XFS_IS_CORRUPT(mp, cursor->blkno == 0)) {
+                       xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
                        return -EFSCORRUPTED;
+               }
        }
 
        if (expected_level != 0)
@@ -275,6 +282,7 @@ xfs_attr_node_list_lookup(
 out_corruptbuf:
        xfs_buf_mark_corrupt(bp);
        xfs_trans_brelse(tp, bp);
+       xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
        return -EFSCORRUPTED;
 }
 
@@ -304,6 +312,8 @@ xfs_attr_node_list(
        if (cursor->blkno > 0) {
                error = xfs_da3_node_read(context->tp, dp, cursor->blkno, &bp,
                                XFS_ATTR_FORK);
+               if (xfs_metadata_is_sick(error))
+                       xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
                if ((error != 0) && (error != -EFSCORRUPTED))
                        return error;
                if (bp) {
@@ -464,8 +474,10 @@ xfs_attr3_leaf_list_int(
                }
 
                if (XFS_IS_CORRUPT(context->dp->i_mount,
-                                  !xfs_attr_namecheck(name, namelen)))
+                                  !xfs_attr_namecheck(name, namelen))) {
+                       xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
                        return -EFSCORRUPTED;
+               }
                context->put_listent(context, entry->flags,
                                              name, namelen, valuelen);
                if (context->seen_enough)
@@ -504,7 +516,7 @@ xfs_attr_list_ilocked(
 {
        struct xfs_inode                *dp = context->dp;
 
-       ASSERT(xfs_isilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
+       xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
 
        /*
         * Decide on what work routines to call based on the inode size.