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",
if (unlikely(rc))
GOTO(out, rc);
+ rc = mdt_pack_encctx_in_reply(info, o);
+ if (unlikely(rc))
+ GOTO(out, rc);
+
rc = mdt_finish_open(info, NULL, o, open_flags, 0, rep);
} else {
/*
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();
ENTRY;
OBD_FAIL_TIMEOUT_ORSET(OBD_FAIL_MDS_PAUSE_OPEN, OBD_FAIL_ONCE,
(obd_timeout + 1) / 4);
- mdt_counter_incr(req, LPROC_MDT_OPEN);
repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
ma->ma_need = MA_INODE;
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;
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));
GOTO(out_child, result);
}
created = 1;
- mdt_counter_incr(req, LPROC_MDT_MKNOD);
+ mdt_counter_incr(req, LPROC_MDT_MKNOD,
+ ktime_us_delta(ktime_get(), kstart));
} else {
/*
* The object is on remote node, return its FID for remote open.
result = -MDT_EREMOTE_OPEN;
GOTO(out_child, result);
} else if (mdt_object_exists(child)) {
+ /* Check early for MDS_OPEN_DIRECTORY/O_DIRECTORY to
+ * avoid opening regular files from lfs getstripe
+ * since doing so breaks the leases used by lfs
+ * mirror. See LU-13693. */
+ if (open_flags & MDS_OPEN_DIRECTORY &&
+ S_ISREG(lu_object_attr(&child->mot_obj)))
+ GOTO(out_child, result = -ENOTDIR);
+
/* We have to get attr & LOV EA & HSM for this
* object. */
mdt_prep_ma_buf_from_rep(info, child, ma);
if (unlikely(rc))
GOTO(out_child, result = rc);
+ rc = mdt_pack_encctx_in_reply(info, child);
+ if (unlikely(rc))
+ GOTO(out_child, result = rc);
+
rc = mdt_check_resent_lock(info, child, lhc);
if (rc < 0) {
GOTO(out_child, result = rc);
mdt_clear_disposition(info, ldlm_rep, DISP_OPEN_CREATE);
}
}
+
+ mdt_counter_incr(req, LPROC_MDT_OPEN,
+ ktime_us_delta(ktime_get(), kstart));
+
EXIT;
out_child_unlock:
if (object_locked)
uc = lu_ucred(env);
uc_cap_save = uc->uc_cap;
- uc->uc_cap |= 1 << 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;
/* 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;
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;
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);
}
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);
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);
}
struct ptlrpc_request *req = tgt_ses_req(tsi);
struct md_attr *ma = &info->mti_attr;
struct mdt_body *repbody = NULL;
+ ktime_t kstart = ktime_get();
int rc, ret = 0;
ENTRY;
- mdt_counter_incr(req, LPROC_MDT_CLOSE);
/* Close may come with the Size-on-MDS update. Unpack it. */
rc = mdt_close_unpack(info);
if (rc)
tsi->tsi_reply_fail_id = OBD_FAIL_MDS_CLOSE_NET_REP;
out:
mdt_thread_info_fini(info);
+ if (rc == 0)
+ mdt_counter_incr(req, LPROC_MDT_CLOSE,
+ ktime_us_delta(ktime_get(), kstart));
RETURN(rc ? rc : ret);
}