Whamcloud - gitweb
b2e9021bee6af0ae85db50b88ba1c33594933196
[fs/lustre-release.git] / lustre / include / dt_object.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2012, Whamcloud, Inc.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #ifndef __LUSTRE_DT_OBJECT_H
38 #define __LUSTRE_DT_OBJECT_H
39
40 /** \defgroup dt dt
41  * Sub-class of lu_object with methods common for "data" objects in OST stack.
42  *
43  * Data objects behave like regular files: you can read/write them, get and
44  * set their attributes. Implementation of dt interface is supposed to
45  * implement some form of garbage collection, normally reference counting
46  * (nlink) based one.
47  *
48  * Examples: osd (lustre/osd) is an implementation of dt interface.
49  * @{
50  */
51
52
53 /*
54  * super-class definitions.
55  */
56 #include <lu_object.h>
57
58 #include <libcfs/libcfs.h>
59
60 struct seq_file;
61 struct proc_dir_entry;
62 struct lustre_cfg;
63
64 struct thandle;
65 struct dt_device;
66 struct dt_object;
67 struct dt_index_features;
68 struct dt_quota_ctxt;
69 struct niobuf_local;
70 struct niobuf_remote;
71
72 typedef enum {
73         MNTOPT_USERXATTR        = 0x00000001,
74         MNTOPT_ACL              = 0x00000002,
75 } mntopt_t;
76
77 struct dt_device_param {
78         unsigned           ddp_max_name_len;
79         unsigned           ddp_max_nlink;
80         unsigned           ddp_block_shift;
81         mntopt_t           ddp_mntopts;
82         unsigned           ddp_max_ea_size;
83         void              *ddp_mnt; /* XXX: old code can retrieve mnt -bzzz */
84         int                ddp_mount_type;
85         unsigned long long ddp_maxbytes;
86         /* percentage of available space to reserve for grant error margin */
87         int                ddp_grant_reserved;
88         /* per-inode space consumption */
89         short              ddp_inodespace;
90         /* per-fragment grant overhead to be used by client for grant
91          * calculation */
92         int                ddp_grant_frag;
93 };
94
95 /**
96  * Per-transaction commit callback function
97  */
98 struct dt_txn_commit_cb;
99 typedef void (*dt_cb_t)(struct lu_env *env, struct thandle *th,
100                         struct dt_txn_commit_cb *cb, int err);
101 /**
102  * Special per-transaction callback for cases when just commit callback
103  * is needed and per-device callback are not convenient to use
104  */
105 struct dt_txn_commit_cb {
106         cfs_list_t dcb_linkage;
107         dt_cb_t    dcb_func;
108 };
109
110 /**
111  * Operations on dt device.
112  */
113 struct dt_device_operations {
114         /**
115          * Return device-wide statistics.
116          */
117         int   (*dt_statfs)(const struct lu_env *env,
118                            struct dt_device *dev, struct obd_statfs *osfs);
119         /**
120          * Create transaction, described by \a param.
121          */
122         struct thandle *(*dt_trans_create)(const struct lu_env *env,
123                                            struct dt_device *dev);
124         /**
125          * Start transaction, described by \a param.
126          */
127         int   (*dt_trans_start)(const struct lu_env *env,
128                                 struct dt_device *dev, struct thandle *th);
129         /**
130          * Finish previously started transaction.
131          */
132         int   (*dt_trans_stop)(const struct lu_env *env,
133                                struct thandle *th);
134         /**
135          * Add commit callback to the transaction.
136          */
137         int   (*dt_trans_cb_add)(struct thandle *th,
138                                  struct dt_txn_commit_cb *dcb);
139         /**
140          * Return fid of root index object.
141          */
142         int   (*dt_root_get)(const struct lu_env *env,
143                              struct dt_device *dev, struct lu_fid *f);
144         /**
145          * Return device configuration data.
146          */
147         void  (*dt_conf_get)(const struct lu_env *env,
148                              const struct dt_device *dev,
149                              struct dt_device_param *param);
150         /**
151          *  handling device state, mostly for tests
152          */
153         int   (*dt_sync)(const struct lu_env *env, struct dt_device *dev);
154         int   (*dt_ro)(const struct lu_env *env, struct dt_device *dev);
155         /**
156           * Start a transaction commit asynchronously
157           *
158           * \param env environment
159           * \param dev dt_device to start commit on
160           *
161           * \return 0 success, negative value if error
162           */
163          int   (*dt_commit_async)(const struct lu_env *env,
164                                   struct dt_device *dev);
165         /**
166          * Initialize capability context.
167          */
168         int   (*dt_init_capa_ctxt)(const struct lu_env *env,
169                                    struct dt_device *dev,
170                                    int mode, unsigned long timeout,
171                                    __u32 alg, struct lustre_capa_key *keys);
172         /**
173          * Initialize quota context.
174          */
175         void (*dt_init_quota_ctxt)(const struct lu_env *env,
176                                    struct dt_device *dev,
177                                    struct dt_quota_ctxt *ctxt, void *data);
178 };
179
180 struct dt_index_features {
181         /** required feature flags from enum dt_index_flags */
182         __u32 dif_flags;
183         /** minimal required key size */
184         size_t dif_keysize_min;
185         /** maximal required key size, 0 if no limit */
186         size_t dif_keysize_max;
187         /** minimal required record size */
188         size_t dif_recsize_min;
189         /** maximal required record size, 0 if no limit */
190         size_t dif_recsize_max;
191         /** pointer size for record */
192         size_t dif_ptrsize;
193 };
194
195 enum dt_index_flags {
196         /** index supports variable sized keys */
197         DT_IND_VARKEY = 1 << 0,
198         /** index supports variable sized records */
199         DT_IND_VARREC = 1 << 1,
200         /** index can be modified */
201         DT_IND_UPDATE = 1 << 2,
202         /** index supports records with non-unique (duplicate) keys */
203         DT_IND_NONUNQ = 1 << 3
204 };
205
206 /**
207  * Features, required from index to support file system directories (mapping
208  * names to fids).
209  */
210 extern const struct dt_index_features dt_directory_features;
211
212 /**
213  * This is a general purpose dt allocation hint.
214  * It now contains the parent object.
215  * It can contain any allocation hint in the future.
216  */
217 struct dt_allocation_hint {
218         struct dt_object           *dah_parent;
219         __u32                       dah_mode;
220 };
221
222 /**
223  * object type specifier.
224  */
225
226 enum dt_format_type {
227         DFT_REGULAR,
228         DFT_DIR,
229         /** for mknod */
230         DFT_NODE,
231         /** for special index */
232         DFT_INDEX,
233         /** for symbolic link */
234         DFT_SYM,
235 };
236
237 /**
238  * object format specifier.
239  */
240 struct dt_object_format {
241         /** type for dt object */
242         enum dt_format_type dof_type;
243         union {
244                 struct dof_regular {
245                 } dof_reg;
246                 struct dof_dir {
247                 } dof_dir;
248                 struct dof_node {
249                 } dof_node;
250                 /**
251                  * special index need feature as parameter to create
252                  * special idx
253                  */
254                 struct dof_index {
255                         const struct dt_index_features *di_feat;
256                 } dof_idx;
257         } u;
258 };
259
260 enum dt_format_type dt_mode_to_dft(__u32 mode);
261
262 typedef __u64 dt_obj_version_t;
263
264 /**
265  * Per-dt-object operations.
266  */
267 struct dt_object_operations {
268         void  (*do_read_lock)(const struct lu_env *env,
269                               struct dt_object *dt, unsigned role);
270         void  (*do_write_lock)(const struct lu_env *env,
271                                struct dt_object *dt, unsigned role);
272         void  (*do_read_unlock)(const struct lu_env *env,
273                                 struct dt_object *dt);
274         void  (*do_write_unlock)(const struct lu_env *env,
275                                  struct dt_object *dt);
276         int  (*do_write_locked)(const struct lu_env *env,
277                                 struct dt_object *dt);
278         /**
279          * Note: following ->do_{x,}attr_{set,get}() operations are very
280          * similar to ->moo_{x,}attr_{set,get}() operations in struct
281          * md_object_operations (see md_object.h). These operations are not in
282          * lu_object_operations, because ->do_{x,}attr_set() versions take
283          * transaction handle as an argument (this transaction is started by
284          * caller). We might factor ->do_{x,}attr_get() into
285          * lu_object_operations, but that would break existing symmetry.
286          */
287
288         /**
289          * Return standard attributes.
290          *
291          * precondition: lu_object_exists(&dt->do_lu);
292          */
293         int   (*do_attr_get)(const struct lu_env *env,
294                              struct dt_object *dt, struct lu_attr *attr,
295                              struct lustre_capa *capa);
296         /**
297          * Set standard attributes.
298          *
299          * precondition: dt_object_exists(dt);
300          */
301         int   (*do_declare_attr_set)(const struct lu_env *env,
302                                      struct dt_object *dt,
303                                      const struct lu_attr *attr,
304                                      struct thandle *handle);
305         int   (*do_attr_set)(const struct lu_env *env,
306                              struct dt_object *dt,
307                              const struct lu_attr *attr,
308                              struct thandle *handle,
309                              struct lustre_capa *capa);
310         /**
311          * Return a value of an extended attribute.
312          *
313          * precondition: dt_object_exists(dt);
314          */
315         int   (*do_xattr_get)(const struct lu_env *env, struct dt_object *dt,
316                               struct lu_buf *buf, const char *name,
317                               struct lustre_capa *capa);
318         /**
319          * Set value of an extended attribute.
320          *
321          * \a fl - flags from enum lu_xattr_flags
322          *
323          * precondition: dt_object_exists(dt);
324          */
325         int   (*do_declare_xattr_set)(const struct lu_env *env,
326                                       struct dt_object *dt,
327                                       const struct lu_buf *buf,
328                                       const char *name, int fl,
329                                       struct thandle *handle);
330         int   (*do_xattr_set)(const struct lu_env *env,
331                               struct dt_object *dt, const struct lu_buf *buf,
332                               const char *name, int fl, struct thandle *handle,
333                               struct lustre_capa *capa);
334         /**
335          * Delete existing extended attribute.
336          *
337          * precondition: dt_object_exists(dt);
338          */
339         int   (*do_declare_xattr_del)(const struct lu_env *env,
340                                       struct dt_object *dt,
341                                       const char *name, struct thandle *handle);
342         int   (*do_xattr_del)(const struct lu_env *env,
343                               struct dt_object *dt,
344                               const char *name, struct thandle *handle,
345                               struct lustre_capa *capa);
346         /**
347          * Place list of existing extended attributes into \a buf (which has
348          * length len).
349          *
350          * precondition: dt_object_exists(dt);
351          */
352         int   (*do_xattr_list)(const struct lu_env *env,
353                                struct dt_object *dt, struct lu_buf *buf,
354                                struct lustre_capa *capa);
355         /**
356          * Init allocation hint using parent object and child mode.
357          * (1) The \a parent might be NULL if this is a partial creation for
358          *     remote object.
359          * (2) The type of child is in \a child_mode.
360          * (3) The result hint is stored in \a ah;
361          */
362         void  (*do_ah_init)(const struct lu_env *env,
363                             struct dt_allocation_hint *ah,
364                             struct dt_object *parent,
365                             cfs_umode_t child_mode);
366         /**
367          * Create new object on this device.
368          *
369          * precondition: !dt_object_exists(dt);
370          * postcondition: ergo(result == 0, dt_object_exists(dt));
371          */
372         int   (*do_declare_create)(const struct lu_env *env,
373                                    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         int   (*do_create)(const struct lu_env *env, struct dt_object *dt,
379                            struct lu_attr *attr,
380                            struct dt_allocation_hint *hint,
381                            struct dt_object_format *dof,
382                            struct thandle *th);
383
384         /**
385           Destroy object on this device
386          * precondition: !dt_object_exists(dt);
387          * postcondition: ergo(result == 0, dt_object_exists(dt));
388          */
389         int   (*do_declare_destroy)(const struct lu_env *env,
390                                     struct dt_object *dt,
391                                     struct thandle *th);
392         int   (*do_destroy)(const struct lu_env *env, struct dt_object *dt,
393                             struct thandle *th);
394
395         /**
396          * Announce that this object is going to be used as an index. This
397          * operation check that object supports indexing operations and
398          * installs appropriate dt_index_operations vector on success.
399          *
400          * Also probes for features. Operation is successful if all required
401          * features are supported.
402          */
403         int   (*do_index_try)(const struct lu_env *env,
404                               struct dt_object *dt,
405                               const struct dt_index_features *feat);
406         /**
407          * Add nlink of the object
408          * precondition: dt_object_exists(dt);
409          */
410         int   (*do_declare_ref_add)(const struct lu_env *env,
411                                     struct dt_object *dt, struct thandle *th);
412         int   (*do_ref_add)(const struct lu_env *env,
413                             struct dt_object *dt, struct thandle *th);
414         /**
415          * Del nlink of the object
416          * precondition: dt_object_exists(dt);
417          */
418         int   (*do_declare_ref_del)(const struct lu_env *env,
419                                     struct dt_object *dt, struct thandle *th);
420         int   (*do_ref_del)(const struct lu_env *env,
421                             struct dt_object *dt, struct thandle *th);
422
423         struct obd_capa *(*do_capa_get)(const struct lu_env *env,
424                                         struct dt_object *dt,
425                                         struct lustre_capa *old,
426                                         __u64 opc);
427         int (*do_object_sync)(const struct lu_env *, struct dt_object *);
428         /**
429          * Get object info of next level. Currently, only get inode from osd.
430          * This is only used by quota b=16542
431          * precondition: dt_object_exists(dt);
432          */
433         int (*do_data_get)(const struct lu_env *env, struct dt_object *dt,
434                            void **data);
435 };
436
437 /**
438  * Per-dt-object operations on "file body".
439  */
440 struct dt_body_operations {
441         /**
442          * precondition: dt_object_exists(dt);
443          */
444         ssize_t (*dbo_read)(const struct lu_env *env, struct dt_object *dt,
445                             struct lu_buf *buf, loff_t *pos,
446                             struct lustre_capa *capa);
447         /**
448          * precondition: dt_object_exists(dt);
449          */
450         ssize_t (*dbo_declare_write)(const struct lu_env *env,
451                                      struct dt_object *dt,
452                                      const loff_t size, loff_t pos,
453                                      struct thandle *handle);
454         ssize_t (*dbo_write)(const struct lu_env *env, struct dt_object *dt,
455                              const struct lu_buf *buf, loff_t *pos,
456                              struct thandle *handle, struct lustre_capa *capa,
457                              int ignore_quota);
458         /*
459          * methods for zero-copy IO
460          */
461
462         /*
463          * precondition: dt_object_exists(dt);
464          * returns:
465          * < 0 - error code
466          * = 0 - illegal
467          * > 0 - number of local buffers prepared
468          */
469         int (*dbo_bufs_get)(const struct lu_env *env, struct dt_object *dt,
470                             loff_t pos, ssize_t len, struct niobuf_local *lb,
471                             int rw, struct lustre_capa *capa);
472         /*
473          * precondition: dt_object_exists(dt);
474          */
475         int (*dbo_bufs_put)(const struct lu_env *env, struct dt_object *dt,
476                             struct niobuf_local *lb, int nr);
477         /*
478          * precondition: dt_object_exists(dt);
479          */
480         int (*dbo_write_prep)(const struct lu_env *env, struct dt_object *dt,
481                               struct niobuf_local *lb, int nr);
482         /*
483          * precondition: dt_object_exists(dt);
484          */
485         int (*dbo_declare_write_commit)(const struct lu_env *env,
486                                         struct dt_object *dt,
487                                         struct niobuf_local *,
488                                         int, struct thandle *);
489         /*
490          * precondition: dt_object_exists(dt);
491          */
492         int (*dbo_write_commit)(const struct lu_env *env, struct dt_object *dt,
493                                 struct niobuf_local *, int, struct thandle *);
494         /*
495          * precondition: dt_object_exists(dt);
496          */
497         int (*dbo_read_prep)(const struct lu_env *env, struct dt_object *dt,
498                              struct niobuf_local *lnb, int nr);
499         int (*dbo_fiemap_get)(const struct lu_env *env, struct dt_object *dt,
500                               struct ll_user_fiemap *fm);
501         /**
502          * Punch object's content
503          * precondition: regular object, not index
504          */
505         int   (*do_declare_punch)(const struct lu_env *, struct dt_object *,
506                                   __u64, __u64, struct thandle *th);
507         int   (*do_punch)(const struct lu_env *env, struct dt_object *dt,
508                           __u64 start, __u64 end, struct thandle *th,
509                           struct lustre_capa *capa);
510 };
511
512 /**
513  * Incomplete type of index record.
514  */
515 struct dt_rec;
516
517 /**
518  * Incomplete type of index key.
519  */
520 struct dt_key;
521
522 /**
523  * Incomplete type of dt iterator.
524  */
525 struct dt_it;
526
527 /**
528  * Per-dt-object operations on object as index.
529  */
530 struct dt_index_operations {
531         /**
532          * precondition: dt_object_exists(dt);
533          */
534         int (*dio_lookup)(const struct lu_env *env, struct dt_object *dt,
535                           struct dt_rec *rec, const struct dt_key *key,
536                           struct lustre_capa *capa);
537         /**
538          * precondition: dt_object_exists(dt);
539          */
540         int (*dio_declare_insert)(const struct lu_env *env,
541                                   struct dt_object *dt,
542                                   const struct dt_rec *rec,
543                                   const struct dt_key *key,
544                                   struct thandle *handle);
545         int (*dio_insert)(const struct lu_env *env, struct dt_object *dt,
546                           const struct dt_rec *rec, const struct dt_key *key,
547                           struct thandle *handle, struct lustre_capa *capa,
548                           int ignore_quota);
549         /**
550          * precondition: dt_object_exists(dt);
551          */
552         int (*dio_declare_delete)(const struct lu_env *env,
553                                   struct dt_object *dt,
554                                   const struct dt_key *key,
555                                   struct thandle *handle);
556         int (*dio_delete)(const struct lu_env *env, struct dt_object *dt,
557                           const struct dt_key *key, struct thandle *handle,
558                           struct lustre_capa *capa);
559         /**
560          * Iterator interface
561          */
562         struct dt_it_ops {
563                 /**
564                  * Allocate and initialize new iterator.
565                  *
566                  * precondition: dt_object_exists(dt);
567                  */
568                 struct dt_it *(*init)(const struct lu_env *env,
569                                       struct dt_object *dt,
570                                       __u32 attr,
571                                       struct lustre_capa *capa);
572                 void          (*fini)(const struct lu_env *env,
573                                       struct dt_it *di);
574                 int            (*get)(const struct lu_env *env,
575                                       struct dt_it *di,
576                                       const struct dt_key *key);
577                 void           (*put)(const struct lu_env *env,
578                                       struct dt_it *di);
579                 int           (*next)(const struct lu_env *env,
580                                       struct dt_it *di);
581                 struct dt_key *(*key)(const struct lu_env *env,
582                                       const struct dt_it *di);
583                 int       (*key_size)(const struct lu_env *env,
584                                       const struct dt_it *di);
585                 int            (*rec)(const struct lu_env *env,
586                                       const struct dt_it *di,
587                                       struct dt_rec *rec,
588                                       __u32 attr);
589                 __u64        (*store)(const struct lu_env *env,
590                                       const struct dt_it *di);
591                 int           (*load)(const struct lu_env *env,
592                                       const struct dt_it *di, __u64 hash);
593                 int        (*key_rec)(const struct lu_env *env,
594                                       const struct dt_it *di, void* key_rec);
595         } dio_it;
596 };
597
598 struct dt_device {
599         struct lu_device                   dd_lu_dev;
600         const struct dt_device_operations *dd_ops;
601
602         /**
603          * List of dt_txn_callback (see below). This is not protected in any
604          * way, because callbacks are supposed to be added/deleted only during
605          * single-threaded start-up shut-down procedures.
606          */
607         cfs_list_t                         dd_txn_callbacks;
608 };
609
610 int  dt_device_init(struct dt_device *dev, struct lu_device_type *t);
611 void dt_device_fini(struct dt_device *dev);
612
613 static inline int lu_device_is_dt(const struct lu_device *d)
614 {
615         return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT);
616 }
617
618 static inline struct dt_device * lu2dt_dev(struct lu_device *l)
619 {
620         LASSERT(lu_device_is_dt(l));
621         return container_of0(l, struct dt_device, dd_lu_dev);
622 }
623
624 struct dt_object {
625         struct lu_object                   do_lu;
626         const struct dt_object_operations *do_ops;
627         const struct dt_body_operations   *do_body_ops;
628         const struct dt_index_operations  *do_index_ops;
629 };
630
631 static inline struct dt_object *lu2dt(struct lu_object *l)
632 {
633         LASSERT(l == NULL || IS_ERR(l) || lu_device_is_dt(l->lo_dev));
634         return container_of0(l, struct dt_object, do_lu);
635 }
636
637 int  dt_object_init(struct dt_object *obj,
638                     struct lu_object_header *h, struct lu_device *d);
639
640 void dt_object_fini(struct dt_object *obj);
641
642 static inline int dt_object_exists(const struct dt_object *dt)
643 {
644         return lu_object_exists(&dt->do_lu);
645 }
646
647 /**
648  * This is the general purpose transaction handle.
649  * 1. Transaction Life Cycle
650  *      This transaction handle is allocated upon starting a new transaction,
651  *      and deallocated after this transaction is committed.
652  * 2. Transaction Nesting
653  *      We do _NOT_ support nested transaction. So, every thread should only
654  *      have one active transaction, and a transaction only belongs to one
655  *      thread. Due to this, transaction handle need no reference count.
656  * 3. Transaction & dt_object locking
657  *      dt_object locks should be taken inside transaction.
658  * 4. Transaction & RPC
659  *      No RPC request should be issued inside transaction.
660  */
661 struct thandle {
662         /** the dt device on which the transactions are executed */
663         struct dt_device *th_dev;
664
665         /** additional tags (layers can add in declare) */
666         __u32             th_tags;
667
668         /** context for this transaction, tag is LCT_TX_HANDLE */
669         struct lu_context th_ctx;
670
671         /** the last operation result in this transaction.
672          * this value is used in recovery */
673         __s32             th_result;
674
675         /** whether we need sync commit */
676         int               th_sync:1;
677
678         /* local transation, no need to inform other layers */
679         int               th_local:1;
680 };
681
682 /**
683  * Transaction call-backs.
684  *
685  * These are invoked by osd (or underlying transaction engine) when
686  * transaction changes state.
687  *
688  * Call-backs are used by upper layers to modify transaction parameters and to
689  * perform some actions on for each transaction state transition. Typical
690  * example is mdt registering call-back to write into last-received file
691  * before each transaction commit.
692  */
693 struct dt_txn_callback {
694         int (*dtc_txn_start)(const struct lu_env *env,
695                              struct thandle *txn, void *cookie);
696         int (*dtc_txn_stop)(const struct lu_env *env,
697                             struct thandle *txn, void *cookie);
698         void (*dtc_txn_commit)(struct thandle *txn, void *cookie);
699         void                *dtc_cookie;
700         __u32                dtc_tag;
701         cfs_list_t           dtc_linkage;
702 };
703
704 void dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb);
705 void dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb);
706
707 int dt_txn_hook_start(const struct lu_env *env,
708                       struct dt_device *dev, struct thandle *txn);
709 int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn);
710 void dt_txn_hook_commit(struct thandle *txn);
711
712 int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj);
713
714 /**
715  * Callback function used for parsing path.
716  * \see llo_store_resolve
717  */
718 typedef int (*dt_entry_func_t)(const struct lu_env *env,
719                             const char *name,
720                             void *pvt);
721
722 #define DT_MAX_PATH 1024
723
724 int dt_path_parser(const struct lu_env *env,
725                    char *local, dt_entry_func_t entry_func,
726                    void *data);
727
728 struct dt_object *dt_store_open(const struct lu_env *env,
729                                 struct dt_device *dt,
730                                 const char *dirname,
731                                 const char *filename,
732                                 struct lu_fid *fid);
733
734 struct dt_object *dt_find_or_create(const struct lu_env *env,
735                                     struct dt_device *dt,
736                                     const struct lu_fid *fid,
737                                     struct dt_object_format *dof,
738                                     struct lu_attr *attr);
739
740 struct dt_object *dt_locate(const struct lu_env *env,
741                             struct dt_device *dev,
742                             const struct lu_fid *fid);
743
744 static inline int dt_object_sync(const struct lu_env *env,
745                                  struct dt_object *o)
746 {
747         LASSERT(o);
748         LASSERT(o->do_ops);
749         LASSERT(o->do_ops->do_object_sync);
750         return o->do_ops->do_object_sync(env, o);
751 }
752
753 int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
754                            struct thandle *th);
755 void dt_version_set(const struct lu_env *env, struct dt_object *o,
756                     dt_obj_version_t version, struct thandle *th);
757 dt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o);
758
759
760 int dt_read(const struct lu_env *env, struct dt_object *dt,
761             struct lu_buf *buf, loff_t *pos);
762 int dt_record_read(const struct lu_env *env, struct dt_object *dt,
763                    struct lu_buf *buf, loff_t *pos);
764 int dt_record_write(const struct lu_env *env, struct dt_object *dt,
765                     const struct lu_buf *buf, loff_t *pos, struct thandle *th);
766
767 static inline struct thandle *dt_trans_create(const struct lu_env *env,
768                                               struct dt_device *d)
769 {
770         LASSERT(d->dd_ops->dt_trans_create);
771         return d->dd_ops->dt_trans_create(env, d);
772 }
773
774 static inline int dt_trans_start(const struct lu_env *env,
775                                  struct dt_device *d, struct thandle *th)
776 {
777         LASSERT(d->dd_ops->dt_trans_start);
778         return d->dd_ops->dt_trans_start(env, d, th);
779 }
780
781 /* for this transaction hooks shouldn't be called */
782 static inline int dt_trans_start_local(const struct lu_env *env,
783                                        struct dt_device *d, struct thandle *th)
784 {
785         LASSERT(d->dd_ops->dt_trans_start);
786         th->th_local = 1;
787         return d->dd_ops->dt_trans_start(env, d, th);
788 }
789
790 static inline int dt_trans_stop(const struct lu_env *env,
791                                 struct dt_device *d, struct thandle *th)
792 {
793         LASSERT(d->dd_ops->dt_trans_stop);
794         return d->dd_ops->dt_trans_stop(env, th);
795 }
796
797 static inline int dt_trans_cb_add(struct thandle *th,
798                                   struct dt_txn_commit_cb *dcb)
799 {
800         LASSERT(th->th_dev->dd_ops->dt_trans_cb_add);
801         return th->th_dev->dd_ops->dt_trans_cb_add(th, dcb);
802 }
803 /** @} dt */
804
805
806 static inline int dt_declare_record_write(const struct lu_env *env,
807                                           struct dt_object *dt,
808                                           int size, loff_t pos,
809                                           struct thandle *th)
810 {
811         int rc;
812
813         LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
814         LASSERT(th != NULL);
815         LASSERT(dt->do_body_ops);
816         LASSERT(dt->do_body_ops->dbo_declare_write);
817         rc = dt->do_body_ops->dbo_declare_write(env, dt, size, pos, th);
818         return rc;
819 }
820
821 static inline int dt_declare_create(const struct lu_env *env,
822                                     struct dt_object *dt,
823                                     struct lu_attr *attr,
824                                     struct dt_allocation_hint *hint,
825                                     struct dt_object_format *dof,
826                                     struct thandle *th)
827 {
828         LASSERT(dt);
829         LASSERT(dt->do_ops);
830         LASSERT(dt->do_ops->do_declare_create);
831         return dt->do_ops->do_declare_create(env, dt, attr, hint, dof, th);
832 }
833
834 static inline int dt_create(const struct lu_env *env,
835                                     struct dt_object *dt,
836                                     struct lu_attr *attr,
837                                     struct dt_allocation_hint *hint,
838                                     struct dt_object_format *dof,
839                                     struct thandle *th)
840 {
841         LASSERT(dt);
842         LASSERT(dt->do_ops);
843         LASSERT(dt->do_ops->do_create);
844         return dt->do_ops->do_create(env, dt, attr, hint, dof, th);
845 }
846
847 static inline int dt_declare_destroy(const struct lu_env *env,
848                                      struct dt_object *dt,
849                                      struct thandle *th)
850 {
851         LASSERT(dt);
852         LASSERT(dt->do_ops);
853         LASSERT(dt->do_ops->do_declare_destroy);
854         return dt->do_ops->do_declare_destroy(env, dt, th);
855 }
856
857 static inline int dt_destroy(const struct lu_env *env,
858                              struct dt_object *dt,
859                              struct thandle *th)
860 {
861         LASSERT(dt);
862         LASSERT(dt->do_ops);
863         LASSERT(dt->do_ops->do_destroy);
864         return dt->do_ops->do_destroy(env, dt, th);
865 }
866
867 static inline void dt_read_lock(const struct lu_env *env,
868                                 struct dt_object *dt,
869                                 unsigned role)
870 {
871         LASSERT(dt);
872         LASSERT(dt->do_ops);
873         LASSERT(dt->do_ops->do_read_lock);
874         dt->do_ops->do_read_lock(env, dt, role);
875 }
876
877 static inline void dt_write_lock(const struct lu_env *env,
878                                 struct dt_object *dt,
879                                 unsigned role)
880 {
881         LASSERT(dt);
882         LASSERT(dt->do_ops);
883         LASSERT(dt->do_ops->do_write_lock);
884         dt->do_ops->do_write_lock(env, dt, role);
885 }
886
887 static inline void dt_read_unlock(const struct lu_env *env,
888                                 struct dt_object *dt)
889 {
890         LASSERT(dt);
891         LASSERT(dt->do_ops);
892         LASSERT(dt->do_ops->do_read_unlock);
893         dt->do_ops->do_read_unlock(env, dt);
894 }
895
896 static inline void dt_write_unlock(const struct lu_env *env,
897                                 struct dt_object *dt)
898 {
899         LASSERT(dt);
900         LASSERT(dt->do_ops);
901         LASSERT(dt->do_ops->do_write_unlock);
902         dt->do_ops->do_write_unlock(env, dt);
903 }
904
905 static inline int dt_write_locked(const struct lu_env *env,
906                                   struct dt_object *dt)
907 {
908         LASSERT(dt);
909         LASSERT(dt->do_ops);
910         LASSERT(dt->do_ops->do_write_locked);
911         return dt->do_ops->do_write_locked(env, dt);
912 }
913
914 static inline int dt_attr_get(const struct lu_env *env, struct dt_object *dt,
915                               struct lu_attr *la, void *arg)
916 {
917         LASSERT(dt);
918         LASSERT(dt->do_ops);
919         LASSERT(dt->do_ops->do_attr_get);
920         return dt->do_ops->do_attr_get(env, dt, la, arg);
921 }
922
923 static inline int dt_declare_attr_set(const struct lu_env *env,
924                                       struct dt_object *dt,
925                                       const struct lu_attr *la,
926                                       struct thandle *th)
927 {
928         LASSERT(dt);
929         LASSERT(dt->do_ops);
930         LASSERT(dt->do_ops->do_declare_attr_set);
931         return dt->do_ops->do_declare_attr_set(env, dt, la, th);
932 }
933
934 static inline int dt_attr_set(const struct lu_env *env, struct dt_object *dt,
935                               const struct lu_attr *la, struct thandle *th,
936                               struct lustre_capa *capa)
937 {
938         LASSERT(dt);
939         LASSERT(dt->do_ops);
940         LASSERT(dt->do_ops->do_attr_set);
941         return dt->do_ops->do_attr_set(env, dt, la, th, capa);
942 }
943
944 static inline int dt_declare_ref_add(const struct lu_env *env,
945                                      struct dt_object *dt, struct thandle *th)
946 {
947         LASSERT(dt);
948         LASSERT(dt->do_ops);
949         LASSERT(dt->do_ops->do_declare_ref_add);
950         return dt->do_ops->do_declare_ref_add(env, dt, th);
951 }
952
953 static inline int dt_ref_add(const struct lu_env *env,
954                              struct dt_object *dt, struct thandle *th)
955 {
956         LASSERT(dt);
957         LASSERT(dt->do_ops);
958         LASSERT(dt->do_ops->do_ref_add);
959         return dt->do_ops->do_ref_add(env, dt, th);
960 }
961
962 static inline int dt_declare_ref_del(const struct lu_env *env,
963                                      struct dt_object *dt, struct thandle *th)
964 {
965         LASSERT(dt);
966         LASSERT(dt->do_ops);
967         LASSERT(dt->do_ops->do_declare_ref_del);
968         return dt->do_ops->do_declare_ref_del(env, dt, th);
969 }
970
971 static inline int dt_ref_del(const struct lu_env *env,
972                              struct dt_object *dt, struct thandle *th)
973 {
974         LASSERT(dt);
975         LASSERT(dt->do_ops);
976         LASSERT(dt->do_ops->do_ref_del);
977         return dt->do_ops->do_ref_del(env, dt, th);
978 }
979
980 static inline struct obd_capa *dt_capa_get(const struct lu_env *env,
981                                            struct dt_object *dt,
982                                            struct lustre_capa *old, __u64 opc)
983 {
984         LASSERT(dt);
985         LASSERT(dt->do_ops);
986         LASSERT(dt->do_ops->do_ref_del);
987         return dt->do_ops->do_capa_get(env, dt, old, opc);
988 }
989
990 static inline int dt_bufs_get(const struct lu_env *env, struct dt_object *d,
991                               struct niobuf_remote *rnb,
992                               struct niobuf_local *lnb, int rw,
993                               struct lustre_capa *capa)
994 {
995         LASSERT(d);
996         LASSERT(d->do_body_ops);
997         LASSERT(d->do_body_ops->dbo_bufs_get);
998         return d->do_body_ops->dbo_bufs_get(env, d, rnb->offset,
999                                             rnb->len, lnb, rw, capa);
1000 }
1001
1002 static inline int dt_bufs_put(const struct lu_env *env, struct dt_object *d,
1003                               struct niobuf_local *lnb, int n)
1004 {
1005         LASSERT(d);
1006         LASSERT(d->do_body_ops);
1007         LASSERT(d->do_body_ops->dbo_bufs_put);
1008         return d->do_body_ops->dbo_bufs_put(env, d, lnb, n);
1009 }
1010
1011 static inline int dt_write_prep(const struct lu_env *env, struct dt_object *d,
1012                                 struct niobuf_local *lnb, int n)
1013 {
1014         LASSERT(d);
1015         LASSERT(d->do_body_ops);
1016         LASSERT(d->do_body_ops->dbo_write_prep);
1017         return d->do_body_ops->dbo_write_prep(env, d, lnb, n);
1018 }
1019
1020 static inline int dt_declare_write_commit(const struct lu_env *env,
1021                                           struct dt_object *d,
1022                                           struct niobuf_local *lnb,
1023                                           int n, struct thandle *th)
1024 {
1025         LASSERTF(d != NULL, "dt is NULL when we want to declare write\n");
1026         LASSERT(th != NULL);
1027         return d->do_body_ops->dbo_declare_write_commit(env, d, lnb, n, th);
1028 }
1029
1030
1031 static inline int dt_write_commit(const struct lu_env *env,
1032                                   struct dt_object *d, struct niobuf_local *lnb,
1033                                   int n, struct thandle *th)
1034 {
1035         LASSERT(d);
1036         LASSERT(d->do_body_ops);
1037         LASSERT(d->do_body_ops->dbo_write_commit);
1038         return d->do_body_ops->dbo_write_commit(env, d, lnb, n, th);
1039 }
1040
1041 static inline int dt_read_prep(const struct lu_env *env, struct dt_object *d,
1042                                struct niobuf_local *lnb, int n)
1043 {
1044         LASSERT(d);
1045         LASSERT(d->do_body_ops);
1046         LASSERT(d->do_body_ops->dbo_read_prep);
1047         return d->do_body_ops->dbo_read_prep(env, d, lnb, n);
1048 }
1049
1050 static inline int dt_declare_punch(const struct lu_env *env,
1051                                    struct dt_object *dt, __u64 start,
1052                                    __u64 end, struct thandle *th)
1053 {
1054         LASSERT(dt);
1055         LASSERT(dt->do_body_ops);
1056         LASSERT(dt->do_body_ops->do_declare_punch);
1057         return dt->do_body_ops->do_declare_punch(env, dt, start, end, th);
1058 }
1059
1060 static inline int dt_punch(const struct lu_env *env, struct dt_object *dt,
1061                            __u64 start, __u64 end, struct thandle *th,
1062                            struct lustre_capa *capa)
1063 {
1064         LASSERT(dt);
1065         LASSERT(dt->do_body_ops);
1066         LASSERT(dt->do_body_ops->do_punch);
1067         return dt->do_body_ops->do_punch(env, dt, start, end, th, capa);
1068 }
1069
1070 static inline int dt_fiemap_get(const struct lu_env *env, struct dt_object *d,
1071                                 struct ll_user_fiemap *fm)
1072 {
1073         LASSERT(d);
1074         if (d->do_body_ops == NULL)
1075                 return -EPROTO;
1076         LASSERT(d->do_body_ops->dbo_fiemap_get);
1077         return d->do_body_ops->dbo_fiemap_get(env, d, fm);
1078 }
1079
1080 static inline int dt_statfs(const struct lu_env *env, struct dt_device *dev,
1081                             struct obd_statfs *osfs)
1082 {
1083         LASSERT(dev);
1084         LASSERT(dev->dd_ops);
1085         LASSERT(dev->dd_ops->dt_statfs);
1086         return dev->dd_ops->dt_statfs(env, dev, osfs);
1087 }
1088
1089 static inline int dt_root_get(const struct lu_env *env, struct dt_device *dev,
1090                               struct lu_fid *f)
1091 {
1092         LASSERT(dev);
1093         LASSERT(dev->dd_ops);
1094         LASSERT(dev->dd_ops->dt_root_get);
1095         return dev->dd_ops->dt_root_get(env, dev, f);
1096 }
1097
1098 static inline void dt_conf_get(const struct lu_env *env,
1099                                const struct dt_device *dev,
1100                                struct dt_device_param *param)
1101 {
1102         LASSERT(dev);
1103         LASSERT(dev->dd_ops);
1104         LASSERT(dev->dd_ops->dt_conf_get);
1105         return dev->dd_ops->dt_conf_get(env, dev, param);
1106 }
1107
1108 static inline int dt_sync(const struct lu_env *env, struct dt_device *dev)
1109 {
1110         LASSERT(dev);
1111         LASSERT(dev->dd_ops);
1112         LASSERT(dev->dd_ops->dt_sync);
1113         return dev->dd_ops->dt_sync(env, dev);
1114 }
1115
1116 static inline int dt_ro(const struct lu_env *env, struct dt_device *dev)
1117 {
1118         LASSERT(dev);
1119         LASSERT(dev->dd_ops);
1120         LASSERT(dev->dd_ops->dt_ro);
1121         return dev->dd_ops->dt_ro(env, dev);
1122 }
1123
1124 static inline int dt_declare_insert(const struct lu_env *env,
1125                                     struct dt_object *dt,
1126                                     const struct dt_rec *rec,
1127                                     const struct dt_key *key,
1128                                     struct thandle *th)
1129 {
1130         LASSERT(dt);
1131         LASSERT(dt->do_index_ops);
1132         LASSERT(dt->do_index_ops->dio_declare_insert);
1133         return dt->do_index_ops->dio_declare_insert(env, dt, rec, key, th);
1134 }
1135
1136 static inline int dt_insert(const struct lu_env *env,
1137                                     struct dt_object *dt,
1138                                     const struct dt_rec *rec,
1139                                     const struct dt_key *key,
1140                                     struct thandle *th,
1141                                     struct lustre_capa *capa,
1142                                     int noquota)
1143 {
1144         LASSERT(dt);
1145         LASSERT(dt->do_index_ops);
1146         LASSERT(dt->do_index_ops->dio_insert);
1147         return dt->do_index_ops->dio_insert(env, dt, rec, key, th,
1148                                             capa, noquota);
1149 }
1150
1151 static inline int dt_declare_xattr_del(const struct lu_env *env,
1152                                        struct dt_object *dt,
1153                                        const char *name,
1154                                        struct thandle *th)
1155 {
1156         LASSERT(dt);
1157         LASSERT(dt->do_ops);
1158         LASSERT(dt->do_ops->do_declare_xattr_del);
1159         return dt->do_ops->do_declare_xattr_del(env, dt, name, th);
1160 }
1161
1162 static inline int dt_xattr_del(const struct lu_env *env,
1163                                struct dt_object *dt, const char *name,
1164                                struct thandle *th,
1165                                struct lustre_capa *capa)
1166 {
1167         LASSERT(dt);
1168         LASSERT(dt->do_ops);
1169         LASSERT(dt->do_ops->do_xattr_del);
1170         return dt->do_ops->do_xattr_del(env, dt, name, th, capa);
1171 }
1172
1173 static inline int dt_declare_xattr_set(const struct lu_env *env,
1174                                       struct dt_object *dt,
1175                                       const struct lu_buf *buf,
1176                                       const char *name, int fl,
1177                                       struct thandle *th)
1178 {
1179         LASSERT(dt);
1180         LASSERT(dt->do_ops);
1181         LASSERT(dt->do_ops->do_declare_xattr_set);
1182         return dt->do_ops->do_declare_xattr_set(env, dt, buf, name, fl, th);
1183 }
1184
1185 static inline int dt_xattr_set(const struct lu_env *env,
1186                               struct dt_object *dt, const struct lu_buf *buf,
1187                               const char *name, int fl, struct thandle *th,
1188                               struct lustre_capa *capa)
1189 {
1190         LASSERT(dt);
1191         LASSERT(dt->do_ops);
1192         LASSERT(dt->do_ops->do_xattr_set);
1193         return dt->do_ops->do_xattr_set(env, dt, buf, name, fl, th, capa);
1194 }
1195
1196 static inline int dt_xattr_get(const struct lu_env *env,
1197                               struct dt_object *dt, struct lu_buf *buf,
1198                               const char *name, struct lustre_capa *capa)
1199 {
1200         LASSERT(dt);
1201         LASSERT(dt->do_ops);
1202         LASSERT(dt->do_ops->do_xattr_get);
1203         return dt->do_ops->do_xattr_get(env, dt, buf, name, capa);
1204 }
1205
1206 static inline int dt_xattr_list(const struct lu_env *env,
1207                                struct dt_object *dt, struct lu_buf *buf,
1208                                struct lustre_capa *capa)
1209 {
1210         LASSERT(dt);
1211         LASSERT(dt->do_ops);
1212         LASSERT(dt->do_ops->do_xattr_list);
1213         return dt->do_ops->do_xattr_list(env, dt, buf, capa);
1214 }
1215
1216 static inline int dt_declare_delete(const struct lu_env *env,
1217                                     struct dt_object *dt,
1218                                     const struct dt_key *key,
1219                                     struct thandle *th)
1220 {
1221         LASSERT(dt);
1222         LASSERT(dt->do_index_ops);
1223         LASSERT(dt->do_index_ops->dio_declare_delete);
1224         return dt->do_index_ops->dio_declare_delete(env, dt, key, th);
1225 }
1226
1227 static inline int dt_delete(const struct lu_env *env,
1228                             struct dt_object *dt,
1229                             const struct dt_key *key,
1230                             struct thandle *th,
1231                             struct lustre_capa *capa)
1232 {
1233         LASSERT(dt);
1234         LASSERT(dt->do_index_ops);
1235         LASSERT(dt->do_index_ops->dio_delete);
1236         return dt->do_index_ops->dio_delete(env, dt, key, th, capa);
1237 }
1238
1239 static inline int dt_commit_async(const struct lu_env *env,
1240                                   struct dt_device *dev)
1241 {
1242         LASSERT(dev);
1243         LASSERT(dev->dd_ops);
1244         LASSERT(dev->dd_ops->dt_commit_async);
1245         return dev->dd_ops->dt_commit_async(env, dev);
1246 }
1247
1248 static inline int dt_lookup(const struct lu_env *env,
1249                             struct dt_object *dt,
1250                             struct dt_rec *rec,
1251                             const struct dt_key *key,
1252                             struct lustre_capa *capa)
1253 {
1254         int ret;
1255
1256         LASSERT(dt);
1257         LASSERT(dt->do_index_ops);
1258         LASSERT(dt->do_index_ops->dio_lookup);
1259
1260         ret = dt->do_index_ops->dio_lookup(env, dt, rec, key, capa);
1261         if (ret > 0)
1262                 ret = 0;
1263         else if (ret == 0)
1264                 ret = -ENOENT;
1265         return ret;
1266 }
1267 #endif /* __LUSTRE_DT_OBJECT_H */