1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre Metadata Client (mdc)
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
35 #include <obd_class.h>
36 #include <lprocfs_status.h>
37 #include <lustre_ver.h>
38 #include "mdc_internal.h"
40 static struct lu_device_operations mdc_lu_ops;
42 static inline int lu_device_is_mdc(struct lu_device *ld)
45 * XXX for now. Tags in lu_device_type->ldt_something are needed.
47 return ergo(ld != NULL && ld->ld_ops != NULL,
48 ld->ld_ops == &mdc_lu_ops);
51 static struct md_device_operations mdc_md_ops = { 0 };
53 /* MDC OBD is set up already and connected to the proper MDS
54 * mdc_add_obd() find that obd by uuid and connects to it.
55 * Local MDT uuid is used for connection
57 static int mdc_add_obd(struct mdc_device *mc, struct lustre_cfg *cfg)
59 struct mdc_cli_desc *desc = &mc->mc_desc;
60 struct obd_device *mdc, *mdt;
61 const char *srv = lustre_cfg_string(cfg, 0);
62 const char *uuid_str = lustre_cfg_string(cfg, 1);
63 const char *index = lustre_cfg_string(cfg, 2);
71 mc->mc_num = simple_strtol(index, &p, 10);
73 CERROR("Invalid index in lustre_cgf, offset 2\n");
77 /* find local MDT obd to get group uuid */
78 mdt = class_name2obd(srv);
80 CERROR("No such OBD %s\n", srv);
83 obd_str2uuid(&desc->cl_srv_uuid, uuid_str);
84 /* try to find MDC OBD connected to the needed MDT */
85 mdc = class_find_client_obd(&desc->cl_srv_uuid, LUSTRE_MDC_NAME,
88 CERROR("Cannot find MDC OBD connected to %s\n", uuid_str);
90 } else if (!mdc->obd_set_up) {
91 CERROR("target %s not set up\n", mdc->obd_name);
94 struct lustre_handle *conn = &desc->cl_conn;
96 CDEBUG(D_CONFIG, "connect to %s(%s)\n",
97 mdc->obd_name, mdc->obd_uuid.uuid);
99 rc = obd_connect(conn, mdc, &mdt->obd_uuid, NULL);
102 CERROR("target %s connect error %d\n",
105 desc->cl_exp = class_conn2export(conn);
112 static int mdc_del_obd(struct mdc_device *mc)
114 struct mdc_cli_desc *desc = &mc->mc_desc;
119 CDEBUG(D_CONFIG, "disconnect from %s\n",
120 class_exp2obd(desc->cl_exp)->obd_name);
122 rc = obd_disconnect(desc->cl_exp);
124 CERROR("target %s disconnect error %d\n",
125 class_exp2obd(desc->cl_exp)->obd_name, rc);
132 static int mdc_process_config(const struct lu_context *ctx,
133 struct lu_device *ld, struct lustre_cfg *cfg)
135 struct mdc_device *mc = lu2mdc_dev(ld);
139 switch (cfg->lcfg_command) {
141 rc = mdc_add_obd(mc, cfg);
149 static struct lu_device_operations mdc_lu_ops = {
150 .ldo_object_alloc = mdc_object_alloc,
151 .ldo_process_config = mdc_process_config
154 static int mdc_device_init(const struct lu_context *ctx,
155 struct lu_device *ld, struct lu_device *next)
160 static struct lu_device *mdc_device_fini(const struct lu_context *ctx,
161 struct lu_device *ld)
163 struct mdc_device *mc = lu2mdc_dev(ld);
172 struct lu_device *mdc_device_alloc(const struct lu_context *ctx,
173 struct lu_device_type *ldt,
174 struct lustre_cfg *cfg)
176 struct lu_device *ld;
177 struct mdc_device *mc;
183 ld = ERR_PTR(-ENOMEM);
185 md_device_init(&mc->mc_md_dev, ldt);
186 mc->mc_md_dev.md_ops = &mdc_md_ops;
188 ld->ld_ops = &mdc_lu_ops;
193 void mdc_device_free(const struct lu_context *ctx, struct lu_device *ld)
195 struct mdc_device *mc = lu2mdc_dev(ld);
197 LASSERT(atomic_read(&ld->ld_ref) == 0);
198 LASSERT(list_empty(&mc->mc_linkage));
199 md_device_fini(&mc->mc_md_dev);
203 /* context key constructor/destructor */
205 static void *mdc_thread_init(const struct lu_context *ctx,
206 struct lu_context_key *key)
208 struct mdc_thread_info *info;
210 CLASSERT(CFS_PAGE_SIZE >= sizeof *info);
213 info = ERR_PTR(-ENOMEM);
217 static void mdc_thread_fini(const struct lu_context *ctx,
218 struct lu_context_key *key, void *data)
220 struct mdc_thread_info *info = data;
224 struct lu_context_key mdc_thread_key = {
225 .lct_init = mdc_thread_init,
226 .lct_fini = mdc_thread_fini
229 int mdc_type_init(struct lu_device_type *ldt)
231 return lu_context_key_register(&mdc_thread_key);
234 void mdc_type_fini(struct lu_device_type *ldt)
236 lu_context_key_degister(&mdc_thread_key);
239 static struct lu_device_type_operations mdc_device_type_ops = {
240 .ldto_init = mdc_type_init,
241 .ldto_fini = mdc_type_fini,
243 .ldto_device_alloc = mdc_device_alloc,
244 .ldto_device_free = mdc_device_free,
246 .ldto_device_init = mdc_device_init,
247 .ldto_device_fini = mdc_device_fini
250 struct lu_device_type mdc_device_type = {
251 .ldt_tags = LU_DEVICE_MD,
252 .ldt_name = LUSTRE_MDC0_NAME,
253 .ldt_ops = &mdc_device_type_ops