[OpenAFS] IPUT Bad refCount 0 on inode 0xf8abadb8 in openafs-1.2.11
chas williams (contractor)
chas@cmf.nrl.navy.mil
Mon, 15 Nov 2004 11:32:51 -0500
In message <20041029140540.GE13909@kalmia.hozed.org>,Troy Benjegerdes writes:
>Trace; f89976c0 <[openafs.mp].rodata.end+4459/d3b9>
>Trace; f8983340 <[openafs.mp]afs_dentry_iput+0/f0>
>Trace; f89a0c44 <[openafs.mp]afs_global_lock+0/1c>
>Trace; f8980168 <[openafs.mp]osi_iput+58/f0>
>Trace; f89976c0 <[openafs.mp].rodata.end+4459/d3b9>
>Trace; f8983340 <[openafs.mp]afs_dentry_iput+0/f0>
>Trace; c015c93b <d_delete+bb/c0>
>Trace; c0153d66 <vfs_unlink+186/280>
>Trace; c0153f1b <sys_unlink+bb/120>
>Trace; c0108efb <system_call+33/38>
can you see if the following attached patch helps this problem.
Index: src/afs/VNOPS/afs_vnop_remove.c
===================================================================
RCS file: /cvs/openafs/src/afs/VNOPS/afs_vnop_remove.c,v
retrieving revision 1.31
diff -u -u -r1.31 afs_vnop_remove.c
--- src/afs/VNOPS/afs_vnop_remove.c 23 Jun 2004 22:25:06 -0000 1.31
+++ src/afs/VNOPS/afs_vnop_remove.c 15 Nov 2004 15:59:50 -0000
@@ -14,9 +14,7 @@
* afs_IsWired (DUX)
* afsremove
* afs_remove
- *
- * Local:
- * newname
+ * afs_newname
*
*/
#include <afsconfig.h>
@@ -110,7 +108,7 @@
register struct conn *tc;
struct AFSFetchStatus OutDirStatus;
struct AFSVolSync tsync;
- XSTATS_DECLS
+ XSTATS_DECLS;
do {
tc = afs_Conn(&adp->fid, treqp, SHARED_LOCK);
if (tc) {
@@ -193,8 +191,8 @@
return (0);
}
-static char *
-newname(void)
+char *
+afs_newname(void)
{
char *name, *sp, *p = ".__afs";
afs_int32 rd = afs_random() & 0xffff;
@@ -412,7 +410,7 @@
#endif
#endif
{
- char *unlname = newname();
+ char *unlname = afs_newname();
ReleaseWriteLock(&adp->lock);
if (tdc)
Index: src/afs/LINUX/osi_vnodeops.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_vnodeops.c,v
retrieving revision 1.83
diff -u -u -r1.83 osi_vnodeops.c
--- src/afs/LINUX/osi_vnodeops.c 19 Aug 2004 00:58:47 -0000 1.83
+++ src/afs/LINUX/osi_vnodeops.c 15 Nov 2004 15:59:50 -0000
@@ -1149,18 +1149,63 @@
int
afs_linux_unlink(struct inode *dip, struct dentry *dp)
{
- int code;
+ int code = EBUSY;
cred_t *credp = crref();
const char *name = dp->d_name.name;
+ struct vcache *tvc = ITOAFS(dp->d_inode);
#if defined(AFS_LINUX26_ENV)
lock_kernel();
#endif
+ if (((VREFCOUNT(tvc) > 0) && tvc->opens > 0)
+ && !(tvc->states & CUnlinked)) {
+ struct dentry *__dp;
+ char *__name;
+ extern char *afs_newname();
+
+ __dp = NULL;
+ __name = NULL;
+ do {
+ dput(__dp);
+
+ AFS_GLOCK();
+ if (__name)
+ osi_FreeSmallSpace(__name);
+ __name = afs_newname();
+ AFS_GUNLOCK();
+
+ __dp = lookup_one_len(__name, dp->d_parent, strlen(__name));
+
+ if (IS_ERR(__dp))
+ goto out;
+ } while (__dp->d_inode != NULL);
+
+ AFS_GLOCK();
+ code = afs_rename(ITOAFS(dip), dp->d_name.name, ITOAFS(dip), __dp->d_name.name, credp);
+ if (!code) {
+ tvc->mvid = __name;
+ crhold(credp);
+ if (tvc->uncred) {
+ crfree(tvc->uncred);
+ }
+ tvc->uncred = credp;
+ tvc->states |= CUnlinked;
+ }
+ AFS_GUNLOCK();
+
+ if (!code)
+ d_move(dp, __dp);
+ dput(__dp);
+
+ goto out;
+ }
+
AFS_GLOCK();
code = afs_remove(ITOAFS(dip), name, credp);
AFS_GUNLOCK();
if (!code)
d_drop(dp);
+out:
#if defined(AFS_LINUX26_ENV)
unlock_kernel();
#endif