xfs: set inode sick state flags when we zap either ondisk fork
[linux-2.6-microblaze.git] / fs / xfs / xfs_inode.c
index c0f1c89..ea6b277 100644 (file)
@@ -37,6 +37,7 @@
 #include "xfs_reflink.h"
 #include "xfs_ag.h"
 #include "xfs_log_priv.h"
+#include "xfs_health.h"
 
 struct kmem_cache *xfs_inode_cache;
 
@@ -661,6 +662,8 @@ xfs_lookup(
 
        if (xfs_is_shutdown(dp->i_mount))
                return -EIO;
+       if (xfs_ifork_zapped(dp, XFS_DATA_FORK))
+               return -EIO;
 
        error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name);
        if (error)
@@ -978,6 +981,8 @@ xfs_create(
 
        if (xfs_is_shutdown(mp))
                return -EIO;
+       if (xfs_ifork_zapped(dp, XFS_DATA_FORK))
+               return -EIO;
 
        prid = xfs_get_initial_prid(dp);
 
@@ -1217,6 +1222,8 @@ xfs_link(
 
        if (xfs_is_shutdown(mp))
                return -EIO;
+       if (xfs_ifork_zapped(tdp, XFS_DATA_FORK))
+               return -EIO;
 
        error = xfs_qm_dqattach(sip);
        if (error)
@@ -2506,6 +2513,8 @@ xfs_remove(
 
        if (xfs_is_shutdown(mp))
                return -EIO;
+       if (xfs_ifork_zapped(dp, XFS_DATA_FORK))
+               return -EIO;
 
        error = xfs_qm_dqattach(dp);
        if (error)
@@ -3758,3 +3767,29 @@ xfs_inode_reload_unlinked(
 
        return error;
 }
+
+/* Has this inode fork been zapped by repair? */
+bool
+xfs_ifork_zapped(
+       const struct xfs_inode  *ip,
+       int                     whichfork)
+{
+       unsigned int            datamask = 0;
+
+       switch (whichfork) {
+       case XFS_DATA_FORK:
+               switch (ip->i_vnode.i_mode & S_IFMT) {
+               case S_IFDIR:
+                       datamask = XFS_SICK_INO_DIR_ZAPPED;
+                       break;
+               case S_IFLNK:
+                       datamask = XFS_SICK_INO_SYMLINK_ZAPPED;
+                       break;
+               }
+               return ip->i_sick & (XFS_SICK_INO_BMBTD_ZAPPED | datamask);
+       case XFS_ATTR_FORK:
+               return ip->i_sick & XFS_SICK_INO_BMBTA_ZAPPED;
+       default:
+               return false;
+       }
+}