1 /* -*- MODE: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Lustre Metadata Server (mdd) routines
7 * Copyright (C) 2006 Cluster File Systems, Inc.
8 * Author: Wang Di <wangdi@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.
29 # define EXPORT_SYMTAB
31 #define DEBUG_SUBSYSTEM S_MDS
33 #include <linux/module.h>
35 #include <linux/obd.h>
36 #include <linux/obd_class.h>
37 #include <linux/lustre_ver.h>
38 #include <linux/obd_support.h>
39 #include <linux/lprocfs_status.h>
42 #include <linux/lu_object.h>
43 #include <linux/md_object.h>
44 #include <linux/dt_object.h>
46 #include "mdd_internal.h"
49 static struct thandle* mdd_trans_start(struct lu_context *ctxt,
52 static void mdd_trans_stop(struct lu_context *ctxt,
53 struct mdd_device *mdd, struct thandle *handle);
54 static struct dt_object* mdd_object_child(struct mdd_object *o);
55 static struct lu_device_operations mdd_lu_ops;
56 static void mdd_lock(struct lu_context *ctx,
57 struct mdd_object *obj, enum dt_lock_mode mode);
58 static void mdd_unlock(struct lu_context *ctx,
59 struct mdd_object *obj, enum dt_lock_mode mode);
61 static struct md_object_operations mdd_obj_ops;
62 static struct md_dir_operations mdd_dir_ops;
63 static struct lu_object_operations mdd_lu_obj_ops;
65 static struct lu_context_key mdd_thread_key;
67 struct mdd_thread_info {
68 struct txn_param mti_param;
71 static struct mdd_thread_info *mdd_ctx_info(struct lu_context *ctx)
73 struct mdd_thread_info *info;
75 info = lu_context_key_get(ctx, &mdd_thread_key);
76 LASSERT(info != NULL);
80 static int lu_device_is_mdd(struct lu_device *d)
83 * XXX for now. Tags in lu_device_type->ldt_something are needed.
85 return ergo(d != NULL && d->ld_ops != NULL, d->ld_ops == &mdd_lu_ops);
88 static struct mdd_device* lu2mdd_dev(struct lu_device *d)
90 LASSERT(lu_device_is_mdd(d));
91 return container_of0(d, struct mdd_device, mdd_md_dev.md_lu_dev);
94 static inline struct lu_device *mdd2lu_dev(struct mdd_device *d)
96 return (&d->mdd_md_dev.md_lu_dev);
99 static struct mdd_object *mdd_obj(struct lu_object *o)
101 LASSERT(lu_device_is_mdd(o->lo_dev));
102 return container_of0(o, struct mdd_object, mod_obj.mo_lu);
105 static struct mdd_device* mdo2mdd(struct md_object *mdo)
107 return lu2mdd_dev(mdo->mo_lu.lo_dev);
110 static struct mdd_object* mdo2mddo(struct md_object *mdo)
112 return container_of0(mdo, struct mdd_object, mod_obj);
115 static inline struct dt_device_operations *mdd_child_ops(struct mdd_device *d)
117 return d->mdd_child->dd_ops;
120 static struct lu_object *mdd_object_alloc(struct lu_context *ctxt,
123 struct mdd_object *mdo;
130 o = &mdo->mod_obj.mo_lu;
131 lu_object_init(o, NULL, d);
132 mdo->mod_obj.mo_ops = &mdd_obj_ops;
133 mdo->mod_obj.mo_dir_ops = &mdd_dir_ops;
134 o->lo_ops = &mdd_lu_obj_ops;
135 return &mdo->mod_obj.mo_lu;
140 static int mdd_object_init(struct lu_context *ctxt, struct lu_object *o)
142 struct mdd_device *d = lu2mdd_dev(o->lo_dev);
143 struct lu_object *below;
144 struct lu_device *under;
147 under = &d->mdd_child->dd_lu_dev;
148 below = under->ld_ops->ldo_object_alloc(ctxt, under);
153 lu_object_add(o, below);
157 static void mdd_object_free(struct lu_context *ctxt, struct lu_object *o)
159 struct lu_object_header *h;
160 struct mdd_object *mdd = mdd_obj(o);
168 mdd_attr_get(struct lu_context *ctxt,
169 struct md_object *obj, struct lu_attr *attr)
171 struct mdd_object *mdd_obj = mdo2mddo(obj);
172 struct dt_object *next = mdd_object_child(mdd_obj);
177 rc = next->do_ops->do_attr_get(ctxt, next, attr);
182 mdd_xattr_get(struct lu_context *ctxt, struct md_object *obj, void *buf,
183 int buf_len, const char *name)
185 struct mdd_object *mdd_obj = mdo2mddo(obj);
186 struct dt_object *next = mdd_object_child(mdd_obj);
191 rc = next->do_ops->do_xattr_get(ctxt, next, buf, buf_len, name);
196 __mdd_object_destroy(struct lu_context *ctxt, struct mdd_object *obj,
197 struct thandle *handle)
199 struct dt_object *next = mdd_object_child(obj);
201 rc = next->do_ops->do_object_destroy(ctxt, next, handle);
205 static int mdd_add_orphan(struct mdd_device *mdd, struct mdd_object *obj,
206 struct thandle *handle)
215 open_orphan(struct mdd_object *obj)
221 mdd_add_unlink_log(struct mdd_device *mdd, struct mdd_object *obj,
222 struct thandle *handle)
228 * number of blocks to reserve for particular operations. Should be function
229 * of ... something. Stub for now.
232 MDD_OBJECT_DESTROY_CREDITS = 10,
233 MDD_OBJECT_CREATE_CREDITS = 10,
234 MDD_ATTR_SET_CREDITS = 10,
235 MDD_XATTR_SET_CREDITS = 10,
236 MDD_INDEX_INSERT_CREDITS = 10,
237 MDD_INDEX_DELETE_CREDITS = 10,
238 MDD_LINK_CREDITS = 10,
239 MDD_RENAME_CREDITS = 10,
240 MDD_MKDIR_CREDITS = 10
244 mdd_object_destroy(struct lu_context *ctxt, struct md_object *obj)
246 struct mdd_device *mdd = mdo2mdd(obj);
247 struct mdd_object *mdd_obj = mdo2mddo(obj);
248 struct thandle *handle;
252 handle = mdd_trans_start(ctxt, mdd,
254 * TXN_PARAM should probably go into
255 * lu_context_key to reduce stack
256 * consumption. Currently this is just one
259 &TXN_PARAM(MDD_OBJECT_DESTROY_CREDITS));
261 RETURN(PTR_ERR(handle));
263 mdd_lock(ctxt, mdd_obj, DT_WRITE_LOCK);
264 if (open_orphan(mdd_obj))
265 rc = mdd_add_orphan(mdd, mdd_obj, handle);
267 rc = __mdd_object_destroy(ctxt, mdd_obj, handle);
269 rc = mdd_add_unlink_log(mdd, mdd_obj, handle);
272 mdd_unlock(ctxt, mdd_obj, DT_WRITE_LOCK);
273 mdd_trans_stop(ctxt, mdd, handle);
277 static void mdd_object_release(struct lu_context *ctxt, struct lu_object *o)
281 static int mdd_object_exists(struct lu_context *ctx, struct lu_object *o)
283 return lu_object_exists(ctx, lu_object_next(o));
286 static int mdd_object_print(struct lu_context *ctxt,
287 struct seq_file *f, const struct lu_object *o)
289 return seq_printf(f, LUSTRE_MDD0_NAME"-object@%p", o);
292 static int mdd_fs_setup(struct lu_context *ctx, struct mdd_device *mdd)
297 static int mdd_fs_cleanup(struct mdd_device *mdd)
302 static int mdd_device_init(struct lu_context *ctx,
303 struct lu_device *d, struct lu_device *next)
305 struct mdd_device *mdd = lu2mdd_dev(d);
310 mdd->mdd_child = lu2dt_dev(next);
312 rc = mdd_fs_setup(ctx, mdd);
322 static struct lu_device *mdd_device_fini(struct lu_context *ctx,
325 struct mdd_device *m = lu2mdd_dev(d);
326 struct lu_device *next = &m->mdd_child->dd_lu_dev;
331 static int mdd_process_config(struct lu_context *ctx,
332 struct lu_device *d, struct lustre_cfg *cfg)
334 struct mdd_device *m = lu2mdd_dev(d);
335 struct lu_device *next = &m->mdd_child->dd_lu_dev;
338 switch(cfg->lcfg_command) {
341 err = next->ld_ops->ldo_process_config(ctx, next, cfg);
347 static struct lu_device_operations mdd_lu_ops = {
348 .ldo_object_alloc = mdd_object_alloc,
349 .ldo_object_free = mdd_object_free,
350 .ldo_process_config = mdd_process_config
353 static struct lu_object_operations mdd_lu_obj_ops = {
354 .loo_object_init = mdd_object_init,
355 .loo_object_release = mdd_object_release,
356 .loo_object_print = mdd_object_print,
357 .loo_object_exists = mdd_object_exists
360 static struct dt_object* mdd_object_child(struct mdd_object *o)
362 return container_of0(lu_object_next(&o->mod_obj.mo_lu),
363 struct dt_object, do_lu);
366 static void mdd_lock(struct lu_context *ctxt,
367 struct mdd_object *obj, enum dt_lock_mode mode)
369 struct dt_object *next = mdd_object_child(obj);
371 next->do_ops->do_object_lock(ctxt, next, mode);
374 static void mdd_unlock(struct lu_context *ctxt,
375 struct mdd_object *obj, enum dt_lock_mode mode)
377 struct dt_object *next = mdd_object_child(obj);
379 next->do_ops->do_object_unlock(ctxt, next, mode);
382 static void mdd_lock2(struct lu_context *ctxt,
383 struct mdd_object *o0, struct mdd_object *o1)
385 mdd_lock(ctxt, o0, DT_WRITE_LOCK);
386 mdd_lock(ctxt, o1, DT_WRITE_LOCK);
389 static void mdd_unlock2(struct lu_context *ctxt,
390 struct mdd_object *o0, struct mdd_object *o1)
392 mdd_unlock(ctxt, o0, DT_WRITE_LOCK);
393 mdd_unlock(ctxt, o1, DT_WRITE_LOCK);
396 static struct thandle* mdd_trans_start(struct lu_context *ctxt,
397 struct mdd_device *mdd,
400 return mdd_child_ops(mdd)->dt_trans_start(ctxt, mdd->mdd_child, p);
403 static void mdd_trans_stop(struct lu_context *ctxt,
404 struct mdd_device *mdd, struct thandle *handle)
406 mdd_child_ops(mdd)->dt_trans_stop(ctxt, handle);
410 __mdd_object_create(struct lu_context *ctxt, struct mdd_object *obj,
411 struct lu_attr *attr, struct thandle *handle)
413 struct dt_object *next = mdd_object_child(obj);
417 rc = next->do_ops->do_object_create(ctxt, next, attr, handle);
418 /*XXX increase the refcount of the object or not?*/
422 static int mdd_object_create(struct lu_context *ctxt, struct md_object *obj,
423 struct lu_attr *attr)
426 struct mdd_device *mdd = mdo2mdd(obj);
427 struct thandle *handle;
431 handle = mdd_trans_start(ctxt, mdd,
432 &TXN_PARAM(MDD_OBJECT_CREATE_CREDITS));
434 RETURN(PTR_ERR(handle));
436 rc = __mdd_object_create(ctxt, mdo2mddo(obj), attr, handle);
438 mdd_trans_stop(ctxt, mdd, handle);
445 __mdd_attr_set(struct lu_context *ctxt, struct md_object *obj,
446 struct lu_attr *attr, struct thandle *handle)
448 struct dt_object *next = mdd_object_child(mdo2mddo(obj));
449 return next->do_ops->do_attr_set(ctxt, next, attr, handle);
453 mdd_attr_set(struct lu_context *ctxt,
454 struct md_object *obj, struct lu_attr *attr)
456 struct mdd_device *mdd = mdo2mdd(obj);
457 struct thandle *handle;
461 handle = mdd_trans_start(ctxt, mdd, &TXN_PARAM(MDD_ATTR_SET_CREDITS));
465 rc = __mdd_attr_set(ctxt, obj, attr, handle);
467 mdd_trans_stop(ctxt, mdd, handle);
475 __mdd_xattr_set(struct lu_context *ctxt, struct mdd_device *mdd,
476 struct mdd_object *obj, void *buf,
477 int buf_len, const char *name, struct thandle *handle)
479 struct dt_object *next = mdd_object_child(obj);
480 return next->do_ops->do_xattr_set(ctxt, next, buf, buf_len,
485 mdd_xattr_set(struct lu_context *ctxt, struct md_object *obj, void *buf,
486 int buf_len, const char *name)
488 struct mdd_device *mdd = mdo2mdd(obj);
489 struct thandle *handle;
493 handle = mdd_trans_start(ctxt, mdd, &TXN_PARAM(MDD_XATTR_SET_CREDITS));
497 rc = __mdd_xattr_set(ctxt, mdd, mdo2mddo(obj), buf, buf_len, name,
500 mdd_trans_stop(ctxt, mdd, handle);
505 static const struct lu_fid *mdd_object_getfid(struct mdd_object *obj)
507 return lu_object_fid(&obj->mod_obj.mo_lu);
511 __mdd_index_insert(struct lu_context *ctxt, struct mdd_object *pobj,
512 const struct lu_fid *lf, const char *name,
513 struct thandle *handle)
516 struct dt_object *next = mdd_object_child(pobj);
518 rc = next->do_index_ops->dio_insert(ctxt, next, (struct dt_rec *)lf,
519 (struct dt_key *)name, handle);
524 __mdd_index_delete(struct lu_context *ctxt, struct mdd_device *mdd,
525 struct mdd_object *pobj,
526 struct mdd_object *obj, const char *name,
527 struct thandle *handle)
530 struct dt_object *next = mdd_object_child(pobj);
533 mdd_lock2(ctxt, pobj, obj);
535 rc = next->do_index_ops->dio_delete(ctxt, next,
536 (const struct dt_rec *)mdd_object_getfid(obj),
537 (struct dt_key *)name, handle);
538 mdd_unlock2(ctxt, pobj, obj);
544 mdd_index_delete(struct lu_context *ctxt, struct md_object *pobj,
545 struct md_object *obj, const char *name)
547 struct mdd_object *mdd_pobj = mdo2mddo(pobj);
548 struct mdd_object *mdd_obj = mdo2mddo(obj);
549 struct mdd_device *mdd = mdo2mdd(obj);
550 struct thandle *handle;
554 handle = mdd_trans_start(ctxt, mdd,
555 &TXN_PARAM(MDD_INDEX_DELETE_CREDITS));
557 RETURN(PTR_ERR(handle));
559 rc = __mdd_index_delete(ctxt, mdd, mdd_pobj, mdd_obj, name, handle);
561 mdd_trans_stop(ctxt, mdd, handle);
567 mdd_link(struct lu_context *ctxt, struct md_object *tgt_obj,
568 struct md_object *src_obj, const char *name)
570 struct mdd_object *mdd_tobj = mdo2mddo(tgt_obj);
571 struct mdd_object *mdd_sobj = mdo2mddo(src_obj);
572 struct mdd_device *mdd = mdo2mdd(src_obj);
573 struct thandle *handle;
577 handle = mdd_trans_start(ctxt, mdd, &TXN_PARAM(MDD_LINK_CREDITS));
579 RETURN(PTR_ERR(handle));
581 mdd_lock2(ctxt, mdd_tobj, mdd_sobj);
583 rc = __mdd_index_insert(ctxt, mdd_tobj, lu_object_fid(&src_obj->mo_lu),
588 rc = mdd_xattr_get(ctxt, src_obj, &nlink, sizeof(nlink), "NLINK");
591 rc = __mdd_xattr_set(ctxt, mdd, mdd_sobj,
592 &nlink, sizeof(nlink), "NLINK", handle);
594 mdd_unlock2(ctxt, mdd_tobj, mdd_sobj);
596 mdd_trans_stop(ctxt, mdd, handle);
600 static void mdd_rename_lock(struct mdd_device *mdd, struct mdd_object *src_pobj,
601 struct mdd_object *tgt_pobj, struct mdd_object *sobj,
602 struct mdd_object *tobj)
607 static void mdd_rename_unlock(struct mdd_device *mdd, struct mdd_object *src_pobj,
608 struct mdd_object *tgt_pobj, struct mdd_object *sobj,
609 struct mdd_object *tobj)
615 mdd_rename(struct lu_context *ctxt, struct md_object *src_pobj,
616 struct md_object *tgt_pobj, struct md_object *sobj,
617 const char *sname, struct md_object *tobj, const char *tname)
619 struct mdd_device *mdd = mdo2mdd(src_pobj);
620 struct mdd_object *mdd_spobj = mdo2mddo(src_pobj);
621 struct mdd_object *mdd_tpobj = mdo2mddo(tgt_pobj);
622 struct mdd_object *mdd_sobj = mdo2mddo(sobj);
623 struct mdd_object *mdd_tobj = mdo2mddo(tobj);
625 struct thandle *handle;
627 handle = mdd_trans_start(ctxt, mdd, &TXN_PARAM(MDD_RENAME_CREDITS));
629 RETURN(PTR_ERR(handle));
631 mdd_rename_lock(mdd, mdd_spobj, mdd_tpobj, mdd_sobj, mdd_tobj);
633 rc = __mdd_index_delete(ctxt, mdd, mdd_spobj, mdd_sobj, sname, handle);
637 rc = __mdd_index_delete(ctxt, mdd, mdd_tpobj, mdd_tobj, tname, handle);
641 rc = __mdd_index_insert(ctxt, mdd_spobj, lu_object_fid(&tobj->mo_lu),
647 * XXX nikita: huh? What is this?
649 rc = __mdd_object_destroy(ctxt, mdd_sobj, handle);
653 mdd_rename_unlock(mdd, mdd_spobj, mdd_tpobj, mdd_sobj, mdd_tobj);
654 mdd_trans_stop(ctxt, mdd, handle);
658 static int mdd_mkdir(struct lu_context *ctxt, struct lu_attr* attr,
659 struct md_object *pobj, const char *name,
660 struct md_object *child)
662 struct mdd_device *mdd = mdo2mdd(pobj);
663 struct mdd_object *mdo = mdo2mddo(pobj);
664 struct thandle *handle;
668 handle = mdd_trans_start(ctxt, mdd, &TXN_PARAM(MDD_MKDIR_CREDITS));
670 RETURN(PTR_ERR(handle));
672 mdd_lock(ctxt, mdo, DT_WRITE_LOCK);
674 rc = __mdd_object_create(ctxt, mdo2mddo(child), attr, handle);
678 rc = __mdd_index_insert(ctxt, mdo, lu_object_fid(&child->mo_lu),
683 mdd_unlock(ctxt, mdo, DT_WRITE_LOCK);
684 mdd_trans_stop(ctxt, mdd, handle);
688 static int mdd_mkname(struct lu_context *ctxt, struct md_object *pobj,
689 const char *name, const struct lu_fid *fid, struct lu_attr *attr)
691 struct mdd_device *mdd = mdo2mdd(pobj);
692 struct mdd_object *mdo = mdo2mddo(pobj);
693 struct thandle *handle;
697 handle = mdd_trans_start(ctxt, mdd,
698 &TXN_PARAM(MDD_INDEX_INSERT_CREDITS));
700 RETURN(PTR_ERR(handle));
702 mdd_lock(ctxt, mdo, DT_WRITE_LOCK);
704 rc = __mdd_index_insert(ctxt, mdo, fid, name, handle);
706 mdd_unlock(ctxt, mdo, DT_WRITE_LOCK);
707 mdd_trans_stop(ctxt, mdd, handle);
711 static int mdd_root_get(struct lu_context *ctx,
712 struct md_device *m, struct lu_fid *f)
714 struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
717 RETURN(mdd_child_ops(mdd)->dt_root_get(ctx, mdd->mdd_child, f));
720 static int mdd_config(struct lu_context *ctx, struct md_device *m,
721 const char *name, void *buf, int size, int mode)
723 struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
727 rc = mdd_child_ops(mdd)->dt_config(ctx, mdd->mdd_child,
728 name, buf, size, mode);
732 static int mdd_statfs(struct lu_context *ctx,
733 struct md_device *m, struct kstatfs *sfs) {
734 struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
739 rc = mdd_child_ops(mdd)->dt_statfs(ctx, mdd->mdd_child, sfs);
744 struct md_device_operations mdd_ops = {
745 .mdo_root_get = mdd_root_get,
746 .mdo_config = mdd_config,
747 .mdo_statfs = mdd_statfs,
750 static struct md_dir_operations mdd_dir_ops = {
751 .mdo_mkdir = mdd_mkdir,
752 .mdo_rename = mdd_rename,
753 .mdo_link = mdd_link,
754 .mdo_name_insert = mdd_mkname
757 static struct md_object_operations mdd_obj_ops = {
758 .moo_attr_get = mdd_attr_get,
759 .moo_attr_set = mdd_attr_set,
760 .moo_xattr_get = mdd_xattr_get,
761 .moo_xattr_set = mdd_xattr_set,
762 .moo_object_create = mdd_object_create
765 static struct obd_ops mdd_obd_device_ops = {
766 .o_owner = THIS_MODULE
769 struct lu_device *mdd_device_alloc(struct lu_device_type *t,
770 struct lustre_cfg *lcfg)
773 struct mdd_device *m;
777 l = ERR_PTR(-ENOMEM);
779 md_device_init(&m->mdd_md_dev, t);
781 l->ld_ops = &mdd_lu_ops;
782 m->mdd_md_dev.md_ops = &mdd_ops;
788 static void mdd_device_free(struct lu_device *lu)
790 struct mdd_device *m = lu2mdd_dev(lu);
792 LASSERT(atomic_read(&lu->ld_ref) == 0);
793 md_device_fini(&m->mdd_md_dev);
798 static int mdd_type_init(struct lu_device_type *t)
800 return lu_context_key_register(&mdd_thread_key);
803 static void mdd_type_fini(struct lu_device_type *t)
805 lu_context_key_degister(&mdd_thread_key);
808 static struct lu_device_type_operations mdd_device_type_ops = {
809 .ldto_init = mdd_type_init,
810 .ldto_fini = mdd_type_fini,
812 .ldto_device_alloc = mdd_device_alloc,
813 .ldto_device_free = mdd_device_free,
815 .ldto_device_init = mdd_device_init,
816 .ldto_device_fini = mdd_device_fini
819 static struct lu_device_type mdd_device_type = {
820 .ldt_tags = LU_DEVICE_MD,
821 .ldt_name = LUSTRE_MDD0_NAME,
822 .ldt_ops = &mdd_device_type_ops
825 static void *mdd_key_init(struct lu_context *ctx)
827 struct mdd_thread_info *info;
831 info = ERR_PTR(-ENOMEM);
835 static void mdd_key_fini(struct lu_context *ctx, void *data)
837 struct mdd_thread_info *info = data;
841 static struct lu_context_key mdd_thread_key = {
842 .lct_init = mdd_key_init,
843 .lct_fini = mdd_key_fini
846 struct lprocfs_vars lprocfs_mdd_obd_vars[] = {
850 struct lprocfs_vars lprocfs_mdd_module_vars[] = {
854 LPROCFS_INIT_VARS(mdd, lprocfs_mdd_module_vars, lprocfs_mdd_obd_vars);
856 static int __init mdd_mod_init(void)
858 struct lprocfs_static_vars lvars;
860 lprocfs_init_vars(mdd, &lvars);
861 return class_register_type(&mdd_obd_device_ops, NULL, lvars.module_vars,
862 LUSTRE_MDD0_NAME, &mdd_device_type);
865 static void __exit mdd_mod_exit(void)
867 class_unregister_type(LUSTRE_MDD0_NAME);
870 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
871 MODULE_DESCRIPTION("Lustre Meta-data Device Prototype ("LUSTRE_MDD0_NAME")");
872 MODULE_LICENSE("GPL");
874 cfs_module(mdd, "0.0.2", mdd_mod_init, mdd_mod_exit);