linux-dentry-deletion-for-unlinked-files-22-version-20020721
[openafs.git] / src / afs / LINUX / osi_vnodeops.c
index 37b0e01..e18d6b3 100644 (file)
@@ -34,7 +34,6 @@ RCSID("$Header$");
 #if defined(AFS_LINUX24_ENV)
 #include "../h/smp_lock.h"
 #endif
-#include "../afs/afs_osidnlc.h"
 
 #ifdef pgoff2loff
 #define pageoff(pp) pgoff2loff((pp)->index)
@@ -43,6 +42,7 @@ RCSID("$Header$");
 #endif
 
 extern struct vcache *afs_globalVp;
+extern afs_rwlock_t afs_xvcache;
 
 extern struct dentry_operations *afs_dops;
 #if defined(AFS_LINUX24_ENV)
@@ -355,6 +355,7 @@ tagain:
              afid.Fid.Unique=ntohl(de->fid.vunique);
              if ((avc->states & CForeign) == 0 &&
                  (ntohl(de->fid.vnode) & 1)) {
+                type=DT_DIR;
              } else if ((tvc=afs_FindVCache(&afid,0,0,0,0))) {
                   if (tvc->mvstat) {
                        type=DT_DIR;
@@ -763,20 +764,33 @@ static int afs_linux_revalidate(struct dentry *dp)
     cred_t *credp;
     struct vrequest treq;
     struct vcache *vcp = ITOAFS(dp->d_inode);
+    struct vcache *rootvp = NULL;
 
     AFS_GLOCK();
+
+    if (afs_fakestat_enable && vcp->mvstat == 1 && vcp->mvid &&
+       (vcp->states & CMValid) && (vcp->states & CStatd)) {
+       ObtainSharedLock(&afs_xvcache, 680);
+       rootvp = afs_FindVCache(vcp->mvid, 0, 0, 0, 0);
+       ReleaseSharedLock(&afs_xvcache);
+    }
+
 #ifdef AFS_LINUX24_ENV
     lock_kernel();
 #endif
 
     /* Make this a fast path (no crref), since it's called so often. */
     if (vcp->states & CStatd) {
-        if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
+       if (*dp->d_name.name != '/' && vcp->mvstat == 2) /* root vnode */
            check_bad_parent(dp); /* check and correct mvid */
-       vcache2inode(vcp);
+       if (rootvp)
+           vcache2fakeinode(rootvp, vcp);
+       else
+           vcache2inode(vcp);
 #ifdef AFS_LINUX24_ENV
        unlock_kernel();
 #endif
+       if (rootvp) afs_PutVCache(rootvp);
        AFS_GUNLOCK();
        return 0;
     }
@@ -893,7 +907,7 @@ static int afs_linux_dentry_revalidate(struct dentry *dp)
 
     unsigned long timeout = 3*HZ; /* 3 seconds */
 
-if (!ip)
+    if (!ip)
        printk("negative dentry: %s\n", dp->d_name.name);
 
     if (!(flags & LOOKUP_CONTINUE)) {
@@ -917,13 +931,31 @@ if (!ip)
 /* afs_dentry_iput */
 static void afs_dentry_iput(struct dentry *dp, struct inode *ip)
 {
+    afs_Trace3(afs_iclSetp, CM_TRACE_DENTRYIPUT,
+              ICL_TYPE_POINTER, ip,
+              ICL_TYPE_STRING, dp->d_parent->d_name.name,
+              ICL_TYPE_STRING, dp->d_name.name);
+
     osi_iput(ip);
 }
 
+static int afs_dentry_delete(struct dentry *dp)
+{
+    afs_Trace3(afs_iclSetp, CM_TRACE_DENTRYDELETE, ICL_TYPE_POINTER, 
+              dp->d_inode, ICL_TYPE_STRING, dp->d_parent->d_name.name,
+              ICL_TYPE_STRING, dp->d_name.name);
+
+    if (dp->d_inode && (ITOAFS(dp->d_inode)->states & CUnlinked))
+       return 1;               /* bad inode? */
+
+    return 0;
+}
+
 #if defined(AFS_LINUX24_ENV)
 struct dentry_operations afs_dentry_operations = {
        d_revalidate:   afs_linux_dentry_revalidate,
        d_iput:         afs_dentry_iput,
+       d_delete:       afs_dentry_delete,
 };
 struct dentry_operations *afs_dops = &afs_dentry_operations;
 #else
@@ -931,7 +963,7 @@ struct dentry_operations afs_dentry_operations = {
        afs_linux_dentry_revalidate,    /* d_validate(struct dentry *) */
        NULL,                   /* d_hash */
        NULL,                   /* d_compare */
-       NULL,                   /* d_delete(struct dentry *) */
+       afs_dentry_delete,      /* d_delete(struct dentry *) */
        NULL,                   /* d_release(struct dentry *) */
        afs_dentry_iput         /* d_iput(struct dentry *, struct inode *) */
 };
@@ -1086,7 +1118,6 @@ int afs_linux_unlink(struct inode *dip, struct dentry *dp)
     int code;
     cred_t *credp = crref();
     const char *name = dp->d_name.name;
-    int putback = 0;
 
     AFS_GLOCK();
     code = afs_remove(ITOAFS(dip), name, credp);