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",
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();
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));
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;
/* 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);
}