Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / mdt / mdt_open.c
index de40195..e2bea57 100644 (file)
@@ -809,6 +809,68 @@ static int mdt_open_by_fid(struct mdt_thread_info* info,
         RETURN(rc);
 }
 
+static int mdt_open_anon_by_fid(struct mdt_thread_info* info,
+                                struct ldlm_reply *rep, 
+                                struct mdt_lock_handle *lhc)
+{
+        __u32                    flags = info->mti_spec.sp_cr_flags;
+        struct mdt_reint_record *rr = &info->mti_rr;
+        struct md_attr          *ma = &info->mti_attr;
+        struct mdt_object       *o;
+        int                      rc;
+        ldlm_mode_t              lm;
+        ENTRY;
+
+        o = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid2);
+        if (IS_ERR(o))
+                RETURN(rc = PTR_ERR(o));
+
+        rc = mdt_object_exists(o);
+        if (rc == 0) {
+                mdt_set_disposition(info, rep, (DISP_LOOKUP_EXECD |
+                                    DISP_LOOKUP_NEG));
+                GOTO(out, rc = -ENOENT);
+        } else if (rc < 0) {
+                CERROR("NFS remote open shouldn't happen.\n");
+                GOTO(out, rc);
+        }
+
+        mdt_set_disposition(info, rep, (DISP_IT_EXECD |
+                                        DISP_LOOKUP_EXECD |
+                                        DISP_LOOKUP_POS));
+
+        if (flags & FMODE_WRITE)
+                lm = LCK_CW;
+        else if (flags & MDS_FMODE_EXEC)
+                lm = LCK_PR;
+        else
+                lm = LCK_CR;
+
+        mdt_lock_handle_init(lhc);
+        mdt_lock_reg_init(lhc, lm);
+        rc = mdt_object_lock(info, o, lhc,
+                             MDS_INODELOCK_LOOKUP | MDS_INODELOCK_OPEN,
+                             MDT_CROSS_LOCK);
+        if (rc)
+                GOTO(out, rc);
+
+        rc = mo_attr_get(info->mti_env, mdt_object_child(o), ma);
+        if (rc)
+                GOTO(out, rc);
+
+        if (flags & MDS_OPEN_LOCK)
+                mdt_set_disposition(info, rep, DISP_OPEN_LOCK);
+        rc = mdt_finish_open(info, NULL, o, flags, 0, rep);
+
+        if (!(flags & MDS_OPEN_LOCK))
+                mdt_object_unlock(info, o, lhc, 1);
+
+        GOTO(out, rc);
+out:
+        mdt_object_put(info->mti_env, o);
+        return rc;
+}
+
 int mdt_pin(struct mdt_thread_info* info)
 {
         ENTRY;
@@ -906,6 +968,10 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         }
         msg_flags = lustre_msg_get_flags(req->rq_reqmsg);
 
+        if ((create_flags & (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS)) &&
+            info->mti_spec.u.sp_ea.eadata == NULL)
+                GOTO(out, result = err_serious(-EINVAL));
+
         CDEBUG(D_INODE, "I am going to open "DFID"/(%s->"DFID") "
                "cr_flag=0%o mode=0%06o msg_flag=0x%x\n",
                PFID(rr->rr_fid1), rr->rr_name,
@@ -933,6 +999,10 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
                 }
                 CDEBUG(D_INFO, "Open replay did find object, continue as "
                        "regular open\n");
+        } else if (rr->rr_namelen == 0 && !info->mti_cross_ref) {
+                result = mdt_open_anon_by_fid(info, ldlm_rep, lhc);
+                if (result != -ENOENT)
+                        GOTO(out, result);
         }
 
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OPEN_PACK))
@@ -1003,6 +1073,12 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
                 /* Not found and with MDS_OPEN_CREAT: let's create it. */
                 mdt_set_disposition(info, ldlm_rep, DISP_OPEN_CREATE);
 
+                info->mti_mos[0] = parent;
+                info->mti_mos[1] = child;
+                result = mdt_version_get_check(info, 0);
+                if (result)
+                        GOTO(out_child, result);
+
                 /* Let lower layers know what is lock mode on directory. */
                 info->mti_spec.sp_cr_mode =
                         mdt_dlm_mode2mdl_mode(lh->mlh_pdo_mode);
@@ -1330,8 +1406,10 @@ int mdt_done_writing(struct mdt_thread_info *info)
         if (mfd == NULL) {
                 spin_unlock(&med->med_open_lock);
                 CDEBUG(D_INODE, "no handle for done write: fid = "DFID
-                       ": cookie = "LPX64"\n", PFID(info->mti_rr.rr_fid1),
-                       info->mti_epoch->handle.cookie);
+                       ": cookie = "LPX64" ioepoch = "LPU64"\n",
+                       PFID(info->mti_rr.rr_fid1),
+                       info->mti_epoch->handle.cookie,
+                       info->mti_epoch->ioepoch);
                 RETURN(-ESTALE);
         }