Whamcloud - gitweb
b=19756
[fs/lustre-release.git] / lustre / mdt / mdt_open.c
index 96b1d8d..bd976a3 100644 (file)
@@ -470,24 +470,36 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
                         LASSERT(info->mti_rr.rr_handle != NULL);
                         old_mfd = mdt_handle2mfd(info, info->mti_rr.rr_handle);
                         if (old_mfd) {
-                                CDEBUG(D_HA, "del orph mfd %p cookie" LPX64"\n",
-                                       mfd, info->mti_rr.rr_handle->cookie);
+                                CDEBUG(D_HA, "del orph mfd %p fid=("DFID") "
+                                       "cookie=" LPX64"\n",
+                                       mfd, 
+                                       PFID(mdt_object_fid(mfd->mfd_object)),
+                                       info->mti_rr.rr_handle->cookie);
                                 spin_lock(&med->med_open_lock);
                                 class_handle_unhash(&old_mfd->mfd_handle);
                                 list_del_init(&old_mfd->mfd_list);
                                 spin_unlock(&med->med_open_lock);
-                                mdt_mfd_free(old_mfd);
+                                mdt_mfd_close(info, old_mfd);
                         }
                         CDEBUG(D_HA, "Store old cookie "LPX64" in new mfd\n",
                                info->mti_rr.rr_handle->cookie);
                         mfd->mfd_old_handle.cookie =
                                                 info->mti_rr.rr_handle->cookie;
                 }
-                spin_lock(&med->med_open_lock);
-                list_add(&mfd->mfd_list, &med->med_open_head);
-                spin_unlock(&med->med_open_lock);
-
                 repbody->handle.cookie = mfd->mfd_handle.h_cookie;
+
+                if (req->rq_export->exp_disconnected) {
+                        spin_lock(&med->med_open_lock);
+                        class_handle_unhash(&mfd->mfd_handle);
+                        list_del_init(&mfd->mfd_list);
+                        spin_unlock(&med->med_open_lock);
+                        mdt_mfd_close(info, mfd);
+                } else {
+                        spin_lock(&med->med_open_lock);
+                        list_add(&mfd->mfd_list, &med->med_open_head);
+                        spin_unlock(&med->med_open_lock);
+                }
+
                 mdt_empty_transno(info);
         } else
                 rc = -ENOMEM;
@@ -726,6 +738,7 @@ void mdt_reconstruct_open(struct mdt_thread_info *info,
                                       PFID(mdt_object_fid(child)), rc,
                                       obd_uuid2str(&exp->exp_client_uuid),
                                       obd_export_nid2str(exp));
+                        mdt_object_put(env, parent);
                         mdt_export_evict(exp);
                         EXIT;
                         return;
@@ -806,6 +819,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;
@@ -896,13 +971,17 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         LASSERT(info->mti_pill->rc_fmt == &RQF_LDLM_INTENT_OPEN);
         ldlm_rep = req_capsule_server_get(info->mti_pill, &RMF_DLM_REP);
 
-        /* TODO: JOIN file */
+        /* JOIN file was deprecated since 1.6.5, but may be revived one day */
         if (create_flags & MDS_OPEN_JOIN_FILE) {
-                CERROR("JOIN file will be supported soon\n");
+                CERROR("file join is unsupported in this version of Lustre\n");
                 GOTO(out, result = err_serious(-EOPNOTSUPP));
         }
         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,
@@ -930,6 +1009,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))
@@ -1000,6 +1083,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);
@@ -1327,8 +1416,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);
         }