ENTRY;
/* Before going further let's check that OBD and export are healthy.
+ * The condition matches one in ptlrpc_send_reply()
*/
- if (exp != NULL &&
- (exp->exp_disconnected || exp->exp_failed ||
- exp->exp_obd->obd_stopping)) {
- CDEBUG(D_INFO, "Skip LVB update, export is %s, obd is %s\n",
- exp->exp_failed ? "failed" : "disconnected",
- exp->exp_obd->obd_stopping ? "stopping" : "OK");
+ if (exp && exp->exp_obd && exp->exp_obd->obd_fail) {
+ CDEBUG(D_INFO, "Skip LVB update, obd is failing over\n");
RETURN(0);
}
if (!info)
GOTO(out_env, rc = -ENOMEM);
}
- if (!info->mti_exp)
- info->mti_exp = req ? req->rq_export : NULL;
- if (!info->mti_mdt)
- info->mti_mdt = mdt;
fid = &info->mti_tmp_fid2;
fid_extract_from_res_name(fid, &res->lr_name);
/* resource on server side never changes. */
mdt = ldlm_res_to_ns(lock->l_resource)->ns_lvbp;
- LASSERT(mdt != NULL);
+ if (!mdt)
+ return 0;
if (IS_LQUOTA_RES(lock->l_resource)) {
if (mdt->mdt_qmt_dev == NULL)
return qmt_hdls.qmth_lvbo_size(mdt->mdt_qmt_dev, lock);
}
+ /* Always prefer DoM LVB data because layout is never returned in
+ * LVB when lock bits are combined with DoM, this is either GETATTR
+ * or OPEN enqueue. Meanwhile GL AST can be issued on such combined
+ * lock bits and it uses LVB for DoM data.
+ */
if (ldlm_has_dom(lock))
return sizeof(struct ost_lvb);
LASSERT(env);
mdt = ldlm_lock_to_ns(lock)->ns_lvbp;
+ if (!mdt)
+ RETURN(0);
+
if (IS_LQUOTA_RES(lock->l_resource)) {
if (mdt->mdt_qmt_dev == NULL)
GOTO(out, rc = 0);
if (!info)
GOTO(out, rc = -ENOMEM);
}
- if (!info->mti_env)
- info->mti_env = env;
- if (!info->mti_exp)
- info->mti_exp = lock->l_export;
- if (!info->mti_mdt)
- info->mti_mdt = mdt;
-
- /* LVB for DoM lock is needed only for glimpse,
- * don't fill DoM data if there is layout lock */
+
+ /* DOM LVB is used by glimpse and IO completion when
+ * DoM bits is always alone.
+ * If DoM bit is combined with any other bit then it is
+ * intent OPEN or GETATTR lock which is not filling
+ * LVB buffer in reply neither for DoM nor for LAYOUT.
+ */
if (ldlm_has_dom(lock)) {
struct ldlm_resource *res = lock->l_resource;
int lvb_len = sizeof(struct ost_lvb);
if (!mdt_dom_lvb_is_valid(res))
- mdt_dom_lvbo_update(lock->l_resource, lock, NULL, 0);
-
- if (lvb_len > *lvblen)
- lvb_len = *lvblen;
+ mdt_dom_lvbo_update(res, lock, NULL, 0);
+ LASSERT(*lvblen >= lvb_len);
lock_res(res);
memcpy(lvb, res->lr_lvb_data, lvb_len);
unlock_res(res);
-
GOTO(out, rc = lvb_len);
}
fid = &info->mti_tmp_fid2;
fid_extract_from_res_name(fid, &lock->l_resource->lr_name);
- obj = mdt_object_find(env, info->mti_mdt, fid);
+ obj = mdt_object_find(env, mdt, fid);
if (IS_ERR(obj))
GOTO(out, rc = PTR_ERR(obj));
* and in that case mdt_max_mdsize is just updated
* but if EA size is less than mdt_max_mdsize then
* it is an error in lvblen value provided. */
- if (rc > info->mti_mdt->mdt_max_mdsize) {
- info->mti_mdt->mdt_max_mdsize = rc;
+ if (rc > mdt->mdt_max_mdsize) {
+ mdt->mdt_max_mdsize = rc;
level = D_INFO;
} else {
- level = D_ERROR;
+ /* The PFL layout EA could be enlarged when
+ * the corresponding layout of some IO range
+ * is started to be written, which can cause
+ * other thread to get incorrect layout size
+ * at mdt_intent_layout, see LU-13261. */
+ level = D_LAYOUT;
}
CDEBUG_LIMIT(level, "%s: small buffer size %d for EA "
"%d (max_mdsize %d): rc = %d\n",
mdt_obd_name(mdt), *lvblen, rc,
- info->mti_mdt->mdt_max_mdsize, -ERANGE);
+ mdt->mdt_max_mdsize, -ERANGE);
*lvblen = rc;
GOTO(out_put, rc = -ERANGE);
}
static int mdt_lvbo_free(struct ldlm_resource *res)
{
if (IS_LQUOTA_RES(res)) {
- struct mdt_device *mdt;
+ struct mdt_device *mdt;
mdt = ldlm_res_to_ns(res)->ns_lvbp;
- if (mdt->mdt_qmt_dev == NULL)
+ if (!mdt || !mdt->mdt_qmt_dev)
return 0;
/* call lvbo free function of quota master */