Whamcloud - gitweb
LU-13261 mdt: PFL layout changed while accessing
[fs/lustre-release.git] / lustre / mdt / mdt_lvb.c
index d4e11ca..1a5e8ba 100644 (file)
@@ -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)
@@ -321,52 +316,44 @@ static int mdt_lvbo_size(struct ldlm_lock *lock)
  *                     and the needed lvb buffer size will be returned in
  *                     @lvblen
  */
-static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock,
+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;
-       struct lu_env _env;
        int rc;
        ENTRY;
 
-       if (!env) {
-               rc = lu_env_init(&_env, LCT_DT_THREAD);
-               if (rc)
-                       RETURN(rc);
-               env = &_env;
-       }
+       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)
-                       GOTO(out_env, rc = 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);
-               GOTO(out_env, rc);
+               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 */
@@ -375,8 +362,7 @@ 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;
@@ -396,7 +382,7 @@ static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock,
        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));
 
@@ -418,16 +404,21 @@ static int mdt_lvbo_fill(const struct lu_env *env, struct ldlm_lock *lock,
                         * 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);
                }
@@ -445,19 +436,16 @@ out_put:
 out:
        if (rc < 0 && rc != -ERANGE)
                rc = 0;
-out_env:
-       if (env == &_env)
-               lu_env_fini(&_env);
        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 */