diff options
author | Dave Chinner <dchinner@redhat.com> | 2016-02-09 00:54:58 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-02-09 00:54:58 -0500 |
commit | 50997470ef95fd8ae0ef6acab3b2e1d886ae2445 (patch) | |
tree | cf2906206f50c18fb77eb3f24ed8e885c63f4114 | |
parent | faeb4e4715be017e88e630bda84477afc1dff38b (diff) |
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 <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/xfs/xfs_icache.c | 22 |
1 files changed, 21 insertions, 1 deletions
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 | |||
@@ -135,6 +135,26 @@ xfs_inode_free( | |||
135 | } | 135 | } |
136 | 136 | ||
137 | /* | 137 | /* |
138 | * When we recycle a reclaimable inode, we need to re-initialise the VFS inode | ||
139 | * part of the structure. This is made more complex by the fact we store | ||
140 | * information about the on-disk values in the VFS inode and so we can't just | ||
141 | * overwrite it's values unconditionally. Hence we save the parameters we | ||
142 | * need to retain across reinitialisation, and rewrite them into the VFS inode | ||
143 | * after resetting it's state even if resetting fails. | ||
144 | */ | ||
145 | static int | ||
146 | xfs_reinit_inode( | ||
147 | struct xfs_mount *mp, | ||
148 | struct inode *inode) | ||
149 | { | ||
150 | int error; | ||
151 | |||
152 | error = inode_init_always(mp->m_super, inode); | ||
153 | |||
154 | return error; | ||
155 | } | ||
156 | |||
157 | /* | ||
138 | * Check the validity of the inode we just found it the cache | 158 | * Check the validity of the inode we just found it the cache |
139 | */ | 159 | */ |
140 | static int | 160 | static int |
@@ -208,7 +228,7 @@ xfs_iget_cache_hit( | |||
208 | spin_unlock(&ip->i_flags_lock); | 228 | spin_unlock(&ip->i_flags_lock); |
209 | rcu_read_unlock(); | 229 | rcu_read_unlock(); |
210 | 230 | ||
211 | error = inode_init_always(mp->m_super, inode); | 231 | error = xfs_reinit_inode(mp, inode); |
212 | if (error) { | 232 | if (error) { |
213 | /* | 233 | /* |
214 | * Re-initializing the inode failed, and we are in deep | 234 | * Re-initializing the inode failed, and we are in deep |