Whamcloud - gitweb
b=23289 no need to always start transaction for attr_set(atime) on close
[fs/lustre-release.git] / lustre / mdt / mdt_open.c
index 269d3c2..d581b82 100644 (file)
@@ -26,7 +26,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -85,8 +85,7 @@ struct mdt_file_data *mdt_handle2mfd(struct mdt_thread_info *info,
         LASSERT(handle != NULL);
         mfd = class_handle2object(handle->cookie);
         /* during dw/setattr replay the mfd can be found by old handle */
-        if (mfd == NULL &&
-            lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) {
+        if (mfd == NULL && req_is_replay(req)) {
                 struct mdt_export_data *med = &req->rq_export->exp_mdt_data;
                 cfs_list_for_each_entry(mfd, &med->med_open_head, mfd_list) {
                         if (mfd->mfd_old_handle.cookie == handle->cookie)
@@ -231,7 +230,7 @@ static int mdt_som_attr_set(struct mdt_thread_info *info,
                 ma->ma_som->msd_size = la->la_valid & LA_SIZE ? la->la_size : 0;
                 ma->ma_som->msd_blocks = la->la_valid & LA_BLOCKS ?
                                          la->la_blocks : 0;
-                ma->ma_som->msd_mountid = mdt->mdt_lut.lut_mount_count;
+                ma->ma_som->msd_mountid = mdt->mdt_lut.lut_obd->u.obt.obt_mount_count;
                 ma->ma_attr.la_valid &= LA_ATIME | LA_MTIME | LA_CTIME;
         } else {
                 ma->ma_som->msd_ioepoch = IOEPOCH_INVAL;
@@ -587,7 +586,7 @@ void mdt_mfd_set_mode(struct mdt_file_data *mfd, int mode)
 }
 
 static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
-                        struct mdt_object *o, int flags, int created)
+                        struct mdt_object *o, __u64 flags, int created)
 {
         struct ptlrpc_request   *req = mdt_info_req(info);
         struct mdt_export_data  *med = &req->rq_export->exp_mdt_data;
@@ -667,7 +666,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
                 mfd->mfd_xid = req->rq_xid;
 
                 /* replay handle */
-                if (lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY) {
+                if (req_is_replay(req)) {
                         struct mdt_file_data *old_mfd;
                         /* Check wheather old cookie already exist in
                          * the list, becasue when do recovery, client
@@ -678,8 +677,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
                         old_mfd = mdt_handle2mfd(info, info->mti_rr.rr_handle);
                         if (old_mfd) {
                                 CDEBUG(D_HA, "del orph mfd %p fid=("DFID") "
-                                       "cookie=" LPX64"\n",
-                                       mfd, 
+                                       "cookie=" LPX64"\n", mfd,
                                        PFID(mdt_object_fid(mfd->mfd_object)),
                                        info->mti_rr.rr_handle->cookie);
                                 cfs_spin_lock(&med->med_open_lock);
@@ -717,7 +715,7 @@ static int mdt_mfd_open(struct mdt_thread_info *info, struct mdt_object *p,
 
 static int mdt_finish_open(struct mdt_thread_info *info,
                            struct mdt_object *p, struct mdt_object *o,
-                           int flags, int created, struct ldlm_reply *rep)
+                           __u64 flags, int created, struct ldlm_reply *rep)
 {
         struct ptlrpc_request   *req = mdt_info_req(info);
         struct obd_export       *exp = req->rq_export;
@@ -1079,7 +1077,7 @@ static int mdt_open_anon_by_fid(struct mdt_thread_info* info,
                 mdt_set_disposition(info, rep, DISP_OPEN_LOCK);
         rc = mdt_finish_open(info, NULL, o, flags, 0, rep);
 
-        if (!(flags & MDS_OPEN_LOCK))
+        if (!(flags & MDS_OPEN_LOCK) || rc)
                 mdt_object_unlock(info, o, lhc, 1);
 
         GOTO(out, rc);
@@ -1153,7 +1151,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         struct mdt_body         *repbody;
         struct lu_fid           *child_fid = &info->mti_tmp_fid1;
         struct md_attr          *ma = &info->mti_attr;
-        __u32                    create_flags = info->mti_spec.sp_cr_flags;
+        __u64                    create_flags = info->mti_spec.sp_cr_flags;
         struct mdt_reint_record *rr = &info->mti_rr;
         struct lu_name          *lname;
         int                      result, rc;
@@ -1164,6 +1162,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         OBD_FAIL_TIMEOUT_ORSET(OBD_FAIL_MDS_PAUSE_OPEN, OBD_FAIL_ONCE,
                                (obd_timeout + 1) / 4);
 
+        mdt_counter_incr(req->rq_export, LPROC_MDT_OPEN);
         repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
 
         ma->ma_lmm = req_capsule_server_get(info->mti_pill, &RMF_MDT_MD);
@@ -1189,12 +1188,12 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
                 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",
+               "cr_flag="LPO64" mode=0%06o msg_flag=0x%x\n",
                PFID(rr->rr_fid1), rr->rr_name,
                PFID(rr->rr_fid2), create_flags,
                ma->ma_attr.la_mode, msg_flags);
 
-        if (msg_flags & MSG_REPLAY ||
+        if (req_is_replay(req) ||
             (req->rq_export->exp_libclient && create_flags&MDS_OPEN_HAS_EA)) {
                 /* This is a replay request or from liblustre with ea. */
                 result = mdt_open_by_fid(info, ldlm_rep);
@@ -1210,7 +1209,8 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
                  * via a regular replay.
                  */
                 if (!(create_flags & MDS_OPEN_CREAT)) {
-                        DEBUG_REQ(D_ERROR, req,"OPEN & CREAT not in open replay.");
+                        DEBUG_REQ(D_ERROR, req,
+                                  "OPEN & CREAT not in open replay.");
                         GOTO(out, result = -EFAULT);
                 }
                 CDEBUG(D_INFO, "Open replay did find object, continue as "
@@ -1244,10 +1244,14 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         if (IS_ERR(parent))
                 GOTO(out, result = PTR_ERR(parent));
 
+        /* get and check version of parent */
+        result = mdt_version_get_check(info, parent, 0);
+        if (result)
+                GOTO(out_parent, result);
+
         fid_zero(child_fid);
 
         lname = mdt_name(info->mti_env, (char *)rr->rr_name, rr->rr_namelen);
-
         result = mdo_lookup(info->mti_env, mdt_object_child(parent),
                             lname, child_fid, &info->mti_spec);
         LASSERTF(ergo(result == 0, fid_is_sane(child_fid)),
@@ -1284,17 +1288,23 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         if (IS_ERR(child))
                 GOTO(out_parent, result = PTR_ERR(child));
 
+        /** check version of child  */
+        rc = mdt_version_get_check(info, child, 1);
+        if (rc)
+                GOTO(out_child, result = rc);
+
         mdt_set_capainfo(info, 1, child_fid, BYPASS_CAPA);
         if (result == -ENOENT) {
+                /* save versions in reply */
+                mdt_version_get_save(info, parent, 0);
+                mdt_version_get_save(info, child, 1);
+
+                /* version of child will be changed */
+                info->mti_mos = child;
+
                 /* 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);
@@ -1369,7 +1379,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
         LASSERT(!lustre_handle_is_used(&lhc->mlh_reg_lh));
 
         /* get openlock if this is not replay and if a client requested it */
-        if (!(msg_flags & MSG_REPLAY) && create_flags & MDS_OPEN_LOCK) {
+        if (!req_is_replay(req) && create_flags & MDS_OPEN_LOCK) {
                 ldlm_mode_t lm;
 
                 if (create_flags & FMODE_WRITE)
@@ -1461,6 +1471,7 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
         if ((mode & MDS_FMODE_EXEC || mode & FMODE_READ || mode & FMODE_WRITE)
             && (ma->ma_valid & MA_INODE) && (ma->ma_attr.la_valid & LA_ATIME)) {
                 /* Set the atime only. */
+                ma->ma_valid = MA_INODE;
                 ma->ma_attr.la_valid = LA_ATIME;
                 rc = mo_attr_set(info->mti_env, next, ma);
         }
@@ -1513,6 +1524,7 @@ int mdt_close(struct mdt_thread_info *info)
         int rc, ret = 0;
         ENTRY;
 
+        mdt_counter_incr(req->rq_export, LPROC_MDT_CLOSE);
         /* Close may come with the Size-on-MDS update. Unpack it. */
         rc = mdt_close_unpack(info);
         if (rc)
@@ -1652,13 +1664,13 @@ int mdt_done_writing(struct mdt_thread_info *info)
         info->mti_attr.ma_valid = 0;
 
         info->mti_attr.ma_lmm_size = info->mti_mdt->mdt_max_mdsize;
-        OBD_ALLOC(info->mti_attr.ma_lmm, info->mti_attr.ma_lmm_size);
+        OBD_ALLOC(info->mti_attr.ma_lmm, info->mti_mdt->mdt_max_mdsize);
         if (info->mti_attr.ma_lmm == NULL)
                 RETURN(-ENOMEM);
 
         rc = mdt_mfd_close(info, mfd);
 
-        OBD_FREE(info->mti_attr.ma_lmm, info->mti_attr.ma_lmm_size);
+        OBD_FREE(info->mti_attr.ma_lmm, info->mti_mdt->mdt_max_mdsize);
         mdt_empty_transno(info);
         RETURN(rc);
 }