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