Whamcloud - gitweb
197ff1e980d2ad6d9e925f582c01ae5b7be739ff
[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_locate(const struct lu_env *env,
735                             struct dt_device *dev,
736                             const struct lu_fid *fid);
737
738 int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
739                            struct thandle *th);
740 void dt_version_set(const struct lu_env *env, struct dt_object *o,
741                     dt_obj_version_t version, struct thandle *th);
742 dt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o);
743
744
745 int dt_read(const struct lu_env *env, struct dt_object *dt,
746             struct lu_buf *buf, loff_t *pos);
747 int dt_record_read(const struct lu_env *env, struct dt_object *dt,
748                    struct lu_buf *buf, loff_t *pos);
749 int dt_record_write(const struct lu_env *env, struct dt_object *dt,
750                     const struct lu_buf *buf, loff_t *pos, struct thandle *th);
751
752 static inline struct thandle *dt_trans_create(const struct lu_env *env,
753                                               struct dt_device *d)
754 {
755         LASSERT(d->dd_ops->dt_trans_create);
756         return d->dd_ops->dt_trans_create(env, d);
757 }
758
759 static inline int dt_trans_start(const struct lu_env *env,
760                                  struct dt_device *d, struct thandle *th)
761 {
762         LASSERT(d->dd_ops->dt_trans_start);
763         return d->dd_ops->dt_trans_start(env, d, th);
764 }
765
766 /* for this transaction hooks shouldn't be called */
767 static inline int dt_trans_start_local(const struct lu_env *env,
768                                        struct dt_device *d, struct thandle *th)
769 {
770         LASSERT(d->dd_ops->dt_trans_start);
771         th->th_local = 1;
772         return d->dd_ops->dt_trans_start(env, d, th);
773 }
774
775 static inline int dt_trans_stop(const struct lu_env *env,
776                                 struct dt_device *d, struct thandle *th)
777 {
778         LASSERT(d->dd_ops->dt_trans_stop);
779         return d->dd_ops->dt_trans_stop(env, th);
780 }
781
782 static inline int dt_trans_cb_add(struct thandle *th,
783                                   struct dt_txn_commit_cb *dcb)
784 {
785         LASSERT(th->th_dev->dd_ops->dt_trans_cb_add);
786         return th->th_dev->dd_ops->dt_trans_cb_add(th, dcb);
787 }
788 /** @} dt */
789
790
791 static inline int dt_declare_record_write(const struct lu_env *env,
792                                           struct dt_object *dt,
793                                           int size, loff_t pos,
794                                           struct thandle *th)
795 {
796         int rc;
797
798         LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
799         LASSERT(th != NULL);
800         LASSERT(dt->do_body_ops);
801         LASSERT(dt->do_body_ops->dbo_declare_write);
802         rc = dt->do_body_ops->dbo_declare_write(env, dt, size, pos, th);
803         return rc;
804 }
805
806 static inline int dt_declare_create(const struct lu_env *env,
807                                     struct dt_object *dt,
808                                     struct lu_attr *attr,
809                                     struct dt_allocation_hint *hint,
810                                     struct dt_object_format *dof,
811                                     struct thandle *th)
812 {
813         LASSERT(dt);
814         LASSERT(dt->do_ops);
815         LASSERT(dt->do_ops->do_declare_create);
816         return dt->do_ops->do_declare_create(env, dt, attr, hint, dof, th);
817 }
818
819 static inline int dt_create(const struct lu_env *env,
820                                     struct dt_object *dt,
821                                     struct lu_attr *attr,
822                                     struct dt_allocation_hint *hint,
823                                     struct dt_object_format *dof,
824                                     struct thandle *th)
825 {
826         LASSERT(dt);
827         LASSERT(dt->do_ops);
828         LASSERT(dt->do_ops->do_create);
829         return dt->do_ops->do_create(env, dt, attr, hint, dof, th);
830 }
831
832 static inline int dt_declare_destroy(const struct lu_env *env,
833                                      struct dt_object *dt,
834                                      struct thandle *th)
835 {
836         LASSERT(dt);
837         LASSERT(dt->do_ops);
838         LASSERT(dt->do_ops->do_declare_destroy);
839         return dt->do_ops->do_declare_destroy(env, dt, th);
840 }
841
842 static inline int dt_destroy(const struct lu_env *env,
843                              struct dt_object *dt,
844                              struct thandle *th)
845 {
846         LASSERT(dt);
847         LASSERT(dt->do_ops);
848         LASSERT(dt->do_ops->do_destroy);
849         return dt->do_ops->do_destroy(env, dt, th);
850 }
851
852 static inline void dt_read_lock(const struct lu_env *env,
853                                 struct dt_object *dt,
854                                 unsigned role)
855 {
856         LASSERT(dt);
857         LASSERT(dt->do_ops);
858         LASSERT(dt->do_ops->do_read_lock);
859         dt->do_ops->do_read_lock(env, dt, role);
860 }
861
862 static inline void dt_write_lock(const struct lu_env *env,
863                                 struct dt_object *dt,
864                                 unsigned role)
865 {
866         LASSERT(dt);
867         LASSERT(dt->do_ops);
868         LASSERT(dt->do_ops->do_write_lock);
869         dt->do_ops->do_write_lock(env, dt, role);
870 }
871
872 static inline void dt_read_unlock(const struct lu_env *env,
873                                 struct dt_object *dt)
874 {
875         LASSERT(dt);
876         LASSERT(dt->do_ops);
877         LASSERT(dt->do_ops->do_read_unlock);
878         dt->do_ops->do_read_unlock(env, dt);
879 }
880
881 static inline void dt_write_unlock(const struct lu_env *env,
882                                 struct dt_object *dt)
883 {
884         LASSERT(dt);
885         LASSERT(dt->do_ops);
886         LASSERT(dt->do_ops->do_write_unlock);
887         dt->do_ops->do_write_unlock(env, dt);
888 }
889
890 static inline int dt_write_locked(const struct lu_env *env,
891                                   struct dt_object *dt)
892 {
893         LASSERT(dt);
894         LASSERT(dt->do_ops);
895         LASSERT(dt->do_ops->do_write_locked);
896         return dt->do_ops->do_write_locked(env, dt);
897 }
898
899 static inline int dt_attr_get(const struct lu_env *env, struct dt_object *dt,
900                               struct lu_attr *la, void *arg)
901 {
902         LASSERT(dt);
903         LASSERT(dt->do_ops);
904         LASSERT(dt->do_ops->do_attr_get);
905         return dt->do_ops->do_attr_get(env, dt, la, arg);
906 }
907
908 static inline int dt_declare_attr_set(const struct lu_env *env,
909                                       struct dt_object *dt,
910                                       const struct lu_attr *la,
911                                       struct thandle *th)
912 {
913         LASSERT(dt);
914         LASSERT(dt->do_ops);
915         LASSERT(dt->do_ops->do_declare_attr_set);
916         return dt->do_ops->do_declare_attr_set(env, dt, la, th);
917 }
918
919 static inline int dt_attr_set(const struct lu_env *env, struct dt_object *dt,
920                               const struct lu_attr *la, struct thandle *th,
921                               struct lustre_capa *capa)
922 {
923         LASSERT(dt);
924         LASSERT(dt->do_ops);
925         LASSERT(dt->do_ops->do_attr_set);
926         return dt->do_ops->do_attr_set(env, dt, la, th, capa);
927 }
928
929 static inline int dt_declare_ref_add(const struct lu_env *env,
930                                      struct dt_object *dt, struct thandle *th)
931 {
932         LASSERT(dt);
933         LASSERT(dt->do_ops);
934         LASSERT(dt->do_ops->do_declare_ref_add);
935         return dt->do_ops->do_declare_ref_add(env, dt, th);
936 }
937
938 static inline int dt_ref_add(const struct lu_env *env,
939                              struct dt_object *dt, struct thandle *th)
940 {
941         LASSERT(dt);
942         LASSERT(dt->do_ops);
943         LASSERT(dt->do_ops->do_ref_add);
944         return dt->do_ops->do_ref_add(env, dt, th);
945 }
946
947 static inline int dt_declare_ref_del(const struct lu_env *env,
948                                      struct dt_object *dt, struct thandle *th)
949 {
950         LASSERT(dt);
951         LASSERT(dt->do_ops);
952         LASSERT(dt->do_ops->do_declare_ref_del);
953         return dt->do_ops->do_declare_ref_del(env, dt, th);
954 }
955
956 static inline int dt_ref_del(const struct lu_env *env,
957                              struct dt_object *dt, struct thandle *th)
958 {
959         LASSERT(dt);
960         LASSERT(dt->do_ops);
961         LASSERT(dt->do_ops->do_ref_del);
962         return dt->do_ops->do_ref_del(env, dt, th);
963 }
964
965 static inline struct obd_capa *dt_capa_get(const struct lu_env *env,
966                                            struct dt_object *dt,
967                                            struct lustre_capa *old, __u64 opc)
968 {
969         LASSERT(dt);
970         LASSERT(dt->do_ops);
971         LASSERT(dt->do_ops->do_ref_del);
972         return dt->do_ops->do_capa_get(env, dt, old, opc);
973 }
974
975 static inline int dt_bufs_get(const struct lu_env *env, struct dt_object *d,
976                               struct niobuf_remote *rnb,
977                               struct niobuf_local *lnb, int rw,
978                               struct lustre_capa *capa)
979 {
980         LASSERT(d);
981         LASSERT(d->do_body_ops);
982         LASSERT(d->do_body_ops->dbo_bufs_get);
983         return d->do_body_ops->dbo_bufs_get(env, d, rnb->offset,
984                                             rnb->len, lnb, rw, capa);
985 }
986
987 static inline int dt_bufs_put(const struct lu_env *env, struct dt_object *d,
988                               struct niobuf_local *lnb, int n)
989 {
990         LASSERT(d);
991         LASSERT(d->do_body_ops);
992         LASSERT(d->do_body_ops->dbo_bufs_put);
993         return d->do_body_ops->dbo_bufs_put(env, d, lnb, n);
994 }
995
996 static inline int dt_write_prep(const struct lu_env *env, struct dt_object *d,
997                                 struct niobuf_local *lnb, int n)
998 {
999         LASSERT(d);
1000         LASSERT(d->do_body_ops);
1001         LASSERT(d->do_body_ops->dbo_write_prep);
1002         return d->do_body_ops->dbo_write_prep(env, d, lnb, n);
1003 }
1004
1005 static inline int dt_declare_write_commit(const struct lu_env *env,
1006                                           struct dt_object *d,
1007                                           struct niobuf_local *lnb,
1008                                           int n, struct thandle *th)
1009 {
1010         LASSERTF(d != NULL, "dt is NULL when we want to declare write\n");
1011         LASSERT(th != NULL);
1012         return d->do_body_ops->dbo_declare_write_commit(env, d, lnb, n, th);
1013 }
1014
1015
1016 static inline int dt_write_commit(const struct lu_env *env,
1017                                   struct dt_object *d, struct niobuf_local *lnb,
1018                                   int n, struct thandle *th)
1019 {
1020         LASSERT(d);
1021         LASSERT(d->do_body_ops);
1022         LASSERT(d->do_body_ops->dbo_write_commit);
1023         return d->do_body_ops->dbo_write_commit(env, d, lnb, n, th);
1024 }
1025
1026 static inline int dt_read_prep(const struct lu_env *env, struct dt_object *d,
1027                                struct niobuf_local *lnb, int n)
1028 {
1029         LASSERT(d);
1030         LASSERT(d->do_body_ops);
1031         LASSERT(d->do_body_ops->dbo_read_prep);
1032         return d->do_body_ops->dbo_read_prep(env, d, lnb, n);
1033 }
1034
1035 static inline int dt_declare_punch(const struct lu_env *env,
1036                                    struct dt_object *dt, __u64 start,
1037                                    __u64 end, struct thandle *th)
1038 {
1039         LASSERT(dt);
1040         LASSERT(dt->do_body_ops);
1041         LASSERT(dt->do_body_ops->do_declare_punch);
1042         return dt->do_body_ops->do_declare_punch(env, dt, start, end, th);
1043 }
1044
1045 static inline int dt_punch(const struct lu_env *env, struct dt_object *dt,
1046                            __u64 start, __u64 end, struct thandle *th,
1047                            struct lustre_capa *capa)
1048 {
1049         LASSERT(dt);
1050         LASSERT(dt->do_body_ops);
1051         LASSERT(dt->do_body_ops->do_punch);
1052         return dt->do_body_ops->do_punch(env, dt, start, end, th, capa);
1053 }
1054
1055 static inline int dt_fiemap_get(const struct lu_env *env, struct dt_object *d,
1056                                 struct ll_user_fiemap *fm)
1057 {
1058         LASSERT(d);
1059         if (d->do_body_ops == NULL)
1060                 return -EPROTO;
1061         LASSERT(d->do_body_ops->dbo_fiemap_get);
1062         return d->do_body_ops->dbo_fiemap_get(env, d, fm);
1063 }
1064
1065 static inline int dt_statfs(const struct lu_env *env, struct dt_device *dev,
1066                             struct obd_statfs *osfs)
1067 {
1068         LASSERT(dev);
1069         LASSERT(dev->dd_ops);
1070         LASSERT(dev->dd_ops->dt_statfs);
1071         return dev->dd_ops->dt_statfs(env, dev, osfs);
1072 }
1073
1074 static inline int dt_root_get(const struct lu_env *env, struct dt_device *dev,
1075                               struct lu_fid *f)
1076 {
1077         LASSERT(dev);
1078         LASSERT(dev->dd_ops);
1079         LASSERT(dev->dd_ops->dt_root_get);
1080         return dev->dd_ops->dt_root_get(env, dev, f);
1081 }
1082
1083 static inline void dt_conf_get(const struct lu_env *env,
1084                                const struct dt_device *dev,
1085                                struct dt_device_param *param)
1086 {
1087         LASSERT(dev);
1088         LASSERT(dev->dd_ops);
1089         LASSERT(dev->dd_ops->dt_conf_get);
1090         return dev->dd_ops->dt_conf_get(env, dev, param);
1091 }
1092
1093 static inline int dt_sync(const struct lu_env *env, struct dt_device *dev)
1094 {
1095         LASSERT(dev);
1096         LASSERT(dev->dd_ops);
1097         LASSERT(dev->dd_ops->dt_sync);
1098         return dev->dd_ops->dt_sync(env, dev);
1099 }
1100
1101 static inline int dt_ro(const struct lu_env *env, struct dt_device *dev)
1102 {
1103         LASSERT(dev);
1104         LASSERT(dev->dd_ops);
1105         LASSERT(dev->dd_ops->dt_ro);
1106         return dev->dd_ops->dt_ro(env, dev);
1107 }
1108
1109 static inline int dt_declare_insert(const struct lu_env *env,
1110                                     struct dt_object *dt,
1111                                     const struct dt_rec *rec,
1112                                     const struct dt_key *key,
1113                                     struct thandle *th)
1114 {
1115         LASSERT(dt);
1116         LASSERT(dt->do_index_ops);
1117         LASSERT(dt->do_index_ops->dio_declare_insert);
1118         return dt->do_index_ops->dio_declare_insert(env, dt, rec, key, th);
1119 }
1120
1121 static inline int dt_insert(const struct lu_env *env,
1122                                     struct dt_object *dt,
1123                                     const struct dt_rec *rec,
1124                                     const struct dt_key *key,
1125                                     struct thandle *th,
1126                                     struct lustre_capa *capa,
1127                                     int noquota)
1128 {
1129         LASSERT(dt);
1130         LASSERT(dt->do_index_ops);
1131         LASSERT(dt->do_index_ops->dio_insert);
1132         return dt->do_index_ops->dio_insert(env, dt, rec, key, th,
1133                                             capa, noquota);
1134 }
1135
1136 static inline int dt_declare_xattr_del(const struct lu_env *env,
1137                                        struct dt_object *dt,
1138                                        const char *name,
1139                                        struct thandle *th)
1140 {
1141         LASSERT(dt);
1142         LASSERT(dt->do_ops);
1143         LASSERT(dt->do_ops->do_declare_xattr_del);
1144         return dt->do_ops->do_declare_xattr_del(env, dt, name, th);
1145 }
1146
1147 static inline int dt_xattr_del(const struct lu_env *env,
1148                                struct dt_object *dt, const char *name,
1149                                struct thandle *th,
1150                                struct lustre_capa *capa)
1151 {
1152         LASSERT(dt);
1153         LASSERT(dt->do_ops);
1154         LASSERT(dt->do_ops->do_xattr_del);
1155         return dt->do_ops->do_xattr_del(env, dt, name, th, capa);
1156 }
1157
1158 static inline int dt_declare_xattr_set(const struct lu_env *env,
1159                                       struct dt_object *dt,
1160                                       const struct lu_buf *buf,
1161                                       const char *name, int fl,
1162                                       struct thandle *th)
1163 {
1164         LASSERT(dt);
1165         LASSERT(dt->do_ops);
1166         LASSERT(dt->do_ops->do_declare_xattr_set);
1167         return dt->do_ops->do_declare_xattr_set(env, dt, buf, name, fl, th);
1168 }
1169
1170 static inline int dt_xattr_set(const struct lu_env *env,
1171                               struct dt_object *dt, const struct lu_buf *buf,
1172                               const char *name, int fl, struct thandle *th,
1173                               struct lustre_capa *capa)
1174 {
1175         LASSERT(dt);
1176         LASSERT(dt->do_ops);
1177         LASSERT(dt->do_ops->do_xattr_set);
1178         return dt->do_ops->do_xattr_set(env, dt, buf, name, fl, th, capa);
1179 }
1180
1181 static inline int dt_xattr_get(const struct lu_env *env,
1182                               struct dt_object *dt, struct lu_buf *buf,
1183                               const char *name, struct lustre_capa *capa)
1184 {
1185         LASSERT(dt);
1186         LASSERT(dt->do_ops);
1187         LASSERT(dt->do_ops->do_xattr_get);
1188         return dt->do_ops->do_xattr_get(env, dt, buf, name, capa);
1189 }
1190
1191 static inline int dt_xattr_list(const struct lu_env *env,
1192                                struct dt_object *dt, struct lu_buf *buf,
1193                                struct lustre_capa *capa)
1194 {
1195         LASSERT(dt);
1196         LASSERT(dt->do_ops);
1197         LASSERT(dt->do_ops->do_xattr_list);
1198         return dt->do_ops->do_xattr_list(env, dt, buf, capa);
1199 }
1200
1201 static inline int dt_declare_delete(const struct lu_env *env,
1202                                     struct dt_object *dt,
1203                                     const struct dt_key *key,
1204                                     struct thandle *th)
1205 {
1206         LASSERT(dt);
1207         LASSERT(dt->do_index_ops);
1208         LASSERT(dt->do_index_ops->dio_declare_delete);
1209         return dt->do_index_ops->dio_declare_delete(env, dt, key, th);
1210 }
1211
1212 static inline int dt_delete(const struct lu_env *env,
1213                             struct dt_object *dt,
1214                             const struct dt_key *key,
1215                             struct thandle *th,
1216                             struct lustre_capa *capa)
1217 {
1218         LASSERT(dt);
1219         LASSERT(dt->do_index_ops);
1220         LASSERT(dt->do_index_ops->dio_delete);
1221         return dt->do_index_ops->dio_delete(env, dt, key, th, capa);
1222 }
1223
1224 static inline int dt_commit_async(const struct lu_env *env,
1225                                   struct dt_device *dev)
1226 {
1227         LASSERT(dev);
1228         LASSERT(dev->dd_ops);
1229         LASSERT(dev->dd_ops->dt_commit_async);
1230         return dev->dd_ops->dt_commit_async(env, dev);
1231 }
1232
1233 static inline int dt_lookup(const struct lu_env *env,
1234                             struct dt_object *dt,
1235                             struct dt_rec *rec,
1236                             const struct dt_key *key,
1237                             struct lustre_capa *capa)
1238 {
1239         int ret;
1240
1241         LASSERT(dt);
1242         LASSERT(dt->do_index_ops);
1243         LASSERT(dt->do_index_ops->dio_lookup);
1244
1245         ret = dt->do_index_ops->dio_lookup(env, dt, rec, key, capa);
1246         if (ret > 0)
1247                 ret = 0;
1248         else if (ret == 0)
1249                 ret = -ENOENT;
1250         return ret;
1251 }
1252 #endif /* __LUSTRE_DT_OBJECT_H */