1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/cmm/cmm_device.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
32 #define DEBUG_SUBSYSTEM S_MDS
34 #include <linux/module.h>
36 #include <linux/obd.h>
37 #include <linux/obd_class.h>
39 #include "cmm_internal.h"
40 #include "mdc_internal.h"
42 #include <linux/lprocfs_status.h>
43 #include <linux/lustre_ver.h>
45 static struct obd_ops cmm_obd_device_ops = {
46 .o_owner = THIS_MODULE
49 static struct lu_device_operations cmm_lu_ops;
51 static inline int lu_device_is_cmm(struct lu_device *d)
54 * XXX for now. Tags in lu_device_type->ldt_something are needed.
56 return ergo(d != NULL && d->ld_ops != NULL, d->ld_ops == &cmm_lu_ops);
59 int cmm_root_get(struct lu_context *ctx, struct md_device *md,
62 struct cmm_device *cmm_dev = md2cmm_dev(md);
64 return cmm_child_ops(cmm_dev)->mdo_root_get(ctx,
65 cmm_dev->cmm_child, fid);
68 int cmm_config(struct lu_context *ctxt, struct md_device *md,
69 const char *name, void *buf, int size, int mode)
71 struct cmm_device *cmm_dev = md2cmm_dev(md);
74 rc = cmm_child_ops(cmm_dev)->mdo_config(ctxt, cmm_dev->cmm_child,
75 name, buf, size, mode);
79 int cmm_statfs(struct lu_context *ctxt, struct md_device *md,
80 struct kstatfs *sfs) {
81 struct cmm_device *cmm_dev = md2cmm_dev(md);
85 rc = cmm_child_ops(cmm_dev)->mdo_statfs(ctxt,
86 cmm_dev->cmm_child, sfs);
90 static struct md_device_operations cmm_md_ops = {
91 .mdo_root_get = cmm_root_get,
92 .mdo_config = cmm_config,
93 .mdo_statfs = cmm_statfs,
96 extern struct lu_device_type mdc_device_type;
98 /* add new MDC to the CMM, create MDC lu_device and connect it to mdc_obd */
99 static int cmm_add_mdc(struct lu_context *ctx,
100 struct cmm_device * cm, struct lustre_cfg *cfg)
102 struct lu_device_type *ldt = &mdc_device_type;
103 struct lu_device *ld;
107 /*TODO check this MDC exists already */
109 ld = ldt->ldt_ops->ldto_device_alloc(ldt, cfg);
111 ld->ld_site = cmm2lu_dev(cm)->ld_site;
113 rc = ldt->ldt_ops->ldto_device_init(ctx, ld, NULL);
115 ldt->ldt_ops->ldto_device_free(ld);
117 /* pass config to the just created MDC */
118 rc = ld->ld_ops->ldo_process_config(ctx, ld, cfg);
120 struct mdc_device *mc = lu2mdc_dev(ld);
121 list_add_tail(&mc->mc_linkage, &cm->cmm_targets);
122 lu_device_get(cmm2lu_dev(cm));
128 static int cmm_process_config(struct lu_context *ctx,
129 struct lu_device *d, struct lustre_cfg *cfg)
131 struct cmm_device *m = lu2cmm_dev(d);
132 struct lu_device *next = md2lu_dev(m->cmm_child);
135 switch(cfg->lcfg_command) {
137 err = cmm_add_mdc(ctx, m, cfg);
141 const char *index = lustre_cfg_string(cfg, 2);
143 m->cmm_local_num = simple_strtol(index, NULL, 10);
144 /* no break; to pass cfg further */
147 err = next->ld_ops->ldo_process_config(ctx, next, cfg);
152 static struct lu_device_operations cmm_lu_ops = {
153 .ldo_object_alloc = cmm_object_alloc,
154 .ldo_object_free = cmm_object_free,
156 .ldo_process_config = cmm_process_config
159 /* --- lu_device_type operations --- */
161 struct lu_device *cmm_device_alloc(struct lu_device_type *t,
162 struct lustre_cfg *cfg)
165 struct cmm_device *m;
171 l = ERR_PTR(-ENOMEM);
173 md_device_init(&m->cmm_md_dev, t);
174 m->cmm_md_dev.md_ops = &cmm_md_ops;
176 l->ld_ops = &cmm_lu_ops;
183 void cmm_device_free(struct lu_device *d)
185 struct cmm_device *m = lu2cmm_dev(d);
187 LASSERT(atomic_read(&d->ld_ref) == 0);
188 md_device_fini(&m->cmm_md_dev);
192 int cmm_type_init(struct lu_device_type *t)
197 void cmm_type_fini(struct lu_device_type *t)
202 static int cmm_device_init(struct lu_context *ctx,
203 struct lu_device *d, struct lu_device *next)
205 struct cmm_device *m = lu2cmm_dev(d);
210 INIT_LIST_HEAD(&m->cmm_targets);
211 m->cmm_tgt_count = 0;
212 m->cmm_child = lu2md_dev(next);
217 static struct lu_device *cmm_device_fini(struct lu_context *ctx,
218 struct lu_device *ld)
220 struct cmm_device *cm = lu2cmm_dev(ld);
221 struct mdc_device *mc, *tmp;
224 /* finish all mdc devices */
225 list_for_each_entry_safe(mc, tmp, &cm->cmm_targets, mc_linkage) {
226 struct lu_device *ld_m = mdc2lu_dev(mc);
228 list_del(&mc->mc_linkage);
229 lu_device_put(cmm2lu_dev(cm));
230 ld->ld_type->ldt_ops->ldto_device_fini(ctx, ld_m);
231 ld->ld_type->ldt_ops->ldto_device_free(ld_m);
235 return md2lu_dev(cm->cmm_child);
238 static struct lu_device_type_operations cmm_device_type_ops = {
239 .ldto_init = cmm_type_init,
240 .ldto_fini = cmm_type_fini,
242 .ldto_device_alloc = cmm_device_alloc,
243 .ldto_device_free = cmm_device_free,
245 .ldto_device_init = cmm_device_init,
246 .ldto_device_fini = cmm_device_fini
249 static struct lu_device_type cmm_device_type = {
250 .ldt_tags = LU_DEVICE_MD,
251 .ldt_name = LUSTRE_CMM0_NAME,
252 .ldt_ops = &cmm_device_type_ops
255 struct lprocfs_vars lprocfs_cmm_obd_vars[] = {
259 struct lprocfs_vars lprocfs_cmm_module_vars[] = {
263 LPROCFS_INIT_VARS(cmm, lprocfs_cmm_module_vars, lprocfs_cmm_obd_vars);
265 static int __init cmm_mod_init(void)
267 struct lprocfs_static_vars lvars;
269 printk(KERN_INFO "Lustre: Clustered Metadata Manager; info@clusterfs.com\n");
271 lprocfs_init_vars(cmm, &lvars);
272 return class_register_type(&cmm_obd_device_ops, NULL, lvars.module_vars,
273 LUSTRE_CMM0_NAME, &cmm_device_type);
276 static void __exit cmm_mod_exit(void)
278 class_unregister_type(LUSTRE_CMM0_NAME);
281 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
282 MODULE_DESCRIPTION("Lustre Clustered Meta-data Manager Prototype ("LUSTRE_CMM0_NAME")");
283 MODULE_LICENSE("GPL");
285 cfs_module(cmm, "0.0.3", cmm_mod_init, cmm_mod_exit);