1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/osd/osd_handler.c
5 * Top-level entry points into osd module
7 * Copyright (c) 2006 Cluster File Systems, Inc.
8 * Author: Nikita Danilov <nikita@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 /* LUSTRE_VERSION_CODE */
37 #include <linux/lustre_ver.h>
39 * XXX temporary stuff: direct access to ldiskfs/jdb. Interface between osd
40 * and file system is not yet specified.
42 /* handle_t, journal_start(), journal_stop() */
43 #include <linux/jbd.h>
45 #include <linux/ldiskfs_fs.h>
47 #include <linux/lvfs.h>
50 * struct OBD_{ALLOC,FREE}*()
53 #include <linux/obd_support.h>
54 /* struct ptlrpc_thread */
55 #include <linux/lustre_net.h>
56 /* LUSTRE_OSD0_NAME */
57 #include <linux/obd.h>
58 /* class_register_type(), class_unregister_type(), class_get_type() */
59 #include <linux/obd_class.h>
60 #include <linux/lustre_disk.h>
63 #include <linux/lustre_fid.h>
64 #include <linux/lustre_iam.h>
66 #include "osd_internal.h"
68 static int osd_root_get (struct lu_context *ctxt,
69 struct dt_device *dev, struct lu_fid *f);
70 static int osd_statfs (struct lu_context *ctxt,
71 struct dt_device *dev, struct kstatfs *sfs);
73 static int lu_device_is_osd (const struct lu_device *d);
74 static void osd_mod_exit (void) __exit;
75 static int osd_mod_init (void) __init;
76 static int osd_type_init (struct lu_device_type *t);
77 static void osd_type_fini (struct lu_device_type *t);
78 static int osd_object_init (struct lu_context *ctxt, struct lu_object *l);
79 static void osd_object_release(struct lu_context *ctxt, struct lu_object *l);
80 static int osd_object_exists (struct lu_context *ctx, struct lu_object *o);
81 static int osd_object_print (struct lu_context *ctx,
82 struct seq_file *f, const struct lu_object *o);
83 static void osd_device_free (struct lu_device *m);
84 static void *osd_key_init (struct lu_context *ctx);
85 static void osd_key_fini (struct lu_context *ctx, void *data);
86 static int osd_has_index (struct osd_object *obj);
87 static void osd_object_init0 (struct osd_object *obj);
88 static int osd_device_init (struct lu_context *ctx,
89 struct lu_device *d, struct lu_device *);
90 static int osd_fid_lookup (struct lu_context *ctx, struct osd_object *obj,
91 const struct lu_fid *fid);
92 static int osd_inode_getattr (struct lu_context *ctx,
93 struct inode *inode, struct lu_attr *attr);
94 static int osd_inode_get_fid (struct osd_device *d, const struct inode *inode,
96 static int osd_param_is_sane (const struct osd_device *dev,
97 const struct txn_param *param);
98 static int osd_index_lookup (struct lu_context *ctxt, struct dt_object *dt,
99 struct dt_rec *rec, const struct dt_key *key);
100 static int osd_index_insert (struct lu_context *ctxt, struct dt_object *dt,
101 const struct dt_rec *rec,
102 const struct dt_key *key,
103 struct thandle *handle);
104 static int osd_index_probe (struct lu_context *ctxt, struct dt_object *dt,
105 const struct dt_index_features *feat);
107 static struct osd_object *osd_obj (const struct lu_object *o);
108 static struct osd_device *osd_dev (const struct lu_device *d);
109 static struct osd_device *osd_dt_dev (const struct dt_device *d);
110 static struct osd_object *osd_dt_obj (const struct dt_object *d);
111 static struct osd_device *osd_obj2dev (struct osd_object *o);
112 static struct lu_device *osd2lu_dev (struct osd_device * osd);
113 static struct lu_device *osd_device_fini (struct lu_context *ctx,
114 struct lu_device *d);
115 static struct lu_device *osd_device_alloc (struct lu_device_type *t,
116 struct lustre_cfg *cfg);
117 static struct lu_object *osd_object_alloc (struct lu_context *ctx,
118 struct lu_device *d);
119 static struct inode *osd_iget (struct osd_thread_info *info,
120 struct osd_device *dev,
121 const struct osd_inode_id *id);
122 static struct super_block *osd_sb (const struct osd_device *dev);
123 static journal_t *osd_journal (const struct osd_device *dev);
125 static struct lu_device_type_operations osd_device_type_ops;
126 static struct lu_device_type osd_device_type;
127 static struct lu_object_operations osd_lu_obj_ops;
128 static struct obd_ops osd_obd_device_ops;
129 static struct lprocfs_vars lprocfs_osd_module_vars[];
130 static struct lprocfs_vars lprocfs_osd_obd_vars[];
131 static struct lu_device_operations osd_lu_ops;
132 static struct lu_context_key osd_key;
133 static struct dt_object_operations osd_obj_ops;
134 static struct dt_body_operations osd_body_ops;
135 static struct dt_index_operations osd_index_ops;
138 struct thandle ot_super;
145 static int osd_root_get(struct lu_context *ctx,
146 struct dt_device *dev, struct lu_fid *f)
148 struct osd_device *d = osd_dt_dev(dev);
150 return osd_inode_get_fid(d, d->od_root_dir->d_inode, f);
155 * OSD object methods.
158 static struct lu_object *osd_object_alloc(struct lu_context *ctx,
161 struct osd_object *mo;
167 l = &mo->oo_dt.do_lu;
168 lu_object_init(l, NULL, d);
169 mo->oo_dt.do_ops = &osd_obj_ops;
170 l->lo_ops = &osd_lu_obj_ops;
171 init_rwsem(&mo->oo_sem);
177 static void osd_object_init0(struct osd_object *obj)
179 LASSERT(obj->oo_inode != NULL);
181 if (osd_has_index(obj))
182 obj->oo_dt.do_index_ops = &osd_index_ops;
184 obj->oo_dt.do_body_ops = &osd_body_ops;
187 static int osd_object_init(struct lu_context *ctxt, struct lu_object *l)
189 struct osd_object *obj = osd_obj(l);
192 result = osd_fid_lookup(ctxt, obj, lu_object_fid(l));
194 if (obj->oo_inode != NULL)
195 osd_object_init0(obj);
200 static void osd_object_free(struct lu_context *ctx, struct lu_object *l)
202 struct osd_object *obj = osd_obj(l);
206 static void osd_object_delete(struct lu_context *ctx, struct lu_object *l)
208 struct osd_object *o = osd_obj(l);
210 if (o->oo_inode != NULL)
214 static int osd_inode_unlinked(const struct inode *inode)
216 return inode->i_nlink == !!S_ISDIR(inode->i_mode);
219 static void osd_object_release(struct lu_context *ctxt, struct lu_object *l)
221 struct osd_object *o = osd_obj(l);
223 if (o->oo_inode != NULL && osd_inode_unlinked(o->oo_inode))
224 set_bit(LU_OBJECT_HEARD_BANSHEE, &l->lo_header->loh_flags);
227 static int osd_object_exists(struct lu_context *ctx, struct lu_object *o)
229 return osd_obj(o)->oo_inode != NULL;
232 static int osd_object_print(struct lu_context *ctx,
233 struct seq_file *f, const struct lu_object *l)
235 struct osd_object *o = osd_obj(l);
237 return seq_printf(f, LUSTRE_OSD0_NAME"-object@%p(i:%p:%lu/%u)",
239 o->oo_inode ? o->oo_inode->i_ino : 0UL,
240 o->oo_inode ? o->oo_inode->i_generation : 0);
243 static int osd_config(struct lu_context *ctx,
244 struct dt_device *d, const char *name,
245 void *buf, int size, int mode)
247 if (mode == LUSTRE_CONFIG_GET) {
248 /* to be continued */
251 /* to be continued */
256 static int osd_statfs(struct lu_context *ctx,
257 struct dt_device *d, struct kstatfs *sfs)
259 struct osd_device *osd = osd_dt_dev(d);
260 struct super_block *sb = osd_sb(osd);
265 memset(sfs, 0, sizeof *sfs);
266 result = sb->s_op->statfs(sb, sfs);
275 static int osd_param_is_sane(const struct osd_device *dev,
276 const struct txn_param *param)
278 return param->tp_credits <= osd_journal(dev)->j_max_transaction_buffers;
281 static struct thandle *osd_trans_start(struct lu_context *ctx,
285 struct osd_device *dev = osd_dt_dev(d);
287 struct osd_thandle *oh;
293 hook_res = dt_txn_hook_start(ctx, d, p);
295 RETURN(ERR_PTR(hook_res));
297 if (osd_param_is_sane(dev, p)) {
301 * XXX temporary stuff. Some abstraction layer should
304 jh = journal_start(osd_journal(dev), p->tp_credits);
309 lu_device_get(&d->dd_lu_dev);
315 th = ERR_PTR(-ENOMEM);
317 CERROR("Invalid transaction parameters\n");
318 th = ERR_PTR(-EINVAL);
324 static void osd_trans_stop(struct lu_context *ctx, struct thandle *th)
327 struct osd_thandle *oh;
331 oh = container_of0(th, struct osd_thandle, ot_super);
332 if (oh->ot_handle != NULL) {
334 * XXX temporary stuff. Some abstraction layer should be used.
336 result = dt_txn_hook_stop(ctx, th->th_dev, th);
338 CERROR("Failure in transaction hook: %d\n", result);
339 result = journal_stop(oh->ot_handle);
341 CERROR("Failure to stop transaction: %d\n", result);
342 oh->ot_handle = NULL;
344 if (th->th_dev != NULL) {
345 lu_device_put(&th->th_dev->dd_lu_dev);
351 static struct dt_device_operations osd_dt_ops = {
352 .dt_root_get = osd_root_get,
353 .dt_config = osd_config,
354 .dt_statfs = osd_statfs,
355 .dt_trans_start = osd_trans_start,
356 .dt_trans_stop = osd_trans_stop,
359 static void osd_object_lock(struct lu_context *ctx, struct dt_object *dt,
360 enum dt_lock_mode mode)
362 struct osd_object *obj = osd_dt_obj(dt);
364 LASSERT(mode == DT_WRITE_LOCK || mode == DT_READ_LOCK);
365 if (mode == DT_WRITE_LOCK)
366 down_write(&obj->oo_sem);
368 down_read(&obj->oo_sem);
371 static void osd_object_unlock(struct lu_context *ctx, struct dt_object *dt,
372 enum dt_lock_mode mode)
374 struct osd_object *obj = osd_dt_obj(dt);
376 LASSERT(mode == DT_WRITE_LOCK || mode == DT_READ_LOCK);
377 if (mode == DT_WRITE_LOCK)
378 up_write(&obj->oo_sem);
380 up_read(&obj->oo_sem);
383 static int osd_attr_get(struct lu_context *ctxt, struct dt_object *dt,
384 struct lu_attr *attr)
386 LASSERT(lu_object_exists(ctxt, &dt->do_lu));
387 return osd_inode_getattr(ctxt, osd_dt_obj(dt)->oo_inode, attr);
393 * XXX temporary solution.
396 static int osd_create_pre(struct osd_thread_info *info, struct osd_object *obj,
397 struct lu_attr *attr, struct thandle *th)
402 static int osd_create_post(struct osd_thread_info *info, struct osd_object *obj,
403 struct lu_attr *attr, struct thandle *th)
405 LASSERT(obj->oo_inode != NULL);
407 osd_object_init0(obj);
411 static void osd_fid_build_name(const struct lu_fid *fid, char *name)
413 static const char *qfmt = LPX64":%lx:%lx";
415 sprintf(name, qfmt, fid_seq(fid), fid_oid(fid), fid_ver(fid));
418 static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj,
419 struct lu_attr *attr, struct thandle *th)
422 struct osd_device *osd = osd_obj2dev(obj);
426 * XXX temporary solution.
428 struct dentry *dentry;
434 LASSERT(obj->oo_inode == NULL);
435 LASSERT(S_ISDIR(attr->la_mode));
436 LASSERT(osd->od_obj_area != NULL);
438 dir = osd->od_obj_area->d_inode;
439 LASSERT(dir->i_op != NULL && dir->i_op->mkdir != NULL);
441 osd_fid_build_name(lu_object_fid(&obj->oo_dt.do_lu), name);
442 str.len = strlen(name);
444 dentry = d_alloc(osd->od_obj_area, &str);
445 if (dentry != NULL) {
446 result = dir->i_op->mkdir(dir, dentry,
447 attr->la_mode & (S_IRWXUGO|S_ISVTX));
449 LASSERT(dentry->d_inode != NULL);
450 obj->oo_inode = dentry->d_inode;
451 igrab(obj->oo_inode);
459 typedef int (*osd_obj_type_f)(struct osd_thread_info *, struct osd_object *,
460 struct lu_attr *, struct thandle *);
462 osd_obj_type_f osd_mkreg = NULL;
463 osd_obj_type_f osd_mksym = NULL;
464 osd_obj_type_f osd_mknod = NULL;
466 static osd_obj_type_f osd_create_type_f(__u32 mode)
468 osd_obj_type_f result;
493 static int osd_object_create(struct lu_context *ctx, struct dt_object *dt,
494 struct lu_attr *attr, struct thandle *th)
496 const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
497 struct osd_object *obj = osd_dt_obj(dt);
498 struct osd_device *osd = osd_obj2dev(obj);
499 struct osd_thread_info *info = lu_context_key_get(ctx, &osd_key);
504 LASSERT(!lu_object_exists(ctx, &dt->do_lu));
507 * XXX missing: permission checks.
511 * XXX missing: sanity checks (valid ->la_mode, etc.)
515 * XXX missing: Quote handling.
518 result = osd_create_pre(info, obj, attr, th);
520 osd_create_type_f(attr->la_mode & S_IFMT)(info, obj, attr, th);
522 result = osd_create_post(info, obj, attr, th);
525 struct osd_inode_id *id = &info->oti_id;
527 LASSERT(obj->oo_inode != NULL);
529 id->oii_ino = obj->oo_inode->i_ino;
530 id->oii_gen = obj->oo_inode->i_generation;
532 osd_oi_write_lock(&osd->od_oi);
533 result = osd_oi_insert(info, &osd->od_oi, fid, id, th);
534 osd_oi_write_unlock(&osd->od_oi);
537 LASSERT(ergo(result == 0, lu_object_exists(ctx, &dt->do_lu)));
541 static struct dt_object_operations osd_obj_ops = {
542 .do_object_lock = osd_object_lock,
543 .do_object_unlock = osd_object_unlock,
544 .do_attr_get = osd_attr_get,
545 .do_object_create = osd_object_create,
548 static struct dt_body_operations osd_body_ops = {
556 * XXX This is temporary solution: inode operations are used until iam is
559 static int osd_index_lookup(struct lu_context *ctxt, struct dt_object *dt,
560 struct dt_rec *rec, const struct dt_key *key)
562 struct osd_object *obj = osd_dt_obj(dt);
563 struct osd_device *osd = osd_obj2dev(obj);
569 * XXX temporary solution.
571 struct dentry *dentry;
573 .name = (const char *)key,
574 .len = strlen((const char *)key)
577 LASSERT(osd_has_index(obj));
578 LASSERT(osd->od_obj_area != NULL);
581 LASSERT(dir->i_op != NULL && dir->i_op->lookup != NULL);
583 dentry = d_alloc(NULL, &str);
584 if (dentry != NULL) {
588 * XXX passing NULL for nameidata should work for
591 d = dir->i_op->lookup(dir, dentry, NULL);
594 * normal case, result is in @dentry.
596 if (dentry->d_inode != NULL) {
597 struct lu_fid *fid = (struct lu_fid *)rec;
599 * Build fid from inode.
601 fid->f_seq = 0; /* XXX hard-coded */
602 fid->f_oid = dentry->d_inode->i_ino;
603 fid->f_ver = dentry->d_inode->i_generation;
608 /* What? Disconnected alias? Ppheeeww... */
609 CERROR("Aliasing where not expected\n");
619 static int osd_index_insert(struct lu_context *ctxt, struct dt_object *dt,
620 const struct dt_rec *rec, const struct dt_key *key,
621 struct thandle *handle)
626 const struct dt_index_features dt_directory_features;
628 static int osd_index_probe(struct lu_context *ctxt, struct dt_object *dt,
629 const struct dt_index_features *feat)
631 struct osd_object *obj = osd_dt_obj(dt);
633 if (feat == &dt_directory_features)
636 return 0; /* nothing yet is supported */
639 static struct dt_index_operations osd_index_ops = {
640 .dio_lookup = osd_index_lookup,
641 .dio_insert = osd_index_insert,
642 .dio_probe = osd_index_probe
646 * OSD device type methods
648 static int osd_type_init(struct lu_device_type *t)
650 return lu_context_key_register(&osd_key);
653 static void osd_type_fini(struct lu_device_type *t)
655 lu_context_key_degister(&osd_key);
658 static struct lu_context_key osd_key = {
659 .lct_init = osd_key_init,
660 .lct_fini = osd_key_fini
663 static void *osd_key_init(struct lu_context *ctx)
665 struct osd_thread_info *info;
669 info = ERR_PTR(-ENOMEM);
673 static void osd_key_fini(struct lu_context *ctx, void *data)
675 struct osd_thread_info *info = data;
679 static int osd_device_init(struct lu_context *ctx,
680 struct lu_device *d, struct lu_device *next)
685 extern void osd_oi_init0(struct osd_oi *oi, __u64 root_ino, __u32 root_gen);
686 extern int osd_oi_find_fid(struct osd_oi *oi,
687 __u64 ino, __u32 gen, struct lu_fid *fid);
689 static int osd_mount(struct lu_context *ctx,
690 struct osd_device *o, struct lustre_cfg *cfg)
692 struct lustre_mount_info *lmi;
693 const char *dev = lustre_cfg_string(cfg, 0);
698 if (o->od_mount != NULL) {
699 CERROR("Already mounted (%s)\n", dev);
704 lmi = server_get_mount(dev);
706 CERROR("Cannot get mount info for %s!\n", dev);
710 LASSERT(lmi != NULL);
711 /* save lustre_mount_info in dt_device */
713 result = osd_oi_init(&o->od_oi, osd_sb(o)->s_root,
714 osd2lu_dev(o)->ld_site);
718 d = simple_mkdir(osd_sb(o)->s_root, "*OBJ-TEMP*", 0777, 1);
722 d = simple_mkdir(osd_sb(o)->s_root, "ROOT", 0777, 1);
724 osd_oi_init0(&o->od_oi, d->d_inode->i_ino,
725 d->d_inode->i_generation);
733 osd_device_fini(ctx, osd2lu_dev(o));
737 static struct lu_device *osd_device_fini(struct lu_context *ctx,
740 struct osd_device *o = osd_dev(d);
743 if (o->od_obj_area != NULL) {
744 dput(o->od_obj_area);
745 o->od_obj_area = NULL;
747 if (o->od_root_dir != NULL) {
748 dput(o->od_root_dir);
749 o->od_root_dir = NULL;
751 osd_oi_fini(&o->od_oi);
754 server_put_mount(o->od_mount->lmi_name, o->od_mount->lmi_mnt);
760 static struct lu_device *osd_device_alloc(struct lu_device_type *t,
761 struct lustre_cfg *cfg)
764 struct osd_device *o;
770 result = dt_device_init(&o->od_dt_dev, t);
773 l->ld_ops = &osd_lu_ops;
774 o->od_dt_dev.dd_ops = &osd_dt_ops;
778 l = ERR_PTR(-ENOMEM);
782 static void osd_device_free(struct lu_device *d)
784 struct osd_device *o = osd_dev(d);
786 dt_device_fini(&o->od_dt_dev);
790 static int osd_process_config(struct lu_context *ctx,
791 struct lu_device *d, struct lustre_cfg *cfg)
793 struct osd_device *o = osd_dev(d);
796 switch(cfg->lcfg_command) {
798 err = osd_mount(ctx, o, cfg);
808 * fid<->inode<->object functions.
811 static int osd_inode_get_fid(struct osd_device *d, const struct inode *inode,
817 * XXX: Should return fid stored together with inode in memory.
820 result = osd_oi_find_fid(&d->od_oi, inode->i_ino,
821 inode->i_generation, fid);
823 fid->f_seq = inode->i_ino;
824 fid->f_oid = inode->i_generation;
830 struct dentry *osd_open(struct dentry *parent, const char *name, mode_t mode)
832 struct dentry *dentry;
833 struct dentry *result;
835 result = dentry = osd_lookup(parent, name);
836 if (IS_ERR(dentry)) {
837 CERROR("Error opening %s: %ld\n", name, PTR_ERR(dentry));
838 dentry = NULL; /* dput(NULL) below is OK */
839 } else if (dentry->d_inode == NULL) {
840 CERROR("Not found: %s\n", name);
841 result = ERR_PTR(-ENOENT);
842 } else if ((dentry->d_inode->i_mode & S_IFMT) != mode) {
843 CERROR("Wrong mode: %s: %o != %o\n", name,
844 dentry->d_inode->i_mode, mode);
845 result = ERR_PTR(mode == S_IFDIR ? -ENOTDIR : -EISDIR);
853 struct dentry *osd_lookup(struct dentry *parent, const char *name)
855 struct dentry *dentry;
857 CDEBUG(D_INODE, "looking up object %s\n", name);
858 down(&parent->d_inode->i_sem);
859 dentry = lookup_one_len(name, parent, strlen(name));
860 up(&parent->d_inode->i_sem);
862 if (IS_ERR(dentry)) {
863 CERROR("error getting %s: %ld\n", name, PTR_ERR(dentry));
864 } else if (dentry->d_inode != NULL && is_bad_inode(dentry->d_inode)) {
865 CERROR("got bad object %s inode %lu\n",
866 name, dentry->d_inode->i_ino);
868 dentry = ERR_PTR(-ENOENT);
873 static struct inode *osd_iget(struct osd_thread_info *info,
874 struct osd_device *dev,
875 const struct osd_inode_id *id)
879 inode = iget(osd_sb(dev), id->oii_ino);
881 CERROR("no inode\n");
882 inode = ERR_PTR(-EACCES);
883 } else if (is_bad_inode(inode)) {
884 CERROR("bad inode\n");
886 inode = ERR_PTR(-ENOENT);
887 } else if (inode->i_generation != id->oii_gen &&
888 id->oii_gen != OSD_GEN_IGNORE) {
889 CERROR("stale inode\n");
891 inode = ERR_PTR(-ESTALE);
897 static int osd_fid_lookup(struct lu_context *ctx,
898 struct osd_object *obj, const struct lu_fid *fid)
900 struct osd_thread_info *info;
901 struct lu_device *ldev = obj->oo_dt.do_lu.lo_dev;
902 struct osd_device *dev;
903 struct osd_inode_id id;
907 LASSERT(obj->oo_inode == NULL);
908 LASSERT(fid_is_sane(fid));
909 LASSERT(fid_is_local(ldev->ld_site, fid));
913 info = lu_context_key_get(ctx, &osd_key);
916 if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
919 osd_oi_read_lock(&dev->od_oi);
920 result = osd_oi_lookup(info, &dev->od_oi, fid, &id);
922 inode = osd_iget(info, dev, &id);
923 if (!IS_ERR(inode)) {
924 obj->oo_inode = inode;
927 result = PTR_ERR(inode);
928 } else if (result == -ENOENT)
930 osd_oi_read_unlock(&dev->od_oi);
934 static int osd_inode_getattr(struct lu_context *ctx,
935 struct inode *inode, struct lu_attr *attr)
937 //attr->la_atime = inode->i_atime;
938 //attr->la_mtime = inode->i_mtime;
939 //attr->la_ctime = inode->i_ctime;
940 attr->la_mode = inode->i_mode;
941 attr->la_size = inode->i_size;
942 attr->la_blocks = inode->i_blocks;
943 attr->la_uid = inode->i_uid;
944 attr->la_gid = inode->i_gid;
945 attr->la_flags = inode->i_flags;
946 attr->la_nlink = inode->i_nlink;
954 static int lu_device_is_osd(const struct lu_device *d)
957 * XXX for now. Tags in lu_device_type->ldt_something are needed.
959 return ergo(d != NULL && d->ld_ops != NULL, d->ld_ops == &osd_lu_ops);
962 static struct osd_object *osd_obj(const struct lu_object *o)
964 LASSERT(lu_device_is_osd(o->lo_dev));
965 return container_of0(o, struct osd_object, oo_dt.do_lu);
968 static struct osd_device *osd_dt_dev(const struct dt_device *d)
970 LASSERT(lu_device_is_osd(&d->dd_lu_dev));
971 return container_of0(d, struct osd_device, od_dt_dev);
974 static struct osd_device *osd_dev(const struct lu_device *d)
976 LASSERT(lu_device_is_osd(d));
977 return osd_dt_dev(container_of0(d, struct dt_device, dd_lu_dev));
980 static struct osd_object *osd_dt_obj(const struct dt_object *d)
982 return osd_obj(&d->do_lu);
985 static struct osd_device *osd_obj2dev(struct osd_object *o)
987 return osd_dev(o->oo_dt.do_lu.lo_dev);
990 static struct lu_device *osd2lu_dev(struct osd_device * osd)
992 return &osd->od_dt_dev.dd_lu_dev;
995 static struct super_block *osd_sb(const struct osd_device *dev)
997 return dev->od_mount->lmi_mnt->mnt_sb;
1000 static journal_t *osd_journal(const struct osd_device *dev)
1002 return LDISKFS_SB(osd_sb(dev))->s_journal;
1005 static int osd_has_index(struct osd_object *obj)
1007 return S_ISDIR(obj->oo_inode->i_mode);
1010 static struct lu_object_operations osd_lu_obj_ops = {
1011 .loo_object_init = osd_object_init,
1012 .loo_object_delete = osd_object_delete,
1013 .loo_object_release = osd_object_release,
1014 .loo_object_print = osd_object_print,
1015 .loo_object_exists = osd_object_exists
1018 static struct lu_device_operations osd_lu_ops = {
1019 .ldo_object_alloc = osd_object_alloc,
1020 .ldo_object_free = osd_object_free,
1021 .ldo_process_config = osd_process_config
1024 static struct lu_device_type_operations osd_device_type_ops = {
1025 .ldto_init = osd_type_init,
1026 .ldto_fini = osd_type_fini,
1028 .ldto_device_alloc = osd_device_alloc,
1029 .ldto_device_free = osd_device_free,
1031 .ldto_device_init = osd_device_init,
1032 .ldto_device_fini = osd_device_fini
1035 static struct lu_device_type osd_device_type = {
1036 .ldt_tags = LU_DEVICE_DT,
1037 .ldt_name = LUSTRE_OSD0_NAME,
1038 .ldt_ops = &osd_device_type_ops
1042 * lprocfs legacy support.
1044 static struct lprocfs_vars lprocfs_osd_obd_vars[] = {
1048 static struct lprocfs_vars lprocfs_osd_module_vars[] = {
1052 static struct obd_ops osd_obd_device_ops = {
1053 .o_owner = THIS_MODULE
1056 LPROCFS_INIT_VARS(osd, lprocfs_osd_module_vars, lprocfs_osd_obd_vars);
1058 static int __init osd_mod_init(void)
1060 struct lprocfs_static_vars lvars;
1062 lprocfs_init_vars(osd, &lvars);
1063 return class_register_type(&osd_obd_device_ops, NULL, lvars.module_vars,
1064 LUSTRE_OSD0_NAME, &osd_device_type);
1067 static void __exit osd_mod_exit(void)
1069 class_unregister_type(LUSTRE_OSD0_NAME);
1072 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
1073 MODULE_DESCRIPTION("Lustre Object Storage Device ("LUSTRE_OSD0_NAME")");
1074 MODULE_LICENSE("GPL");
1076 cfs_module(osd, "0.0.2", osd_mod_init, osd_mod_exit);