Whamcloud - gitweb
LU-14494 mdt: check object exists in mdt_close_handle_layouts()
[fs/lustre-release.git] / lustre / mdt / mdt_open.c
index 9f10fc6..b839eaa 100644 (file)
@@ -900,15 +900,7 @@ static int mdt_object_open_lock(struct mdt_thread_info *info,
                        lhc = &info->mti_lh[MDT_LH_LOCAL];
                } else if (dom_lock) {
                        lm = (open_flags & MDS_FMODE_WRITE) ? LCK_PW : LCK_PR;
-                       if (dom_lock == TRYLOCK_DOM_ON_OPEN) {
-                               trybits |= MDS_INODELOCK_DOM |
-                                          MDS_INODELOCK_LAYOUT;
-                       } else {
-                               /* dom_lock == ALWAYS_DOM_LOCK_ON_OPEN */
-                               *ibits = MDS_INODELOCK_DOM;
-                               if (info->mti_mdt->mdt_opts.mo_dom_read_open)
-                                       trybits |= MDS_INODELOCK_LAYOUT;
-                       }
+                       trybits |= MDS_INODELOCK_DOM | MDS_INODELOCK_LAYOUT;
                }
 
                CDEBUG(D_INODE, "normal open:"DFID" lease count: %d, lm: %d\n",
@@ -1321,6 +1313,7 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
        int result, rc;
        int created = 0;
        int object_locked = 0;
+       enum ldlm_mode lock_mode = LCK_PR;
        u32 msg_flags;
        ktime_t kstart = ktime_get();
 
@@ -1398,25 +1391,27 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
        if (result < 0)
                GOTO(out, result);
 
-       lh = &info->mti_lh[MDT_LH_PARENT];
-       mdt_lock_pdo_init(lh, (open_flags & MDS_OPEN_CREAT) ? LCK_PW : LCK_PR,
-                         &rr->rr_name);
-
        parent = mdt_object_find(info->mti_env, mdt, rr->rr_fid1);
        if (IS_ERR(parent))
                GOTO(out, result = PTR_ERR(parent));
 
-       result = mdt_object_lock(info, parent, lh, MDS_INODELOCK_UPDATE);
-       if (result != 0) {
+       /* get and check version of parent */
+       result = mdt_version_get_check(info, parent, 0);
+       if (result) {
                mdt_object_put(info->mti_env, parent);
                GOTO(out, result);
        }
 
-       /* get and check version of parent */
-       result = mdt_version_get_check(info, parent, 0);
-       if (result)
-               GOTO(out_parent, result);
+       OBD_RACE(OBD_FAIL_MDS_REINT_OPEN);
+again_pw:
+       lh = &info->mti_lh[MDT_LH_PARENT];
+       mdt_lock_pdo_init(lh, lock_mode, &rr->rr_name);
 
+       result = mdt_object_lock(info, parent, lh, MDS_INODELOCK_UPDATE);
+       if (result != 0) {
+               mdt_object_put(info->mti_env, parent);
+               GOTO(out, result);
+       }
        fid_zero(child_fid);
 
        result = -ENOENT;
@@ -1432,12 +1427,24 @@ int mdt_reint_open(struct mdt_thread_info *info, struct mdt_lock_handle *lhc)
        if (result != 0 && result != -ENOENT)
                GOTO(out_parent, result);
 
+       OBD_RACE(OBD_FAIL_MDS_REINT_OPEN2);
+
        if (result == -ENOENT) {
                mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_NEG);
                if (!(open_flags & MDS_OPEN_CREAT))
                        GOTO(out_parent, result);
                if (mdt_rdonly(req->rq_export))
                        GOTO(out_parent, result = -EROFS);
+
+               if (lock_mode == LCK_PR) {
+                       /* first pass: get write lock and restart */
+                       mdt_object_unlock(info, parent, lh, 1);
+                       mdt_clear_disposition(info, ldlm_rep, DISP_LOOKUP_NEG);
+                       mdt_lock_handle_init(lh);
+                       lock_mode = LCK_PW;
+                       goto again_pw;
+               }
+
                *child_fid = *info->mti_rr.rr_fid2;
                LASSERTF(fid_is_sane(child_fid), "fid="DFID"\n",
                         PFID(child_fid));
@@ -1688,7 +1695,7 @@ static struct mdt_object *mdt_orphan_open(struct mdt_thread_info *info,
 
        uc = lu_ucred(env);
        uc_cap_save = uc->uc_cap;
-       uc->uc_cap |= BIT(CFS_CAP_DAC_OVERRIDE);
+       uc->uc_cap |= BIT(CAP_DAC_OVERRIDE);
        rc = mdo_create(env, mdt_object_child(local_root), &lname,
                        mdt_object_child(obj), spec, attr);
        uc->uc_cap = uc_cap_save;
@@ -1960,7 +1967,7 @@ static int mdt_hsm_release(struct mdt_thread_info *info, struct mdt_object *o,
        /* The orphan has root ownership so we need to raise
         * CAP_FOWNER to set the HSM attributes. */
        cap = uc->uc_cap;
-       uc->uc_cap |= MD_CAP_TO_MASK(CFS_CAP_FOWNER);
+       uc->uc_cap |= MD_CAP_TO_MASK(CAP_FOWNER);
        rc = mo_xattr_set(info->mti_env, mdt_object_child(orphan), buf,
                          XATTR_NAME_HSM, 0);
        uc->uc_cap = cap;
@@ -2029,7 +2036,7 @@ int mdt_close_handle_layouts(struct mdt_thread_info *info,
        struct mdt_lock_handle  *lh2 = &info->mti_lh[MDT_LH_OLD];
        struct close_data       *data;
        struct ldlm_lock        *lease;
-       struct mdt_object       *o1 = o, *o2;
+       struct mdt_object       *o1 = o, *o2 = NULL;
        bool                     lease_broken;
        bool                     swap_objects;
        int                      rc;
@@ -2063,10 +2070,11 @@ int mdt_close_handle_layouts(struct mdt_thread_info *info,
        if (IS_ERR(o2))
                GOTO(out_lease, rc = PTR_ERR(o2));
 
-       if (!S_ISREG(lu_object_attr(&o2->mot_obj))) {
-               swap_objects = false; /* not swapped yet */
+       if (!mdt_object_exists(o2))
+               GOTO(out_obj, rc = -ENOENT);
+
+       if (!S_ISREG(lu_object_attr(&o2->mot_obj)))
                GOTO(out_obj, rc = -EINVAL);
-       }
 
        if (swap_objects)
                swap(o1, o2);
@@ -2174,7 +2182,9 @@ out_unlock_sem:
        }
 
 out_obj:
-       mdt_object_put(info->mti_env, swap_objects ? o1 : o2);
+       /* Callee takes care of o, we must put the other one. We know
+        * that o1 != o2 from check of lu_fid_cmp() above. */
+       mdt_object_put(info->mti_env, o1 != o ? o1 : o2);
 
        ldlm_reprocess_all(lease->l_resource, lease);
 
@@ -2393,6 +2403,13 @@ int mdt_mfd_close(struct mdt_thread_info *info, struct mdt_file_data *mfd)
                ma->ma_valid = MA_INODE;
                ma->ma_attr_flags |= MDS_CLOSE_UPDATE_TIMES;
                ma->ma_attr.la_valid &= (LA_ATIME | LA_MTIME | LA_CTIME);
+
+               if (ma->ma_attr.la_valid & LA_MTIME) {
+                       rc = mdt_attr_get_pfid(info, o, &ma->ma_pfid);
+                       if (!rc)
+                               ma->ma_valid |= MA_PFID;
+               }
+
                rc = mo_attr_set(info->mti_env, next, ma);
        }