Whamcloud - gitweb
d02d66464412b09a6486fb8789ae11a7147a069e
[fs/lustre-release.git] / lustre / include / dt_object.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  */
32 /*
33  * Copyright (c) 2011 Whamcloud, Inc.
34  */
35 /*
36  * This file is part of Lustre, http://www.lustre.org/
37  * Lustre is a trademark of Sun Microsystems, Inc.
38  */
39
40 #ifndef __LUSTRE_DT_OBJECT_H
41 #define __LUSTRE_DT_OBJECT_H
42
43 /** \defgroup dt dt
44  * Sub-class of lu_object with methods common for "data" objects in OST stack.
45  *
46  * Data objects behave like regular files: you can read/write them, get and
47  * set their attributes. Implementation of dt interface is supposed to
48  * implement some form of garbage collection, normally reference counting
49  * (nlink) based one.
50  *
51  * Examples: osd (lustre/osd) is an implementation of dt interface.
52  * @{
53  */
54
55
56 /*
57  * super-class definitions.
58  */
59 #include <lu_object.h>
60
61 #include <libcfs/libcfs.h>
62
63 struct seq_file;
64 struct proc_dir_entry;
65 struct lustre_cfg;
66
67 struct thandle;
68 struct txn_param;
69 struct dt_device;
70 struct dt_object;
71 struct dt_index_features;
72 struct dt_quota_ctxt;
73
74 typedef enum {
75         MNTOPT_USERXATTR        = 0x00000001,
76         MNTOPT_ACL              = 0x00000002,
77 } mntopt_t;
78
79 struct dt_device_param {
80         unsigned           ddp_max_name_len;
81         unsigned           ddp_max_nlink;
82         unsigned           ddp_block_shift;
83         mntopt_t           ddp_mntopts;
84 };
85
86 /**
87  * Basic transaction credit op
88  */
89 enum dt_txn_op {
90         DTO_INDEX_INSERT,
91         DTO_INDEX_DELETE,
92         DTO_IDNEX_UPDATE,
93         DTO_OBJECT_CREATE,
94         DTO_OBJECT_DELETE,
95         DTO_ATTR_SET_BASE,
96         DTO_XATTR_SET,
97         DTO_LOG_REC, /**< XXX temporary: dt layer knows nothing about llog. */
98         DTO_WRITE_BASE,
99         DTO_WRITE_BLOCK,
100         DTO_ATTR_SET_CHOWN,
101
102         DTO_NR
103 };
104
105 /**
106  * Operations on dt device.
107  */
108 struct dt_device_operations {
109         /**
110          * Return device-wide statistics.
111          */
112         int   (*dt_statfs)(const struct lu_env *env,
113                            struct dt_device *dev, cfs_kstatfs_t *sfs);
114         /**
115          * Start transaction, described by \a param.
116          */
117         struct thandle *(*dt_trans_start)(const struct lu_env *env,
118                                           struct dt_device *dev,
119                                           struct txn_param *param);
120         /**
121          * Finish previously started transaction.
122          */
123         void  (*dt_trans_stop)(const struct lu_env *env,
124                                struct thandle *th);
125         /**
126          * Return fid of root index object.
127          */
128         int   (*dt_root_get)(const struct lu_env *env,
129                              struct dt_device *dev, struct lu_fid *f);
130         /**
131          * Return device configuration data.
132          */
133         void  (*dt_conf_get)(const struct lu_env *env,
134                              const struct dt_device *dev,
135                              struct dt_device_param *param);
136         /**
137          *  handling device state, mostly for tests
138          */
139         int   (*dt_sync)(const struct lu_env *env, struct dt_device *dev);
140         void  (*dt_ro)(const struct lu_env *env, struct dt_device *dev);
141         /**
142           * Start a transaction commit asynchronously
143           *
144           * \param env environment
145           * \param dev dt_device to start commit on
146           *
147           * \return 0 success, negative value if error
148           */
149          int   (*dt_commit_async)(const struct lu_env *env,
150                                   struct dt_device *dev);
151         /**
152          * Initialize capability context.
153          */
154         int   (*dt_init_capa_ctxt)(const struct lu_env *env,
155                                    struct dt_device *dev,
156                                    int mode, unsigned long timeout,
157                                    __u32 alg, struct lustre_capa_key *keys);
158         /**
159          * Initialize quota context.
160          */
161         void (*dt_init_quota_ctxt)(const struct lu_env *env,
162                                    struct dt_device *dev,
163                                    struct dt_quota_ctxt *ctxt, void *data);
164
165         /**
166          *  get transaction credits for given \a op.
167          */
168         int (*dt_credit_get)(const struct lu_env *env, struct dt_device *dev,
169                              enum dt_txn_op);
170 };
171
172 struct dt_index_features {
173         /** required feature flags from enum dt_index_flags */
174         __u32 dif_flags;
175         /** minimal required key size */
176         size_t dif_keysize_min;
177         /** maximal required key size, 0 if no limit */
178         size_t dif_keysize_max;
179         /** minimal required record size */
180         size_t dif_recsize_min;
181         /** maximal required record size, 0 if no limit */
182         size_t dif_recsize_max;
183         /** pointer size for record */
184         size_t dif_ptrsize;
185 };
186
187 enum dt_index_flags {
188         /** index supports variable sized keys */
189         DT_IND_VARKEY = 1 << 0,
190         /** index supports variable sized records */
191         DT_IND_VARREC = 1 << 1,
192         /** index can be modified */
193         DT_IND_UPDATE = 1 << 2,
194         /** index supports records with non-unique (duplicate) keys */
195         DT_IND_NONUNQ = 1 << 3
196 };
197
198 /**
199  * Features, required from index to support file system directories (mapping
200  * names to fids).
201  */
202 extern const struct dt_index_features dt_directory_features;
203
204 /**
205  * This is a general purpose dt allocation hint.
206  * It now contains the parent object.
207  * It can contain any allocation hint in the future.
208  */
209 struct dt_allocation_hint {
210         struct dt_object           *dah_parent;
211         __u32                       dah_mode;
212 };
213
214 /**
215  * object type specifier.
216  */
217
218 enum dt_format_type {
219         DFT_REGULAR,
220         DFT_DIR,
221         /** for mknod */
222         DFT_NODE,
223         /** for special index */
224         DFT_INDEX,
225         /** for symbolic link */
226         DFT_SYM,
227 };
228
229 /**
230  * object format specifier.
231  */
232 struct dt_object_format {
233         /** type for dt object */
234         enum dt_format_type dof_type;
235         union {
236                 struct dof_regular {
237                 } dof_reg;
238                 struct dof_dir {
239                 } dof_dir;
240                 struct dof_node {
241                 } dof_node;
242                 /**
243                  * special index need feature as parameter to create
244                  * special idx
245                  */
246                 struct dof_index {
247                         const struct dt_index_features *di_feat;
248                 } dof_idx;
249         } u;
250 };
251
252 enum dt_format_type dt_mode_to_dft(__u32 mode);
253
254 /** Version type. May differ in DMU and ldiskfs */
255 typedef __u64 dt_obj_version_t;
256
257 /**
258  * Per-dt-object operations.
259  */
260 struct dt_object_operations {
261         void  (*do_read_lock)(const struct lu_env *env,
262                               struct dt_object *dt, unsigned role);
263         void  (*do_write_lock)(const struct lu_env *env,
264                                struct dt_object *dt, unsigned role);
265         void  (*do_read_unlock)(const struct lu_env *env,
266                                 struct dt_object *dt);
267         void  (*do_write_unlock)(const struct lu_env *env,
268                                  struct dt_object *dt);
269         int  (*do_write_locked)(const struct lu_env *env,
270                                 struct dt_object *dt);
271         /**
272          * Note: following ->do_{x,}attr_{set,get}() operations are very
273          * similar to ->moo_{x,}attr_{set,get}() operations in struct
274          * md_object_operations (see md_object.h). These operations are not in
275          * lu_object_operations, because ->do_{x,}attr_set() versions take
276          * transaction handle as an argument (this transaction is started by
277          * caller). We might factor ->do_{x,}attr_get() into
278          * lu_object_operations, but that would break existing symmetry.
279          */
280
281         /**
282          * Return standard attributes.
283          *
284          * precondition: lu_object_exists(&dt->do_lu);
285          */
286         int   (*do_attr_get)(const struct lu_env *env,
287                              struct dt_object *dt, struct lu_attr *attr,
288                              struct lustre_capa *capa);
289         /**
290          * Set standard attributes.
291          *
292          * precondition: dt_object_exists(dt);
293          */
294         int   (*do_attr_set)(const struct lu_env *env,
295                              struct dt_object *dt,
296                              const struct lu_attr *attr,
297                              struct thandle *handle,
298                              struct lustre_capa *capa);
299         /**
300          * Return a value of an extended attribute.
301          *
302          * precondition: dt_object_exists(dt);
303          */
304         int   (*do_xattr_get)(const struct lu_env *env, struct dt_object *dt,
305                               struct lu_buf *buf, const char *name,
306                               struct lustre_capa *capa);
307         /**
308          * Set value of an extended attribute.
309          *
310          * \a fl - flags from enum lu_xattr_flags
311          *
312          * precondition: dt_object_exists(dt);
313          */
314         int   (*do_xattr_set)(const struct lu_env *env,
315                               struct dt_object *dt, const struct lu_buf *buf,
316                               const char *name, int fl, struct thandle *handle,
317                               struct lustre_capa *capa);
318         /**
319          * Delete existing extended attribute.
320          *
321          * precondition: dt_object_exists(dt);
322          */
323         int   (*do_xattr_del)(const struct lu_env *env,
324                               struct dt_object *dt,
325                               const char *name, struct thandle *handle,
326                               struct lustre_capa *capa);
327         /**
328          * Place list of existing extended attributes into \a buf (which has
329          * length len).
330          *
331          * precondition: dt_object_exists(dt);
332          */
333         int   (*do_xattr_list)(const struct lu_env *env,
334                                struct dt_object *dt, struct lu_buf *buf,
335                                struct lustre_capa *capa);
336         /**
337          * Init allocation hint using parent object and child mode.
338          * (1) The \a parent might be NULL if this is a partial creation for
339          *     remote object.
340          * (2) The type of child is in \a child_mode.
341          * (3) The result hint is stored in \a ah;
342          */
343         void  (*do_ah_init)(const struct lu_env *env,
344                             struct dt_allocation_hint *ah,
345                             struct dt_object *parent,
346                             cfs_umode_t child_mode);
347         /**
348          * Create new object on this device.
349          *
350          * precondition: !dt_object_exists(dt);
351          * postcondition: ergo(result == 0, dt_object_exists(dt));
352          */
353         int   (*do_create)(const struct lu_env *env, struct dt_object *dt,
354                            struct lu_attr *attr,
355                            struct dt_allocation_hint *hint,
356                            struct dt_object_format *dof,
357                            struct thandle *th);
358
359         /**
360          * Announce that this object is going to be used as an index. This
361          * operation check that object supports indexing operations and
362          * installs appropriate dt_index_operations vector on success.
363          *
364          * Also probes for features. Operation is successful if all required
365          * features are supported.
366          */
367         int   (*do_index_try)(const struct lu_env *env,
368                               struct dt_object *dt,
369                               const struct dt_index_features *feat);
370         /**
371          * Add nlink of the object
372          * precondition: dt_object_exists(dt);
373          */
374         void  (*do_ref_add)(const struct lu_env *env,
375                             struct dt_object *dt, struct thandle *th);
376         /**
377          * Del nlink of the object
378          * precondition: dt_object_exists(dt);
379          */
380         void  (*do_ref_del)(const struct lu_env *env,
381                             struct dt_object *dt, struct thandle *th);
382
383         struct obd_capa *(*do_capa_get)(const struct lu_env *env,
384                                         struct dt_object *dt,
385                                         struct lustre_capa *old,
386                                         __u64 opc);
387         int (*do_object_sync)(const struct lu_env *, struct dt_object *);
388         dt_obj_version_t (*do_version_get)(const struct lu_env *env,
389                                            struct dt_object *dt);
390         void (*do_version_set)(const struct lu_env *env, struct dt_object *dt,
391                                dt_obj_version_t new_version);
392         /**
393          * Get object info of next level. Currently, only get inode from osd.
394          * This is only used by quota b=16542
395          * precondition: dt_object_exists(dt);
396          */
397         int (*do_data_get)(const struct lu_env *env, struct dt_object *dt,
398                            void **data);
399 };
400
401 /**
402  * Per-dt-object operations on "file body".
403  */
404 struct dt_body_operations {
405         /**
406          * precondition: dt_object_exists(dt);
407          */
408         ssize_t (*dbo_read)(const struct lu_env *env, struct dt_object *dt,
409                             struct lu_buf *buf, loff_t *pos,
410                             struct lustre_capa *capa);
411         /**
412          * precondition: dt_object_exists(dt);
413          */
414         ssize_t (*dbo_write)(const struct lu_env *env, struct dt_object *dt,
415                              const struct lu_buf *buf, loff_t *pos,
416                              struct thandle *handle, struct lustre_capa *capa,
417                              int ignore_quota);
418 };
419
420 /**
421  * Incomplete type of index record.
422  */
423 struct dt_rec;
424
425 /**
426  * Incomplete type of index key.
427  */
428 struct dt_key;
429
430 /**
431  * Incomplete type of dt iterator.
432  */
433 struct dt_it;
434
435 /**
436  * Per-dt-object operations on object as index.
437  */
438 struct dt_index_operations {
439         /**
440          * precondition: dt_object_exists(dt);
441          */
442         int (*dio_lookup)(const struct lu_env *env, struct dt_object *dt,
443                           struct dt_rec *rec, const struct dt_key *key,
444                           struct lustre_capa *capa);
445         /**
446          * precondition: dt_object_exists(dt);
447          */
448         int (*dio_insert)(const struct lu_env *env, struct dt_object *dt,
449                           const struct dt_rec *rec, const struct dt_key *key,
450                           struct thandle *handle, struct lustre_capa *capa,
451                           int ignore_quota);
452         /**
453          * precondition: dt_object_exists(dt);
454          */
455         int (*dio_delete)(const struct lu_env *env, struct dt_object *dt,
456                           const struct dt_key *key, struct thandle *handle,
457                           struct lustre_capa *capa);
458         /**
459          * Iterator interface
460          */
461         struct dt_it_ops {
462                 /**
463                  * Allocate and initialize new iterator.
464                  *
465                  * precondition: dt_object_exists(dt);
466                  */
467                 struct dt_it *(*init)(const struct lu_env *env,
468                                       struct dt_object *dt,
469                                       __u32 attr,
470                                       struct lustre_capa *capa);
471                 void          (*fini)(const struct lu_env *env,
472                                       struct dt_it *di);
473                 int            (*get)(const struct lu_env *env,
474                                       struct dt_it *di,
475                                       const struct dt_key *key);
476                 void           (*put)(const struct lu_env *env,
477                                       struct dt_it *di);
478                 int           (*next)(const struct lu_env *env,
479                                       struct dt_it *di);
480                 struct dt_key *(*key)(const struct lu_env *env,
481                                       const struct dt_it *di);
482                 int       (*key_size)(const struct lu_env *env,
483                                       const struct dt_it *di);
484                 int            (*rec)(const struct lu_env *env,
485                                       const struct dt_it *di,
486                                       struct lu_dirent *lde,
487                                       __u32 attr);
488                 __u64        (*store)(const struct lu_env *env,
489                                       const struct dt_it *di);
490                 int           (*load)(const struct lu_env *env,
491                                       const struct dt_it *di, __u64 hash);
492         } dio_it;
493 };
494
495 struct dt_device {
496         struct lu_device                   dd_lu_dev;
497         const struct dt_device_operations *dd_ops;
498
499         /**
500          * List of dt_txn_callback (see below). This is not protected in any
501          * way, because callbacks are supposed to be added/deleted only during
502          * single-threaded start-up shut-down procedures.
503          */
504         cfs_list_t                         dd_txn_callbacks;
505 };
506
507 int  dt_device_init(struct dt_device *dev, struct lu_device_type *t);
508 void dt_device_fini(struct dt_device *dev);
509
510 static inline int lu_device_is_dt(const struct lu_device *d)
511 {
512         return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT);
513 }
514
515 static inline struct dt_device * lu2dt_dev(struct lu_device *l)
516 {
517         LASSERT(lu_device_is_dt(l));
518         return container_of0(l, struct dt_device, dd_lu_dev);
519 }
520
521 struct dt_object {
522         struct lu_object                   do_lu;
523         const struct dt_object_operations *do_ops;
524         const struct dt_body_operations   *do_body_ops;
525         const struct dt_index_operations  *do_index_ops;
526 };
527
528 int  dt_object_init(struct dt_object *obj,
529                     struct lu_object_header *h, struct lu_device *d);
530
531 void dt_object_fini(struct dt_object *obj);
532
533 static inline int dt_object_exists(const struct dt_object *dt)
534 {
535         return lu_object_exists(&dt->do_lu);
536 }
537
538 struct txn_param {
539         /** number of blocks this transaction will modify */
540         unsigned int tp_credits;
541         /** sync transaction is needed */
542         __u32        tp_sync:1;
543 };
544
545 static inline void txn_param_init(struct txn_param *p, unsigned int credits)
546 {
547         memset(p, 0, sizeof(*p));
548         p->tp_credits = credits;
549 }
550
551 static inline void txn_param_credit_add(struct txn_param *p,
552                                         unsigned int credits)
553 {
554         p->tp_credits += credits;
555 }
556
557 static inline void txn_param_sync(struct txn_param *p)
558 {
559         p->tp_sync = 1;
560 }
561
562 /**
563  * This is the general purpose transaction handle.
564  * 1. Transaction Life Cycle
565  *      This transaction handle is allocated upon starting a new transaction,
566  *      and deallocated after this transaction is committed.
567  * 2. Transaction Nesting
568  *      We do _NOT_ support nested transaction. So, every thread should only
569  *      have one active transaction, and a transaction only belongs to one
570  *      thread. Due to this, transaction handle need no reference count.
571  * 3. Transaction & dt_object locking
572  *      dt_object locks should be taken inside transaction.
573  * 4. Transaction & RPC
574  *      No RPC request should be issued inside transaction.
575  */
576 struct thandle {
577         /** the dt device on which the transactions are executed */
578         struct dt_device *th_dev;
579
580         /** context for this transaction, tag is LCT_TX_HANDLE */
581         struct lu_context th_ctx;
582
583         /** the last operation result in this transaction.
584          * this value is used in recovery */
585         __s32             th_result;
586 };
587
588 /**
589  * Transaction call-backs.
590  *
591  * These are invoked by osd (or underlying transaction engine) when
592  * transaction changes state.
593  *
594  * Call-backs are used by upper layers to modify transaction parameters and to
595  * perform some actions on for each transaction state transition. Typical
596  * example is mdt registering call-back to write into last-received file
597  * before each transaction commit.
598  */
599 struct dt_txn_callback {
600         int (*dtc_txn_start)(const struct lu_env *env,
601                              struct txn_param *param, void *cookie);
602         int (*dtc_txn_stop)(const struct lu_env *env,
603                             struct thandle *txn, void *cookie);
604         int (*dtc_txn_commit)(const struct lu_env *env,
605                               struct thandle *txn, void *cookie);
606         void                *dtc_cookie;
607         __u32                dtc_tag;
608         cfs_list_t           dtc_linkage;
609 };
610
611 void dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb);
612 void dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb);
613
614 int dt_txn_hook_start(const struct lu_env *env,
615                       struct dt_device *dev, struct txn_param *param);
616 int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn);
617 int dt_txn_hook_commit(const struct lu_env *env, struct thandle *txn);
618
619 int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj);
620
621 /**
622  * Callback function used for parsing path.
623  * \see llo_store_resolve
624  */
625 typedef int (*dt_entry_func_t)(const struct lu_env *env,
626                             const char *name,
627                             void *pvt);
628
629 #define DT_MAX_PATH 1024
630
631 int dt_path_parser(const struct lu_env *env,
632                    char *local, dt_entry_func_t entry_func,
633                    void *data);
634
635 struct dt_object *dt_store_open(const struct lu_env *env,
636                                 struct dt_device *dt,
637                                 const char *dirname,
638                                 const char *filename,
639                                 struct lu_fid *fid);
640
641 struct dt_object *dt_locate(const struct lu_env *env,
642                             struct dt_device *dev,
643                             const struct lu_fid *fid);
644
645 static inline dt_obj_version_t do_version_get(const struct lu_env *env,
646                                               struct dt_object *o)
647 {
648         LASSERT(o->do_ops->do_version_get);
649         return o->do_ops->do_version_get(env, o);
650 }
651
652 static inline void do_version_set(const struct lu_env *env,
653                                   struct dt_object *o, dt_obj_version_t v)
654 {
655         LASSERT(o->do_ops->do_version_set);
656         return o->do_ops->do_version_set(env, o, v);
657 }
658
659 int dt_record_read(const struct lu_env *env, struct dt_object *dt,
660                    struct lu_buf *buf, loff_t *pos);
661 int dt_record_write(const struct lu_env *env, struct dt_object *dt,
662                     const struct lu_buf *buf, loff_t *pos, struct thandle *th);
663
664
665 static inline struct thandle *dt_trans_start(const struct lu_env *env,
666                                              struct dt_device *d,
667                                              struct txn_param *p)
668 {
669         LASSERT(d->dd_ops->dt_trans_start);
670         return d->dd_ops->dt_trans_start(env, d, p);
671 }
672
673 static inline void dt_trans_stop(const struct lu_env *env,
674                                  struct dt_device *d,
675                                  struct thandle *th)
676 {
677         LASSERT(d->dd_ops->dt_trans_stop);
678         return d->dd_ops->dt_trans_stop(env, th);
679 }
680 /** @} dt */
681 #endif /* __LUSTRE_DT_OBJECT_H */