From: "J. Bruce Fields" <bfields@fieldses.org>
If the NFS daemon is presented with a filehandle for a file that has
been deleted, it does an iget() in fs/exportfs/expfs.c:export_iget() and
gets a bad inode back. When it subsequently iput()s the inode, the
result is:
Mar 27 12:53:40 snoopy kernel: EXT2-fs error (device ide0(3,3)): ext2_free_blocks: Freeing blocks not in datazone - block =
1802201963, count = 27499
Mar 27 12:53:40 snoopy kernel: Remounting filesystem read-only
The same can happen if ext2_get_inode() returns an error - ext2_read_inode()
will return an uninitialised inode and ext2_put_inode() is not allowed to go
looking inside the bad inode.
}
/*
- * Called at each iput()
+ * Called at each iput().
+ *
+ * The inode may be "bad" if ext2_read_inode() saw an error from
+ * ext2_get_inode(), so we need to check that to avoid freeing random disk
+ * blocks.
*/
-void ext2_put_inode (struct inode * inode)
+void ext2_put_inode(struct inode *inode)
{
- ext2_discard_prealloc (inode);
+ if (!is_bad_inode(inode))
+ ext2_discard_prealloc(inode);
}
/*
/*
* Called at each iput()
+ *
+ * The inode may be "bad" if ext3_read_inode() saw an error from
+ * ext3_get_inode(), so we need to check that to avoid freeing random disk
+ * blocks.
*/
-void ext3_put_inode (struct inode * inode)
+void ext3_put_inode(struct inode *inode)
{
- ext3_discard_prealloc (inode);
+ if (!is_bad_inode(inode))
+ ext3_discard_prealloc(inode);
}
/*