Subject: | .put_inode() cleanup on linux |
Date: | Sun, 13 Aug 2006 12:30:46 -0400 |
To: | openafs-bugs@openafs.org |
From: | chas williams - CONTRACTOR <chas@cmf.nrl.navy.mil> |
at one point there was a discussion on openafs-devel about put_inode()
causing deadlocks in certain conditions (low memory/swapping) since it
takes the glock.
dentry_iput() is called when the linux fs layer no longer needs the inode
associated with the path (dentry). i.e. this inode is now inactive.
the inode wont go away since the vlru still holds a reference but the
inode is ready for recycling. this is probably more correct anyway but
possibly not a complete solution to the problem.
Index: src/afs/LINUX/osi_vfsops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v
retrieving revision 1.42.4.6
diff -u -u -r1.42.4.6 osi_vfsops.c
--- src/afs/LINUX/osi_vfsops.c 11 Aug 2006 21:40:56 -0000 1.42.4.6
+++ src/afs/LINUX/osi_vfsops.c 13 Aug 2006 16:19:52 -0000
@@ -350,23 +350,6 @@
#endif
}
-/* afs_put_inode
- * Linux version of inactive. When refcount == 2, we are about to
- * decrement to 1 and the only reference remaining should be for
- * the VLRU
- */
-
-static void
-afs_put_inode(struct inode *ip)
-{
- struct vcache *vcp = VTOAFS(ip);
-
- AFS_GLOCK();
- if (VREFCOUNT(vcp) == 2)
- afs_InactiveVCache(vcp, NULL);
- AFS_GUNLOCK();
-}
-
/* afs_put_super
* Called from unmount to release super_block. */
static void
@@ -452,7 +435,6 @@
.destroy_inode = afs_destroy_inode,
#endif
.clear_inode = afs_clear_inode,
- .put_inode = afs_put_inode,
.put_super = afs_put_super,
.statfs = afs_statfs,
#if !defined(AFS_LINUX24_ENV)
Index: src/afs/LINUX/osi_vnodeops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v
retrieving revision 1.126.2.3
diff -u -u -r1.126.2.3 osi_vnodeops.c
--- src/afs/LINUX/osi_vnodeops.c 31 Jul 2006 21:27:39 -0000 1.126.2.3
+++ src/afs/LINUX/osi_vnodeops.c 13 Aug 2006 16:19:52 -0000
@@ -825,8 +825,9 @@
struct vcache *vcp = VTOAFS(ip);
AFS_GLOCK();
- if (vcp->states & CUnlinked)
- (void) afs_InactiveVCache(vcp, NULL);
+ ObtainWriteLock(&vcp->lock, 537);
+ (void) afs_InactiveVCache(vcp, NULL);
+ ReleaseWriteLock(&vcp->lock);
AFS_GUNLOCK();
iput(ip);
causing deadlocks in certain conditions (low memory/swapping) since it
takes the glock.
dentry_iput() is called when the linux fs layer no longer needs the inode
associated with the path (dentry). i.e. this inode is now inactive.
the inode wont go away since the vlru still holds a reference but the
inode is ready for recycling. this is probably more correct anyway but
possibly not a complete solution to the problem.
Index: src/afs/LINUX/osi_vfsops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v
retrieving revision 1.42.4.6
diff -u -u -r1.42.4.6 osi_vfsops.c
--- src/afs/LINUX/osi_vfsops.c 11 Aug 2006 21:40:56 -0000 1.42.4.6
+++ src/afs/LINUX/osi_vfsops.c 13 Aug 2006 16:19:52 -0000
@@ -350,23 +350,6 @@
#endif
}
-/* afs_put_inode
- * Linux version of inactive. When refcount == 2, we are about to
- * decrement to 1 and the only reference remaining should be for
- * the VLRU
- */
-
-static void
-afs_put_inode(struct inode *ip)
-{
- struct vcache *vcp = VTOAFS(ip);
-
- AFS_GLOCK();
- if (VREFCOUNT(vcp) == 2)
- afs_InactiveVCache(vcp, NULL);
- AFS_GUNLOCK();
-}
-
/* afs_put_super
* Called from unmount to release super_block. */
static void
@@ -452,7 +435,6 @@
.destroy_inode = afs_destroy_inode,
#endif
.clear_inode = afs_clear_inode,
- .put_inode = afs_put_inode,
.put_super = afs_put_super,
.statfs = afs_statfs,
#if !defined(AFS_LINUX24_ENV)
Index: src/afs/LINUX/osi_vnodeops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v
retrieving revision 1.126.2.3
diff -u -u -r1.126.2.3 osi_vnodeops.c
--- src/afs/LINUX/osi_vnodeops.c 31 Jul 2006 21:27:39 -0000 1.126.2.3
+++ src/afs/LINUX/osi_vnodeops.c 13 Aug 2006 16:19:52 -0000
@@ -825,8 +825,9 @@
struct vcache *vcp = VTOAFS(ip);
AFS_GLOCK();
- if (vcp->states & CUnlinked)
- (void) afs_InactiveVCache(vcp, NULL);
+ ObtainWriteLock(&vcp->lock, 537);
+ (void) afs_InactiveVCache(vcp, NULL);
+ ReleaseWriteLock(&vcp->lock);
AFS_GUNLOCK();
iput(ip);