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