}
 
        if (rinfo->head->is_dentry) {
+               struct inode *dir = req->r_locked_dir;
+
+               err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
+                                session, req->r_request_started, -1,
+                                &req->r_caps_reservation);
+               if (err < 0)
+                       return err;
+       }
+
+       if (rinfo->head->is_dentry && !req->r_aborted) {
                /*
                 * lookup link rename   : null -> possibly existing inode
                 * mknod symlink mkdir  : null -> new inode
                BUG_ON(ceph_snap(dir) !=
                       le64_to_cpu(rinfo->diri.in->snapid));
 
-               err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
-                                session, req->r_request_started, -1,
-                                &req->r_caps_reservation);
-               if (err < 0)
-                       return err;
-
                /* do we have a lease on the whole dir? */
                have_dir_cap =
                        (le32_to_cpu(rinfo->diri.in->cap.caps) &
 
                err = PTR_ERR(req->r_reply);
                req->r_reply = NULL;
 
-               /* clean up */
-               __unregister_request(mdsc, req);
-               if (!list_empty(&req->r_unsafe_item))
-                       list_del_init(&req->r_unsafe_item);
-               complete(&req->r_safe_completion);
+               if (err == -ERESTARTSYS) {
+                       /* aborted */
+                       req->r_aborted = true;
+
+                       if (req->r_locked_dir &&
+                           (req->r_op & CEPH_MDS_OP_WRITE)) {
+                               struct ceph_inode_info *ci =
+                                       ceph_inode(req->r_locked_dir);
+
+                               dout("aborted, clearing I_COMPLETE on %p\n", 
+                                    req->r_locked_dir);
+                               spin_lock(&req->r_locked_dir->i_lock);
+                               ci->i_ceph_flags &= ~CEPH_I_COMPLETE;
+                               ci->i_release_count++;
+                               spin_unlock(&req->r_locked_dir->i_lock);
+                       }
+               } else {
+                       /* clean up this request */
+                       __unregister_request(mdsc, req);
+                       if (!list_empty(&req->r_unsafe_item))
+                               list_del_init(&req->r_unsafe_item);
+                       complete(&req->r_safe_completion);
+               }
        } else if (req->r_err) {
                err = req->r_err;
        } else {
 
        struct ceph_msg  *r_reply;
        struct ceph_mds_reply_info_parsed r_reply_info;
        int r_err;
+       bool r_aborted;
 
        unsigned long r_timeout;  /* optional.  jiffies */
        unsigned long r_started;  /* start time to measure timeout against */