X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_lvb.c;h=1a5e8bab6ab9e5a7e3965dd950127690b6e13cdd;hb=45c46c6effd8273dc4ca52f32447f9f7103057b1;hp=9ee1989fbf4b7ac2b8868ac6ec6a5d09143aa037;hpb=e02cb40761ff8aae3df76c4210a345420b6d4ba1;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_lvb.c b/lustre/mdt/mdt_lvb.c index 9ee1989..1a5e8ba 100644 --- a/lustre/mdt/mdt_lvb.c +++ b/lustre/mdt/mdt_lvb.c @@ -34,7 +34,7 @@ #include "mdt_internal.h" /* Called with res->lr_lvb_sem held */ -static int mdt_lvbo_init(const struct lu_env *env, struct ldlm_resource *res) +static int mdt_lvbo_init(struct ldlm_resource *res) { if (IS_LQUOTA_RES(res)) { struct mdt_device *mdt; @@ -140,11 +140,11 @@ int mdt_dom_disk_lvbo_update(const struct lu_env *env, struct mdt_object *mo, RETURN(rc); } -int mdt_dom_lvbo_update(const struct lu_env *env, struct ldlm_resource *res, - struct ldlm_lock *lock, struct ptlrpc_request *req, - bool increase_only) +int mdt_dom_lvbo_update(struct ldlm_resource *res, struct ldlm_lock *lock, + struct ptlrpc_request *req, bool increase_only) { struct obd_export *exp = lock ? lock->l_export : NULL; + const struct lu_env *env = lu_env_find(); struct mdt_device *mdt; struct mdt_object *mo; struct mdt_thread_info *info; @@ -184,10 +184,6 @@ int mdt_dom_lvbo_update(const struct lu_env *env, struct ldlm_resource *res, 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); @@ -251,9 +247,8 @@ out_env: return rc; } -static int mdt_lvbo_update(const struct lu_env *env, struct ldlm_resource *res, - struct ldlm_lock *lock, struct ptlrpc_request *req, - int increase_only) +static int mdt_lvbo_update(struct ldlm_resource *res, struct ldlm_lock *lock, + struct ptlrpc_request *req, int increase_only) { ENTRY; @@ -275,8 +270,7 @@ static int mdt_lvbo_update(const struct lu_env *env, struct ldlm_resource *res, * by MDT for DOM objects only. */ if (lock == NULL || ldlm_has_dom(lock)) - return mdt_dom_lvbo_update(env, res, lock, req, - !!increase_only); + return mdt_dom_lvbo_update(res, lock, req, !!increase_only); return 0; } @@ -287,7 +281,8 @@ static int mdt_lvbo_size(struct ldlm_lock *lock) /* 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) @@ -306,44 +301,59 @@ static int mdt_lvbo_size(struct ldlm_lock *lock) return 0; } -static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock, - void *lvb, int lvblen) +/** + * Implementation of ldlm_valblock_ops::lvbo_fill for MDT. + * + * This function is called to fill the given RPC buffer \a buf with LVB data + * + * \param[in] env execution environment + * \param[in] lock LDLM lock + * \param[in] buf RPC buffer to fill + * \param[in,out] lvblen lvb buffer length + * + * \retval size of LVB data written into \a buf buffer + * or -ERANGE when the provided @lvblen is not big enough, + * and the needed lvb buffer size will be returned in + * @lvblen + */ +static int mdt_lvbo_fill(struct ldlm_lock *lock, + void *lvb, int *lvblen) { struct mdt_thread_info *info; struct mdt_device *mdt; + struct lu_env *env; struct lu_fid *fid; struct mdt_object *obj = NULL; struct md_object *child = NULL; int rc; ENTRY; + env = lu_env_find(); + 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) - RETURN(0); + GOTO(out, rc = 0); /* call lvbo fill function of quota master */ rc = qmt_hdls.qmth_lvbo_fill(mdt->mdt_qmt_dev, lock, lvb, - lvblen); - RETURN(rc); + *lvblen); + GOTO(out, rc); } info = lu_context_key_get(&env->le_ctx, &mdt_thread_key); if (!info) { - rc = lu_env_refill_by_tags((struct lu_env *)env, - LCT_MD_THREAD, 0); + rc = lu_env_refill_by_tags(env, LCT_MD_THREAD, 0); if (rc) GOTO(out, rc); info = lu_context_key_get(&env->le_ctx, &mdt_thread_key); 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 */ @@ -352,11 +362,10 @@ static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock, int lvb_len = sizeof(struct ost_lvb); if (!mdt_dom_lvb_is_valid(res)) - mdt_dom_lvbo_update(env, lock->l_resource, - lock, NULL, 0); + mdt_dom_lvbo_update(lock->l_resource, lock, NULL, 0); - if (lvb_len > lvblen) - lvb_len = lvblen; + if (lvb_len > *lvblen) + lvb_len = *lvblen; lock_res(res); memcpy(lvb, res->lr_lvb_data, lvb_len); @@ -366,14 +375,14 @@ static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock, } /* Only fill layout if layout lock is granted */ - if (!ldlm_has_layout(lock) || lock->l_granted_mode != lock->l_req_mode) + if (!ldlm_has_layout(lock) || !ldlm_is_granted(lock)) GOTO(out, rc = 0); /* XXX get fid by resource id. why don't include fid in ldlm_resource */ 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)); @@ -388,23 +397,29 @@ static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock, GOTO(out_put, rc); if (rc > 0) { struct lu_buf *lmm = NULL; - if (lvblen < rc) { + if (*lvblen < rc) { int level; /* The layout EA may be larger than mdt_max_mdsize * 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_obd_name(mdt), *lvblen, rc, + mdt->mdt_max_mdsize, -ERANGE); + *lvblen = rc; GOTO(out_put, rc = -ERANGE); } lmm = &info->mti_buf; @@ -419,16 +434,18 @@ out_put: if (obj != NULL && !IS_ERR(obj)) mdt_object_put(env, obj); out: - RETURN(rc < 0 ? 0 : rc); + if (rc < 0 && rc != -ERANGE) + rc = 0; + RETURN(rc); } 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 */