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