[OpenAFS-devel] AFS 1.3.82 failing in kernel, tracing back to link_path_walk/dput/iput.
chas williams - CONTRACTOR
chas@cmf.nrl.navy.mil
Fri, 03 Jun 2005 10:23:08 -0400
In message <OF51AE5234.55C8166D-ONC1257015.004C3357-C1257015.004C4D98@de.ibm.co
m>,Sven Oehme writes:
> wake_up_inode(inode);
> if (inode->i_state != I_CLEAR)
>line 1023 ---->> BUG();
> destroy_inode(inode);
>}
i thought it might be. it looks like afs might be racing to get a
vnode from the lru and isnt "respecting" the i_state flags. once
osi_clear_inode() makes the vnode inactive, it is ready for use
again. we only hold GLOCK during osi_clear_inode, but a quick
fix might hold GLOCK during more of drop operation to keep other
parts of afs from grabbing a vnode until its truly been recycled.
try this patch. note that you should not hold the GLOCK before entering
generic_delete_inode() since inode_lock (spinlock) is already held at
this point. so afs_delete_inode() does it normal GLOCK but the GUNLOCK
is moved until after generic_delete_inode() is finished.
i havent seen this race but my machine is rather slow (dual 1Ghz).
Index: src/afs/LINUX/osi_vfsops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vfsops.c,v
retrieving revision 1.32
diff -u -u -r1.32 osi_vfsops.c
--- src/afs/LINUX/osi_vfsops.c 11 Mar 2005 04:35:42 -0000 1.32
+++ src/afs/LINUX/osi_vfsops.c 3 Jun 2005 14:15:44 -0000
@@ -289,6 +287,14 @@
static void
+afs_drop_inode(struct inode *ip)
+{
+ generic_delete_inode(ip);
+ AFS_GUNLOCK(); /* locked by afs_delete_inode() */
+}
+
+
+static void
afs_destroy_inode(struct inode *ip)
{
ip->i_state = 0;
@@ -305,13 +311,15 @@
static void
afs_delete_inode(struct inode *ip)
{
-#ifdef AFS_LINUX26_ENV
+#if defined(AFS_LINUX26_ENV)
+ AFS_GLOCK(); /* after spin_unlock(inode_lock) */
put_inode_on_dummy_list(ip);
-#endif
-
+ osi_clear_inode(ip);
+#else
AFS_GLOCK();
osi_clear_inode(ip);
AFS_GUNLOCK();
+#endif
}
@@ -404,7 +414,7 @@
struct super_operations afs_sops = {
#if defined(AFS_LINUX26_ENV)
- .drop_inode = generic_delete_inode,
+ .drop_inode = afs_drop_inode,
.destroy_inode = afs_destroy_inode,
#endif
.delete_inode = afs_delete_inode,