summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_icache.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index d53a316162d6..9a18f69f6e96 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -483,7 +483,28 @@ xfs_iget_cache_miss(
trace_xfs_iget_miss(ip);
- if ((VFS_I(ip)->i_mode == 0) && !(flags & XFS_IGET_CREATE)) {
+
+ /*
+ * If we are allocating a new inode, then check what was returned is
+ * actually a free, empty inode. If we are not allocating an inode,
+ * the check we didn't find a free inode.
+ */
+ if (flags & XFS_IGET_CREATE) {
+ if (VFS_I(ip)->i_mode != 0) {
+ xfs_warn(mp,
+"Corruption detected! Free inode 0x%llx not marked free on disk",
+ ino);
+ error = -EFSCORRUPTED;
+ goto out_destroy;
+ }
+ if (ip->i_d.di_nblocks != 0) {
+ xfs_warn(mp,
+"Corruption detected! Free inode 0x%llx has blocks allocated!",
+ ino);
+ error = -EFSCORRUPTED;
+ goto out_destroy;
+ }
+ } else if (VFS_I(ip)->i_mode == 0) {
error = -ENOENT;
goto out_destroy;
}