Whamcloud - gitweb
LU-365 Update copyright for files modified by Whamcloud
[fs/lustre-release.git] / lustre / mdt / mdt_open.c
index f91fa02..e708584 100644 (file)
  * 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.
+ *
+ * Copyright (c) 2011 Whamcloud, Inc.
+ *
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -107,8 +110,8 @@ static int mdt_create_data(struct mdt_thread_info *info,
                            struct mdt_object *p, struct mdt_object *o)
 {
         struct md_op_spec     *spec = &info->mti_spec;
-        struct md_attr        *ma = &info->mti_attr;
-        int rc;
+        struct md_attr        *ma   = &info->mti_attr;
+        int                    rc   = 0;
         ENTRY;
 
         if (!md_should_create(spec->sp_cr_flags))
@@ -116,9 +119,15 @@ static int mdt_create_data(struct mdt_thread_info *info,
 
         ma->ma_need = MA_INODE | MA_LOV;
         ma->ma_valid = 0;
-        rc = mdo_create_data(info->mti_env,
-                             p ? mdt_object_child(p) : NULL,
-                             mdt_object_child(o), spec, ma);
+        cfs_down(&o->mot_lov_sem);
+        if (!(o->mot_flags & MOF_LOV_CREATED)) {
+                rc = mdo_create_data(info->mti_env,
+                                     p ? mdt_object_child(p) : NULL,
+                                     mdt_object_child(o), spec, ma);
+                if (rc == 0 && ma->ma_valid & MA_LOV)
+                        o->mot_flags |= MOF_LOV_CREATED;
+        }
+        cfs_up(&o->mot_lov_sem);
         RETURN(rc);
 }
 
@@ -230,7 +239,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;
@@ -551,10 +560,8 @@ static void mdt_empty_transno(struct mdt_thread_info* info)
 
         ENTRY;
         /* transaction has occurred already */
-        if (lustre_msg_get_transno(req->rq_repmsg) != 0) {
-                EXIT;
-                return;
-        }
+        if (lustre_msg_get_transno(req->rq_repmsg) != 0)
+                RETURN_EXIT;
 
         cfs_spin_lock(&mdt->mdt_lut.lut_translock);
         if (info->mti_transno == 0) {
@@ -586,7 +593,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;
@@ -677,14 +684,15 @@ 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);
                                 class_handle_unhash(&old_mfd->mfd_handle);
                                 cfs_list_del_init(&old_mfd->mfd_list);
                                 cfs_spin_unlock(&med->med_open_lock);
+                                /* no attr update for that close */
+                                la->la_valid = 0;
                                 mdt_mfd_close(info, old_mfd);
                         }
                         CDEBUG(D_HA, "Store old cookie "LPX64" in new mfd\n",
@@ -716,7 +724,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;
@@ -910,8 +918,8 @@ void mdt_reconstruct_open(struct mdt_thread_info *info,
         mdt_req_from_lcd(req, lcd);
         mdt_set_disposition(info, ldlm_rep, lcd->lcd_last_data);
 
-        CERROR("This is reconstruct open: disp="LPX64", result=%d\n",
-                ldlm_rep->lock_policy_res1, req->rq_status);
+        CDEBUG(D_INODE, "This is reconstruct open: disp="LPX64", result=%d\n",
+               ldlm_rep->lock_policy_res1, req->rq_status);
 
         if (mdt_get_disposition(ldlm_rep, DISP_OPEN_CREATE) &&
             req->rq_status != 0)
@@ -929,12 +937,11 @@ void mdt_reconstruct_open(struct mdt_thread_info *info,
                         rc = PTR_ERR(parent);
                         LCONSOLE_WARN("Parent "DFID" lookup error %d."
                                       " Evicting client %s with export %s.\n",
-                                      PFID(mdt_object_fid(parent)), rc,
+                                      PFID(rr->rr_fid1), rc,
                                       obd_uuid2str(&exp->exp_client_uuid),
                                       obd_export_nid2str(exp));
                         mdt_export_evict(exp);
-                        EXIT;
-                        return;
+                        RETURN_EXIT;
                 }
                 child = mdt_object_find(env, mdt, rr->rr_fid2);
                 if (IS_ERR(child)) {
@@ -946,8 +953,7 @@ void mdt_reconstruct_open(struct mdt_thread_info *info,
                                       obd_export_nid2str(exp));
                         mdt_object_put(env, parent);
                         mdt_export_evict(exp);
-                        EXIT;
-                        return;
+                        RETURN_EXIT;
                 }
                 rc = mdt_object_exists(child);
                 if (rc > 0) {
@@ -1025,19 +1031,37 @@ static int mdt_open_by_fid(struct mdt_thread_info* info,
         RETURN(rc);
 }
 
-static int mdt_open_anon_by_fid(struct mdt_thread_infoinfo,
+static int mdt_open_anon_by_fid(struct mdt_thread_info *info,
                                 struct ldlm_reply *rep, 
                                 struct mdt_lock_handle *lhc)
 {
+        const struct lu_env     *env   = info->mti_env;
+        struct mdt_device       *mdt   = info->mti_mdt;
         __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_reint_record *rr    = &info->mti_rr;
+        struct md_attr          *ma    = &info->mti_attr;
+        struct mdt_object       *parent= NULL;
         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 (md_should_create(flags)) {
+                if (!lu_fid_eq(rr->rr_fid1, rr->rr_fid2)) {
+                        parent = mdt_object_find(env, mdt, rr->rr_fid1);
+                        if (IS_ERR(parent)) {
+                                CDEBUG(D_INODE, "Fail to find parent "DFID
+                                       " for anonymous created %ld, try to"
+                                       " use server-side parent.\n",
+                                       PFID(rr->rr_fid1), PTR_ERR(parent));
+                                parent = NULL;
+                        }
+                }
+                if (parent == NULL)
+                        ma->ma_need |= MA_PFID;
+        }
+
+        o = mdt_object_find(env, mdt, rr->rr_fid2);
         if (IS_ERR(o))
                 RETURN(rc = PTR_ERR(o));
 
@@ -1050,7 +1074,6 @@ static int mdt_open_anon_by_fid(struct mdt_thread_info* info,
                 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));
@@ -1070,20 +1093,33 @@ static int mdt_open_anon_by_fid(struct mdt_thread_info* info,
         if (rc)
                 GOTO(out, rc);
 
-        rc = mo_attr_get(info->mti_env, mdt_object_child(o), ma);
+        rc = mo_attr_get(env, mdt_object_child(o), ma);
         if (rc)
                 GOTO(out, rc);
 
+        if (ma->ma_valid & MA_PFID) {
+                parent = mdt_object_find(env, mdt, &ma->ma_pfid);
+                if (IS_ERR(parent)) {
+                        CDEBUG(D_INODE, "Fail to find parent "DFID
+                               " for anonymous created %ld, try to"
+                               " use system default.\n",
+                               PFID(&ma->ma_pfid), PTR_ERR(parent));
+                        parent = NULL;
+                }
+        }
+
         if (flags & MDS_OPEN_LOCK)
                 mdt_set_disposition(info, rep, DISP_OPEN_LOCK);
-        rc = mdt_finish_open(info, NULL, o, flags, 0, rep);
+        rc = mdt_finish_open(info, parent, 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);
 out:
-        mdt_object_put(info->mti_env, o);
+        mdt_object_put(env, o);
+        if (parent != NULL)
+                mdt_object_put(env, parent);
         return rc;
 }
 
@@ -1152,7 +1188,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;
@@ -1163,6 +1199,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);
@@ -1188,7 +1225,7 @@ 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);
@@ -1209,7 +1246,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 "
@@ -1470,12 +1508,13 @@ 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);
         }
 
         ma->ma_need |= MA_INODE;
-        ma->ma_valid = 0;
+        ma->ma_valid &= ~MA_INODE;
 
         if (!MFD_CLOSED(mode))
                 rc = mo_close(info->mti_env, next, ma);
@@ -1522,6 +1561,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)
@@ -1661,13 +1701,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_LARGE(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_LARGE(info->mti_attr.ma_lmm, info->mti_mdt->mdt_max_mdsize);
         mdt_empty_transno(info);
         RETURN(rc);
 }