Whamcloud - gitweb
LU-7988 hsm: run HSM coordinator once per second at most
[fs/lustre-release.git] / lustre / mdt / mdt_lvb.c
index 892c0ea..d4c5097 100644 (file)
@@ -21,7 +21,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012, Intel, Inc.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  * Use is subject to license terms.
  *
  * lustre/mdt/mdt_lvb.c
@@ -72,10 +72,13 @@ static int mdt_lvbo_update(struct ldlm_resource *res,
 
 static int mdt_lvbo_size(struct ldlm_lock *lock)
 {
-       if (IS_LQUOTA_RES(lock->l_resource)) {
-               struct mdt_device       *mdt;
+       struct mdt_device *mdt;
+
+       /* resource on server side never changes. */
+       mdt = ldlm_res_to_ns(lock->l_resource)->ns_lvbp;
+       LASSERT(mdt != NULL);
 
-               mdt = ldlm_res_to_ns(lock->l_resource)->ns_lvbp;
+       if (IS_LQUOTA_RES(lock->l_resource)) {
                if (mdt->mdt_qmt_dev == NULL)
                        return 0;
 
@@ -83,24 +86,98 @@ static int mdt_lvbo_size(struct ldlm_lock *lock)
                return qmt_hdls.qmth_lvbo_size(mdt->mdt_qmt_dev, lock);
        }
 
+       if (ldlm_has_layout(lock))
+               return mdt->mdt_max_mdsize;
+
        return 0;
 }
 
 static int mdt_lvbo_fill(struct ldlm_lock *lock, void *lvb, int lvblen)
 {
+       struct lu_env env;
+       struct mdt_thread_info *info;
+       struct mdt_device *mdt;
+       struct lu_fid *fid;
+       struct mdt_object *obj = NULL;
+       struct md_object *child = NULL;
+       int rc;
+       ENTRY;
+
+       mdt = ldlm_lock_to_ns(lock)->ns_lvbp;
        if (IS_LQUOTA_RES(lock->l_resource)) {
-               struct mdt_device       *mdt;
-
-               mdt = ldlm_res_to_ns(lock->l_resource)->ns_lvbp;
                if (mdt->mdt_qmt_dev == NULL)
-                       return 0;
+                       RETURN(0);
 
                /* call lvbo fill function of quota master */
-               return qmt_hdls.qmth_lvbo_fill(mdt->mdt_qmt_dev, lock, lvb,
-                                              lvblen);
+               rc = qmt_hdls.qmth_lvbo_fill(mdt->mdt_qmt_dev, lock, lvb,
+                                            lvblen);
+               RETURN(rc);
        }
 
-       return 0;
+       /* Only fill layout if layout lock is granted */
+       if (!ldlm_has_layout(lock) || lock->l_granted_mode != lock->l_req_mode)
+               RETURN(0);
+
+       /* layout lock will be granted to client, fill in lvb with layout */
+
+       /* XXX create an env to talk to mdt stack. We should get this env from
+        * ptlrpc_thread->t_env. */
+       rc = lu_env_init(&env, LCT_MD_THREAD);
+       /* Likely ENOMEM */
+       if (rc)
+               RETURN(rc);
+
+       info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
+       /* Likely ENOMEM */
+       if (info == NULL)
+               GOTO(out, rc = -ENOMEM);
+
+       memset(info, 0, sizeof *info);
+       info->mti_env = &env;
+       info->mti_exp = lock->l_export;
+       info->mti_mdt = mdt;
+
+       /* 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);
+       if (IS_ERR(obj))
+               GOTO(out, rc = PTR_ERR(obj));
+
+       if (!mdt_object_exists(obj) || mdt_object_remote(obj))
+               GOTO(out, rc = -ENOENT);
+
+       child = mdt_object_child(obj);
+
+       /* get the length of lsm */
+       rc = mo_xattr_get(&env, child, &LU_BUF_NULL, XATTR_NAME_LOV);
+       if (rc < 0)
+               GOTO(out, rc);
+
+       if (rc > 0) {
+               struct lu_buf *lmm = NULL;
+
+               if (lvblen < rc) {
+                       CERROR("%s: expected %d actual %d.\n",
+                               mdt_obd_name(mdt), rc, lvblen);
+                       GOTO(out, rc = -ERANGE);
+               }
+
+               lmm = &info->mti_buf;
+               lmm->lb_buf = lvb;
+               lmm->lb_len = rc;
+
+               rc = mo_xattr_get(&env, child, lmm, XATTR_NAME_LOV);
+               if (rc < 0)
+                       GOTO(out, rc);
+       }
+
+out:
+       if (obj != NULL && !IS_ERR(obj))
+               mdt_object_put(&env, obj);
+       lu_env_fini(&env);
+       RETURN(rc < 0 ? 0 : rc);
 }
 
 static int mdt_lvbo_free(struct ldlm_resource *res)
@@ -120,9 +197,9 @@ static int mdt_lvbo_free(struct ldlm_resource *res)
 }
 
 struct ldlm_valblock_ops mdt_lvbo = {
-       lvbo_init:      mdt_lvbo_init,
-       lvbo_update:    mdt_lvbo_update,
-       lvbo_size:      mdt_lvbo_size,
-       lvbo_fill:      mdt_lvbo_fill,
-       lvbo_free:      mdt_lvbo_free
+       .lvbo_init      = mdt_lvbo_init,
+       .lvbo_update    = mdt_lvbo_update,
+       .lvbo_size      = mdt_lvbo_size,
+       .lvbo_fill      = mdt_lvbo_fill,
+       .lvbo_free      = mdt_lvbo_free
 };