[OpenAFS-devel] osi_vfsops.c / afs_put_inode (LINUX) - editing bug?
chas williams - CONTRACTOR
chas@cmf.nrl.navy.mil
Fri, 24 Feb 2006 14:11:46 -0500
In message <43FAD0C0.1080401@pclella.cern.ch>,Rainer Toebbicke writes:
>The code in 1.4.1-rc7 looks a bit odd:
>
> if (VREFCOUNT(vcp) == 2) {
> if (VREFCOUNT(vcp) == 2)
> afs_InactiveVCache(vcp, NULL);
this is the result of a poor patch that apparently didnt remove
everything cleanly. at one point, i was checking outside AFS_GLOCK
to see if the refcount was 2 before taking AFS_GLOCK (since it
typically isnt going to be 2). this is racy on multiple cpus as
others have pointed out. so the only choice is to always take
the lock.
>More seriously however, afs_InactiveVCache() through the subsequently
>called afs_InvalidateAllSegments() needs the vnode to be locked. I'm
>worried that given that this is an upcall from the kernel this might
>not always be the case, e.g. when invoked through afs_linux_lookup().
yep, this is true. but...
>(Besides I still believe this function can be called with the global
>lock already held and thus deadlock, but this is another story.)
you are right about this. i never wanted to constantly grab the
AFS_GLOCK in ->put_inode. i now believe that this can simply be moved
entirely to ->d_iput. when ->d_iput is called, the linux vfs layer has
no more references to the file -- it's "done". i am using the attached
with no ill effect. as you mentioned, it probably should grab a write
lock though.
Index: src/afs/LINUX/osi_vfsops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v
retrieving revision 1.29.2.12
diff -u -u -r1.29.2.12 osi_vfsops.c
--- src/afs/LINUX/osi_vfsops.c 29 Nov 2005 03:20:28 -0000 1.29.2.12
+++ src/afs/LINUX/osi_vfsops.c 24 Feb 2006 19:04:46 -0000
@@ -332,25 +332,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) {
- if (VREFCOUNT(vcp) == 2)
- afs_InactiveVCache(vcp, NULL);
- }
- AFS_GUNLOCK();
-}
-
/* afs_put_super
* Called from unmount to release super_block. */
static void
@@ -436,7 +417,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.81.2.40
diff -u -u -r1.81.2.40 osi_vnodeops.c
--- src/afs/LINUX/osi_vnodeops.c 11 Jan 2006 21:38:30 -0000 1.81.2.40
+++ src/afs/LINUX/osi_vnodeops.c 24 Feb 2006 19:04:46 -0000
@@ -788,8 +788,7 @@
struct vcache *vcp = VTOAFS(ip);
AFS_GLOCK();
- if (vcp->states & CUnlinked)
- (void) afs_InactiveVCache(vcp, NULL);
+ (void) afs_InactiveVCache(vcp, NULL);
AFS_GUNLOCK();
iput(ip);