-MODULES := cmm
-cmm-objs := cmm_device.o cmm_object.o cmm_mdc.o
+MODULES := cmm cmmmdc
+cmm-objs := cmm_device.o cmm_object.o
+cmmmdc-objs := cmm_mdc.o mdc_object.o
@INCLUDE_RULES@
# See the file COPYING in this distribution
if MODULES
-modulefs_DATA = cmm$(KMODEXT)
+modulefs_DATA = cmm$(KMODEXT) cmmmdc$(KMODEXT)
endif
MOSTLYCLEANFILES := @MOSTLYCLEANFILES@
-DIST_SOURCES = $(cmm-objs:%.o=%.c) cmm_internal.h
+DIST_SOURCES = $(cmm-objs:%.o=%.c) $(cmmmdc-objs:%.o=%.c) \
+ cmm_internal.h mdc_internal.h
#include <linux/obd_class.h>
#include "cmm_internal.h"
+#include "mdc_internal.h"
#include <linux/lprocfs_status.h>
#include <linux/lustre_ver.h>
ENTRY;
+ INIT_LIST_HEAD(&m->cmm_targets);
+ m->cmm_tgt_count = 0;
m->cmm_child = lu2md_dev(next);
RETURN(err);
}
-static struct lu_device *cmm_device_fini(struct lu_device *d)
+static struct lu_device *cmm_device_fini(struct lu_device *ld)
{
- struct cmm_device *m = lu2cmm_dev(d);
- struct lu_device *next = md2lu_dev(m->cmm_child);
-
+ struct cmm_device *cm = lu2cmm_dev(ld);
+ struct mdc_device *mc, *tmp;
ENTRY;
+
+ /* finish all mdc devices */
+ list_for_each_entry_safe(mc, tmp, &cm->cmm_targets, mc_linkage) {
+ struct lu_device *ld_m = mdc2lu_dev(mc);
+
+ list_del(&mc->mc_linkage);
+ lu_device_put(cmm2lu_dev(cm));
+ ld->ld_type->ldt_ops->ldto_device_fini(ld_m);
+ ld->ld_type->ldt_ops->ldto_device_free(ld_m);
+ }
+
EXIT;
- return next;
+ return md2lu_dev(cm->cmm_child);
+}
+
+/* add new MDC to the CMM, create MDC lu_device and connect it to mdc_obd */
+static int cmm_add_mdc(struct cmm_device * cm, struct lustre_cfg *cfg)
+{
+ struct lu_device_type *ldt;
+ struct lu_device *ld;
+ struct obd_device *obd;
+ const char *name = lustre_cfg_string(cfg, 1);
+ int rc;
+ ENTRY;
+
+ /*TODO check this MDC exists already */
+ obd = class_name2obd(name);
+ if (obd) {
+ ld = obd->obd_lu_dev;
+ } else {
+ RETURN(-ENOENT);
+ }
+
+ ldt = ld->ld_type;
+ ld->ld_site = cmm2lu_dev(cm)->ld_site;
+
+ rc = ldt->ldt_ops->ldto_device_init(ld, NULL);
+ if (rc)
+ ldt->ldt_ops->ldto_device_free(ld);
+
+ /* pass config to the just created MDC */
+ rc = ld->ld_ops->ldo_process_config(ld, cfg);
+ if (rc == 0) {
+ struct mdc_device *mc = lu2mdc_dev(ld);
+ list_add_tail(&mc->mc_linkage, &cm->cmm_targets);
+ lu_device_get(cmm2lu_dev(cm));
+ }
+ RETURN(rc);
}
+
static int cmm_process_config(struct lu_device *d, struct lustre_cfg *cfg)
{
struct cmm_device *m = lu2cmm_dev(d);
#include <linux/obd.h>
#include <linux/md_object.h>
-struct cmm_mdc_device {
- struct md_device mdc_md_dev;
- /* other MD servers in cluster */
- __u32 cmm_tgt_count;
- struct list_head cmm_tgt_linkage;
-};
-
struct cmm_device {
struct md_device cmm_md_dev;
/* underlaying device in MDS stack, usually MDD */
struct md_device *cmm_child;
/* other MD servers in cluster */
- __u32 local_num;
+ __u32 cmm_local_num;
__u32 cmm_tgt_count;
struct list_head cmm_targets;
};
}
struct cmm_object {
- struct md_object cmo_obj;
+ struct md_object cmo_obj;
+ /* mds number where object is placed */
+ __u32 cmo_num;
};
static inline struct cmm_device *cmm_obj2dev(struct cmm_object *c)
return container_of0(o, struct cmm_object, cmo_obj.mo_lu);
}
+static inline int cmm_is_local_obj(struct cmm_object *c)
+{
+ return (c->cmo_num == cmm_obj2dev(c)->cmm_local_num);
+}
+
/* get cmm object from md_object */
static inline struct cmm_object *md2cmm_obj(struct md_object *o)
{
return lu2md(lu_object_next(&o->cmo_obj.mo_lu));
}
-/* cmm device */
-int cmm_add_mdc(struct cmm_device *, struct lustre_cfg *);
-
/* cmm_object.c */
struct lu_object *cmm_object_alloc(struct lu_context *ctx, struct lu_device *);
void cmm_object_free(struct lu_context *ctx, struct lu_object *o);
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * lustre/cmm/cmm_device.c
- * Lustre Cluster Metadata Manager (cmm)
+ * lustre/cmm/cmm_mdc.c
+ * Lustre Metadata Client (mdc)
*
* Copyright (c) 2006 Cluster File Systems, Inc.
* Author: Mike Pershin <tappro@clusterfs.com>
#endif
#define DEBUG_SUBSYSTEM S_MDS
-#include <linux/module.h>
-
#include <linux/obd.h>
-#include <linux/obd_class.h>
+#include<linux/obd_class.h>
-#include "cmm_internal.h"
+#include "mdc_internal.h"
#include <linux/lprocfs_status.h>
+#include <linux/module.h>
#include <linux/lustre_ver.h>
-int cmm_add_mdc(struct cmm_device * cm, struct lustre_cfg *cfg)
+static struct lu_device_operations mdc_lu_ops;
+
+static inline int lu_device_is_mdc(struct lu_device *ld)
+{
+ /*
+ * XXX for now. Tags in lu_device_type->ldt_something are needed.
+ */
+ return ergo(ld != NULL && ld->ld_ops != NULL,
+ ld->ld_ops == &mdc_lu_ops);
+}
+
+static int mdc_root_get(struct lu_context *ctx, struct md_device *md,
+ struct lu_fid *fid)
+{
+ //struct mdc_device *mdc_dev = md2mdc_dev(md);
+
+ return -EOPNOTSUPP;
+}
+
+static int mdc_config(struct lu_context *ctxt,
+ struct md_device *md, const char *name,
+ void *buf, int size, int mode)
+{
+ //struct mdc_device *mdc_dev = md2mdc_dev(md);
+ int rc;
+ ENTRY;
+ rc = -EOPNOTSUPP;
+ RETURN(rc);
+}
+
+static int mdc_statfs(struct lu_context *ctxt,
+ struct md_device *md, struct kstatfs *sfs) {
+ //struct mdc_device *mdc_dev = md2mdc_dev(md);
+ int rc;
+
+ ENTRY;
+ rc = -EOPNOTSUPP;
+ RETURN (rc);
+}
+
+static struct md_device_operations mdc_md_ops = {
+ .mdo_root_get = mdc_root_get,
+ .mdo_config = mdc_config,
+ .mdo_statfs = mdc_statfs
+};
+
+static int mdc_process_config(struct lu_device *ld, struct lustre_cfg *cfg)
{
- const char *mdc = lustre_cfg_string(cfg, 1);
+ struct mdc_device *mc = lu2mdc_dev(ld);
const char *index = lustre_cfg_string(cfg, 2);
+ int rc;
+
+ ENTRY;
+ switch (cfg->lcfg_command) {
+ case LCFG_ADD_MDC:
+ mc->mc_num = simple_strtol(index, NULL, 10);
+ rc = 0;
+ break;
+ default:
+ rc = -EOPNOTSUPP;
+ }
+ RETURN(rc);
+}
+
+static struct lu_device_operations mdc_lu_ops = {
+ .ldo_object_alloc = mdc_object_alloc,
+ .ldo_object_free = mdc_object_free,
+
+ .ldo_process_config = mdc_process_config
+};
+
+static int mdc_device_init(struct lu_device *ld, struct lu_device *next)
+{
+ struct mdc_device *mc = lu2mdc_dev(ld);
+ struct mdc_cli_desc *desc = &mc->mc_desc;
+ struct obd_device *obd = ld->ld_obd;
+ int rc = 0;
+ struct obd_import *imp;
+ int rq_portal, rp_portal, connect_op;
ENTRY;
+
+ //sema_init(&desc->cl_rpcl_sem, 1);
+ ptlrpcd_addref();
+
+ rq_portal = MDS_REQUEST_PORTAL;
+ rp_portal = MDC_REPLY_PORTAL;
+ connect_op = MDS_CONNECT;
+ rc = ldlm_get_ref();
+ if (rc != 0) {
+ CERROR("ldlm_get_ref failed: %d\n", rc);
+ GOTO(err, rc);
+ }
+
+ ptlrpc_init_client(rq_portal, rp_portal, obd->obd_type->typ_name,
+ &desc->cl_ldlm_client);
+
+ imp = class_new_import(obd);
+ if (imp == NULL)
+ GOTO(err_ldlm, rc = -ENOENT);
+
+ imp->imp_client = &desc->cl_ldlm_client;
+ imp->imp_connect_op = connect_op;
+ imp->imp_initial_recov = 1;
+ imp->imp_initial_recov_bk = 0;
+ INIT_LIST_HEAD(&imp->imp_pinger_chain);
+ class_import_put(imp);
+ rc = client_import_add_conn(imp, &desc->cl_server_uuid, 1);
+ if (rc) {
+ CERROR("can't add initial connection\n");
+ GOTO(err_import, rc);
+ }
+
+ desc->cl_import = imp;
+
+ //TODO other initializations
- CDEBUG(D_INFO, "Add new MDC %s index %s\n", mdc, index);
RETURN(0);
+
+err_import:
+ class_destroy_import(imp);
+err_ldlm:
+ ldlm_put_ref(0);
+err:
+ ptlrpcd_decref();
+ RETURN(rc);
+}
+
+static struct lu_device *mdc_device_fini(struct lu_device *ld)
+{
+ struct mdc_device *mc = lu2mdc_dev(ld);
+ struct mdc_cli_desc *desc = &mc->mc_desc;
+
+ ENTRY;
+
+ class_destroy_import(desc->cl_import);
+ //TODO: force param
+ ldlm_put_ref(1);
+ ptlrpcd_decref();
+
+ RETURN (NULL);
}
+
+struct lu_device *mdc_device_alloc(struct lu_device_type *ldt,
+ struct lustre_cfg *cfg)
+{
+ struct lu_device *ld;
+ struct mdc_device *mc;
+
+ ENTRY;
+
+ OBD_ALLOC_PTR(mc);
+ if (mc == NULL) {
+ ld = ERR_PTR(-ENOMEM);
+ } else {
+ md_device_init(&mc->mc_md_dev, ldt);
+ mc->mc_md_dev.md_ops = &mdc_md_ops;
+ ld = mdc2lu_dev(mc);
+ ld->ld_ops = &mdc_lu_ops;
+ memcpy(mc->mc_desc.cl_server_uuid.uuid,
+ lustre_cfg_buf(cfg, 2),
+ min_t(unsigned int, LUSTRE_CFG_BUFLEN(cfg, 2),
+ sizeof(struct obd_uuid)));
+ memcpy(mc->mc_desc.cl_target_uuid.uuid,
+ lustre_cfg_buf(cfg, 1),
+ min_t(unsigned int, LUSTRE_CFG_BUFLEN(cfg, 1),
+ sizeof(struct obd_uuid)));
+
+ }
+
+ RETURN (ld);
+}
+
+void mdc_device_free(struct lu_device *ld)
+{
+ struct mdc_device *mc = lu2mdc_dev(ld);
+
+ LASSERT(atomic_read(&ld->ld_ref) == 0);
+ md_device_fini(&mc->mc_md_dev);
+ OBD_FREE_PTR(mc);
+}
+
+int mdc_type_init(struct lu_device_type *ldt)
+{
+ return 0;
+}
+
+void mdc_type_fini(struct lu_device_type *ldt)
+{
+ return;
+}
+
+static struct lu_device_type_operations mdc_device_type_ops = {
+ .ldto_init = mdc_type_init,
+ .ldto_fini = mdc_type_fini,
+
+ .ldto_device_alloc = mdc_device_alloc,
+ .ldto_device_free = mdc_device_free,
+
+ .ldto_device_init = mdc_device_init,
+ .ldto_device_fini = mdc_device_fini
+};
+
+struct lu_device_type mdc_device_type = {
+ .ldt_tags = LU_DEVICE_MD,
+ .ldt_name = LUSTRE_MDC0_NAME,
+ .ldt_ops = &mdc_device_type_ops
+};
+
+static struct obd_ops mdc0_obd_device_ops = {
+ .o_owner = THIS_MODULE
+};
+
+struct lprocfs_vars lprocfs_mdc0_obd_vars[] = {
+ { 0 }
+};
+
+struct lprocfs_vars lprocfs_mdc0_module_vars[] = {
+ { 0 }
+};
+
+LPROCFS_INIT_VARS(mdc0, lprocfs_mdc0_module_vars, lprocfs_mdc0_obd_vars);
+
+static int __init mdc0_mod_init(void)
+{
+ struct lprocfs_static_vars lvars;
+
+ printk(KERN_INFO "Lustre: Metadata Client; info@clusterfs.com\n");
+
+ lprocfs_init_vars(mdc0, &lvars);
+ return class_register_type(&mdc0_obd_device_ops, NULL,
+ lvars.module_vars, LUSTRE_MDC0_NAME,
+ &mdc_device_type);
+}
+
+static void __exit mdc0_mod_exit(void)
+{
+ class_unregister_type(LUSTRE_MDC0_NAME);
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre Metadata Client Prototype ("LUSTRE_MDC0_NAME")");
+MODULE_LICENSE("GPL");
+
+cfs_module(mdc, "0.0.1", mdc0_mod_init, mdc0_mod_exit);
#define DEBUG_SUBSYSTEM S_MDS
#include "cmm_internal.h"
+#include "mdc_internal.h"
static struct md_object_operations cmm_mo_ops;
static struct md_dir_operations cmm_dir_ops;
/* get child device by mdsnum*/
static struct lu_device *cmm_get_child(struct cmm_device *d, __u32 num)
{
- struct lu_device *next;
+ struct lu_device *next = NULL;
- if (likely(num != d->local_num)) {
+ if (likely(num == d->cmm_local_num)) {
next = &d->cmm_child->md_lu_dev;
} else {
- next = &d->cmm_child->md_lu_dev;
+ struct mdc_device *mdc;
+ list_for_each_entry(mdc, &d->cmm_targets, mc_linkage) {
+ if (mdc->mc_num == num) {
+ next = mdc2lu_dev(mdc);
+ break;
+ }
+ }
}
return next;
}
/* under device can be MDD or MDC */
mdsnum = cmm_fld_lookup(fid);
under = cmm_get_child(d, mdsnum);
+ if (under == NULL)
+ RETURN(-ENOENT);
below = under->ld_ops->ldo_object_alloc(ctxt, under);
if (below != NULL) {
+ struct cmm_object *co = lu2cmm_obj(o);
+
lu_object_add(o, below);
+ co->cmo_num = mdsnum;
RETURN(0);
} else
RETURN(-ENOMEM);
return seq_printf(f, LUSTRE_CMM0_NAME"-object@%p", o);
}
-/* Locking API */
-#if 0
-static void cmm_lock(struct lu_context *ctxt, struct md_object *obj, __u32 mode)
-{
- struct cmm_object *cmm_obj = md2cmm_obj(obj);
- struct cmm_device *cmm_dev = cmm_obj2dev(cmm_obj);
- struct md_object *next = cmm2child_obj(cmm_obj);
-
- next->mo_ops->moo_object_lock(ctxt, next, mode);
-}
-
-static void cmm_unlock(struct lu_context *ctxt,
- struct md_object *obj, __u32 mode)
-{
- struct cmm_object *cmm_obj = md2cmm_obj(obj);
- struct cmm_device *cmm_dev = cmm_obj2dev(cmm_obj);
- struct md_object *next = cmm2child_obj(cmm_obj);
-
- next->mo_ops->moo_object_unlock(ctxt, next, mode);
-}
-#endif
-/* Llog API */
-/* Object API */
/* Metadata API */
int cmm_root_get(struct lu_context *ctx,
struct md_device *md, struct lu_fid *fid)
RETURN (result);
}
-int cmm_mkdir(struct lu_context *ctxt, struct lu_attr* attr,
- struct md_object *md_parent,
- const char *name, struct md_object *md_child)
+int cmm_mkdir(struct lu_context *ctxt, struct lu_attr *attr,
+ struct md_object *p, const char *name, struct md_object *c)
{
- struct cmm_object *cmm_parent = md2cmm_obj(md_parent);
- struct md_object *next = cmm2child_obj(cmm_parent);
+ struct cmm_object *cmm_p = md2cmm_obj(p);
+ struct cmm_object *cmm_c = md2cmm_obj(c);
+ struct md_object *local = cmm2child_obj(cmm_p);
+ int result;
- return next->mo_dir_ops->mdo_mkdir(ctxt, attr, next, name, md_child);
+ if (cmm_is_local_obj(cmm_c)) {
+ /* fully local mkdir */
+ result = local->mo_dir_ops->mdo_mkdir(ctxt, attr, local, name,
+ cmm2child_obj(cmm_c));
+ } else {
+ /* remote object creation and local name insert */
+ result = -EOPNOTSUPP;
+ }
+
+ RETURN(result);
}
int cmm_attr_get(struct lu_context *ctxt, struct md_object *obj,
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2006 Cluster File Systems, Inc.
+ *
+ * This file is part of Lustre, http://www.lustre.org.
+ *
+ * Lustre is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Lustre; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _CMM_MDC_INTERNAL_H
+#define _CMM_MDC_INTERNAL_H
+
+#if defined(__KERNEL__)
+
+#include <linux/obd.h>
+#include <linux/md_object.h>
+
+struct mdc_cli_desc {
+ struct obd_connect_data cl_conn_data;
+ struct semaphore cl_rpcl_sem;
+ struct ptlrpc_client cl_ldlm_client;
+ struct obd_uuid cl_server_uuid;
+ struct obd_uuid cl_target_uuid;
+ struct obd_import *cl_import;
+};
+
+struct mdc_device {
+ struct md_device mc_md_dev;
+ /* other MD servers in cluster */
+ struct list_head mc_linkage;
+ __u32 mc_num;
+ struct mdc_cli_desc mc_desc;
+};
+
+struct mdc_object {
+ struct md_object mco_obj;
+};
+
+static inline struct lu_device *mdc2lu_dev(struct mdc_device *mc)
+{
+ return (&mc->mc_md_dev.md_lu_dev);
+}
+
+static inline struct mdc_device *md2mdc_dev(struct md_device *md)
+{
+ return container_of0(md, struct mdc_device, mc_md_dev);
+}
+
+static inline struct mdc_device *mdc_obj2dev(struct mdc_object *mco)
+{
+ return (md2mdc_dev(md_device_get(&mco->mco_obj)));
+}
+
+static inline struct mdc_object *lu2mdc_obj(struct lu_object *lo)
+{
+ return container_of0(lo, struct mdc_object, mco_obj.mo_lu);
+}
+
+static inline struct mdc_object *md2mdc_obj(struct md_object *mo)
+{
+ return container_of0(mo, struct mdc_object, mco_obj);
+}
+
+static inline struct mdc_device *lu2mdc_dev(struct lu_device *ld)
+{
+ return container_of0(ld, struct mdc_device, mc_md_dev.md_lu_dev);
+}
+
+int mdc_object_init(struct lu_context *, struct lu_object*);
+struct lu_object *mdc_object_alloc(struct lu_context *, struct lu_device *);
+void mdc_object_free(struct lu_context *, struct lu_object *);
+void mdc_object_release(struct lu_context *, struct lu_object *);
+
+#endif /* __KERNEL__ */
+#endif /* _CMM_MDC_INTERNAL_H */
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre/cmm/mdc_object.c
+ * Lustre Cluster Metadata Manager (cmm)
+ *
+ * Copyright (c) 2006 Cluster File Systems, Inc.
+ * Author: Mike Pershin <tappro@clusterfs.com>
+ *
+ * This file is part of the Lustre file system, http://www.lustre.org
+ * Lustre is a trademark of Cluster File Systems, Inc.
+ *
+ * You may have signed or agreed to another license before downloading
+ * this software. If so, you are bound by the terms and conditions
+ * of that agreement, and the following does not apply to you. See the
+ * LICENSE file included with this distribution for more information.
+ *
+ * If you did not agree to a different license, then this copy of Lustre
+ * is open source software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In either case, Lustre is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * license text for more details.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include "mdc_internal.h"
+
+static struct md_object_operations mdc_mo_ops;
+static struct md_dir_operations mdc_dir_ops;
+static struct lu_object_operations mdc_obj_ops;
+
+struct lu_object *mdc_object_alloc(struct lu_context *ctx,
+ struct lu_device *ld)
+{
+ struct mdc_object *mco;
+ ENTRY;
+
+ OBD_ALLOC_PTR(mco);
+ if (mco != NULL) {
+ struct lu_object *lo;
+
+ lo = &mco->mco_obj.mo_lu;
+ lu_object_init(lo, NULL, ld);
+ mco->mco_obj.mo_ops = &mdc_mo_ops;
+ mco->mco_obj.mo_dir_ops = &mdc_dir_ops;
+ lo->lo_ops = &mdc_obj_ops;
+ RETURN(lo);
+ } else
+ RETURN(NULL);
+}
+
+int mdc_object_init(struct lu_context *ctxt, struct lu_object *lo)
+{
+ //struct mdc_device *d = lu2mdc_dev(o->lo_dev);
+ //struct lu_device *under;
+ //struct lu_fid *fid = &o->lo_header->loh_fid;
+
+ ENTRY;
+
+ RETURN(0);
+}
+
+void mdc_object_free(struct lu_context *ctx, struct lu_object *lo)
+{
+ struct mdc_object *mco = lu2mdc_obj(lo);
+ lu_object_fini(lo);
+ OBD_FREE_PTR(mco);
+}
+
+void mdc_object_release(struct lu_context *ctxt, struct lu_object *lo)
+{
+ return;
+}
+
+static int mdc_object_exists(struct lu_context *ctx, struct lu_object *lo)
+{
+ return 0;
+}
+
+static int mdc_object_print(struct lu_context *ctx,
+ struct seq_file *f, const struct lu_object *lo)
+{
+ return seq_printf(f, LUSTRE_MDC0_NAME"-object@%p", lo);
+}
+
+static struct md_dir_operations mdc_dir_ops = {
+};
+
+static struct md_object_operations mdc_mo_ops = {
+};
+
+static struct lu_object_operations mdc_obj_ops = {
+ .loo_object_init = mdc_object_init,
+ .loo_object_release = mdc_object_release,
+ .loo_object_print = mdc_object_print,
+ .loo_object_exists = mdc_object_exists
+};
+