diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c
index 5f9f3266fe29873caf5a60c20191199eea503081..3875d7b32153b77616c0d45ca7f6961707cedac2 100644
--- a/lustre/mds/handler.c
+++ b/lustre/mds/handler.c
@@ -1308,7 +1308,6 @@ static int mdt_obj_create(struct ptlrpc_request *req)
         struct ldlm_res_id res_id = { .name = {0} };
         struct mds_obd *mds = &obd->u.mds;
         struct ost_body *body, *repbody;
-        int rc, size = sizeof(*repbody);
         char fidname[LL_FID_NAMELEN];
         struct inode *parent_inode;
         struct lustre_handle lockh;
@@ -1316,7 +1315,7 @@ static int mdt_obj_create(struct ptlrpc_request *req)
         ldlm_policy_data_t policy;
         struct dentry *new = NULL;
         struct dentry_params dp;
-        int mealen, flags = 0;
+        int mealen, flags = 0, rc, size = sizeof(*repbody), cleanup_phase = 0;
         unsigned int tmpname;
         struct lvfs_ucred uc;
         struct mea *mea;
@@ -1327,8 +1326,7 @@ static int mdt_obj_create(struct ptlrpc_request *req)
 
         parent_inode = mds->mds_objects_dir->d_inode;
 
-        body = lustre_swab_reqbuf(req, 0, sizeof(*body),
-                                  lustre_swab_ost_body);
+        body = lustre_swab_reqbuf(req, 0, sizeof(*body), lustre_swab_ost_body);
         if (body == NULL)
                 RETURN(-EFAULT);
 
@@ -1363,7 +1361,8 @@ static int mdt_obj_create(struct ptlrpc_request *req)
                         repbody->oa.o_id = new->d_inode->i_ino;
                         repbody->oa.o_generation = new->d_inode->i_generation;
                         repbody->oa.o_valid |= OBD_MD_FLID | OBD_MD_FLGENER;
-                        GOTO(cleanup2, rc = 0);
+                        cleanup_phase = 1;
+                        GOTO(cleanup, rc = 0);
                 }
                 CWARN("hmm. for some reason dir %lu/%lu (or reply) got lost\n",
                       (unsigned long) fid.id, (unsigned long) fid.generation);
@@ -1375,6 +1374,7 @@ static int mdt_obj_create(struct ptlrpc_request *req)
         down(&parent_inode->i_sem);
         handle = fsfilt_start(obd, parent_inode, FSFILT_OP_MKDIR, NULL);
         LASSERT(!IS_ERR(handle));
+        cleanup_phase = 1; /* transaction */
 
 repeat:
         tmpname = ll_insecure_random_int();
@@ -1429,6 +1429,7 @@ repeat:
                                 NULL, 0, NULL, &lockh);
                 if (rc != ELDLM_OK)
                         GOTO(cleanup, rc);
+                cleanup_phase = 2; /* valid lockh */
 
                 CDEBUG(D_OTHER, "created dirobj: %lu/%lu mode %o\n",
                                 (unsigned long) new->d_inode->i_ino,
@@ -1437,9 +1438,10 @@ repeat:
         } else {
                 up(&parent_inode->i_sem);
                 CERROR("%s: can't create dirobj: %d\n", obd->obd_name, rc);
+                GOTO(cleanup, rc);
         }
 
-        if (rc == 0 && body->oa.o_valid & OBD_MD_FLID) {
+        if (body->oa.o_valid & OBD_MD_FLID) {
                 /* this is new object for splitted dir. we have to
                  * prevent recursive splitting on it -bzzz */
                 mealen = obd_size_diskmd(mds->mds_lmv_exp, NULL);
@@ -1454,17 +1456,21 @@ repeat:
                 CDEBUG(D_OTHER, "%s: mark non-splittable %lu/%u - %d\n",
                        obd->obd_name, new->d_inode->i_ino,
                        new->d_inode->i_generation, flags);
-        } else if (rc == 0 && body->oa.o_easize) {
+        } else if (body->oa.o_easize) {
                 mds_try_to_split_dir(obd, new, NULL, body->oa.o_easize);
         }
 
 cleanup:
-        rc = mds_finish_transno(mds, parent_inode, handle, req, rc, 0);
-        if (rc == 0)
-                ptlrpc_save_lock(req, &lockh, LCK_EX);
-        else
-                ldlm_lock_decref(&lockh, LCK_EX);
-cleanup2:
+        if (cleanup_phase == 1) /* transaction */
+                rc = mds_finish_transno(mds, parent_inode, handle, req, rc, 0);
+
+        if (cleanup_phase == 2) { /* valid lockh */
+                if (rc == 0)
+                        ptlrpc_save_lock(req, &lockh, LCK_EX);
+                else
+                        ldlm_lock_decref(&lockh, LCK_EX);
+        }
+
         l_dput(new);
         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, &uc);
         RETURN(rc);