Whamcloud - gitweb
- merge 0.7rc1 from b_devel to HEAD (20030612 merge point)
[fs/lustre-release.git] / lustre / llite / dcache.c
index 41c68d9..0c9fcf7 100644 (file)
@@ -39,6 +39,16 @@ void ll_release(struct dentry *de)
         EXIT;
 }
 
+int ll_delete(struct dentry *de)
+{
+        if (de->d_it != 0) {
+                CERROR("%s put dentry %p+%p with d_it %p\n", current->comm,
+                       de, de->d_fsdata, de->d_it);
+                LBUG();
+        }
+        return 0;
+}
+
 void ll_set_dd(struct dentry *de)
 {
         ENTRY;
@@ -61,8 +71,6 @@ void ll_intent_release(struct dentry *de, struct lookup_intent *it)
         struct lustre_handle *handle;
         ENTRY;
 
-        LASSERT(ll_d2d(de) != NULL);
-
         if (it->it_lock_mode) {
                 handle = (struct lustre_handle *)it->it_lock_handle;
                 ldlm_lock_decref(handle, it->it_lock_mode);
@@ -80,8 +88,9 @@ void ll_intent_release(struct dentry *de, struct lookup_intent *it)
 
         if (de->d_it == it)
                 LL_GET_INTENT(de, it);
-        else 
-                CERROR("STRANGE intent release: %p %p\n", de->d_it, it);
+        else
+                CDEBUG(D_INODE, "STRANGE intent release: %p %p\n",
+                       de->d_it, it);
 
         EXIT;
 }
@@ -89,25 +98,66 @@ void ll_intent_release(struct dentry *de, struct lookup_intent *it)
 extern struct dentry *ll_find_alias(struct inode *, struct dentry *);
 
 static int revalidate2_finish(int flag, struct ptlrpc_request *request,
-                              struct dentry **de, struct lookup_intent *it,
-                              int offset, obd_id ino)
+                              struct inode *parent, struct dentry **de,
+                              struct lookup_intent *it, int offset, obd_id ino)
 {
-        struct mds_body *body;
-        struct lov_mds_md *lmm = NULL;
-        int rc = 0; 
+        struct ll_sb_info     *sbi = ll_i2sbi(parent);
+        struct mds_body       *body;
+        struct lov_stripe_md  *lsm = NULL;
+        struct lov_mds_md     *lmm;
+        int                    lmmsize;
+        int                    rc = 0;
         ENTRY;
 
-        if (!(flag & LL_LOOKUP_NEGATIVE)) {
-                body = lustre_msg_buf(request->rq_repmsg, offset);
-                if (body->valid & OBD_MD_FLEASIZE)
-                        lmm = lustre_msg_buf(request->rq_repmsg, offset + 1);
-                ll_update_inode((*de)->d_inode, body, lmm);
-                mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle,
-                                   (*de)->d_inode);
-        } else 
-                rc = -ENOENT;
-
-        ptlrpc_req_finished(request);
+        /* NB 1 request reference will be taken away by ll_intent_lock()
+         * when I return */
+
+        if ((flag & LL_LOOKUP_NEGATIVE) != 0)
+                GOTO (out, rc = -ENOENT);
+
+        /* We only get called if the mdc_enqueue() called from
+         * ll_intent_lock() was successful.  Therefore the mds_body is
+         * present and correct, and the eadata is present (but still
+         * opaque, so only obd_unpackmd() can check the size) */
+        body = lustre_msg_buf(request->rq_repmsg, offset, sizeof (*body));
+        LASSERT (body != NULL);
+        LASSERT_REPSWABBED (request, offset);
+
+        if (body->valid & OBD_MD_FLEASIZE) {
+                /* Only bother with this if inodes's LSM not set? */
+
+                if (body->eadatasize == 0) {
+                        CERROR ("OBD_MD_FLEASIZE set, but eadatasize 0\n");
+                        GOTO (out, rc = -EPROTO);
+                }
+                lmmsize = body->eadatasize;
+                lmm = lustre_msg_buf (request->rq_repmsg, offset + 1, lmmsize);
+                LASSERT (lmm != NULL);
+                LASSERT_REPSWABBED (request, offset + 1);
+
+                rc = obd_unpackmd (&sbi->ll_osc_conn,
+                                   &lsm, lmm, lmmsize);
+                if (rc < 0) {
+                        CERROR ("Error %d unpacking eadata\n", rc);
+                        LBUG();
+                        /* XXX don't know if I should do this... */
+                        GOTO (out, rc);
+                        /* or skip the ll_update_inode but still do
+                         * mdc_lock_set_inode() */
+                }
+                LASSERT (rc >= sizeof (*lsm));
+                rc = 0;
+        }
+
+        ll_update_inode((*de)->d_inode, body, lsm);
+
+        if (lsm != NULL &&
+            ll_i2info((*de)->d_inode)->lli_smd != lsm)
+                obd_free_memmd (&sbi->ll_osc_conn, &lsm);
+
+        ll_mdc_lock_set_inode((struct lustre_handle *)it->it_lock_handle,
+                              (*de)->d_inode);
+ out:
         RETURN(rc);
 }
 
@@ -146,6 +196,8 @@ int ll_revalidate2(struct dentry *de, int flags, struct lookup_intent *it)
 {
         int rc;
         ENTRY;
+        CDEBUG(D_VFSTRACE, "VFS Op:name=%s,intent=%s\n", de->d_name.name,
+               LL_IT2STR(it));
 
         /* We don't want to cache negative dentries, so return 0 immediately.
          * We believe that this is safe, that negative dentries cannot be
@@ -221,4 +273,5 @@ struct dentry_operations ll_d_ops = {
         .d_revalidate2 = ll_revalidate2,
         .d_intent_release = ll_intent_release,
         .d_release = ll_release,
+        .d_delete = ll_delete,
 };