From 50997470ef95fd8ae0ef6acab3b2e1d886ae2445 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 9 Feb 2016 16:54:58 +1100 Subject: xfs: reinitialise recycled VFS inode correctly We are going to keep certain on-disk information in the VFS inode rather than in a separate XFS specific stucture, so we have to be careful of the VFS code clearing that information when we re-initialise reclaimable cached inodes during lookup. If we don't do this, then we lose critical information from the inode and that results in corruption being detected. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_icache.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'fs/xfs/xfs_icache.c') diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 7c26f8611891..9ca2865575ab 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -134,6 +134,26 @@ xfs_inode_free( call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); } +/* + * When we recycle a reclaimable inode, we need to re-initialise the VFS inode + * part of the structure. This is made more complex by the fact we store + * information about the on-disk values in the VFS inode and so we can't just + * overwrite it's values unconditionally. Hence we save the parameters we + * need to retain across reinitialisation, and rewrite them into the VFS inode + * after resetting it's state even if resetting fails. + */ +static int +xfs_reinit_inode( + struct xfs_mount *mp, + struct inode *inode) +{ + int error; + + error = inode_init_always(mp->m_super, inode); + + return error; +} + /* * Check the validity of the inode we just found it the cache */ @@ -208,7 +228,7 @@ xfs_iget_cache_hit( spin_unlock(&ip->i_flags_lock); rcu_read_unlock(); - error = inode_init_always(mp->m_super, inode); + error = xfs_reinit_inode(mp, inode); if (error) { /* * Re-initializing the inode failed, and we are in deep -- cgit