1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/cmm/mdc_object.c
5 * Lustre Cluster Metadata Manager (cmm)
7 * Copyright (c) 2006 Cluster File Systems, Inc.
8 * Author: Mike Pershin <tappro@clusterfs.com>
10 * This file is part of the Lustre file system, http://www.lustre.org
11 * Lustre is a trademark of Cluster File Systems, Inc.
13 * You may have signed or agreed to another license before downloading
14 * this software. If so, you are bound by the terms and conditions
15 * of that agreement, and the following does not apply to you. See the
16 * LICENSE file included with this distribution for more information.
18 * If you did not agree to a different license, then this copy of Lustre
19 * is open source software; you can redistribute it and/or modify it
20 * under the terms of version 2 of the GNU General Public License as
21 * published by the Free Software Foundation.
23 * In either case, Lustre is distributed in the hope that it will be
24 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
25 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * license text for more details.
30 # define EXPORT_SYMTAB
33 #define DEBUG_SUBSYSTEM S_MDS
34 #include <obd_support.h>
35 #include <lustre_lib.h>
36 #include <obd_class.h>
37 #include <lustre_mdc.h>
38 #include "cmm_internal.h"
39 #include "mdc_internal.h"
41 static struct md_object_operations mdc_mo_ops;
42 static struct md_dir_operations mdc_dir_ops;
43 static struct lu_object_operations mdc_obj_ops;
45 extern struct lu_context_key mdc_thread_key;
47 struct lu_object *mdc_object_alloc(const struct lu_env *env,
48 const struct lu_object_header *hdr,
51 struct mdc_object *mco;
58 lo = &mco->mco_obj.mo_lu;
59 lu_object_init(lo, NULL, ld);
60 mco->mco_obj.mo_ops = &mdc_mo_ops;
61 mco->mco_obj.mo_dir_ops = &mdc_dir_ops;
62 lo->lo_ops = &mdc_obj_ops;
68 static void mdc_object_free(const struct lu_env *env, struct lu_object *lo)
70 struct mdc_object *mco = lu2mdc_obj(lo);
75 static int mdc_object_init(const struct lu_env *env, struct lu_object *lo)
78 lo->lo_header->loh_attr |= LOHA_REMOTE;
82 static int mdc_object_print(const struct lu_env *env, void *cookie,
83 lu_printer_t p, const struct lu_object *lo)
85 return (*p)(env, cookie, LUSTRE_CMM_MDC_NAME"-object@%p", lo);
88 static struct lu_object_operations mdc_obj_ops = {
89 .loo_object_init = mdc_object_init,
90 .loo_object_free = mdc_object_free,
91 .loo_object_print = mdc_object_print,
94 /* md_object_operations */
96 struct mdc_thread_info *mdc_info_get(const struct lu_env *env)
98 struct mdc_thread_info *mci;
100 mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
106 struct mdc_thread_info *mdc_info_init(const struct lu_env *env)
108 struct mdc_thread_info *mci;
110 mci = mdc_info_get(env);
112 memset(mci, 0, sizeof(*mci));
117 static void mdc_body2attr(struct mdt_body *body, struct md_attr *ma)
119 struct lu_attr *la = &ma->ma_attr;
121 if (body->valid & OBD_MD_FLCTIME && body->ctime >= la->la_ctime) {
122 la->la_ctime = body->ctime;
123 if (body->valid & OBD_MD_FLMTIME)
124 la->la_mtime = body->mtime;
127 if (body->valid & OBD_MD_FLMODE)
128 la->la_mode = body->mode;
129 if (body->valid & OBD_MD_FLSIZE)
130 la->la_size = body->size;
131 if (body->valid & OBD_MD_FLBLOCKS)
132 la->la_blocks = body->blocks;
133 if (body->valid & OBD_MD_FLUID)
134 la->la_uid = body->uid;
135 if (body->valid & OBD_MD_FLGID)
136 la->la_gid = body->gid;
137 if (body->valid & OBD_MD_FLFLAGS)
138 la->la_flags = body->flags;
139 if (body->valid & OBD_MD_FLNLINK)
140 la->la_nlink = body->nlink;
141 if (body->valid & OBD_MD_FLRDEV)
142 la->la_rdev = body->rdev;
144 ma->ma_valid = MA_INODE;
147 static int mdc_req2attr_update(const struct lu_env *env,
150 struct mdc_thread_info *mci;
151 struct ptlrpc_request *req;
152 struct mdt_body *body;
153 struct lov_mds_md *lov;
154 struct llog_cookie *cookie;
157 mci = mdc_info_get(env);
160 body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*body));
162 mdc_body2attr(body, ma);
164 if (!(body->valid & OBD_MD_FLEASIZE))
167 if (body->eadatasize == 0) {
168 CERROR("OBD_MD_FLEASIZE is set but eadatasize is zero\n");
172 lov = lustre_swab_repbuf(req, REPLY_REC_OFF + 1,
173 body->eadatasize, NULL);
175 CERROR("Can't unpack MDS EA data\n");
179 LASSERT(ma->ma_lmm != NULL);
180 LASSERT(ma->ma_lmm_size >= body->eadatasize);
181 ma->ma_lmm_size = body->eadatasize;
182 memcpy(ma->ma_lmm, lov, ma->ma_lmm_size);
183 ma->ma_valid |= MA_LOV;
184 if (!(body->valid & OBD_MD_FLCOOKIE))
187 if (body->aclsize == 0) {
188 CERROR("OBD_MD_FLCOOKIE is set but cookie size is zero\n");
192 cookie = lustre_msg_buf(req->rq_repmsg,
193 REPLY_REC_OFF + 2, body->aclsize);
194 if (cookie == NULL) {
195 CERROR("Can't unpack unlink cookie data\n");
199 LASSERT(ma->ma_cookie != NULL);
200 LASSERT(ma->ma_cookie_size == body->aclsize);
201 memcpy(ma->ma_cookie, cookie, ma->ma_cookie_size);
202 ma->ma_valid |= MA_COOKIE;
206 static int mdc_attr_get(const struct lu_env *env, struct md_object *mo,
209 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
210 struct mdc_thread_info *mci;
214 mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
217 memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
219 /* FIXME: split capability */
220 rc = md_getattr(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu), NULL,
221 OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID |
226 /* get attr from request */
227 rc = mdc_req2attr_update(env, ma);
230 ptlrpc_req_finished(mci->mci_req);
236 static int mdc_object_create(const struct lu_env *env,
237 struct md_object *mo,
238 const struct md_create_spec *spec,
241 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
242 struct lu_attr *la = &ma->ma_attr;
243 struct mdc_thread_info *mci;
245 struct md_ucred *uc = md_ucred(env);
252 LASSERT(spec->u.sp_pfid != NULL);
253 mci = mdc_info_init(env);
254 mci->mci_opdata.fid2 = *lu_object_fid(&mo->mo_lu);
255 /* parent fid is needed to create dotdot on the remote node */
256 mci->mci_opdata.fid1 = *(spec->u.sp_pfid);
257 mci->mci_opdata.mod_time = la->la_mtime;
259 ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
261 if (la->la_mode & S_ISGID)
266 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD))
267 mci->mci_opdata.suppgids[0] = uc->mu_suppgids[0];
269 mci->mci_opdata.suppgids[0] = -1;
274 mci->mci_opdata.suppgids[0] = -1;
277 /* get data from spec */
278 if (spec->sp_cr_flags & MDS_CREATE_SLAVE_OBJ) {
279 symname = spec->u.sp_ea.eadata;
280 symlen = spec->u.sp_ea.eadatalen;
281 mci->mci_opdata.fid1 = *(spec->u.sp_ea.fid);
282 mci->mci_opdata.flags |= MDS_CREATE_SLAVE_OBJ;
284 symname = spec->u.sp_symname;
285 symlen = symname ? strlen(symname) + 1 : 0;
288 rc = md_create(mc->mc_desc.cl_exp, &mci->mci_opdata,
290 la->la_mode, uid, gid, cap, la->la_rdev,
294 /* get attr from request */
295 rc = mdc_req2attr_update(env, ma);
298 ptlrpc_req_finished(mci->mci_req);
303 static int mdc_ref_add(const struct lu_env *env, struct md_object *mo)
305 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
306 struct mdc_thread_info *mci;
307 struct md_ucred *uc = md_ucred(env);
311 mci = lu_context_key_get(&env->le_ctx, &mdc_thread_key);
314 memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata));
315 mci->mci_opdata.fid1 = *lu_object_fid(&mo->mo_lu);
316 //mci->mci_opdata.mod_time = la->la_ctime;
317 //mci->mci_opdata.fsuid = la->la_uid;
318 //mci->mci_opdata.fsgid = la->la_gid;
319 mci->mci_opdata.mod_time = CURRENT_SECONDS;
321 ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
322 mci->mci_opdata.fsuid = uc->mu_fsuid;
323 mci->mci_opdata.fsgid = uc->mu_fsgid;
324 mci->mci_opdata.cap = uc->mu_cap;
325 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
326 mci->mci_opdata.suppgids[0] = uc->mu_suppgids[0];
327 mci->mci_opdata.suppgids[1] = uc->mu_suppgids[1];
329 mci->mci_opdata.suppgids[0] =
330 mci->mci_opdata.suppgids[1] = -1;
333 mci->mci_opdata.fsuid = current->fsuid;
334 mci->mci_opdata.fsgid = current->fsgid;
335 mci->mci_opdata.cap = current->cap_effective;
336 mci->mci_opdata.suppgids[0] = mci->mci_opdata.suppgids[1] = -1;
340 rc = md_link(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
342 ptlrpc_req_finished(mci->mci_req);
347 static int mdc_ref_del(const struct lu_env *env, struct md_object *mo,
350 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
351 struct lu_attr *la = &ma->ma_attr;
352 struct mdc_thread_info *mci;
353 struct md_ucred *uc = md_ucred(env);
357 mci = mdc_info_init(env);
358 mci->mci_opdata.fid1 = *lu_object_fid(&mo->mo_lu);
359 mci->mci_opdata.mode = la->la_mode;
360 mci->mci_opdata.mod_time = la->la_ctime;
362 ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
363 mci->mci_opdata.fsuid = uc->mu_fsuid;
364 mci->mci_opdata.fsgid = uc->mu_fsgid;
365 mci->mci_opdata.cap = uc->mu_cap;
366 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD))
367 mci->mci_opdata.suppgids[0] = uc->mu_suppgids[0];
369 mci->mci_opdata.suppgids[0] = -1;
371 mci->mci_opdata.fsuid = la->la_uid;
372 mci->mci_opdata.fsgid = la->la_gid;
373 mci->mci_opdata.cap = current->cap_effective;
374 mci->mci_opdata.suppgids[0] = -1;
377 rc = md_unlink(mc->mc_desc.cl_exp, &mci->mci_opdata, &mci->mci_req);
379 /* get attr from request */
380 rc = mdc_req2attr_update(env, ma);
383 ptlrpc_req_finished(mci->mci_req);
388 #ifdef HAVE_SPLIT_SUPPORT
389 int mdc_send_page(struct cmm_device *cm, const struct lu_env *env,
390 struct md_object *mo, struct page *page, __u32 offset)
392 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
396 rc = mdc_sendpage(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
398 CDEBUG(D_INFO, "send page %p offset %d fid "DFID" rc %d \n",
399 page, offset, PFID(lu_object_fid(&mo->mo_lu)), rc);
404 static struct md_object_operations mdc_mo_ops = {
405 .moo_attr_get = mdc_attr_get,
406 .moo_object_create = mdc_object_create,
407 .moo_ref_add = mdc_ref_add,
408 .moo_ref_del = mdc_ref_del,
411 /* md_dir_operations */
412 static int mdc_rename_tgt(const struct lu_env *env, struct md_object *mo_p,
413 struct md_object *mo_t, const struct lu_fid *lf,
414 const char *name, struct md_attr *ma)
416 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo_p));
417 struct lu_attr *la = &ma->ma_attr;
418 struct mdc_thread_info *mci;
419 struct md_ucred *uc = md_ucred(env);
423 mci = mdc_info_init(env);
424 mci->mci_opdata.fid1 = *lu_object_fid(&mo_p->mo_lu);
425 mci->mci_opdata.fid2 = *lf;
426 mci->mci_opdata.mode = la->la_mode;
427 mci->mci_opdata.mod_time = la->la_ctime;
429 ((uc->mu_valid == UCRED_OLD) || (uc->mu_valid == UCRED_NEW))) {
430 mci->mci_opdata.fsuid = uc->mu_fsuid;
431 mci->mci_opdata.fsgid = uc->mu_fsgid;
432 mci->mci_opdata.cap = uc->mu_cap;
433 if (uc->mu_ginfo || (uc->mu_valid == UCRED_OLD)) {
434 mci->mci_opdata.suppgids[0] = uc->mu_suppgids[0];
435 mci->mci_opdata.suppgids[1] = uc->mu_suppgids[1];
437 mci->mci_opdata.suppgids[0] =
438 mci->mci_opdata.suppgids[1] = -1;
441 mci->mci_opdata.fsuid = la->la_uid;
442 mci->mci_opdata.fsgid = la->la_gid;
443 mci->mci_opdata.cap = current->cap_effective;
444 mci->mci_opdata.suppgids[0] = mci->mci_opdata.suppgids[1] = -1;
447 rc = md_rename(mc->mc_desc.cl_exp, &mci->mci_opdata, NULL, 0,
448 name, strlen(name), &mci->mci_req);
450 /* get attr from request */
451 mdc_req2attr_update(env, ma);
454 ptlrpc_req_finished(mci->mci_req);
459 static int mdc_is_subdir(const struct lu_env *env, struct md_object *mo,
460 const struct lu_fid *fid, struct lu_fid *sfid)
462 struct mdc_device *mc = md2mdc_dev(md_obj2dev(mo));
463 struct mdc_thread_info *mci;
464 struct mdt_body *body;
468 mci = mdc_info_init(env);
470 /* FIXME: capability for split! */
471 rc = md_is_subdir(mc->mc_desc.cl_exp, lu_object_fid(&mo->mo_lu),
472 fid, NULL, NULL, &mci->mci_req);
476 body = lustre_msg_buf(mci->mci_req->rq_repmsg, REPLY_REC_OFF,
479 LASSERT(body->valid & (OBD_MD_FLMODE | OBD_MD_FLID) &&
480 (body->mode == 0 || body->mode == 1 || body->mode == EREMOTE));
484 CDEBUG(D_INFO, "Remote mdo_is_subdir(), new src "
485 DFID"\n", PFID(&body->fid1));
490 ptlrpc_req_finished(mci->mci_req);
494 static struct md_dir_operations mdc_dir_ops = {
495 .mdo_is_subdir = mdc_is_subdir,
496 .mdo_rename_tgt = mdc_rename_tgt