Whamcloud - gitweb
- landing of b_hd_cleanup_merge to HEAD.
[fs/lustre-release.git] / lustre / mdc / mdc_locks.c
index cc7053c..7998565 100644 (file)
@@ -451,8 +451,8 @@ int mdc_intent_lock(struct obd_export *exp,
         ENTRY;
         LASSERT(it);
 
-        CDEBUG(D_DLMTRACE, "name: %*s in %ld, intent: %s\n", len, name,
-               pfid ? (unsigned long) pfid->id : 0 , ldlm_it2str(it->it_op));
+        CDEBUG(D_DLMTRACE, "name: %*s in inode "LPU64", intent: %s flags %#o\n",
+               len, name, pfid->id, ldlm_it2str(it->it_op), it->it_flags);
 
         if (cfid && (it->it_op == IT_LOOKUP || it->it_op == IT_GETATTR ||
                      it->it_op == IT_CHDIR)) {
@@ -488,7 +488,11 @@ int mdc_intent_lock(struct obd_export *exp,
                                sizeof(lockh));
                         it->d.lustre.it_lock_mode = mode;
                 }
-                RETURN(rc);
+
+                /* Only return failure if it was not GETATTR by cfid
+                   (from inode_revalidate) */
+                if (rc || name)
+                        RETURN(rc);
         }
 
         /* lookup_it may be called only after revalidate_it has run, because
@@ -512,7 +516,24 @@ int mdc_intent_lock(struct obd_export *exp,
         }
         request = *reqp = it->d.lustre.it_data;
         LASSERT(request != NULL);
+        
+        /* If we're doing an IT_OPEN which did not result in an actual
+         * successful open, then we need to remove the bit which saves
+         * this request for unconditional replay.
+         *
+         * It's important that we do this first!  Otherwise we might exit the
+         * function without doing so, and try to replay a failed create
+         * (bug 3440) */
+        if (it->it_op & IT_OPEN) {
+                if (!it_disposition(it, DISP_OPEN_OPEN) ||
+                    it->d.lustre.it_status != 0) {
+                        unsigned long irqflags;
 
+                        spin_lock_irqsave(&request->rq_lock, irqflags);
+                        request->rq_replay = 0;
+                        spin_unlock_irqrestore(&request->rq_lock, irqflags);
+                }
+        }
         if (!it_disposition(it, DISP_IT_EXECD)) {
                 /* The server failed before it even started executing the
                  * intent, i.e. because it couldn't unpack the request. */
@@ -541,20 +562,6 @@ int mdc_intent_lock(struct obd_export *exp,
                         RETURN(-ESTALE);
         }
 
-        /* If we're doing an IT_OPEN which did not result in an actual
-         * successful open, then we need to remove the bit which saves
-         * this request for unconditional replay. */
-        if (it->it_op & IT_OPEN) {
-                if (!it_disposition(it, DISP_OPEN_OPEN) ||
-                    it->d.lustre.it_status != 0) {
-                        unsigned long irqflags;
-
-                        spin_lock_irqsave(&request->rq_lock, irqflags);
-                        request->rq_replay = 0;
-                        spin_unlock_irqrestore(&request->rq_lock, irqflags);
-                }
-        }
-
         rc = it_open_error(DISP_LOOKUP_EXECD, it);
         if (rc)
                 RETURN(rc);
@@ -564,13 +571,13 @@ int mdc_intent_lock(struct obd_export *exp,
          */
         if (it_disposition(it, DISP_OPEN_CREATE) &&
             !it_open_error(DISP_OPEN_CREATE, it))
-                ptlrpc_request_addref(request);
+                ptlrpc_request_addref(request); /* balanced in ll_create_node */
         if (it_disposition(it, DISP_OPEN_OPEN) &&
             !it_open_error(DISP_OPEN_OPEN, it))
-                ptlrpc_request_addref(request);
+                ptlrpc_request_addref(request); /* balanced in ll_file_open */
 
         if (it->it_op & IT_CREAT) {
-                /* XXX this belongs in ll_create_iit */
+                /* XXX this belongs in ll_create_it */
         } else if (it->it_op == IT_OPEN) {
                 LASSERT(!it_disposition(it, DISP_OPEN_CREATE));
         } else {