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