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 * struct OBD_{ALLOC,FREE}*()
42 #include <linux/obd_support.h>
43 /* struct ptlrpc_thread */
44 #include <linux/lustre_net.h>
45 /* LUSTRE_OSD0_NAME */
46 #include <linux/obd.h>
47 /* class_register_type(), class_unregister_type(), class_get_type() */
48 #include <linux/obd_class.h>
49 #include <linux/lustre_disk.h>
52 #include <linux/lustre_fid.h>
54 #include "osd_internal.h"
56 static int osd_root_get (struct lu_context *ctxt,
57 struct dt_device *dev, struct lu_fid *f);
58 static int osd_statfs (struct lu_context *ctxt,
59 struct dt_device *dev, struct kstatfs *sfs);
61 static int lu_device_is_osd (const struct lu_device *d);
62 static void osd_mod_exit (void) __exit;
63 static int osd_mod_init (void) __init;
64 static int osd_type_init (struct lu_device_type *t);
65 static void osd_type_fini (struct lu_device_type *t);
66 static int osd_object_init (struct lu_context *ctxt, struct lu_object *l);
67 static void osd_object_release(struct lu_context *ctxt, struct lu_object *l);
68 static int osd_object_print (struct lu_context *ctx,
69 struct seq_file *f, const struct lu_object *o);
70 static void osd_device_free (struct lu_device *m);
71 static void osd_device_fini (struct lu_device *d);
72 static int osd_device_init (struct lu_device *d, const char *conf);
73 static void *osd_key_init (struct lu_context *ctx);
74 static void osd_key_fini (struct lu_context *ctx, void *data);
75 static int osd_fid_lookup (struct lu_context *ctx, struct osd_object *obj,
76 const struct lu_fid *fid);
78 static struct osd_object *osd_obj (const struct lu_object *o);
79 static struct osd_device *osd_dev (const struct lu_device *d);
80 static struct osd_device *osd_dt_dev (const struct dt_device *d);
81 static struct lu_device *osd_device_alloc (struct lu_device_type *t,
82 struct lustre_cfg *cfg);
83 static struct lu_object *osd_object_alloc (struct lu_context *ctx,
85 static struct inode *osd_iget (struct osd_thread_info *info,
86 struct osd_device *dev,
87 const struct osd_inode_id *id);
88 static struct super_block *osd_sb (const struct osd_device *dev);
89 static struct lu_fid *osd_inode_get_fid(const struct inode *inode,
92 static struct lu_device_type_operations osd_device_type_ops;
93 static struct lu_device_type osd_device_type;
94 static struct obd_ops osd_obd_device_ops;
95 static struct lprocfs_vars lprocfs_osd_module_vars[];
96 static struct lprocfs_vars lprocfs_osd_obd_vars[];
97 static struct lu_device_operations osd_lu_ops;
98 static struct lu_context_key osd_key;
103 static int osd_root_get(struct lu_context *ctx,
104 struct dt_device *dev, struct lu_fid *f)
106 osd_inode_get_fid(osd_dt_dev(dev)->od_root_dir->d_inode, f);
112 * OSD object methods.
115 static struct lu_object *osd_object_alloc(struct lu_context *ctx,
118 struct osd_object *mo;
124 l = &mo->oo_dt.do_lu;
125 lu_object_init(l, NULL, d);
131 static int osd_getattr(struct lu_context *ctx,
132 struct inode *inode, struct lu_attr *attr)
134 //attr->la_atime = inode->i_atime;
135 //attr->la_mtime = inode->i_mtime;
136 //attr->la_ctime = inode->i_ctime;
137 attr->la_mode = inode->i_mode;
138 attr->la_size = inode->i_size;
139 attr->la_blocks = inode->i_blocks;
140 attr->la_uid = inode->i_uid;
141 attr->la_gid = inode->i_gid;
142 attr->la_flags = inode->i_flags;
143 attr->la_nlink = inode->i_nlink;
147 static int osd_object_init(struct lu_context *ctxt, struct lu_object *l)
149 struct osd_object *o = osd_obj(l);
152 result = osd_fid_lookup(ctxt, o, lu_object_fid(l));
154 /* fill lu_attr in ctxt */
155 result = osd_getattr(ctxt, o->oo_inode, &ctxt->lc_attr);
159 static void osd_object_free(struct lu_context *ctx, struct lu_object *l)
161 struct osd_object *obj = osd_obj(l);
165 static void osd_object_delete(struct lu_context *ctx, struct lu_object *l)
167 struct osd_object *o = osd_obj(l);
169 if (o->oo_inode != NULL)
173 static int osd_inode_unlinked(const struct inode *inode)
175 return inode->i_nlink == !!S_ISDIR(inode->i_mode);
178 static void osd_object_release(struct lu_context *ctxt, struct lu_object *l)
180 struct osd_object *o = osd_obj(l);
182 if (o->oo_inode != NULL && osd_inode_unlinked(o->oo_inode))
183 set_bit(LU_OBJECT_HEARD_BANSHEE, &l->lo_header->loh_flags);
186 static int osd_object_print(struct lu_context *ctx,
187 struct seq_file *f, const struct lu_object *l)
189 struct osd_object *o = osd_obj(l);
191 return seq_printf(f, LUSTRE_OSD0_NAME"-object@%p(i:%p:%lu/%u)",
193 o->oo_inode ? o->oo_inode->i_ino : 0UL,
194 o->oo_inode ? o->oo_inode->i_generation : 0);
197 static int osd_config(struct lu_context *ctx,
198 struct dt_device *d, const char *name,
199 void *buf, int size, int mode)
201 if (mode == LUSTRE_CONFIG_GET) {
202 /* to be continued */
205 /* to be continued */
210 static int osd_statfs(struct lu_context *ctx,
211 struct dt_device *d, struct kstatfs *sfs)
213 struct osd_device *osd = dt2osd_dev(d);
214 struct super_block *sb = osd_sb(osd);
219 memset(sfs, 0, sizeof(*sfs));
220 result = sb->s_op->statfs(sb, sfs);
225 static int osd_xattr_get(struct lu_context *ctxt, struct dt_object *dt,
226 void *buf, int size, const char *name,
227 struct md_params *arg)
229 //struct osd_object *o = dt2osd_obj(dt);
230 //struct osd_device *dev = osd_obj2dev(o);
231 //struct super_block *sb = osd_sb(dev);
232 //struct inode *inode = o->oo_inode;
233 int result = -EOPNOTSUPP;
237 memset(buf, 0, size);
243 static struct dt_device_operations osd_dt_ops = {
244 .dt_root_get = osd_root_get,
245 .dt_config = osd_config,
246 .dt_statfs = osd_statfs
250 * OSD device type methods
252 static int osd_type_init(struct lu_device_type *t)
254 return lu_context_key_register(&osd_key);
257 static void osd_type_fini(struct lu_device_type *t)
259 lu_context_key_degister(&osd_key);
262 static struct lu_context_key osd_key = {
263 .lct_init = osd_key_init,
264 .lct_fini = osd_key_fini
267 static void *osd_key_init(struct lu_context *ctx)
269 struct osd_thread_info *info;
273 info = ERR_PTR(-ENOMEM);
277 static void osd_key_fini(struct lu_context *ctx, void *data)
279 struct osd_thread_info *info = data;
283 static int osd_device_init(struct lu_device *d, const char *top)
285 struct osd_device *o = osd_dev(d);
286 struct lustre_mount_info *lmi;
291 lmi = server_get_mount(top);
293 struct lustre_sb_info *lsi;
294 struct lustre_disk_data *ldd;
295 struct lustre_mount_data *lmd;
297 /* We already mounted in lustre_fill_super */
298 lsi = s2lsi(lmi->lmi_sb);
302 CDEBUG(D_INFO, "OSD info: device=%s,\n opts=%s,\n",
303 lmd->lmd_dev, ldd->ldd_mount_opts);
305 /* save lustre_mount_info in dt_device */
307 result = osd_oi_init(&o->od_oi, osd_sb(o)->s_root,
308 o->od_dt_dev.dd_lu_dev.ld_site);
310 o->od_root_dir = osd_open(osd_sb(o)->s_root,
312 if (IS_ERR(o->od_root_dir)) {
313 result = PTR_ERR(o->od_root_dir);
314 o->od_root_dir = NULL;
318 CERROR("Cannot get mount info for %s!\n", top);
326 static void osd_device_fini(struct lu_device *d)
328 struct osd_device *o = osd_dev(d);
330 if (o->od_root_dir != NULL) {
331 dput(o->od_root_dir);
332 o->od_root_dir = NULL;
334 osd_oi_fini(&o->od_oi);
335 if (o->od_mount != NULL) {
336 server_put_mount(o->od_mount->lmi_name, o->od_mount->lmi_mnt);
341 static struct lu_device *osd_device_alloc(struct lu_device_type *t,
342 struct lustre_cfg *cfg)
345 struct osd_device *o;
349 l = &o->od_dt_dev.dd_lu_dev;
350 lu_device_init(&o->od_dt_dev.dd_lu_dev, t);
351 o->od_dt_dev.dd_lu_dev.ld_ops = &osd_lu_ops;
352 o->od_dt_dev.dd_ops = &osd_dt_ops;
354 l = ERR_PTR(-ENOMEM);
358 static void osd_device_free(struct lu_device *d)
360 struct osd_device *o = osd_dev(d);
367 * fid<->inode<->object functions.
370 static struct lu_fid *osd_inode_get_fid(const struct inode *inode,
374 * XXX: Should return fid stored together with inode in memory.
376 fid->f_seq = inode->i_ino;
377 fid->f_oid = inode->i_generation;
381 struct dentry *osd_open(struct dentry *parent, const char *name, mode_t mode)
383 struct dentry *dentry;
384 struct dentry *result;
386 result = dentry = osd_lookup(parent, name);
387 if (IS_ERR(dentry)) {
388 CERROR("Error opening %s: %ld\n", name, PTR_ERR(dentry));
389 dentry = NULL; /* dput(NULL) below is OK */
390 } else if (dentry->d_inode == NULL) {
391 CERROR("Not found: %s\n", name);
392 result = ERR_PTR(-ENOENT);
393 } else if ((dentry->d_inode->i_mode & S_IFMT) != mode) {
394 CERROR("Wrong mode: %s: %o != %o\n", name,
395 dentry->d_inode->i_mode, mode);
396 result = ERR_PTR(mode == S_IFDIR ? -ENOTDIR : -EISDIR);
404 struct dentry *osd_lookup(struct dentry *parent, const char *name)
406 struct dentry *dentry;
408 CDEBUG(D_INODE, "looking up object %s\n", name);
409 down(&parent->d_inode->i_sem);
410 dentry = lookup_one_len(name, parent, strlen(name));
411 up(&parent->d_inode->i_sem);
413 if (IS_ERR(dentry)) {
414 CERROR("error getting %s: %ld\n", name, PTR_ERR(dentry));
415 } else if (dentry->d_inode != NULL && is_bad_inode(dentry->d_inode)) {
416 CERROR("got bad object %s inode %lu\n",
417 name, dentry->d_inode->i_ino);
419 dentry = ERR_PTR(-ENOENT);
424 static struct inode *osd_iget(struct osd_thread_info *info,
425 struct osd_device *dev,
426 const struct osd_inode_id *id)
430 inode = iget(osd_sb(dev), id->oii_ino);
432 CERROR("no inode\n");
433 inode = ERR_PTR(-EACCES);
434 } else if (is_bad_inode(inode)) {
435 CERROR("bad inode\n");
437 inode = ERR_PTR(-ENOENT);
438 } else if (inode->i_generation != id->oii_gen &&
439 id->oii_gen != OSD_GEN_IGNORE) {
440 CERROR("stale inode\n");
442 inode = ERR_PTR(-ESTALE);
448 static int osd_fid_lookup(struct lu_context *ctx,
449 struct osd_object *obj, const struct lu_fid *fid)
451 struct osd_thread_info *info;
452 struct lu_device *ldev = obj->oo_dt.do_lu.lo_dev;
453 struct osd_device *dev;
454 struct osd_inode_id id;
458 LASSERT(obj->oo_inode == NULL);
459 LASSERT(fid_is_sane(fid));
460 LASSERT(fid_is_local(ldev->ld_site, fid));
464 info = lu_context_key_get(ctx, &osd_key);
467 if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
470 osd_oi_read_lock(&dev->od_oi);
471 result = osd_oi_lookup(info, &dev->od_oi, fid, &id);
473 inode = osd_iget(info, dev, &id);
474 if (!IS_ERR(inode)) {
475 obj->oo_inode = inode;
478 result = PTR_ERR(inode);
480 osd_oi_read_unlock(&dev->od_oi);
488 static int lu_device_is_osd(const struct lu_device *d)
491 * XXX for now. Tags in lu_device_type->ldt_something are needed.
493 return ergo(d->ld_ops != NULL, d->ld_ops == &osd_lu_ops);
496 static struct osd_object *osd_obj(const struct lu_object *o)
498 LASSERT(lu_device_is_osd(o->lo_dev));
499 return container_of(o, struct osd_object, oo_dt.do_lu);
502 static struct osd_device *osd_dt_dev(const struct dt_device *d)
504 LASSERT(lu_device_is_osd(&d->dd_lu_dev));
505 return container_of(d, struct osd_device, od_dt_dev);
508 static struct osd_device *osd_dev(const struct lu_device *d)
510 LASSERT(lu_device_is_osd(d));
511 return osd_dt_dev(container_of(d, struct dt_device, dd_lu_dev));
514 static struct super_block *osd_sb(const struct osd_device *dev)
516 return dev->od_mount->lmi_mnt->mnt_sb;
519 static struct lu_device_operations osd_lu_ops = {
520 .ldo_object_alloc = osd_object_alloc,
521 .ldo_object_init = osd_object_init,
522 .ldo_object_free = osd_object_free,
523 .ldo_object_release = osd_object_release,
524 .ldo_object_delete = osd_object_delete,
525 .ldo_object_print = osd_object_print
528 static struct lu_device_type_operations osd_device_type_ops = {
529 .ldto_init = osd_type_init,
530 .ldto_fini = osd_type_fini,
532 .ldto_device_alloc = osd_device_alloc,
533 .ldto_device_free = osd_device_free,
535 .ldto_device_init = osd_device_init,
536 .ldto_device_fini = osd_device_fini
539 static struct lu_device_type osd_device_type = {
540 .ldt_tags = LU_DEVICE_DT,
541 .ldt_name = LUSTRE_OSD0_NAME,
542 .ldt_ops = &osd_device_type_ops
546 * lprocfs legacy support.
548 static struct lprocfs_vars lprocfs_osd_obd_vars[] = {
552 static struct lprocfs_vars lprocfs_osd_module_vars[] = {
556 static struct obd_ops osd_obd_device_ops = {
557 .o_owner = THIS_MODULE
560 LPROCFS_INIT_VARS(osd, lprocfs_osd_module_vars, lprocfs_osd_obd_vars);
562 static int __init osd_mod_init(void)
564 struct lprocfs_static_vars lvars;
566 lprocfs_init_vars(osd, &lvars);
567 return class_register_type(&osd_obd_device_ops, lvars.module_vars,
568 LUSTRE_OSD0_NAME, &osd_device_type);
571 static void __exit osd_mod_exit(void)
573 class_unregister_type(LUSTRE_OSD0_NAME);
576 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
577 MODULE_DESCRIPTION("Lustre Object Storage Device ("LUSTRE_OSD0_NAME")");
578 MODULE_LICENSE("GPL");
580 cfs_module(osd, "0.0.2", osd_mod_init, osd_mod_exit);