Whamcloud - gitweb
LU-957 scrub: osd-ldiskfs itable based iteration
[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          * index support fixed-size keys sorted with natural numerical way
206          * and is able to return left-side value if no exact value found
207          */
208         DT_IND_RANGE = 1 << 4,
209 };
210
211 /**
212  * Features, required from index to support file system directories (mapping
213  * names to fids).
214  */
215 extern const struct dt_index_features dt_directory_features;
216 extern const struct dt_index_features dt_otable_features;
217
218 /**
219  * This is a general purpose dt allocation hint.
220  * It now contains the parent object.
221  * It can contain any allocation hint in the future.
222  */
223 struct dt_allocation_hint {
224         struct dt_object           *dah_parent;
225         __u32                       dah_mode;
226 };
227
228 /**
229  * object type specifier.
230  */
231
232 enum dt_format_type {
233         DFT_REGULAR,
234         DFT_DIR,
235         /** for mknod */
236         DFT_NODE,
237         /** for special index */
238         DFT_INDEX,
239         /** for symbolic link */
240         DFT_SYM,
241 };
242
243 /**
244  * object format specifier.
245  */
246 struct dt_object_format {
247         /** type for dt object */
248         enum dt_format_type dof_type;
249         union {
250                 struct dof_regular {
251                 } dof_reg;
252                 struct dof_dir {
253                 } dof_dir;
254                 struct dof_node {
255                 } dof_node;
256                 /**
257                  * special index need feature as parameter to create
258                  * special idx
259                  */
260                 struct dof_index {
261                         const struct dt_index_features *di_feat;
262                 } dof_idx;
263         } u;
264 };
265
266 enum dt_format_type dt_mode_to_dft(__u32 mode);
267
268 typedef __u64 dt_obj_version_t;
269
270 /**
271  * Per-dt-object operations.
272  */
273 struct dt_object_operations {
274         void  (*do_read_lock)(const struct lu_env *env,
275                               struct dt_object *dt, unsigned role);
276         void  (*do_write_lock)(const struct lu_env *env,
277                                struct dt_object *dt, unsigned role);
278         void  (*do_read_unlock)(const struct lu_env *env,
279                                 struct dt_object *dt);
280         void  (*do_write_unlock)(const struct lu_env *env,
281                                  struct dt_object *dt);
282         int  (*do_write_locked)(const struct lu_env *env,
283                                 struct dt_object *dt);
284         /**
285          * Note: following ->do_{x,}attr_{set,get}() operations are very
286          * similar to ->moo_{x,}attr_{set,get}() operations in struct
287          * md_object_operations (see md_object.h). These operations are not in
288          * lu_object_operations, because ->do_{x,}attr_set() versions take
289          * transaction handle as an argument (this transaction is started by
290          * caller). We might factor ->do_{x,}attr_get() into
291          * lu_object_operations, but that would break existing symmetry.
292          */
293
294         /**
295          * Return standard attributes.
296          *
297          * precondition: lu_object_exists(&dt->do_lu);
298          */
299         int   (*do_attr_get)(const struct lu_env *env,
300                              struct dt_object *dt, struct lu_attr *attr,
301                              struct lustre_capa *capa);
302         /**
303          * Set standard attributes.
304          *
305          * precondition: dt_object_exists(dt);
306          */
307         int   (*do_declare_attr_set)(const struct lu_env *env,
308                                      struct dt_object *dt,
309                                      const struct lu_attr *attr,
310                                      struct thandle *handle);
311         int   (*do_attr_set)(const struct lu_env *env,
312                              struct dt_object *dt,
313                              const struct lu_attr *attr,
314                              struct thandle *handle,
315                              struct lustre_capa *capa);
316         /**
317          * Return a value of an extended attribute.
318          *
319          * precondition: dt_object_exists(dt);
320          */
321         int   (*do_xattr_get)(const struct lu_env *env, struct dt_object *dt,
322                               struct lu_buf *buf, const char *name,
323                               struct lustre_capa *capa);
324         /**
325          * Set value of an extended attribute.
326          *
327          * \a fl - flags from enum lu_xattr_flags
328          *
329          * precondition: dt_object_exists(dt);
330          */
331         int   (*do_declare_xattr_set)(const struct lu_env *env,
332                                       struct dt_object *dt,
333                                       const struct lu_buf *buf,
334                                       const char *name, int fl,
335                                       struct thandle *handle);
336         int   (*do_xattr_set)(const struct lu_env *env,
337                               struct dt_object *dt, const struct lu_buf *buf,
338                               const char *name, int fl, struct thandle *handle,
339                               struct lustre_capa *capa);
340         /**
341          * Delete existing extended attribute.
342          *
343          * precondition: dt_object_exists(dt);
344          */
345         int   (*do_declare_xattr_del)(const struct lu_env *env,
346                                       struct dt_object *dt,
347                                       const char *name, struct thandle *handle);
348         int   (*do_xattr_del)(const struct lu_env *env,
349                               struct dt_object *dt,
350                               const char *name, struct thandle *handle,
351                               struct lustre_capa *capa);
352         /**
353          * Place list of existing extended attributes into \a buf (which has
354          * length len).
355          *
356          * precondition: dt_object_exists(dt);
357          */
358         int   (*do_xattr_list)(const struct lu_env *env,
359                                struct dt_object *dt, struct lu_buf *buf,
360                                struct lustre_capa *capa);
361         /**
362          * Init allocation hint using parent object and child mode.
363          * (1) The \a parent might be NULL if this is a partial creation for
364          *     remote object.
365          * (2) The type of child is in \a child_mode.
366          * (3) The result hint is stored in \a ah;
367          */
368         void  (*do_ah_init)(const struct lu_env *env,
369                             struct dt_allocation_hint *ah,
370                             struct dt_object *parent,
371                             cfs_umode_t child_mode);
372         /**
373          * Create new object on this device.
374          *
375          * precondition: !dt_object_exists(dt);
376          * postcondition: ergo(result == 0, dt_object_exists(dt));
377          */
378         int   (*do_declare_create)(const struct lu_env *env,
379                                    struct dt_object *dt,
380                                    struct lu_attr *attr,
381                                    struct dt_allocation_hint *hint,
382                                    struct dt_object_format *dof,
383                                    struct thandle *th);
384         int   (*do_create)(const struct lu_env *env, struct dt_object *dt,
385                            struct lu_attr *attr,
386                            struct dt_allocation_hint *hint,
387                            struct dt_object_format *dof,
388                            struct thandle *th);
389
390         /**
391           Destroy object on this device
392          * precondition: !dt_object_exists(dt);
393          * postcondition: ergo(result == 0, dt_object_exists(dt));
394          */
395         int   (*do_declare_destroy)(const struct lu_env *env,
396                                     struct dt_object *dt,
397                                     struct thandle *th);
398         int   (*do_destroy)(const struct lu_env *env, struct dt_object *dt,
399                             struct thandle *th);
400
401         /**
402          * Announce that this object is going to be used as an index. This
403          * operation check that object supports indexing operations and
404          * installs appropriate dt_index_operations vector on success.
405          *
406          * Also probes for features. Operation is successful if all required
407          * features are supported.
408          */
409         int   (*do_index_try)(const struct lu_env *env,
410                               struct dt_object *dt,
411                               const struct dt_index_features *feat);
412         /**
413          * Add nlink of the object
414          * precondition: dt_object_exists(dt);
415          */
416         int   (*do_declare_ref_add)(const struct lu_env *env,
417                                     struct dt_object *dt, struct thandle *th);
418         int   (*do_ref_add)(const struct lu_env *env,
419                             struct dt_object *dt, struct thandle *th);
420         /**
421          * Del nlink of the object
422          * precondition: dt_object_exists(dt);
423          */
424         int   (*do_declare_ref_del)(const struct lu_env *env,
425                                     struct dt_object *dt, struct thandle *th);
426         int   (*do_ref_del)(const struct lu_env *env,
427                             struct dt_object *dt, struct thandle *th);
428
429         struct obd_capa *(*do_capa_get)(const struct lu_env *env,
430                                         struct dt_object *dt,
431                                         struct lustre_capa *old,
432                                         __u64 opc);
433         int (*do_object_sync)(const struct lu_env *, struct dt_object *);
434         /**
435          * Get object info of next level. Currently, only get inode from osd.
436          * This is only used by quota b=16542
437          * precondition: dt_object_exists(dt);
438          */
439         int (*do_data_get)(const struct lu_env *env, struct dt_object *dt,
440                            void **data);
441 };
442
443 /**
444  * Per-dt-object operations on "file body".
445  */
446 struct dt_body_operations {
447         /**
448          * precondition: dt_object_exists(dt);
449          */
450         ssize_t (*dbo_read)(const struct lu_env *env, struct dt_object *dt,
451                             struct lu_buf *buf, loff_t *pos,
452                             struct lustre_capa *capa);
453         /**
454          * precondition: dt_object_exists(dt);
455          */
456         ssize_t (*dbo_declare_write)(const struct lu_env *env,
457                                      struct dt_object *dt,
458                                      const loff_t size, loff_t pos,
459                                      struct thandle *handle);
460         ssize_t (*dbo_write)(const struct lu_env *env, struct dt_object *dt,
461                              const struct lu_buf *buf, loff_t *pos,
462                              struct thandle *handle, struct lustre_capa *capa,
463                              int ignore_quota);
464         /*
465          * methods for zero-copy IO
466          */
467
468         /*
469          * precondition: dt_object_exists(dt);
470          * returns:
471          * < 0 - error code
472          * = 0 - illegal
473          * > 0 - number of local buffers prepared
474          */
475         int (*dbo_bufs_get)(const struct lu_env *env, struct dt_object *dt,
476                             loff_t pos, ssize_t len, struct niobuf_local *lb,
477                             int rw, struct lustre_capa *capa);
478         /*
479          * precondition: dt_object_exists(dt);
480          */
481         int (*dbo_bufs_put)(const struct lu_env *env, struct dt_object *dt,
482                             struct niobuf_local *lb, int nr);
483         /*
484          * precondition: dt_object_exists(dt);
485          */
486         int (*dbo_write_prep)(const struct lu_env *env, struct dt_object *dt,
487                               struct niobuf_local *lb, int nr);
488         /*
489          * precondition: dt_object_exists(dt);
490          */
491         int (*dbo_declare_write_commit)(const struct lu_env *env,
492                                         struct dt_object *dt,
493                                         struct niobuf_local *,
494                                         int, struct thandle *);
495         /*
496          * precondition: dt_object_exists(dt);
497          */
498         int (*dbo_write_commit)(const struct lu_env *env, struct dt_object *dt,
499                                 struct niobuf_local *, int, struct thandle *);
500         /*
501          * precondition: dt_object_exists(dt);
502          */
503         int (*dbo_read_prep)(const struct lu_env *env, struct dt_object *dt,
504                              struct niobuf_local *lnb, int nr);
505         int (*dbo_fiemap_get)(const struct lu_env *env, struct dt_object *dt,
506                               struct ll_user_fiemap *fm);
507         /**
508          * Punch object's content
509          * precondition: regular object, not index
510          */
511         int   (*do_declare_punch)(const struct lu_env *, struct dt_object *,
512                                   __u64, __u64, struct thandle *th);
513         int   (*do_punch)(const struct lu_env *env, struct dt_object *dt,
514                           __u64 start, __u64 end, struct thandle *th,
515                           struct lustre_capa *capa);
516 };
517
518 /**
519  * Incomplete type of index record.
520  */
521 struct dt_rec;
522
523 /**
524  * Incomplete type of index key.
525  */
526 struct dt_key;
527
528 /**
529  * Incomplete type of dt iterator.
530  */
531 struct dt_it;
532
533 /**
534  * Per-dt-object operations on object as index.
535  */
536 struct dt_index_operations {
537         /**
538          * precondition: dt_object_exists(dt);
539          */
540         int (*dio_lookup)(const struct lu_env *env, struct dt_object *dt,
541                           struct dt_rec *rec, const struct dt_key *key,
542                           struct lustre_capa *capa);
543         /**
544          * precondition: dt_object_exists(dt);
545          */
546         int (*dio_declare_insert)(const struct lu_env *env,
547                                   struct dt_object *dt,
548                                   const struct dt_rec *rec,
549                                   const struct dt_key *key,
550                                   struct thandle *handle);
551         int (*dio_insert)(const struct lu_env *env, struct dt_object *dt,
552                           const struct dt_rec *rec, const struct dt_key *key,
553                           struct thandle *handle, struct lustre_capa *capa,
554                           int ignore_quota);
555         /**
556          * precondition: dt_object_exists(dt);
557          */
558         int (*dio_declare_delete)(const struct lu_env *env,
559                                   struct dt_object *dt,
560                                   const struct dt_key *key,
561                                   struct thandle *handle);
562         int (*dio_delete)(const struct lu_env *env, struct dt_object *dt,
563                           const struct dt_key *key, struct thandle *handle,
564                           struct lustre_capa *capa);
565         /**
566          * Iterator interface
567          */
568         struct dt_it_ops {
569                 /**
570                  * Allocate and initialize new iterator.
571                  *
572                  * precondition: dt_object_exists(dt);
573                  */
574                 struct dt_it *(*init)(const struct lu_env *env,
575                                       struct dt_object *dt,
576                                       __u32 attr,
577                                       struct lustre_capa *capa);
578                 void          (*fini)(const struct lu_env *env,
579                                       struct dt_it *di);
580                 int            (*get)(const struct lu_env *env,
581                                       struct dt_it *di,
582                                       const struct dt_key *key);
583                 void           (*put)(const struct lu_env *env,
584                                       struct dt_it *di);
585                 int           (*next)(const struct lu_env *env,
586                                       struct dt_it *di);
587                 struct dt_key *(*key)(const struct lu_env *env,
588                                       const struct dt_it *di);
589                 int       (*key_size)(const struct lu_env *env,
590                                       const struct dt_it *di);
591                 int            (*rec)(const struct lu_env *env,
592                                       const struct dt_it *di,
593                                       struct dt_rec *rec,
594                                       __u32 attr);
595                 __u64        (*store)(const struct lu_env *env,
596                                       const struct dt_it *di);
597                 int           (*load)(const struct lu_env *env,
598                                       const struct dt_it *di, __u64 hash);
599                 int        (*key_rec)(const struct lu_env *env,
600                                       const struct dt_it *di, void* key_rec);
601         } dio_it;
602 };
603
604 enum dt_otable_it_valid {
605         DOIV_ERROR_HANDLE       = 0x0001,
606 };
607
608 enum dt_otable_it_flags {
609         /* Exit when fail. */
610         DOIF_FAILOUT    = 0x0001,
611
612         /* Reset iteration position to the device beginning. */
613         DOIF_RESET      = 0x0002,
614
615         /* There is up layer component uses the iteration. */
616         DOIF_OUTUSED    = 0x0004,
617 };
618
619 /* otable based iteration needs to use the common DT interation APIs.
620  * To initialize the iteration, it needs call dio_it::init() firstly.
621  * Here is how the otable based iteration should prepare arguments to
622  * call dt_it_ops::init().
623  *
624  * For otable based iteration, the 32-bits 'attr' for dt_it_ops::init()
625  * is composed of two parts:
626  * low 16-bits is for valid bits, high 16-bits is for flags bits. */
627 #define DT_OTABLE_IT_FLAGS_SHIFT        16
628 #define DT_OTABLE_IT_FLAGS_MASK         0xffff0000
629
630 struct dt_device {
631         struct lu_device                   dd_lu_dev;
632         const struct dt_device_operations *dd_ops;
633
634         /**
635          * List of dt_txn_callback (see below). This is not protected in any
636          * way, because callbacks are supposed to be added/deleted only during
637          * single-threaded start-up shut-down procedures.
638          */
639         cfs_list_t                         dd_txn_callbacks;
640 };
641
642 int  dt_device_init(struct dt_device *dev, struct lu_device_type *t);
643 void dt_device_fini(struct dt_device *dev);
644
645 static inline int lu_device_is_dt(const struct lu_device *d)
646 {
647         return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT);
648 }
649
650 static inline struct dt_device * lu2dt_dev(struct lu_device *l)
651 {
652         LASSERT(lu_device_is_dt(l));
653         return container_of0(l, struct dt_device, dd_lu_dev);
654 }
655
656 struct dt_object {
657         struct lu_object                   do_lu;
658         const struct dt_object_operations *do_ops;
659         const struct dt_body_operations   *do_body_ops;
660         const struct dt_index_operations  *do_index_ops;
661 };
662
663 static inline struct dt_object *lu2dt(struct lu_object *l)
664 {
665         LASSERT(l == NULL || IS_ERR(l) || lu_device_is_dt(l->lo_dev));
666         return container_of0(l, struct dt_object, do_lu);
667 }
668
669 int  dt_object_init(struct dt_object *obj,
670                     struct lu_object_header *h, struct lu_device *d);
671
672 void dt_object_fini(struct dt_object *obj);
673
674 static inline int dt_object_exists(const struct dt_object *dt)
675 {
676         return lu_object_exists(&dt->do_lu);
677 }
678
679 /**
680  * This is the general purpose transaction handle.
681  * 1. Transaction Life Cycle
682  *      This transaction handle is allocated upon starting a new transaction,
683  *      and deallocated after this transaction is committed.
684  * 2. Transaction Nesting
685  *      We do _NOT_ support nested transaction. So, every thread should only
686  *      have one active transaction, and a transaction only belongs to one
687  *      thread. Due to this, transaction handle need no reference count.
688  * 3. Transaction & dt_object locking
689  *      dt_object locks should be taken inside transaction.
690  * 4. Transaction & RPC
691  *      No RPC request should be issued inside transaction.
692  */
693 struct thandle {
694         /** the dt device on which the transactions are executed */
695         struct dt_device *th_dev;
696
697         /** additional tags (layers can add in declare) */
698         __u32             th_tags;
699
700         /** context for this transaction, tag is LCT_TX_HANDLE */
701         struct lu_context th_ctx;
702
703         /** the last operation result in this transaction.
704          * this value is used in recovery */
705         __s32             th_result;
706
707         /** whether we need sync commit */
708         int               th_sync:1;
709
710         /* local transation, no need to inform other layers */
711         int               th_local:1;
712 };
713
714 /**
715  * Transaction call-backs.
716  *
717  * These are invoked by osd (or underlying transaction engine) when
718  * transaction changes state.
719  *
720  * Call-backs are used by upper layers to modify transaction parameters and to
721  * perform some actions on for each transaction state transition. Typical
722  * example is mdt registering call-back to write into last-received file
723  * before each transaction commit.
724  */
725 struct dt_txn_callback {
726         int (*dtc_txn_start)(const struct lu_env *env,
727                              struct thandle *txn, void *cookie);
728         int (*dtc_txn_stop)(const struct lu_env *env,
729                             struct thandle *txn, void *cookie);
730         void (*dtc_txn_commit)(struct thandle *txn, void *cookie);
731         void                *dtc_cookie;
732         __u32                dtc_tag;
733         cfs_list_t           dtc_linkage;
734 };
735
736 void dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb);
737 void dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb);
738
739 int dt_txn_hook_start(const struct lu_env *env,
740                       struct dt_device *dev, struct thandle *txn);
741 int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn);
742 void dt_txn_hook_commit(struct thandle *txn);
743
744 int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj);
745
746 /**
747  * Callback function used for parsing path.
748  * \see llo_store_resolve
749  */
750 typedef int (*dt_entry_func_t)(const struct lu_env *env,
751                             const char *name,
752                             void *pvt);
753
754 #define DT_MAX_PATH 1024
755
756 int dt_path_parser(const struct lu_env *env,
757                    char *local, dt_entry_func_t entry_func,
758                    void *data);
759
760 struct dt_object *dt_store_open(const struct lu_env *env,
761                                 struct dt_device *dt,
762                                 const char *dirname,
763                                 const char *filename,
764                                 struct lu_fid *fid);
765
766 struct dt_object *dt_find_or_create(const struct lu_env *env,
767                                     struct dt_device *dt,
768                                     const struct lu_fid *fid,
769                                     struct dt_object_format *dof,
770                                     struct lu_attr *attr);
771
772 struct dt_object *dt_locate(const struct lu_env *env,
773                             struct dt_device *dev,
774                             const struct lu_fid *fid);
775
776 static inline int dt_object_sync(const struct lu_env *env,
777                                  struct dt_object *o)
778 {
779         LASSERT(o);
780         LASSERT(o->do_ops);
781         LASSERT(o->do_ops->do_object_sync);
782         return o->do_ops->do_object_sync(env, o);
783 }
784
785 int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
786                            struct thandle *th);
787 void dt_version_set(const struct lu_env *env, struct dt_object *o,
788                     dt_obj_version_t version, struct thandle *th);
789 dt_obj_version_t dt_version_get(const struct lu_env *env, struct dt_object *o);
790
791
792 int dt_read(const struct lu_env *env, struct dt_object *dt,
793             struct lu_buf *buf, loff_t *pos);
794 int dt_record_read(const struct lu_env *env, struct dt_object *dt,
795                    struct lu_buf *buf, loff_t *pos);
796 int dt_record_write(const struct lu_env *env, struct dt_object *dt,
797                     const struct lu_buf *buf, loff_t *pos, struct thandle *th);
798
799 static inline struct thandle *dt_trans_create(const struct lu_env *env,
800                                               struct dt_device *d)
801 {
802         LASSERT(d->dd_ops->dt_trans_create);
803         return d->dd_ops->dt_trans_create(env, d);
804 }
805
806 static inline int dt_trans_start(const struct lu_env *env,
807                                  struct dt_device *d, struct thandle *th)
808 {
809         LASSERT(d->dd_ops->dt_trans_start);
810         return d->dd_ops->dt_trans_start(env, d, th);
811 }
812
813 /* for this transaction hooks shouldn't be called */
814 static inline int dt_trans_start_local(const struct lu_env *env,
815                                        struct dt_device *d, struct thandle *th)
816 {
817         LASSERT(d->dd_ops->dt_trans_start);
818         th->th_local = 1;
819         return d->dd_ops->dt_trans_start(env, d, th);
820 }
821
822 static inline int dt_trans_stop(const struct lu_env *env,
823                                 struct dt_device *d, struct thandle *th)
824 {
825         LASSERT(d->dd_ops->dt_trans_stop);
826         return d->dd_ops->dt_trans_stop(env, th);
827 }
828
829 static inline int dt_trans_cb_add(struct thandle *th,
830                                   struct dt_txn_commit_cb *dcb)
831 {
832         LASSERT(th->th_dev->dd_ops->dt_trans_cb_add);
833         return th->th_dev->dd_ops->dt_trans_cb_add(th, dcb);
834 }
835 /** @} dt */
836
837
838 static inline int dt_declare_record_write(const struct lu_env *env,
839                                           struct dt_object *dt,
840                                           int size, loff_t pos,
841                                           struct thandle *th)
842 {
843         int rc;
844
845         LASSERTF(dt != NULL, "dt is NULL when we want to write record\n");
846         LASSERT(th != NULL);
847         LASSERT(dt->do_body_ops);
848         LASSERT(dt->do_body_ops->dbo_declare_write);
849         rc = dt->do_body_ops->dbo_declare_write(env, dt, size, pos, th);
850         return rc;
851 }
852
853 static inline int dt_declare_create(const struct lu_env *env,
854                                     struct dt_object *dt,
855                                     struct lu_attr *attr,
856                                     struct dt_allocation_hint *hint,
857                                     struct dt_object_format *dof,
858                                     struct thandle *th)
859 {
860         LASSERT(dt);
861         LASSERT(dt->do_ops);
862         LASSERT(dt->do_ops->do_declare_create);
863         return dt->do_ops->do_declare_create(env, dt, attr, hint, dof, th);
864 }
865
866 static inline int dt_create(const struct lu_env *env,
867                                     struct dt_object *dt,
868                                     struct lu_attr *attr,
869                                     struct dt_allocation_hint *hint,
870                                     struct dt_object_format *dof,
871                                     struct thandle *th)
872 {
873         LASSERT(dt);
874         LASSERT(dt->do_ops);
875         LASSERT(dt->do_ops->do_create);
876         return dt->do_ops->do_create(env, dt, attr, hint, dof, th);
877 }
878
879 static inline int dt_declare_destroy(const struct lu_env *env,
880                                      struct dt_object *dt,
881                                      struct thandle *th)
882 {
883         LASSERT(dt);
884         LASSERT(dt->do_ops);
885         LASSERT(dt->do_ops->do_declare_destroy);
886         return dt->do_ops->do_declare_destroy(env, dt, th);
887 }
888
889 static inline int dt_destroy(const struct lu_env *env,
890                              struct dt_object *dt,
891                              struct thandle *th)
892 {
893         LASSERT(dt);
894         LASSERT(dt->do_ops);
895         LASSERT(dt->do_ops->do_destroy);
896         return dt->do_ops->do_destroy(env, dt, th);
897 }
898
899 static inline void dt_read_lock(const struct lu_env *env,
900                                 struct dt_object *dt,
901                                 unsigned role)
902 {
903         LASSERT(dt);
904         LASSERT(dt->do_ops);
905         LASSERT(dt->do_ops->do_read_lock);
906         dt->do_ops->do_read_lock(env, dt, role);
907 }
908
909 static inline void dt_write_lock(const struct lu_env *env,
910                                 struct dt_object *dt,
911                                 unsigned role)
912 {
913         LASSERT(dt);
914         LASSERT(dt->do_ops);
915         LASSERT(dt->do_ops->do_write_lock);
916         dt->do_ops->do_write_lock(env, dt, role);
917 }
918
919 static inline void dt_read_unlock(const struct lu_env *env,
920                                 struct dt_object *dt)
921 {
922         LASSERT(dt);
923         LASSERT(dt->do_ops);
924         LASSERT(dt->do_ops->do_read_unlock);
925         dt->do_ops->do_read_unlock(env, dt);
926 }
927
928 static inline void dt_write_unlock(const struct lu_env *env,
929                                 struct dt_object *dt)
930 {
931         LASSERT(dt);
932         LASSERT(dt->do_ops);
933         LASSERT(dt->do_ops->do_write_unlock);
934         dt->do_ops->do_write_unlock(env, dt);
935 }
936
937 static inline int dt_write_locked(const struct lu_env *env,
938                                   struct dt_object *dt)
939 {
940         LASSERT(dt);
941         LASSERT(dt->do_ops);
942         LASSERT(dt->do_ops->do_write_locked);
943         return dt->do_ops->do_write_locked(env, dt);
944 }
945
946 static inline int dt_attr_get(const struct lu_env *env, struct dt_object *dt,
947                               struct lu_attr *la, void *arg)
948 {
949         LASSERT(dt);
950         LASSERT(dt->do_ops);
951         LASSERT(dt->do_ops->do_attr_get);
952         return dt->do_ops->do_attr_get(env, dt, la, arg);
953 }
954
955 static inline int dt_declare_attr_set(const struct lu_env *env,
956                                       struct dt_object *dt,
957                                       const struct lu_attr *la,
958                                       struct thandle *th)
959 {
960         LASSERT(dt);
961         LASSERT(dt->do_ops);
962         LASSERT(dt->do_ops->do_declare_attr_set);
963         return dt->do_ops->do_declare_attr_set(env, dt, la, th);
964 }
965
966 static inline int dt_attr_set(const struct lu_env *env, struct dt_object *dt,
967                               const struct lu_attr *la, struct thandle *th,
968                               struct lustre_capa *capa)
969 {
970         LASSERT(dt);
971         LASSERT(dt->do_ops);
972         LASSERT(dt->do_ops->do_attr_set);
973         return dt->do_ops->do_attr_set(env, dt, la, th, capa);
974 }
975
976 static inline int dt_declare_ref_add(const struct lu_env *env,
977                                      struct dt_object *dt, struct thandle *th)
978 {
979         LASSERT(dt);
980         LASSERT(dt->do_ops);
981         LASSERT(dt->do_ops->do_declare_ref_add);
982         return dt->do_ops->do_declare_ref_add(env, dt, th);
983 }
984
985 static inline int dt_ref_add(const struct lu_env *env,
986                              struct dt_object *dt, struct thandle *th)
987 {
988         LASSERT(dt);
989         LASSERT(dt->do_ops);
990         LASSERT(dt->do_ops->do_ref_add);
991         return dt->do_ops->do_ref_add(env, dt, th);
992 }
993
994 static inline int dt_declare_ref_del(const struct lu_env *env,
995                                      struct dt_object *dt, struct thandle *th)
996 {
997         LASSERT(dt);
998         LASSERT(dt->do_ops);
999         LASSERT(dt->do_ops->do_declare_ref_del);
1000         return dt->do_ops->do_declare_ref_del(env, dt, th);
1001 }
1002
1003 static inline int dt_ref_del(const struct lu_env *env,
1004                              struct dt_object *dt, struct thandle *th)
1005 {
1006         LASSERT(dt);
1007         LASSERT(dt->do_ops);
1008         LASSERT(dt->do_ops->do_ref_del);
1009         return dt->do_ops->do_ref_del(env, dt, th);
1010 }
1011
1012 static inline struct obd_capa *dt_capa_get(const struct lu_env *env,
1013                                            struct dt_object *dt,
1014                                            struct lustre_capa *old, __u64 opc)
1015 {
1016         LASSERT(dt);
1017         LASSERT(dt->do_ops);
1018         LASSERT(dt->do_ops->do_ref_del);
1019         return dt->do_ops->do_capa_get(env, dt, old, opc);
1020 }
1021
1022 static inline int dt_bufs_get(const struct lu_env *env, struct dt_object *d,
1023                               struct niobuf_remote *rnb,
1024                               struct niobuf_local *lnb, int rw,
1025                               struct lustre_capa *capa)
1026 {
1027         LASSERT(d);
1028         LASSERT(d->do_body_ops);
1029         LASSERT(d->do_body_ops->dbo_bufs_get);
1030         return d->do_body_ops->dbo_bufs_get(env, d, rnb->offset,
1031                                             rnb->len, lnb, rw, capa);
1032 }
1033
1034 static inline int dt_bufs_put(const struct lu_env *env, struct dt_object *d,
1035                               struct niobuf_local *lnb, int n)
1036 {
1037         LASSERT(d);
1038         LASSERT(d->do_body_ops);
1039         LASSERT(d->do_body_ops->dbo_bufs_put);
1040         return d->do_body_ops->dbo_bufs_put(env, d, lnb, n);
1041 }
1042
1043 static inline int dt_write_prep(const struct lu_env *env, struct dt_object *d,
1044                                 struct niobuf_local *lnb, int n)
1045 {
1046         LASSERT(d);
1047         LASSERT(d->do_body_ops);
1048         LASSERT(d->do_body_ops->dbo_write_prep);
1049         return d->do_body_ops->dbo_write_prep(env, d, lnb, n);
1050 }
1051
1052 static inline int dt_declare_write_commit(const struct lu_env *env,
1053                                           struct dt_object *d,
1054                                           struct niobuf_local *lnb,
1055                                           int n, struct thandle *th)
1056 {
1057         LASSERTF(d != NULL, "dt is NULL when we want to declare write\n");
1058         LASSERT(th != NULL);
1059         return d->do_body_ops->dbo_declare_write_commit(env, d, lnb, n, th);
1060 }
1061
1062
1063 static inline int dt_write_commit(const struct lu_env *env,
1064                                   struct dt_object *d, struct niobuf_local *lnb,
1065                                   int n, struct thandle *th)
1066 {
1067         LASSERT(d);
1068         LASSERT(d->do_body_ops);
1069         LASSERT(d->do_body_ops->dbo_write_commit);
1070         return d->do_body_ops->dbo_write_commit(env, d, lnb, n, th);
1071 }
1072
1073 static inline int dt_read_prep(const struct lu_env *env, struct dt_object *d,
1074                                struct niobuf_local *lnb, int n)
1075 {
1076         LASSERT(d);
1077         LASSERT(d->do_body_ops);
1078         LASSERT(d->do_body_ops->dbo_read_prep);
1079         return d->do_body_ops->dbo_read_prep(env, d, lnb, n);
1080 }
1081
1082 static inline int dt_declare_punch(const struct lu_env *env,
1083                                    struct dt_object *dt, __u64 start,
1084                                    __u64 end, struct thandle *th)
1085 {
1086         LASSERT(dt);
1087         LASSERT(dt->do_body_ops);
1088         LASSERT(dt->do_body_ops->do_declare_punch);
1089         return dt->do_body_ops->do_declare_punch(env, dt, start, end, th);
1090 }
1091
1092 static inline int dt_punch(const struct lu_env *env, struct dt_object *dt,
1093                            __u64 start, __u64 end, struct thandle *th,
1094                            struct lustre_capa *capa)
1095 {
1096         LASSERT(dt);
1097         LASSERT(dt->do_body_ops);
1098         LASSERT(dt->do_body_ops->do_punch);
1099         return dt->do_body_ops->do_punch(env, dt, start, end, th, capa);
1100 }
1101
1102 static inline int dt_fiemap_get(const struct lu_env *env, struct dt_object *d,
1103                                 struct ll_user_fiemap *fm)
1104 {
1105         LASSERT(d);
1106         if (d->do_body_ops == NULL)
1107                 return -EPROTO;
1108         LASSERT(d->do_body_ops->dbo_fiemap_get);
1109         return d->do_body_ops->dbo_fiemap_get(env, d, fm);
1110 }
1111
1112 static inline int dt_statfs(const struct lu_env *env, struct dt_device *dev,
1113                             struct obd_statfs *osfs)
1114 {
1115         LASSERT(dev);
1116         LASSERT(dev->dd_ops);
1117         LASSERT(dev->dd_ops->dt_statfs);
1118         return dev->dd_ops->dt_statfs(env, dev, osfs);
1119 }
1120
1121 static inline int dt_root_get(const struct lu_env *env, struct dt_device *dev,
1122                               struct lu_fid *f)
1123 {
1124         LASSERT(dev);
1125         LASSERT(dev->dd_ops);
1126         LASSERT(dev->dd_ops->dt_root_get);
1127         return dev->dd_ops->dt_root_get(env, dev, f);
1128 }
1129
1130 static inline void dt_conf_get(const struct lu_env *env,
1131                                const struct dt_device *dev,
1132                                struct dt_device_param *param)
1133 {
1134         LASSERT(dev);
1135         LASSERT(dev->dd_ops);
1136         LASSERT(dev->dd_ops->dt_conf_get);
1137         return dev->dd_ops->dt_conf_get(env, dev, param);
1138 }
1139
1140 static inline int dt_sync(const struct lu_env *env, struct dt_device *dev)
1141 {
1142         LASSERT(dev);
1143         LASSERT(dev->dd_ops);
1144         LASSERT(dev->dd_ops->dt_sync);
1145         return dev->dd_ops->dt_sync(env, dev);
1146 }
1147
1148 static inline int dt_ro(const struct lu_env *env, struct dt_device *dev)
1149 {
1150         LASSERT(dev);
1151         LASSERT(dev->dd_ops);
1152         LASSERT(dev->dd_ops->dt_ro);
1153         return dev->dd_ops->dt_ro(env, dev);
1154 }
1155
1156 static inline int dt_declare_insert(const struct lu_env *env,
1157                                     struct dt_object *dt,
1158                                     const struct dt_rec *rec,
1159                                     const struct dt_key *key,
1160                                     struct thandle *th)
1161 {
1162         LASSERT(dt);
1163         LASSERT(dt->do_index_ops);
1164         LASSERT(dt->do_index_ops->dio_declare_insert);
1165         return dt->do_index_ops->dio_declare_insert(env, dt, rec, key, th);
1166 }
1167
1168 static inline int dt_insert(const struct lu_env *env,
1169                                     struct dt_object *dt,
1170                                     const struct dt_rec *rec,
1171                                     const struct dt_key *key,
1172                                     struct thandle *th,
1173                                     struct lustre_capa *capa,
1174                                     int noquota)
1175 {
1176         LASSERT(dt);
1177         LASSERT(dt->do_index_ops);
1178         LASSERT(dt->do_index_ops->dio_insert);
1179         return dt->do_index_ops->dio_insert(env, dt, rec, key, th,
1180                                             capa, noquota);
1181 }
1182
1183 static inline int dt_declare_xattr_del(const struct lu_env *env,
1184                                        struct dt_object *dt,
1185                                        const char *name,
1186                                        struct thandle *th)
1187 {
1188         LASSERT(dt);
1189         LASSERT(dt->do_ops);
1190         LASSERT(dt->do_ops->do_declare_xattr_del);
1191         return dt->do_ops->do_declare_xattr_del(env, dt, name, th);
1192 }
1193
1194 static inline int dt_xattr_del(const struct lu_env *env,
1195                                struct dt_object *dt, const char *name,
1196                                struct thandle *th,
1197                                struct lustre_capa *capa)
1198 {
1199         LASSERT(dt);
1200         LASSERT(dt->do_ops);
1201         LASSERT(dt->do_ops->do_xattr_del);
1202         return dt->do_ops->do_xattr_del(env, dt, name, th, capa);
1203 }
1204
1205 static inline int dt_declare_xattr_set(const struct lu_env *env,
1206                                       struct dt_object *dt,
1207                                       const struct lu_buf *buf,
1208                                       const char *name, int fl,
1209                                       struct thandle *th)
1210 {
1211         LASSERT(dt);
1212         LASSERT(dt->do_ops);
1213         LASSERT(dt->do_ops->do_declare_xattr_set);
1214         return dt->do_ops->do_declare_xattr_set(env, dt, buf, name, fl, th);
1215 }
1216
1217 static inline int dt_xattr_set(const struct lu_env *env,
1218                               struct dt_object *dt, const struct lu_buf *buf,
1219                               const char *name, int fl, struct thandle *th,
1220                               struct lustre_capa *capa)
1221 {
1222         LASSERT(dt);
1223         LASSERT(dt->do_ops);
1224         LASSERT(dt->do_ops->do_xattr_set);
1225         return dt->do_ops->do_xattr_set(env, dt, buf, name, fl, th, capa);
1226 }
1227
1228 static inline int dt_xattr_get(const struct lu_env *env,
1229                               struct dt_object *dt, struct lu_buf *buf,
1230                               const char *name, struct lustre_capa *capa)
1231 {
1232         LASSERT(dt);
1233         LASSERT(dt->do_ops);
1234         LASSERT(dt->do_ops->do_xattr_get);
1235         return dt->do_ops->do_xattr_get(env, dt, buf, name, capa);
1236 }
1237
1238 static inline int dt_xattr_list(const struct lu_env *env,
1239                                struct dt_object *dt, struct lu_buf *buf,
1240                                struct lustre_capa *capa)
1241 {
1242         LASSERT(dt);
1243         LASSERT(dt->do_ops);
1244         LASSERT(dt->do_ops->do_xattr_list);
1245         return dt->do_ops->do_xattr_list(env, dt, buf, capa);
1246 }
1247
1248 static inline int dt_declare_delete(const struct lu_env *env,
1249                                     struct dt_object *dt,
1250                                     const struct dt_key *key,
1251                                     struct thandle *th)
1252 {
1253         LASSERT(dt);
1254         LASSERT(dt->do_index_ops);
1255         LASSERT(dt->do_index_ops->dio_declare_delete);
1256         return dt->do_index_ops->dio_declare_delete(env, dt, key, th);
1257 }
1258
1259 static inline int dt_delete(const struct lu_env *env,
1260                             struct dt_object *dt,
1261                             const struct dt_key *key,
1262                             struct thandle *th,
1263                             struct lustre_capa *capa)
1264 {
1265         LASSERT(dt);
1266         LASSERT(dt->do_index_ops);
1267         LASSERT(dt->do_index_ops->dio_delete);
1268         return dt->do_index_ops->dio_delete(env, dt, key, th, capa);
1269 }
1270
1271 static inline int dt_commit_async(const struct lu_env *env,
1272                                   struct dt_device *dev)
1273 {
1274         LASSERT(dev);
1275         LASSERT(dev->dd_ops);
1276         LASSERT(dev->dd_ops->dt_commit_async);
1277         return dev->dd_ops->dt_commit_async(env, dev);
1278 }
1279
1280 static inline int dt_lookup(const struct lu_env *env,
1281                             struct dt_object *dt,
1282                             struct dt_rec *rec,
1283                             const struct dt_key *key,
1284                             struct lustre_capa *capa)
1285 {
1286         int ret;
1287
1288         LASSERT(dt);
1289         LASSERT(dt->do_index_ops);
1290         LASSERT(dt->do_index_ops->dio_lookup);
1291
1292         ret = dt->do_index_ops->dio_lookup(env, dt, rec, key, capa);
1293         if (ret > 0)
1294                 ret = 0;
1295         else if (ret == 0)
1296                 ret = -ENOENT;
1297         return ret;
1298 }
1299
1300 #define LU221_BAD_TIME (0x80000000U + 24 * 3600)
1301
1302 #endif /* __LUSTRE_DT_OBJECT_H */