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>
37 #include <obd_class.h>
38 #include <lprocfs_status.h>
39 #include <lustre_ver.h>
40 #include "cmm_internal.h"
41 #include "mdc_internal.h"
43 static struct obd_ops cmm_obd_device_ops = {
44 .o_owner = THIS_MODULE
47 static struct lu_device_operations cmm_lu_ops;
49 static inline int lu_device_is_cmm(struct lu_device *d)
52 * XXX for now. Tags in lu_device_type->ldt_something are needed.
54 return ergo(d != NULL && d->ld_ops != NULL, d->ld_ops == &cmm_lu_ops);
57 static int cmm_root_get(const struct lu_context *ctx, struct md_device *md,
60 struct cmm_device *cmm_dev = md2cmm_dev(md);
62 return cmm_child_ops(cmm_dev)->mdo_root_get(ctx,
63 cmm_dev->cmm_child, fid);
66 static int cmm_statfs(const struct lu_context *ctxt, struct md_device *md,
67 struct kstatfs *sfs) {
68 struct cmm_device *cmm_dev = md2cmm_dev(md);
72 rc = cmm_child_ops(cmm_dev)->mdo_statfs(ctxt,
73 cmm_dev->cmm_child, sfs);
77 static struct md_device_operations cmm_md_ops = {
78 .mdo_root_get = cmm_root_get,
79 .mdo_statfs = cmm_statfs,
82 extern struct lu_device_type mdc_device_type;
84 /* --- cmm_lu_operations --- */
85 /* add new MDC to the CMM, create MDC lu_device and connect it to mdc_obd */
86 static int cmm_add_mdc(const struct lu_context *ctx,
87 struct cmm_device *cm, struct lustre_cfg *cfg)
89 struct lu_device_type *ldt = &mdc_device_type;
91 struct mdc_device *mc, *tmp;
92 char *p, *num = lustre_cfg_string(cfg, 2);
97 /* find out that there is no such mdc */
99 mdc_num = simple_strtol(num, &p, 10);
101 CERROR("Invalid index in lustre_cgf, offset 2\n");
105 spin_lock(&cm->cmm_tgt_guard);
106 list_for_each_entry_safe(mc, tmp, &cm->cmm_targets,
108 if (mc->mc_num == mdc_num) {
109 spin_unlock(&cm->cmm_tgt_guard);
113 spin_unlock(&cm->cmm_tgt_guard);
114 ld = ldt->ldt_ops->ldto_device_alloc(ctx, ldt, cfg);
115 ld->ld_site = cmm2lu_dev(cm)->ld_site;
117 rc = ldt->ldt_ops->ldto_device_init(ctx, ld, NULL);
119 ldt->ldt_ops->ldto_device_free(ctx, ld);
122 /* pass config to the just created MDC */
123 rc = ld->ld_ops->ldo_process_config(ctx, ld, cfg);
125 spin_lock(&cm->cmm_tgt_guard);
126 list_for_each_entry_safe(mc, tmp, &cm->cmm_targets,
128 if (mc->mc_num == mdc_num) {
129 spin_unlock(&cm->cmm_tgt_guard);
130 ldt->ldt_ops->ldto_device_fini(ctx, ld);
131 ldt->ldt_ops->ldto_device_free(ctx, ld);
136 list_add_tail(&mc->mc_linkage, &cm->cmm_targets);
138 spin_unlock(&cm->cmm_tgt_guard);
140 lu_device_get(cmm2lu_dev(cm));
142 fld_client_add_export(&cm->cmm_fld,
149 static int cmm_process_config(const struct lu_context *ctx,
150 struct lu_device *d, struct lustre_cfg *cfg)
152 struct cmm_device *m = lu2cmm_dev(d);
153 struct lu_device *next = md2lu_dev(m->cmm_child);
156 switch(cfg->lcfg_command) {
158 err = cmm_add_mdc(ctx, m, cfg);
159 /* the first ADD_MDC can be counted as setup is finished */
160 if (m->cmm_flags & CMM_INITIALIZED == 0)
161 m->cmm_flags |= CMM_INITIALIZED;
165 const char *index = lustre_cfg_string(cfg, 2);
169 /* lower layers should be set up at first */
170 err = next->ld_ops->ldo_process_config(ctx, next, cfg);
172 m->cmm_local_num = simple_strtol(index, &p, 10);
174 CERROR("Invalid index in lustre_cgf\n");
181 err = next->ld_ops->ldo_process_config(ctx, next, cfg);
186 static struct lu_device_operations cmm_lu_ops = {
187 .ldo_object_alloc = cmm_object_alloc,
188 .ldo_process_config = cmm_process_config
191 /* --- lu_device_type operations --- */
193 static struct lu_device *cmm_device_alloc(const struct lu_context *ctx,
194 struct lu_device_type *t,
195 struct lustre_cfg *cfg)
198 struct cmm_device *m;
204 l = ERR_PTR(-ENOMEM);
206 md_device_init(&m->cmm_md_dev, t);
207 m->cmm_md_dev.md_ops = &cmm_md_ops;
209 l->ld_ops = &cmm_lu_ops;
215 static void cmm_device_free(const struct lu_context *ctx, struct lu_device *d)
217 struct cmm_device *m = lu2cmm_dev(d);
219 LASSERT(atomic_read(&d->ld_ref) == 0);
220 LASSERT(m->cmm_tgt_count == 0);
221 LASSERT(list_empty(&m->cmm_targets));
222 md_device_fini(&m->cmm_md_dev);
226 static int cmm_type_init(struct lu_device_type *t)
231 static void cmm_type_fini(struct lu_device_type *t)
236 static int cmm_device_init(const struct lu_context *ctx,
237 struct lu_device *d, struct lu_device *next)
239 struct cmm_device *m = lu2cmm_dev(d);
244 spin_lock_init(&m->cmm_tgt_guard);
245 INIT_LIST_HEAD(&m->cmm_targets);
246 m->cmm_tgt_count = 0;
247 m->cmm_child = lu2md_dev(next);
249 err = fld_client_init(&m->cmm_fld, LUSTRE_CLI_FLD_HASH_RRB);
251 CERROR("can't init FLD, err %d\n", err);
256 static struct lu_device *cmm_device_fini(const struct lu_context *ctx,
257 struct lu_device *ld)
259 struct cmm_device *cm = lu2cmm_dev(ld);
260 struct mdc_device *mc, *tmp;
263 fld_client_fini(&cm->cmm_fld);
264 /* finish all mdc devices */
265 spin_lock(&cm->cmm_tgt_guard);
266 list_for_each_entry_safe(mc, tmp, &cm->cmm_targets, mc_linkage) {
267 struct lu_device *ld_m = mdc2lu_dev(mc);
269 list_del_init(&mc->mc_linkage);
270 lu_device_put(cmm2lu_dev(cm));
271 ld->ld_type->ldt_ops->ldto_device_fini(ctx, ld_m);
272 ld->ld_type->ldt_ops->ldto_device_free(ctx, ld_m);
275 spin_unlock(&cm->cmm_tgt_guard);
277 RETURN (md2lu_dev(cm->cmm_child));
280 static struct lu_device_type_operations cmm_device_type_ops = {
281 .ldto_init = cmm_type_init,
282 .ldto_fini = cmm_type_fini,
284 .ldto_device_alloc = cmm_device_alloc,
285 .ldto_device_free = cmm_device_free,
287 .ldto_device_init = cmm_device_init,
288 .ldto_device_fini = cmm_device_fini
291 static struct lu_device_type cmm_device_type = {
292 .ldt_tags = LU_DEVICE_MD,
293 .ldt_name = LUSTRE_CMM0_NAME,
294 .ldt_ops = &cmm_device_type_ops
297 struct lprocfs_vars lprocfs_cmm_obd_vars[] = {
301 struct lprocfs_vars lprocfs_cmm_module_vars[] = {
305 LPROCFS_INIT_VARS(cmm, lprocfs_cmm_module_vars, lprocfs_cmm_obd_vars);
307 static int __init cmm_mod_init(void)
309 struct lprocfs_static_vars lvars;
311 printk(KERN_INFO "Lustre: Clustered Metadata Manager; info@clusterfs.com\n");
313 lprocfs_init_vars(cmm, &lvars);
314 return class_register_type(&cmm_obd_device_ops, NULL, lvars.module_vars,
315 LUSTRE_CMM0_NAME, &cmm_device_type);
318 static void __exit cmm_mod_exit(void)
320 class_unregister_type(LUSTRE_CMM0_NAME);
323 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
324 MODULE_DESCRIPTION("Lustre Clustered Metadata Manager ("LUSTRE_CMM0_NAME")");
325 MODULE_LICENSE("GPL");
327 cfs_module(cmm, "0.1.0", cmm_mod_init, cmm_mod_exit);