4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA
24 * Copyright (c) 2012, 2015, Intel Corporation.
25 * Use is subject to license terms.
27 * lustre/mdt/mdt_lvb.c
29 * Author: Jinshan Xiong <jinshan.xiong@intel.com>
32 #define DEBUG_SUBSYSTEM S_MDS
34 #include "mdt_internal.h"
36 /* Called with res->lr_lvb_sem held */
37 static int mdt_lvbo_init(struct ldlm_resource *res)
39 if (IS_LQUOTA_RES(res)) {
40 struct mdt_device *mdt;
42 mdt = ldlm_res_to_ns(res)->ns_lvbp;
43 if (mdt->mdt_qmt_dev == NULL)
46 /* call lvbo init function of quota master */
47 return qmt_hdls.qmth_lvbo_init(mdt->mdt_qmt_dev, res);
53 static int mdt_lvbo_update(struct ldlm_resource *res,
54 struct ldlm_lock *lock,
55 struct ptlrpc_request *req,
58 if (IS_LQUOTA_RES(res)) {
59 struct mdt_device *mdt;
61 mdt = ldlm_res_to_ns(res)->ns_lvbp;
62 if (mdt->mdt_qmt_dev == NULL)
65 /* call lvbo update function of quota master */
66 return qmt_hdls.qmth_lvbo_update(mdt->mdt_qmt_dev, res, req,
74 static int mdt_lvbo_size(struct ldlm_lock *lock)
76 struct mdt_device *mdt;
78 /* resource on server side never changes. */
79 mdt = ldlm_res_to_ns(lock->l_resource)->ns_lvbp;
82 if (IS_LQUOTA_RES(lock->l_resource)) {
83 if (mdt->mdt_qmt_dev == NULL)
86 /* call lvbo size function of quota master */
87 return qmt_hdls.qmth_lvbo_size(mdt->mdt_qmt_dev, lock);
90 if (ldlm_has_layout(lock))
91 return mdt->mdt_max_mdsize;
96 static int mdt_lvbo_fill(struct ldlm_lock *lock, void *lvb, int lvblen)
99 struct mdt_thread_info *info;
100 struct mdt_device *mdt;
102 struct mdt_object *obj = NULL;
103 struct md_object *child = NULL;
107 mdt = ldlm_lock_to_ns(lock)->ns_lvbp;
108 if (IS_LQUOTA_RES(lock->l_resource)) {
109 if (mdt->mdt_qmt_dev == NULL)
112 /* call lvbo fill function of quota master */
113 rc = qmt_hdls.qmth_lvbo_fill(mdt->mdt_qmt_dev, lock, lvb,
118 /* Only fill layout if layout lock is granted */
119 if (!ldlm_has_layout(lock) || lock->l_granted_mode != lock->l_req_mode)
122 /* layout lock will be granted to client, fill in lvb with layout */
124 /* XXX create an env to talk to mdt stack. We should get this env from
125 * ptlrpc_thread->t_env. */
126 rc = lu_env_init(&env, LCT_MD_THREAD);
131 info = lu_context_key_get(&env.le_ctx, &mdt_thread_key);
134 GOTO(out, rc = -ENOMEM);
136 memset(info, 0, sizeof *info);
137 info->mti_env = &env;
138 info->mti_exp = lock->l_export;
141 /* XXX get fid by resource id. why don't include fid in ldlm_resource */
142 fid = &info->mti_tmp_fid2;
143 fid_extract_from_res_name(fid, &lock->l_resource->lr_name);
145 obj = mdt_object_find(&env, info->mti_mdt, fid);
147 GOTO(out, rc = PTR_ERR(obj));
149 if (!mdt_object_exists(obj) || mdt_object_remote(obj))
150 GOTO(out, rc = -ENOENT);
152 child = mdt_object_child(obj);
154 /* get the length of lsm */
155 rc = mo_xattr_get(&env, child, &LU_BUF_NULL, XATTR_NAME_LOV);
160 struct lu_buf *lmm = NULL;
163 CERROR("%s: expected %d actual %d.\n",
164 mdt_obd_name(mdt), rc, lvblen);
165 GOTO(out, rc = -ERANGE);
168 lmm = &info->mti_buf;
172 rc = mo_xattr_get(&env, child, lmm, XATTR_NAME_LOV);
178 if (obj != NULL && !IS_ERR(obj))
179 mdt_object_put(&env, obj);
181 RETURN(rc < 0 ? 0 : rc);
184 static int mdt_lvbo_free(struct ldlm_resource *res)
186 if (IS_LQUOTA_RES(res)) {
187 struct mdt_device *mdt;
189 mdt = ldlm_res_to_ns(res)->ns_lvbp;
190 if (mdt->mdt_qmt_dev == NULL)
193 /* call lvbo free function of quota master */
194 return qmt_hdls.qmth_lvbo_free(mdt->mdt_qmt_dev, res);
200 struct ldlm_valblock_ops mdt_lvbo = {
201 .lvbo_init = mdt_lvbo_init,
202 .lvbo_update = mdt_lvbo_update,
203 .lvbo_size = mdt_lvbo_size,
204 .lvbo_fill = mdt_lvbo_fill,
205 .lvbo_free = mdt_lvbo_free