Commit ba403ab4 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nathan Scott

[XFS] Retry linux inode cacech lookup if we found a stale inode. This

fixes crashes under high nfs load

SGI-PV: 941429
SGI-Modid: xfs-linux:xfs-kern:197929a
Signed-off-by: default avatarChristoph Hellwig <hch@sgi.com>
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent efa092f3
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
* http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
*/ */
#include <linux/delay.h>
#include "xfs.h" #include "xfs.h"
#include "xfs_macros.h" #include "xfs_macros.h"
...@@ -507,14 +509,13 @@ xfs_iget( ...@@ -507,14 +509,13 @@ xfs_iget(
XFS_STATS_INC(xs_ig_attempts); XFS_STATS_INC(xs_ig_attempts);
retry:
if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) { if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) {
bhv_desc_t *bdp; bhv_desc_t *bdp;
xfs_inode_t *ip; xfs_inode_t *ip;
int newnode;
vp = LINVFS_GET_VP(inode); vp = LINVFS_GET_VP(inode);
if (inode->i_state & I_NEW) { if (inode->i_state & I_NEW) {
inode_allocate:
vn_initialize(inode); vn_initialize(inode);
error = xfs_iget_core(vp, mp, tp, ino, flags, error = xfs_iget_core(vp, mp, tp, ino, flags,
lock_flags, ipp, bno); lock_flags, ipp, bno);
...@@ -525,22 +526,25 @@ xfs_iget( ...@@ -525,22 +526,25 @@ xfs_iget(
iput(inode); iput(inode);
} }
} else { } else {
if (is_bad_inode(inode)) { /*
* If the inode is not fully constructed due to
* filehandle mistmatches wait for the inode to go
* away and try again.
*
* iget_locked will call __wait_on_freeing_inode
* to wait for the inode to go away.
*/
if (is_bad_inode(inode) ||
((bdp = vn_bhv_lookup(VN_BHV_HEAD(vp),
&xfs_vnodeops)) == NULL)) {
iput(inode); iput(inode);
return EIO; delay(1);
goto retry;
} }
bdp = vn_bhv_lookup(VN_BHV_HEAD(vp), &xfs_vnodeops);
if (bdp == NULL) {
XFS_STATS_INC(xs_ig_dup);
goto inode_allocate;
}
ip = XFS_BHVTOI(bdp); ip = XFS_BHVTOI(bdp);
if (lock_flags != 0) if (lock_flags != 0)
xfs_ilock(ip, lock_flags); xfs_ilock(ip, lock_flags);
newnode = (ip->i_d.di_mode == 0);
if (newnode)
xfs_iocore_inode_reinit(ip);
XFS_STATS_INC(xs_ig_found); XFS_STATS_INC(xs_ig_found);
*ipp = ip; *ipp = ip;
error = 0; error = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment