1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/cmm/cmm_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
35 #include <lustre_fid.h>
36 #include "cmm_internal.h"
37 #include "mdc_internal.h"
39 static int cmm_fld_lookup(struct cmm_device *cm,
40 const struct lu_fid *fid, mdsno_t *mds)
45 LASSERT(fid_is_sane(fid));
47 rc = fld_client_lookup(&cm->cmm_fld, fid_seq(fid), mds);
49 CERROR("can't find mds by seq "LPU64", rc %d\n",
54 if (*mds > cm->cmm_tgt_count) {
55 CERROR("Got invalid mdsno: "LPU64" (max: %u)\n",
56 *mds, cm->cmm_tgt_count);
59 CDEBUG(D_INFO, "CMM: got MDS "LPU64" for sequence: "LPU64"\n",
66 static struct md_object_operations cml_mo_ops;
67 static struct md_dir_operations cml_dir_ops;
68 static struct lu_object_operations cml_obj_ops;
70 static struct md_object_operations cmr_mo_ops;
71 static struct md_dir_operations cmr_dir_ops;
72 static struct lu_object_operations cmr_obj_ops;
74 struct lu_object *cmm_object_alloc(const struct lu_context *ctx,
75 const struct lu_object_header *loh,
78 struct lu_object *lo = NULL;
79 const struct lu_fid *fid = &loh->loh_fid;
80 struct cmm_device *cd;
87 if (cd->cmm_flags & CMM_INITIALIZED) {
88 /* get object location */
89 rc = cmm_fld_lookup(lu2cmm_dev(ld), fid, &mdsnum);
94 * Device is not yet initialized, cmm_object is being created
95 * as part of early bootstrap procedure (it is /ROOT, or /fld,
96 * etc.). Such object *has* to be local.
98 mdsnum = cd->cmm_local_num;
100 /* select the proper set of operations based on object location */
101 if (mdsnum == cd->cmm_local_num) {
102 struct cml_object *clo;
106 lo = &clo->cmm_obj.cmo_obj.mo_lu;
107 lu_object_init(lo, NULL, ld);
108 clo->cmm_obj.cmo_obj.mo_ops = &cml_mo_ops;
109 clo->cmm_obj.cmo_obj.mo_dir_ops = &cml_dir_ops;
110 lo->lo_ops = &cml_obj_ops;
111 clo->cmm_obj.cmo_local = 1;
114 struct cmr_object *cro;
118 lo = &cro->cmm_obj.cmo_obj.mo_lu;
119 lu_object_init(lo, NULL, ld);
120 cro->cmm_obj.cmo_obj.mo_ops = &cmr_mo_ops;
121 cro->cmm_obj.cmo_obj.mo_dir_ops = &cmr_dir_ops;
122 lo->lo_ops = &cmr_obj_ops;
123 cro->cmo_num = mdsnum;
124 cro->cmm_obj.cmo_local = 0;
131 * CMM has two types of objects - local and remote. They have different set
132 * of operations so we are avoiding multiple checks in code.
136 * local CMM object operations. cml_...
138 static inline struct cml_object *lu2cml_obj(struct lu_object *o)
140 return container_of0(o, struct cml_object, cmm_obj.cmo_obj.mo_lu);
142 static inline struct cml_object *md2cml_obj(struct md_object *mo)
144 return container_of0(mo, struct cml_object, cmm_obj.cmo_obj);
146 static inline struct cml_object *cmm2cml_obj(struct cmm_object *co)
148 return container_of0(co, struct cml_object, cmm_obj);
150 /* get local child device */
151 static struct lu_device *cml_child_dev(struct cmm_device *d)
153 return &d->cmm_child->md_lu_dev;
156 /* lu_object operations */
157 static void cml_object_free(const struct lu_context *ctx,
158 struct lu_object *lo)
160 struct cml_object *clo = lu2cml_obj(lo);
165 static int cml_object_init(const struct lu_context *ctx, struct lu_object *lo)
167 struct cmm_device *cd = lu2cmm_dev(lo->lo_dev);
168 struct lu_device *c_dev;
169 struct lu_object *c_obj;
174 c_dev = cml_child_dev(cd);
178 c_obj = c_dev->ld_ops->ldo_object_alloc(ctx,
179 lo->lo_header, c_dev);
181 lu_object_add(lo, c_obj);
191 static int cml_object_exists(const struct lu_context *ctx,
192 struct lu_object *lo)
194 return lu_object_exists(ctx, lu_object_next(lo));
197 static int cml_object_print(const struct lu_context *ctx,
198 struct seq_file *f, const struct lu_object *lo)
200 return seq_printf(f, LUSTRE_CMM0_NAME"-local@%p", lo);
203 static struct lu_object_operations cml_obj_ops = {
204 .loo_object_init = cml_object_init,
205 .loo_object_free = cml_object_free,
206 .loo_object_print = cml_object_print,
207 .loo_object_exists = cml_object_exists
210 /* CMM local md_object operations */
211 static int cml_object_create(const struct lu_context *ctx,
212 struct md_object *mo,
213 struct lu_attr *attr)
217 rc = mo_object_create(ctx, md_object_next(mo), attr);
221 static int cml_attr_get(const struct lu_context *ctx, struct md_object *mo,
222 struct lu_attr *attr)
226 rc = mo_attr_get(ctx, md_object_next(mo), attr);
230 static int cml_attr_set(const struct lu_context *ctx, struct md_object *mo,
231 const struct lu_attr *attr)
235 rc = mo_attr_set(ctx, md_object_next(mo), attr);
239 static int cml_xattr_get(const struct lu_context *ctx, struct md_object *mo,
240 void *buf, int buflen, const char *name)
244 rc = mo_xattr_get(ctx, md_object_next(mo),
249 static int cml_xattr_set(const struct lu_context *ctx, struct md_object *mo,
250 const void *buf, int buflen, const char *name)
254 rc = mo_xattr_set(ctx, md_object_next(mo),
259 static int cml_ref_add(const struct lu_context *ctx, struct md_object *mo)
263 rc = mo_ref_add(ctx, md_object_next(mo));
267 static int cml_ref_del(const struct lu_context *ctx, struct md_object *mo)
271 rc = mo_ref_del(ctx, md_object_next(mo));
275 static int cml_open(const struct lu_context *ctx, struct md_object *mo)
279 rc = mo_open(ctx, md_object_next(mo));
283 static int cml_close(const struct lu_context *ctx, struct md_object *mo)
287 rc = mo_close(ctx, md_object_next(mo));
291 static struct md_object_operations cml_mo_ops = {
292 .moo_attr_get = cml_attr_get,
293 .moo_attr_set = cml_attr_set,
294 .moo_xattr_get = cml_xattr_get,
295 .moo_xattr_set = cml_xattr_set,
296 .moo_object_create = cml_object_create,
297 .moo_ref_add = cml_ref_add,
298 .moo_ref_del = cml_ref_del,
299 .moo_open = cml_open,
300 .moo_close = cml_close
303 /* md_dir operations */
304 static int cml_lookup(const struct lu_context *ctx, struct md_object *mo_p,
305 const char *name, struct lu_fid *lf)
309 rc = mdo_lookup(ctx, md_object_next(mo_p), name, lf);
314 static int cml_create(const struct lu_context *ctx,
315 struct md_object *mo_p, const char *name,
316 struct md_object *mo_c, struct lu_attr *attr)
320 rc = mdo_create(ctx, md_object_next(mo_p), name,
321 md_object_next(mo_c), attr);
325 static int cml_link(const struct lu_context *ctx, struct md_object *mo_p,
326 struct md_object *mo_s, const char *name)
330 rc = mdo_link(ctx, md_object_next(mo_p),
331 md_object_next(mo_s), name);
335 static int cml_unlink(const struct lu_context *ctx, struct md_object *mo_p,
336 struct md_object *mo_c, const char *name)
340 rc = mdo_unlink(ctx, md_object_next(mo_p),
341 md_object_next(mo_c), name);
345 /* rename is split to local/remote by location of new parent dir */
346 static int cml_rename(const struct lu_context *ctx, struct md_object *mo_po,
347 struct md_object *mo_pn, const struct lu_fid *lf,
348 const char *s_name, struct md_object *mo_t,
354 if (mo_t && !cmm_is_local_obj(md2cmm_obj(mo_t))) {
355 /* mo_t is remote object and there is RPC to unlink it */
356 rc = mo_ref_del(ctx, md_object_next(mo_t));
361 /* local rename, mo_t can be NULL */
362 rc = mdo_rename(ctx, md_object_next(mo_po),
363 md_object_next(mo_pn), lf, s_name,
364 md_object_next(mo_t), t_name);
369 static int cml_rename_tgt(const struct lu_context *ctx,
370 struct md_object *mo_p, struct md_object *mo_t,
371 const struct lu_fid *lf, const char *name)
376 rc = mdo_rename_tgt(ctx, md_object_next(mo_p),
377 md_object_next(mo_t), lf, name);
381 static struct md_dir_operations cml_dir_ops = {
382 .mdo_lookup = cml_lookup,
383 .mdo_create = cml_create,
384 .mdo_link = cml_link,
385 .mdo_unlink = cml_unlink,
386 .mdo_rename = cml_rename,
387 .mdo_rename_tgt = cml_rename_tgt,
390 /* -------------------------------------------------------------------
391 * remote CMM object operations. cmr_...
393 static inline struct cmr_object *lu2cmr_obj(struct lu_object *o)
395 return container_of0(o, struct cmr_object, cmm_obj.cmo_obj.mo_lu);
397 static inline struct cmr_object *md2cmr_obj(struct md_object *mo)
399 return container_of0(mo, struct cmr_object, cmm_obj.cmo_obj);
401 static inline struct cmr_object *cmm2cmr_obj(struct cmm_object *co)
403 return container_of0(co, struct cmr_object, cmm_obj);
406 /* get proper child device from MDCs */
407 static struct lu_device *cmr_child_dev(struct cmm_device *d, __u32 num)
409 struct lu_device *next = NULL;
410 struct mdc_device *mdc;
412 spin_lock(&d->cmm_tgt_guard);
413 list_for_each_entry(mdc, &d->cmm_targets, mc_linkage) {
414 if (mdc->mc_num == num) {
415 next = mdc2lu_dev(mdc);
419 spin_unlock(&d->cmm_tgt_guard);
423 /* lu_object operations */
424 static void cmr_object_free(const struct lu_context *ctx,
425 struct lu_object *lo)
427 struct cmr_object *cro = lu2cmr_obj(lo);
432 static int cmr_object_init(const struct lu_context *ctx, struct lu_object *lo)
434 struct cmm_device *cd = lu2cmm_dev(lo->lo_dev);
435 struct lu_device *c_dev;
436 struct lu_object *c_obj;
441 c_dev = cmr_child_dev(cd, lu2cmr_obj(lo)->cmo_num);
445 c_obj = c_dev->ld_ops->ldo_object_alloc(ctx,
446 lo->lo_header, c_dev);
448 lu_object_add(lo, c_obj);
458 static int cmr_object_exists(const struct lu_context *ctx,
459 struct lu_object *lo)
461 return lu_object_exists(ctx, lu_object_next(lo));
464 static int cmr_object_print(const struct lu_context *ctx,
465 struct seq_file *f, const struct lu_object *lo)
467 return seq_printf(f, LUSTRE_CMM0_NAME"-remote@%p", lo);
470 static struct lu_object_operations cmr_obj_ops = {
471 .loo_object_init = cmr_object_init,
472 .loo_object_free = cmr_object_free,
473 .loo_object_print = cmr_object_print,
474 .loo_object_exists = cmr_object_exists
477 /* CMM remote md_object operations. All are invalid */
478 static int cmr_object_create(const struct lu_context *ctx,
479 struct md_object *mo,
480 struct lu_attr *attr)
485 static int cmr_attr_get(const struct lu_context *ctx, struct md_object *mo,
486 struct lu_attr *attr)
491 static int cmr_attr_set(const struct lu_context *ctx, struct md_object *mo,
492 const struct lu_attr *attr)
497 static int cmr_xattr_get(const struct lu_context *ctx, struct md_object *mo,
498 void *buf, int buflen, const char *name)
503 static int cmr_xattr_set(const struct lu_context *ctx, struct md_object *mo,
504 const void *buf, int buflen, const char *name)
509 static int cmr_ref_add(const struct lu_context *ctx, struct md_object *mo)
514 static int cmr_ref_del(const struct lu_context *ctx, struct md_object *mo)
519 static int cmr_open(const struct lu_context *ctx, struct md_object *mo)
524 static int cmr_close(const struct lu_context *ctx, struct md_object *mo)
529 static struct md_object_operations cmr_mo_ops = {
530 .moo_attr_get = cmr_attr_get,
531 .moo_attr_set = cmr_attr_set,
532 .moo_xattr_get = cmr_xattr_get,
533 .moo_xattr_set = cmr_xattr_set,
534 .moo_object_create = cmr_object_create,
535 .moo_ref_add = cmr_ref_add,
536 .moo_ref_del = cmr_ref_del,
537 .moo_open = cmr_open,
538 .moo_close = cmr_close
541 /* remote part of md_dir operations */
542 static int cmr_lookup(const struct lu_context *ctx, struct md_object *mo_p,
543 const char *name, struct lu_fid *lf)
545 /*this can happens while rename()
546 * If new parent is remote dir, lookup will happens here */
552 * All methods below are cross-ref by nature. They consist of remote call and
553 * local operation. Due to future rollback functionality there are several
554 * limitations for such methods:
555 * 1) remote call should be done at first to do epoch negotiation between all
556 * MDS involved and to avoid the RPC inside transaction.
557 * 2) only one RPC can be sent - also due to epoch negotiation.
558 * For more details see rollback HLD/DLD.
561 static int cmr_create(const struct lu_context *ctx,
562 struct md_object *mo_p, const char *name,
563 struct md_object *mo_c, struct lu_attr *attr)
569 //XXX: make sure that MDT checks name isn't exist
571 /* remote object creation and local name insert */
572 rc = mo_object_create(ctx, md_object_next(mo_c), attr);
574 rc = mdo_name_insert(ctx, md_object_next(mo_p),
575 name, lu_object_fid(&mo_c->mo_lu));
581 static int cmr_link(const struct lu_context *ctx, struct md_object *mo_p,
582 struct md_object *mo_s, const char *name)
587 //XXX: make sure that MDT checks name isn't exist
589 rc = mo_ref_add(ctx, md_object_next(mo_s));
591 rc = mdo_name_insert(ctx, md_object_next(mo_p),
592 name, lu_object_fid(&mo_s->mo_lu));
598 static int cmr_unlink(const struct lu_context *ctx, struct md_object *mo_p,
599 struct md_object *mo_c, const char *name)
604 rc = mo_ref_del(ctx, md_object_next(mo_c));
606 rc = mdo_name_remove(ctx, md_object_next(mo_p),
613 static int cmr_rename(const struct lu_context *ctx, struct md_object *mo_po,
614 struct md_object *mo_pn, const struct lu_fid *lf,
615 const char *s_name, struct md_object *mo_t,
621 /* the mo_pn is remote directory, so we cannot even know if there is
622 * mo_t or not. Therefore mo_t is NULL here but remote server should do
623 * lookup and process this further */
625 LASSERT(mo_t == NULL);
626 rc = mdo_rename_tgt(ctx, md_object_next(mo_pn),
627 NULL/* mo_t */, lf, t_name);
628 /* only old name is removed localy */
630 rc = mdo_name_remove(ctx, md_object_next(mo_po),
636 /* part of cross-ref rename(). Used to insert new name in new parent
637 * and unlink target with same name if it exists */
638 static int cmr_rename_tgt(const struct lu_context *ctx,
639 struct md_object *mo_p, struct md_object *mo_t,
640 const struct lu_fid *lf, const char *name)
644 /* target object is remote one */
645 rc = mo_ref_del(ctx, md_object_next(mo_t));
646 /* continue locally with name handling only */
648 rc = mdo_rename_tgt(ctx, md_object_next(mo_p),
653 static struct md_dir_operations cmr_dir_ops = {
654 .mdo_lookup = cmr_lookup,
655 .mdo_create = cmr_create,
656 .mdo_link = cmr_link,
657 .mdo_unlink = cmr_unlink,
658 .mdo_rename = cmr_rename,
659 .mdo_rename_tgt = cmr_rename_tgt,