diff options
author | Christoph Hellwig <hch@sgi.com> | 2005-09-05 02:33:00 +0400 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2005-09-05 02:33:00 +0400 |
commit | ba403ab43e896c57f32995ccba9a6bd6ec8dd1b9 (patch) | |
tree | 1262d9ec73d90bd4a73093cdd8afe8d2459dae72 /fs/xfs | |
parent | efa092f3d4c60be7e81de515db9f06e5f8426afc (diff) | |
download | linux-ba403ab43e896c57f32995ccba9a6bd6ec8dd1b9.tar.xz |
[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: Christoph Hellwig <hch@sgi.com>
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_iget.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index fa796910f3aa..0d9ae8fb4138 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -30,6 +30,8 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ +#include <linux/delay.h> + #include "xfs.h" #include "xfs_macros.h" @@ -507,14 +509,13 @@ xfs_iget( XFS_STATS_INC(xs_ig_attempts); +retry: if ((inode = iget_locked(XFS_MTOVFS(mp)->vfs_super, ino))) { bhv_desc_t *bdp; xfs_inode_t *ip; - int newnode; vp = LINVFS_GET_VP(inode); if (inode->i_state & I_NEW) { -inode_allocate: vn_initialize(inode); error = xfs_iget_core(vp, mp, tp, ino, flags, lock_flags, ipp, bno); @@ -525,22 +526,25 @@ inode_allocate: iput(inode); } } 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); - 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); if (lock_flags != 0) 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); *ipp = ip; error = 0; |