Whamcloud - gitweb
- add another sanity test
[fs/lustre-release.git] / lustre / llite / dcache.c
index f66fc5d..53c0ef4 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <linux/obd_support.h>
 #include <linux/lustre_lite.h>
+#include <linux/lustre_idl.h>
 #include <linux/lustre_dlm.h>
 
 extern struct address_space_operations ll_aops;
@@ -46,6 +47,9 @@ void ll_intent_release(struct dentry *de, struct lookup_intent *it)
         struct lustre_handle *handle;
         ENTRY;
 
+        /* XXX the check for RENAME2 is a workaround for old kernels 
+           which call intent_release twice in rename 
+        */
         if (it == NULL || it->it_op == IT_RENAME2) {
                 EXIT;
                 return;
@@ -57,23 +61,25 @@ void ll_intent_release(struct dentry *de, struct lookup_intent *it)
                 handle = (struct lustre_handle *)it->it_lock_handle;
                 if (it->it_op == IT_SETATTR) {
                         int rc;
-                        struct inode *inode = de->d_inode;
                         ldlm_lock_decref(handle, it->it_lock_mode);
                         rc = ldlm_cli_cancel(handle);
                         if (rc < 0)
                                 CERROR("ldlm_cli_cancel: %d\n", rc);
-                        /* XXX should we only do this when the last lock goes? */
-                        LASSERT(igrab(inode) == inode);
-                        d_delete_aliases(inode);
-                        iput(inode);
                 } else
                         ldlm_lock_decref(handle, it->it_lock_mode);
         }
 
-        if (it->it_op != IT_RELEASED_MAGIC) {
+        if (it->it_op == IT_RELEASED_MAGIC) {
+                EXIT; 
+                return;
+        }
+
+        if (de->d_it && de->d_it == it) { 
+                de->d_it = NULL;
                 up(&ll_d2d(de)->lld_it_sem);
                 it->it_op = IT_RELEASED_MAGIC;
         }
+
         EXIT;
 }
 
@@ -90,6 +96,36 @@ static int revalidate2_finish(int flag, struct ptlrpc_request *request,
         return 0;
 }
 
+static int ll_have_lock(struct dentry *de)
+{
+       struct ll_sb_info *sbi = ll_s2sbi(de->d_sb);
+        struct lustre_handle lockh;
+        __u64 res_id[RES_NAME_SIZE] = {0};
+        struct obd_device *obddev;
+        ENTRY;
+
+       if (!de->d_inode)
+               RETURN(0);
+
+        obddev = class_conn2obd(&sbi->ll_mdc_conn);
+        res_id[0] = de->d_inode->i_ino;
+
+        CDEBUG(D_INFO, "trying to match res "LPU64"\n", res_id[0]);
+
+        if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN,
+                            NULL, 0, LCK_PR, &lockh)) {
+                ldlm_lock_decref(&lockh, LCK_PR);
+                RETURN(1);
+        }
+
+        if (ldlm_lock_match(obddev->obd_namespace, res_id, LDLM_PLAIN,
+                            NULL, 0, LCK_PW, &lockh)) {
+                ldlm_lock_decref(&lockh, LCK_PW);
+                RETURN(1);
+        }
+        RETURN(0);
+}
+
 int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
 {
         int rc;
@@ -103,6 +139,9 @@ int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
                 RETURN(0);
         }
 
+        if (ll_have_lock(de))
+                GOTO(out, rc = 0);
+
         rc = ll_intent_lock(de->d_parent->d_inode, &de, it, revalidate2_finish);
         if (rc < 0) {
                 /* Something bad happened; overwrite it_status? */
@@ -115,11 +154,9 @@ int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
         spin_unlock(&dcache_lock);
         d_rehash(de);
 
-        if (it != NULL) { 
-                LL_SAVE_INTENT(de, it);
-        } else {
+ out:
+        if (!it)
                 de->d_it = NULL;
-        }
 
         RETURN(1);
 }