Whamcloud - gitweb
rename: attr_{set,get} -> xattr_{set,get}
[fs/lustre-release.git] / lustre / osd / osd_handler.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  lustre/osd/osd_handler.c
5  *  Top-level entry points into osd module
6  *
7  *  Copyright (c) 2006 Cluster File Systems, Inc.
8  *   Author: Nikita Danilov <nikita@clusterfs.com>
9  *
10  *   This file is part of the Lustre file system, http://www.lustre.org
11  *   Lustre is a trademark of Cluster File Systems, Inc.
12  *
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.
17  *
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.
22  *
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.
27  */
28
29 #ifndef EXPORT_SYMTAB
30 # define EXPORT_SYMTAB
31 #endif
32 #define DEBUG_SUBSYSTEM S_MDS
33
34 #include <linux/module.h>
35
36 /* LUSTRE_VERSION_CODE */
37 #include <linux/lustre_ver.h>
38 /*
39  * struct OBD_{ALLOC,FREE}*()
40  * OBD_FAIL_CHECK
41  */
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>
50
51 /* fid_is_local() */
52 #include <linux/lustre_fid.h>
53
54 #include "osd_internal.h"
55
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);
60
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);
77
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,
84                                              struct lu_device *d);
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,
90                                              struct lu_fid *fid);
91
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;
99
100 /*
101  * DT methods.
102  */
103 static int osd_root_get(struct lu_context *ctx,
104                         struct dt_device *dev, struct lu_fid *f)
105 {
106         osd_inode_get_fid(osd_dt_dev(dev)->od_root_dir->d_inode, f);
107         return 0;
108 }
109
110
111 /*
112  * OSD object methods.
113  */
114
115 static struct lu_object *osd_object_alloc(struct lu_context *ctx,
116                                           struct lu_device *d)
117 {
118         struct osd_object *mo;
119
120         OBD_ALLOC_PTR(mo);
121         if (mo != NULL) {
122                 struct lu_object *l;
123
124                 l = &mo->oo_dt.do_lu;
125                 lu_object_init(l, NULL, d);
126                 return l;
127         } else
128                 return NULL;
129 }
130
131 static int osd_getattr(struct lu_context *ctx,
132                        struct inode *inode, struct lu_attr *attr)
133 {
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;
144         return 0;
145 }
146
147 static int osd_object_init(struct lu_context *ctxt, struct lu_object *l)
148 {
149         struct osd_object *o = osd_obj(l);
150         int result;
151
152         result = osd_fid_lookup(ctxt, o, lu_object_fid(l));
153         if (result == 0)
154                 /* fill lu_attr in ctxt */
155                 result = osd_getattr(ctxt, o->oo_inode, &ctxt->lc_attr);
156         return result;
157 }
158
159 static void osd_object_free(struct lu_context *ctx, struct lu_object *l)
160 {
161         struct osd_object *obj = osd_obj(l);
162         OBD_FREE_PTR(obj);
163 }
164
165 static void osd_object_delete(struct lu_context *ctx, struct lu_object *l)
166 {
167         struct osd_object *o = osd_obj(l);
168
169         if (o->oo_inode != NULL)
170                 iput(o->oo_inode);
171 }
172
173 static int osd_inode_unlinked(const struct inode *inode)
174 {
175         return inode->i_nlink == !!S_ISDIR(inode->i_mode);
176 }
177
178 static void osd_object_release(struct lu_context *ctxt, struct lu_object *l)
179 {
180         struct osd_object *o = osd_obj(l);
181
182         if (o->oo_inode != NULL && osd_inode_unlinked(o->oo_inode))
183                 set_bit(LU_OBJECT_HEARD_BANSHEE, &l->lo_header->loh_flags);
184 }
185
186 static int osd_object_print(struct lu_context *ctx,
187                             struct seq_file *f, const struct lu_object *l)
188 {
189         struct osd_object  *o = osd_obj(l);
190
191         return seq_printf(f, LUSTRE_OSD0_NAME"-object@%p(i:%p:%lu/%u)",
192                           o, o->oo_inode,
193                           o->oo_inode ? o->oo_inode->i_ino : 0UL,
194                           o->oo_inode ? o->oo_inode->i_generation : 0);
195 }
196
197 static int osd_config(struct lu_context *ctx,
198                       struct dt_device *d, const char *name,
199                       void *buf, int size, int mode)
200 {
201         if (mode == LUSTRE_CONFIG_GET) {
202                 /* to be continued */
203                 return 0;
204         } else {
205                 /* to be continued */
206                 return 0;
207         }
208 }
209
210 static int osd_statfs(struct lu_context *ctx,
211                       struct dt_device *d, struct kstatfs *sfs)
212 {
213         struct osd_device *osd = dt2osd_dev(d);
214         struct super_block *sb = osd_sb(osd);
215         int result;
216
217         ENTRY;
218
219         memset(sfs, 0, sizeof(*sfs));
220         result = sb->s_op->statfs(sb, sfs);
221
222         RETURN (result);
223 }
224
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)
228 {
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;
234
235         ENTRY;
236
237         memset(buf, 0, size);
238         //TODO
239         RETURN (result);
240
241 }
242
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
247 };
248
249 /*
250  * OSD device type methods
251  */
252 static int osd_type_init(struct lu_device_type *t)
253 {
254         return lu_context_key_register(&osd_key);
255 }
256
257 static void osd_type_fini(struct lu_device_type *t)
258 {
259         lu_context_key_degister(&osd_key);
260 }
261
262 static struct lu_context_key osd_key = {
263         .lct_init = osd_key_init,
264         .lct_fini = osd_key_fini
265 };
266
267 static void *osd_key_init(struct lu_context *ctx)
268 {
269         struct osd_thread_info *info;
270
271         OBD_ALLOC_PTR(info);
272         if (info == NULL)
273                 info = ERR_PTR(-ENOMEM);
274         return info;
275 }
276
277 static void osd_key_fini(struct lu_context *ctx, void *data)
278 {
279         struct osd_thread_info *info = data;
280         OBD_FREE_PTR(info);
281 }
282
283 static int osd_device_init(struct lu_device *d, const char *top)
284 {
285         struct osd_device *o = osd_dev(d);
286         struct lustre_mount_info *lmi;
287         int result;
288
289         ENTRY;
290
291         lmi = server_get_mount(top);
292         if (lmi != NULL) {
293                 struct lustre_sb_info    *lsi;
294                 struct lustre_disk_data  *ldd;
295                 struct lustre_mount_data *lmd;
296
297                 /* We already mounted in lustre_fill_super */
298                 lsi = s2lsi(lmi->lmi_sb);
299                 ldd = lsi->lsi_ldd;
300                 lmd = lsi->lsi_lmd;
301
302                 CDEBUG(D_INFO, "OSD info: device=%s,\n opts=%s,\n",
303                        lmd->lmd_dev, ldd->ldd_mount_opts);
304
305                 /* save lustre_mount_info in dt_device */
306                 o->od_mount = lmi;
307                 result = osd_oi_init(&o->od_oi, osd_sb(o)->s_root,
308                                      o->od_dt_dev.dd_lu_dev.ld_site);
309                 if (result == 0) {
310                         o->od_root_dir = osd_open(osd_sb(o)->s_root,
311                                                   "ROOT", S_IFDIR);
312                         if (IS_ERR(o->od_root_dir)) {
313                                 result = PTR_ERR(o->od_root_dir);
314                                 o->od_root_dir = NULL;
315                         }
316                 }
317         } else {
318                 CERROR("Cannot get mount info for %s!\n", top);
319                 result = -EFAULT;
320         }
321         if (result != 0)
322                 osd_device_fini(d);
323         RETURN(result);
324 }
325
326 static void osd_device_fini(struct lu_device *d)
327 {
328         struct osd_device *o = osd_dev(d);
329
330         if (o->od_root_dir != NULL) {
331                 dput(o->od_root_dir);
332                 o->od_root_dir = NULL;
333         }
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);
337                 o->od_mount = NULL;
338         }
339 }
340
341 static struct lu_device *osd_device_alloc(struct lu_device_type *t,
342                                           struct lustre_cfg *cfg)
343 {
344         struct lu_device  *l;
345         struct osd_device *o;
346
347         OBD_ALLOC_PTR(o);
348         if (o != NULL) {
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;
353         } else
354                 l = ERR_PTR(-ENOMEM);
355         return l;
356 }
357
358 static void osd_device_free(struct lu_device *d)
359 {
360         struct osd_device *o = osd_dev(d);
361
362         lu_device_fini(d);
363         OBD_FREE_PTR(o);
364 }
365
366 /*
367  * fid<->inode<->object functions.
368  */
369
370 static struct lu_fid *osd_inode_get_fid(const struct inode *inode,
371                                         struct lu_fid *fid)
372 {
373         /*
374          * XXX: Should return fid stored together with inode in memory.
375          */
376         fid->f_seq = inode->i_ino;
377         fid->f_oid = inode->i_generation;
378         return fid;
379 }
380
381 struct dentry *osd_open(struct dentry *parent, const char *name, mode_t mode)
382 {
383         struct dentry *dentry;
384         struct dentry *result;
385
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);
397         }
398
399         if (IS_ERR(result))
400                 dput(dentry);
401         return result;
402 }
403
404 struct dentry *osd_lookup(struct dentry *parent, const char *name)
405 {
406         struct dentry *dentry;
407
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);
412
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);
418                 dput(dentry);
419                 dentry = ERR_PTR(-ENOENT);
420         }
421         return dentry;
422 }
423
424 static struct inode *osd_iget(struct osd_thread_info *info,
425                               struct osd_device *dev,
426                               const struct osd_inode_id *id)
427 {
428         struct inode *inode;
429
430         inode = iget(osd_sb(dev), id->oii_ino);
431         if (inode == NULL) {
432                 CERROR("no inode\n");
433                 inode = ERR_PTR(-EACCES);
434         } else if (is_bad_inode(inode)) {
435                 CERROR("bad inode\n");
436                 iput(inode);
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");
441                 iput(inode);
442                 inode = ERR_PTR(-ESTALE);
443         }
444         return inode;
445
446 }
447
448 static int osd_fid_lookup(struct lu_context *ctx,
449                           struct osd_object *obj, const struct lu_fid *fid)
450 {
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;
455         struct inode           *inode;
456         int                     result;
457
458         LASSERT(obj->oo_inode == NULL);
459         LASSERT(fid_is_sane(fid));
460         LASSERT(fid_is_local(ldev->ld_site, fid));
461
462         ENTRY;
463
464         info = lu_context_key_get(ctx, &osd_key);
465         dev  = osd_dev(ldev);
466
467         if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
468                 RETURN(-ENOENT);
469
470         osd_oi_read_lock(&dev->od_oi);
471         result = osd_oi_lookup(info, &dev->od_oi, fid, &id);
472         if (result == 0) {
473                 inode = osd_iget(info, dev, &id);
474                 if (!IS_ERR(inode)) {
475                         obj->oo_inode = inode;
476                         result = 0;
477                 } else
478                         result = PTR_ERR(inode);
479         }
480         osd_oi_read_unlock(&dev->od_oi);
481         RETURN(result);
482 }
483
484 /*
485  * Helpers.
486  */
487
488 static int lu_device_is_osd(const struct lu_device *d)
489 {
490         /*
491          * XXX for now. Tags in lu_device_type->ldt_something are needed.
492          */
493         return ergo(d->ld_ops != NULL, d->ld_ops == &osd_lu_ops);
494 }
495
496 static struct osd_object *osd_obj(const struct lu_object *o)
497 {
498         LASSERT(lu_device_is_osd(o->lo_dev));
499         return container_of(o, struct osd_object, oo_dt.do_lu);
500 }
501
502 static struct osd_device *osd_dt_dev(const struct dt_device *d)
503 {
504         LASSERT(lu_device_is_osd(&d->dd_lu_dev));
505         return container_of(d, struct osd_device, od_dt_dev);
506 }
507
508 static struct osd_device *osd_dev(const struct lu_device *d)
509 {
510         LASSERT(lu_device_is_osd(d));
511         return osd_dt_dev(container_of(d, struct dt_device, dd_lu_dev));
512 }
513
514 static struct super_block *osd_sb(const struct osd_device *dev)
515 {
516         return dev->od_mount->lmi_mnt->mnt_sb;
517 }
518
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
526 };
527
528 static struct lu_device_type_operations osd_device_type_ops = {
529         .ldto_init = osd_type_init,
530         .ldto_fini = osd_type_fini,
531
532         .ldto_device_alloc = osd_device_alloc,
533         .ldto_device_free  = osd_device_free,
534
535         .ldto_device_init    = osd_device_init,
536         .ldto_device_fini    = osd_device_fini
537 };
538
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
543 };
544
545 /*
546  * lprocfs legacy support.
547  */
548 static struct lprocfs_vars lprocfs_osd_obd_vars[] = {
549         { 0 }
550 };
551
552 static struct lprocfs_vars lprocfs_osd_module_vars[] = {
553         { 0 }
554 };
555
556 static struct obd_ops osd_obd_device_ops = {
557         .o_owner = THIS_MODULE
558 };
559
560 LPROCFS_INIT_VARS(osd, lprocfs_osd_module_vars, lprocfs_osd_obd_vars);
561
562 static int __init osd_mod_init(void)
563 {
564         struct lprocfs_static_vars lvars;
565
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);
569 }
570
571 static void __exit osd_mod_exit(void)
572 {
573         class_unregister_type(LUSTRE_OSD0_NAME);
574 }
575
576 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
577 MODULE_DESCRIPTION("Lustre Object Storage Device ("LUSTRE_OSD0_NAME")");
578 MODULE_LICENSE("GPL");
579
580 cfs_module(osd, "0.0.2", osd_mod_init, osd_mod_exit);