xfsqa: test open_by_handle() on unlinked and freed inode clusters
authorDave Chinner <dchinner@redhat.com>
Thu, 24 Jun 2010 22:26:25 +0000 (08:26 +1000)
committerDave Chinner <david@fromorbit.com>
Thu, 24 Jun 2010 22:26:25 +0000 (08:26 +1000)
commit794798fa7464bcdf860d4e47d9b257e86a9bfbfa
tree53b60dd768a9da836280fbef83372834b7f8d4b7
parent96c0dfc5abdada270212b1db377755edac99c305
xfsqa: test open_by_handle() on unlinked and freed inode clusters

When Christoph and I were discussing bulkstat coherency on IRC, we
realised that inode lookup from bulkstat was not actually looking up
the inode allocation btree in xfs_imap() before reading the inode
buffer from disk in xfs_iread(). Bulkstat uses the same lookup
mechanism as handle validation to avoid shutting down the filesystem
if inode numbers that point to non-inode buffers (i.e. invalid) are
passed in the handle.

The problem with this is that when we delete inodes from disk and we
remove the inode chunk (i.e. deallocate inodes) we mark both the
inodes in memory and the cluster buffer as stale, thereby preventing
it from being written back to disk. The result of this is that some
number of inodes remain on disk looking like allocated, in use
inodes (i.e.  di_mode is not zero).

Hence if we get a cold cache lookup from a stale handle that
references such an inode, we can read the inode off disk even though
it has been deleted because we don't check if the inode is allocated
or not.  If the inode chunk has not been overwritten, then the inode
read will succeed and the handle-to-dentry conversion will not error
out like it is supposed to. The result is that stale NFS filehandles
and open_by_handle() will succeed incorrectly on unlinked files for
cold cache lookups.

This is a bug that has been present ever since the inode chunk
deletion code was implemented. This test exercises the problem and
documents the hoops you have to jump through to reproduce it.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
238 [new file with mode: 0755]
238.out [new file with mode: 0644]
group
src/Makefile
src/stale_handle.c [new file with mode: 0644]