Whamcloud - gitweb
- land b_hd_ver_recov
[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  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
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 txn_param;
66 struct dt_device;
67 struct dt_object;
68 struct dt_index_features;
69 struct dt_quota_ctxt;
70
71 struct dt_device_param {
72         unsigned           ddp_max_name_len;
73         unsigned           ddp_max_nlink;
74         unsigned           ddp_block_shift;
75 };
76
77 /**
78  * Basic transaction credit op
79  */
80 enum dt_txn_op {
81         DTO_INDEX_INSERT,
82         DTO_INDEX_DELETE,
83         DTO_IDNEX_UPDATE,
84         DTO_OBJECT_CREATE,
85         DTO_OBJECT_DELETE,
86         DTO_ATTR_SET_BASE,
87         DTO_XATTR_SET,
88         DTO_LOG_REC, /**< XXX temporary: dt layer knows nothing about llog. */
89         DTO_WRITE_BASE,
90         DTO_WRITE_BLOCK,
91         DTO_ATTR_SET_CHOWN,
92
93         DTO_NR
94 };
95
96 /**
97  * Operations on dt device.
98  */
99 struct dt_device_operations {
100         /**
101          * Return device-wide statistics.
102          */
103         int   (*dt_statfs)(const struct lu_env *env,
104                            struct dt_device *dev, struct kstatfs *sfs);
105         /**
106          * Start transaction, described by \a param.
107          */
108         struct thandle *(*dt_trans_start)(const struct lu_env *env,
109                                           struct dt_device *dev,
110                                           struct txn_param *param);
111         /**
112          * Finish previously started transaction.
113          */
114         void  (*dt_trans_stop)(const struct lu_env *env,
115                                struct thandle *th);
116         /**
117          * Return fid of root index object.
118          */
119         int   (*dt_root_get)(const struct lu_env *env,
120                              struct dt_device *dev, struct lu_fid *f);
121         /**
122          * Return device configuration data.
123          */
124         void  (*dt_conf_get)(const struct lu_env *env,
125                              const struct dt_device *dev,
126                              struct dt_device_param *param);
127         /**
128          *  handling device state, mostly for tests
129          */
130         int   (*dt_sync)(const struct lu_env *env, struct dt_device *dev);
131         void  (*dt_ro)(const struct lu_env *env, struct dt_device *dev);
132         /**
133           * Start a transaction commit asynchronously
134           *
135           * \param env environment
136           * \param dev dt_device to start commit on
137           *
138           * \return 0 success, negative value if error
139           */
140          int   (*dt_commit_async)(const struct lu_env *env,
141                                   struct dt_device *dev);
142         /**
143          * Initialize capability context.
144          */
145         int   (*dt_init_capa_ctxt)(const struct lu_env *env,
146                                    struct dt_device *dev,
147                                    int mode, unsigned long timeout,
148                                    __u32 alg, struct lustre_capa_key *keys);
149         /**
150          * Initialize quota context.
151          */
152         void (*dt_init_quota_ctxt)(const struct lu_env *env,
153                                    struct dt_device *dev,
154                                    struct dt_quota_ctxt *ctxt, void *data);
155
156         /**
157          *  get transaction credits for given \a op.
158          */
159         int (*dt_credit_get)(const struct lu_env *env, struct dt_device *dev,
160                              enum dt_txn_op);
161 };
162
163 struct dt_index_features {
164         /** required feature flags from enum dt_index_flags */
165         __u32 dif_flags;
166         /** minimal required key size */
167         size_t dif_keysize_min;
168         /** maximal required key size, 0 if no limit */
169         size_t dif_keysize_max;
170         /** minimal required record size */
171         size_t dif_recsize_min;
172         /** maximal required record size, 0 if no limit */
173         size_t dif_recsize_max;
174         /** pointer size for record */
175         size_t dif_ptrsize;
176 };
177
178 enum dt_index_flags {
179         /** index supports variable sized keys */
180         DT_IND_VARKEY = 1 << 0,
181         /** index supports variable sized records */
182         DT_IND_VARREC = 1 << 1,
183         /** index can be modified */
184         DT_IND_UPDATE = 1 << 2,
185         /** index supports records with non-unique (duplicate) keys */
186         DT_IND_NONUNQ = 1 << 3
187 };
188
189 /**
190  * Features, required from index to support file system directories (mapping
191  * names to fids).
192  */
193 extern const struct dt_index_features dt_directory_features;
194
195 /**
196  * This is a general purpose dt allocation hint.
197  * It now contains the parent object.
198  * It can contain any allocation hint in the future.
199  */
200 struct dt_allocation_hint {
201         struct dt_object           *dah_parent;
202         __u32                       dah_mode;
203 };
204
205 /**
206  * object type specifier.
207  */
208
209 enum dt_format_type {
210         DFT_REGULAR,
211         DFT_DIR,
212         /** for mknod */
213         DFT_NODE,
214         /** for special index */
215         DFT_INDEX,
216         /** for symbolic link */
217         DFT_SYM,
218 };
219
220 /**
221  * object format specifier.
222  */
223 struct dt_object_format {
224         /** type for dt object */
225         enum dt_format_type dof_type;
226         union {
227                 struct dof_regular {
228                 } dof_reg;
229                 struct dof_dir {
230                 } dof_dir;
231                 struct dof_node {
232                 } dof_node;
233                 /**
234                  * special index need feature as parameter to create
235                  * special idx
236                  */
237                 struct dof_index {
238                         const struct dt_index_features *di_feat;
239                 } dof_idx;
240         } u;
241 };
242
243 enum dt_format_type dt_mode_to_dft(__u32 mode);
244
245 /** Version type. May differ in DMU and ldiskfs */
246 typedef __u64 dt_obj_version_t;
247
248 /**
249  * Per-dt-object operations.
250  */
251 struct dt_object_operations {
252         void  (*do_read_lock)(const struct lu_env *env,
253                               struct dt_object *dt, unsigned role);
254         void  (*do_write_lock)(const struct lu_env *env,
255                                struct dt_object *dt, unsigned role);
256         void  (*do_read_unlock)(const struct lu_env *env,
257                                 struct dt_object *dt);
258         void  (*do_write_unlock)(const struct lu_env *env,
259                                  struct dt_object *dt);
260         /**
261          * Note: following ->do_{x,}attr_{set,get}() operations are very
262          * similar to ->moo_{x,}attr_{set,get}() operations in struct
263          * md_object_operations (see md_object.h). These operations are not in
264          * lu_object_operations, because ->do_{x,}attr_set() versions take
265          * transaction handle as an argument (this transaction is started by
266          * caller). We might factor ->do_{x,}attr_get() into
267          * lu_object_operations, but that would break existing symmetry.
268          */
269
270         /**
271          * Return standard attributes.
272          *
273          * precondition: lu_object_exists(&dt->do_lu);
274          */
275         int   (*do_attr_get)(const struct lu_env *env,
276                              struct dt_object *dt, struct lu_attr *attr,
277                              struct lustre_capa *capa);
278         /**
279          * Set standard attributes.
280          *
281          * precondition: dt_object_exists(dt);
282          */
283         int   (*do_attr_set)(const struct lu_env *env,
284                              struct dt_object *dt,
285                              const struct lu_attr *attr,
286                              struct thandle *handle,
287                              struct lustre_capa *capa);
288         /**
289          * Return a value of an extended attribute.
290          *
291          * precondition: dt_object_exists(dt);
292          */
293         int   (*do_xattr_get)(const struct lu_env *env, struct dt_object *dt,
294                               struct lu_buf *buf, const char *name,
295                               struct lustre_capa *capa);
296         /**
297          * Set value of an extended attribute.
298          *
299          * \a fl - flags from enum lu_xattr_flags
300          *
301          * precondition: dt_object_exists(dt);
302          */
303         int   (*do_xattr_set)(const struct lu_env *env,
304                               struct dt_object *dt, const struct lu_buf *buf,
305                               const char *name, int fl, struct thandle *handle,
306                               struct lustre_capa *capa);
307         /**
308          * Delete existing extended attribute.
309          *
310          * precondition: dt_object_exists(dt);
311          */
312         int   (*do_xattr_del)(const struct lu_env *env,
313                               struct dt_object *dt,
314                               const char *name, struct thandle *handle,
315                               struct lustre_capa *capa);
316         /**
317          * Place list of existing extended attributes into \a buf (which has
318          * length len).
319          *
320          * precondition: dt_object_exists(dt);
321          */
322         int   (*do_xattr_list)(const struct lu_env *env,
323                                struct dt_object *dt, struct lu_buf *buf,
324                                struct lustre_capa *capa);
325         /**
326          * Init allocation hint using parent object and child mode.
327          * (1) The \a parent might be NULL if this is a partial creation for
328          *     remote object.
329          * (2) The type of child is in \a child_mode.
330          * (3) The result hint is stored in \a ah;
331          */
332         void  (*do_ah_init)(const struct lu_env *env,
333                             struct dt_allocation_hint *ah,
334                             struct dt_object *parent,
335                             umode_t child_mode);
336         /**
337          * Create new object on this device.
338          *
339          * precondition: !dt_object_exists(dt);
340          * postcondition: ergo(result == 0, dt_object_exists(dt));
341          */
342         int   (*do_create)(const struct lu_env *env, struct dt_object *dt,
343                            struct lu_attr *attr,
344                            struct dt_allocation_hint *hint,
345                            struct dt_object_format *dof,
346                            struct thandle *th);
347
348         /**
349          * Announce that this object is going to be used as an index. This
350          * operation check that object supports indexing operations and
351          * installs appropriate dt_index_operations vector on success.
352          *
353          * Also probes for features. Operation is successful if all required
354          * features are supported.
355          */
356         int   (*do_index_try)(const struct lu_env *env,
357                               struct dt_object *dt,
358                               const struct dt_index_features *feat);
359         /**
360          * Add nlink of the object
361          * precondition: dt_object_exists(dt);
362          */
363         void  (*do_ref_add)(const struct lu_env *env,
364                             struct dt_object *dt, struct thandle *th);
365         /**
366          * Del nlink of the object
367          * precondition: dt_object_exists(dt);
368          */
369         void  (*do_ref_del)(const struct lu_env *env,
370                             struct dt_object *dt, struct thandle *th);
371
372         struct obd_capa *(*do_capa_get)(const struct lu_env *env,
373                                         struct dt_object *dt,
374                                         struct lustre_capa *old,
375                                         __u64 opc);
376         int (*do_object_sync)(const struct lu_env *, struct dt_object *);
377         dt_obj_version_t (*do_version_get)(const struct lu_env *env,
378                                            struct dt_object *dt);
379         void (*do_version_set)(const struct lu_env *env, struct dt_object *dt,
380                                dt_obj_version_t new_version);
381         /**
382          * Get object info of next level. Currently, only get inode from osd.
383          * This is only used by quota b=16542
384          * precondition: dt_object_exists(dt);
385          */
386         int (*do_data_get)(const struct lu_env *env, struct dt_object *dt,
387                            void **data);
388 };
389
390 /**
391  * Per-dt-object operations on "file body".
392  */
393 struct dt_body_operations {
394         /**
395          * precondition: dt_object_exists(dt);
396          */
397         ssize_t (*dbo_read)(const struct lu_env *env, struct dt_object *dt,
398                             struct lu_buf *buf, loff_t *pos,
399                             struct lustre_capa *capa);
400         /**
401          * precondition: dt_object_exists(dt);
402          */
403         ssize_t (*dbo_write)(const struct lu_env *env, struct dt_object *dt,
404                              const struct lu_buf *buf, loff_t *pos,
405                              struct thandle *handle, struct lustre_capa *capa,
406                              int ignore_quota);
407 };
408
409 /**
410  * Incomplete type of index record.
411  */
412 struct dt_rec;
413
414 /**
415  * Incomplete type of index key.
416  */
417 struct dt_key;
418
419 /**
420  * Incomplete type of dt iterator.
421  */
422 struct dt_it;
423
424 /**
425  * Per-dt-object operations on object as index.
426  */
427 struct dt_index_operations {
428         /**
429          * precondition: dt_object_exists(dt);
430          */
431         int (*dio_lookup)(const struct lu_env *env, struct dt_object *dt,
432                           struct dt_rec *rec, const struct dt_key *key,
433                           struct lustre_capa *capa);
434         /**
435          * precondition: dt_object_exists(dt);
436          */
437         int (*dio_insert)(const struct lu_env *env, struct dt_object *dt,
438                           const struct dt_rec *rec, const struct dt_key *key,
439                           struct thandle *handle, struct lustre_capa *capa,
440                           int ignore_quota);
441         /**
442          * precondition: dt_object_exists(dt);
443          */
444         int (*dio_delete)(const struct lu_env *env, struct dt_object *dt,
445                           const struct dt_key *key, struct thandle *handle,
446                           struct lustre_capa *capa);
447         /**
448          * Iterator interface
449          */
450         struct dt_it_ops {
451                 /**
452                  * Allocate and initialize new iterator.
453                  *
454                  * precondition: dt_object_exists(dt);
455                  */
456                 struct dt_it *(*init)(const struct lu_env *env,
457                                       struct dt_object *dt,
458                                       struct lustre_capa *capa);
459                 void          (*fini)(const struct lu_env *env,
460                                       struct dt_it *di);
461                 int            (*get)(const struct lu_env *env,
462                                       struct dt_it *di,
463                                       const struct dt_key *key);
464                 void           (*put)(const struct lu_env *env,
465                                       struct dt_it *di);
466                 int           (*next)(const struct lu_env *env,
467                                       struct dt_it *di);
468                 struct dt_key *(*key)(const struct lu_env *env,
469                                       const struct dt_it *di);
470                 int       (*key_size)(const struct lu_env *env,
471                                       const struct dt_it *di);
472                 struct dt_rec *(*rec)(const struct lu_env *env,
473                                       const struct dt_it *di);
474                 __u64        (*store)(const struct lu_env *env,
475                                       const struct dt_it *di);
476                 int           (*load)(const struct lu_env *env,
477                                       const struct dt_it *di, __u64 hash);
478         } dio_it;
479 };
480
481 struct dt_device {
482         struct lu_device                   dd_lu_dev;
483         const struct dt_device_operations *dd_ops;
484
485         /**
486          * List of dt_txn_callback (see below). This is not protected in any
487          * way, because callbacks are supposed to be added/deleted only during
488          * single-threaded start-up shut-down procedures.
489          */
490         struct list_head                   dd_txn_callbacks;
491 };
492
493 int  dt_device_init(struct dt_device *dev, struct lu_device_type *t);
494 void dt_device_fini(struct dt_device *dev);
495
496 static inline int lu_device_is_dt(const struct lu_device *d)
497 {
498         return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_DT);
499 }
500
501 static inline struct dt_device * lu2dt_dev(struct lu_device *l)
502 {
503         LASSERT(lu_device_is_dt(l));
504         return container_of0(l, struct dt_device, dd_lu_dev);
505 }
506
507 struct dt_object {
508         struct lu_object                   do_lu;
509         const struct dt_object_operations *do_ops;
510         const struct dt_body_operations   *do_body_ops;
511         const struct dt_index_operations  *do_index_ops;
512 };
513
514 int  dt_object_init(struct dt_object *obj,
515                     struct lu_object_header *h, struct lu_device *d);
516
517 void dt_object_fini(struct dt_object *obj);
518
519 static inline int dt_object_exists(const struct dt_object *dt)
520 {
521         return lu_object_exists(&dt->do_lu);
522 }
523
524 struct txn_param {
525         /** number of blocks this transaction will modify */
526         unsigned int tp_credits;
527         /** sync transaction is needed */
528         __u32        tp_sync:1;
529 };
530
531 static inline void txn_param_init(struct txn_param *p, unsigned int credits)
532 {
533         memset(p, 0, sizeof(*p));
534         p->tp_credits = credits;
535 }
536
537 /**
538  * This is the general purpose transaction handle.
539  * 1. Transaction Life Cycle
540  *      This transaction handle is allocated upon starting a new transaction,
541  *      and deallocated after this transaction is committed.
542  * 2. Transaction Nesting
543  *      We do _NOT_ support nested transaction. So, every thread should only
544  *      have one active transaction, and a transaction only belongs to one
545  *      thread. Due to this, transaction handle need no reference count.
546  * 3. Transaction & dt_object locking
547  *      dt_object locks should be taken inside transaction.
548  * 4. Transaction & RPC
549  *      No RPC request should be issued inside transaction.
550  */
551 struct thandle {
552         /** the dt device on which the transactions are executed */
553         struct dt_device *th_dev;
554
555         /** context for this transaction, tag is LCT_TX_HANDLE */
556         struct lu_context th_ctx;
557
558         /** the last operation result in this transaction.
559          * this value is used in recovery */
560         __s32             th_result;
561 };
562
563 /**
564  * Transaction call-backs.
565  *
566  * These are invoked by osd (or underlying transaction engine) when
567  * transaction changes state.
568  *
569  * Call-backs are used by upper layers to modify transaction parameters and to
570  * perform some actions on for each transaction state transition. Typical
571  * example is mdt registering call-back to write into last-received file
572  * before each transaction commit.
573  */
574 struct dt_txn_callback {
575         int (*dtc_txn_start)(const struct lu_env *env,
576                              struct txn_param *param, void *cookie);
577         int (*dtc_txn_stop)(const struct lu_env *env,
578                             struct thandle *txn, void *cookie);
579         int (*dtc_txn_commit)(const struct lu_env *env,
580                               struct thandle *txn, void *cookie);
581         void            *dtc_cookie;
582         __u32            dtc_tag;
583         struct list_head dtc_linkage;
584 };
585
586 void dt_txn_callback_add(struct dt_device *dev, struct dt_txn_callback *cb);
587 void dt_txn_callback_del(struct dt_device *dev, struct dt_txn_callback *cb);
588
589 int dt_txn_hook_start(const struct lu_env *env,
590                       struct dt_device *dev, struct txn_param *param);
591 int dt_txn_hook_stop(const struct lu_env *env, struct thandle *txn);
592 int dt_txn_hook_commit(const struct lu_env *env, struct thandle *txn);
593
594 int dt_try_as_dir(const struct lu_env *env, struct dt_object *obj);
595
596 /**
597  * Callback function used for parsing path.
598  * \see llo_store_resolve
599  */
600 typedef int (*dt_entry_func_t)(const struct lu_env *env,
601                             const char *name,
602                             void *pvt);
603
604 #define DT_MAX_PATH 1024
605
606 int dt_path_parser(const struct lu_env *env,
607                    char *local, dt_entry_func_t entry_func,
608                    void *data);
609
610 struct dt_object *dt_store_open(const struct lu_env *env,
611                                 struct dt_device *dt,
612                                 const char *dirname,
613                                 const char *filename,
614                                 struct lu_fid *fid);
615
616 struct dt_object *dt_locate(const struct lu_env *env,
617                             struct dt_device *dev,
618                             const struct lu_fid *fid);
619
620 static inline dt_obj_version_t do_version_get(const struct lu_env *env,
621                                               struct dt_object *o)
622 {
623         LASSERT(o->do_ops->do_version_get);
624         return o->do_ops->do_version_get(env, o);
625 }
626
627 static inline void do_version_set(const struct lu_env *env,
628                                   struct dt_object *o, dt_obj_version_t v)
629 {
630         LASSERT(o->do_ops->do_version_set);
631         return o->do_ops->do_version_set(env, o, v);
632 }
633
634 int dt_record_read(const struct lu_env *env, struct dt_object *dt,
635                    struct lu_buf *buf, loff_t *pos);
636 int dt_record_write(const struct lu_env *env, struct dt_object *dt,
637                     const struct lu_buf *buf, loff_t *pos, struct thandle *th);
638
639
640 static inline struct thandle *dt_trans_start(const struct lu_env *env,
641                                              struct dt_device *d,
642                                              struct txn_param *p)
643 {
644         LASSERT(d->dd_ops->dt_trans_start);
645         return d->dd_ops->dt_trans_start(env, d, p);
646 }
647
648 static inline void dt_trans_stop(const struct lu_env *env,
649                                  struct dt_device *d,
650                                  struct thandle *th)
651 {
652         LASSERT(d->dd_ops->dt_trans_stop);
653         return d->dd_ops->dt_trans_stop(env, th);
654 }
655 /** @} dt */
656 #endif /* __LUSTRE_DT_OBJECT_H */