Whamcloud - gitweb
b7c53cb02b98ab10333d60ec659773b86abe467d
[fs/lustre-release.git] / lustre / osd / osd_iam.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 [sun.com URL with a
20  * copy of GPLv2].
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  * osd_iam.c
37  * Top-level entry points into osd module
38  *
39  * Author: Wang Di <wangdi@clusterfs.com>
40  * Author: Nikita Danilov <nikita@clusterfs.com>
41  */
42
43 #ifndef __LINUX_LUSTRE_IAM_H__
44 #define __LINUX_LUSTRE_IAM_H__
45
46 #include <linux/module.h>
47 #include <asm/unaligned.h>
48 #include <linux/dynlocks.h>
49
50 /*
51  *  linux/include/linux/osd_iam.h
52  */
53 #ifndef CLASSERT
54 #define CLASSERT(cond) do {switch(42) {case (cond): case 0: break;}} while (0)
55 #endif
56 /* implication */
57 #define ergo(a, b) (!(a) || (b))
58 /* logical equivalence */
59 #define equi(a, b) (!!(a) == !!(b))
60
61 enum {
62         /*
63          * Maximal number of non-leaf levels in htree. In the stock ldiskfs this
64          * is 2.
65          */
66         /*
67          * XXX reduced back to 2 to make per-node locking work.
68          */
69         DX_MAX_TREE_HEIGHT = 5,
70         /*
71          * Scratch keys used by generic code for temporaries.
72          *
73          * Allocation:
74          *
75          *         [0] reserved for assertions and as a staging area for
76          *         record keys immediately used for key comparisons.
77          *
78          *         [1] reserved for record key, stored during iteration over
79          *         node records (see dx_node_check()).
80          *
81          *         [2] reserved for leaf node operations.
82          *
83          *         [3] reserved for index operations.
84          *
85          *         [4] reserved for path->ip_ikey_target
86          *
87          */
88         DX_SCRATCH_KEYS    = 5,
89         /*
90          * Maximal format name length.
91          */
92         DX_FMT_NAME_LEN    = 16,
93 };
94
95 #ifdef __KERNEL__
96 /* handle_t, journal_start(), journal_stop() */
97 #include <linux/jbd.h>
98
99 /*
100  * Debugging.
101  *
102  * Various debugging levels.
103  */
104
105 #if 0
106 /*
107  * Following macros are defined in config.h and are tunable through
108  * appropriate configure switches (indicated below).
109  */
110
111 /*
112  * Compile basic assertions in. You want this most of the time.
113  *
114  * --{enable,disable}-ldiskfs-assert (on by default).
115  */
116 #define LDISKFS_ASSERT (1)
117
118 /*
119  * Compile heavier correctness checks in. You want this during development
120  * cycle.
121  *
122  * --{enable,disable}-ldiskfs-correctness (off by default).
123  */
124 #define LDISKFS_CORRECTNESS (1)
125
126 /*
127  * Compile heavy invariant checking in. You want this early during development
128  * or when chasing a bug.
129  *
130  * --{enable,disable}-ldiskfs-invariant (off by default).
131  */
132 #define LDISKFS_INVARIANT (1)
133 #endif
134
135 #if defined(LDISKFS_ASSERT)
136 #define LDISKFS_ASSERT_ON (1)
137 #else
138 #define LDISKFS_ASSERT_ON (0)
139 #endif
140
141 #if defined(LDISKFS_CORRECTNESS)
142 #define LDISKFS_CORRECTNESS_ON (1)
143 #else
144 #define LDISKFS_CORRECTNESS_ON (0)
145 #endif
146
147 #if defined(LDISKFS_INVARIANT)
148 #define LDISKFS_INVARIANT_ON (1)
149 #else
150 #define LDISKFS_INVARIANT_ON (0)
151 #endif
152
153 #ifndef assert
154 #if LDISKFS_ASSERT_ON
155 #define assert(test) J_ASSERT(test)
156 #else
157 #define assert(test) ((void)(test))
158 #endif
159 #endif
160
161 #if LDISKFS_CORRECTNESS_ON
162 #define assert_corr(test) J_ASSERT(test)
163 #define do_corr(exp) exp
164 #else
165 #define assert_corr(test) do {;} while (0)
166 #define do_corr(exp) do {;} while (0)
167 #endif
168
169 #if LDISKFS_INVARIANT_ON
170 #define assert_inv(test) J_ASSERT(test)
171 #else
172 #define assert_inv(test) do {;} while (0)
173 #endif
174
175 /*
176  * Entry within index tree node. Consists of a key immediately followed
177  * (without padding) by a pointer to the child node.
178  *
179  * Both key and pointer are of variable size, hence incomplete type.
180  */
181 struct iam_entry;
182
183 struct iam_entry_compat {
184         __le32 hash;
185         __le32 block;
186 };
187
188 /*
189  * Incomplete type used to refer to keys in iam container.
190  *
191  * As key size can be different from container to container, iam has to use
192  * incomplete type. Clients cast pointer to iam_key to real key type and back.
193  */
194 struct iam_key;
195
196 /*
197  * Incomplete type use to refer to the records stored in iam containers.
198  */
199 struct iam_rec;
200
201 /*
202  * Key in index node. Possibly compressed. Fixed size.
203  */
204 struct iam_ikey;
205
206 /*
207  * Scalar type into which certain iam_key's can be uniquely mapped. Used to
208  * support interfaces like readdir(), where iteration over index has to be
209  * re-startable.
210  */
211 typedef __u32 iam_ptr_t;
212
213 /*
214  * Index node traversed during tree lookup.
215  */
216 struct iam_frame {
217         struct buffer_head *bh;    /* buffer holding node data */
218         struct iam_entry *entries; /* array of entries */
219         struct iam_entry *at;      /* target entry, found by binary search */
220         iam_ptr_t         leaf;    /* (logical) offset of child node found by
221                                     * binary search. */
222         iam_ptr_t         curidx;  /* (logical) offset of this node. Used to
223                                     * per-node locking to detect concurrent
224                                     * splits. */
225 };
226
227 /*
228  * Opaque entry in the leaf node.
229  */
230 struct iam_lentry;
231
232 struct iam_path;
233 struct iam_container;
234
235
236 /* leaf node reached by tree lookup */
237 struct iam_leaf {
238         struct iam_path    *il_path;
239         struct buffer_head *il_bh;
240         struct iam_lentry  *il_entries;
241         struct iam_lentry  *il_at;
242         /*
243          * Lock on a leaf node.
244          */
245         struct dynlock_handle *il_lock;
246         iam_ptr_t              il_curidx; /* logical offset of leaf node. */
247         void               *il_descr_data;
248 };
249
250 /*
251  * Return values of ->lookup() operation from struct iam_leaf_operations.
252  */
253 enum iam_lookup_t {
254         /*
255          * lookup found a record with the key requested
256          */
257         IAM_LOOKUP_EXACT  = 0,
258         /*
259          * lookup positioned leaf on some record
260          */
261         IAM_LOOKUP_OK     = 1,
262         /*
263          * leaf was empty
264          */
265         IAM_LOOKUP_EMPTY  = 2,
266         /*
267          * lookup positioned leaf before first record
268          */
269         IAM_LOOKUP_BEFORE = 3,
270         /*
271          * Found hash may have a continuation in the next leaf.
272          */
273         IAM_LOOKUP_LAST   = 0x100
274 };
275
276 /*
277  * Format-specific container operations. These are called by generic iam code.
278  */
279 struct iam_operations {
280         /*
281          * Returns pointer (in the same sense as pointer in index entry) to
282          * the root node.
283          */
284         __u32 (*id_root_ptr)(struct iam_container *c);
285
286         /*
287          * Check validity and consistency of index node.
288          */
289         int (*id_node_check)(struct iam_path *path, struct iam_frame *frame);
290         /*
291          * Copy some data from node header into frame. This is called when
292          * new node is loaded into frame.
293          */
294         int (*id_node_load)(struct iam_path *path, struct iam_frame *frame);
295         /*
296          * Initialize new node (stored in @bh) that is going to be added into
297          * tree.
298          */
299         int (*id_node_init)(struct iam_container *c,
300                             struct buffer_head *bh, int root);
301         int (*id_node_read)(struct iam_container *c, iam_ptr_t ptr,
302                             handle_t *h, struct buffer_head **bh);
303         /*
304          * Key comparison functions. Returns -1, 0, +1.
305          */
306         int (*id_ikeycmp)(const struct iam_container *c,
307                           const struct iam_ikey *k1,
308                           const struct iam_ikey *k2);
309         /*
310          * Modify root node when tree height increases.
311          */
312         struct iam_entry *(*id_root_inc)(struct iam_container *c,
313                                          struct iam_path *path,
314                                          struct iam_frame *frame);
315
316         struct iam_path_descr *(*id_ipd_alloc)(const struct iam_container *c,
317                                                void *area);
318         void (*id_ipd_free)(struct iam_path_descr *ipd);
319         /*
320          * Format name.
321          */
322         char id_name[DX_FMT_NAME_LEN];
323 };
324
325 /*
326  * Another format-specific operation vector, consisting of methods to access
327  * leaf nodes. This is separated from struct iam_operations, because it is
328  * assumed that there will be many formats with different format of leaf
329  * nodes, yes the same struct iam_operations.
330  */
331 struct iam_leaf_operations {
332                 /*
333                  * leaf operations.
334                  */
335
336         /*
337          * initialize just loaded leaf node.
338          */
339         int (*init)(struct iam_leaf *p);
340         /*
341          * Format new node.
342          */
343         void (*init_new)(struct iam_container *c, struct buffer_head *bh);
344         /*
345          * Release resources.
346          */
347         void (*fini)(struct iam_leaf *l);
348                 /*
349                  * returns true iff leaf is positioned at the last entry.
350                  */
351         int (*at_end)(const struct iam_leaf *l);
352                 /* position leaf at the first entry */
353         void (*start)(struct iam_leaf *l);
354                 /* more leaf to the next entry. */
355         void (*next)(struct iam_leaf *l);
356         /*
357          * return key of current leaf record. This method may return
358          * either pointer to the key stored in node, or copy key into
359          * @k buffer supplied by caller and return pointer to this
360          * buffer. The latter approach is used when keys in nodes are
361          * not stored in plain form (e.g., htree doesn't store keys at
362          * all).
363          *
364          * Caller should assume that returned pointer is only valid
365          * while leaf node is pinned and locked.
366          */
367         struct iam_ikey *(*ikey)(const struct iam_leaf *l, struct iam_ikey *k);
368         struct iam_key *(*key)(const struct iam_leaf *l);
369         /* return pointer to entry body. Pointer is valid while
370            corresponding leaf node is locked and pinned. */
371         struct iam_rec *(*rec)(const struct iam_leaf *l);
372
373         void (*key_set)(struct iam_leaf *l, const struct iam_key *k);
374         void (*rec_set)(struct iam_leaf *l, const struct iam_rec *r);
375         void (*rec_get)(const struct iam_leaf *l, struct iam_rec *r);
376
377         int (*key_cmp)(const struct iam_leaf *l, const struct iam_key *k);
378         int (*key_eq)(const struct iam_leaf *l, const struct iam_key *k);
379
380         int (*key_size)(const struct iam_leaf *l);
381         /*
382          * Search leaf @l for a record with key @k or for a place
383          * where such record is to be inserted.
384          *
385          * Scratch keys from @path can be used.
386          */
387         int (*lookup)(struct iam_leaf *l, const struct iam_key *k);
388         int (*ilookup)(struct iam_leaf *l, const struct iam_ikey *ik);
389
390         int (*can_add)(const struct iam_leaf *l,
391                        const struct iam_key *k, const struct iam_rec *r);
392         /*
393          * add rec for a leaf
394          */
395         void (*rec_add)(struct iam_leaf *l,
396                         const struct iam_key *k, const struct iam_rec *r);
397         /*
398          * remove rec for a leaf
399          */
400         void (*rec_del)(struct iam_leaf *l, int shift);
401         /*
402          * split leaf node, moving some entries into @bh (the latter currently
403          * is assumed to be empty).
404          */
405         void (*split)(struct iam_leaf *l, struct buffer_head **bh,
406                       iam_ptr_t newblknr);
407 };
408
409 /*
410  * Parameters, describing a flavor of iam container.
411  */
412 struct iam_descr {
413         /*
414          * Size of a key in this container, in bytes.
415          */
416          size_t       id_key_size;
417         /*
418          * Size of a key in index nodes, in bytes.
419          */
420          size_t       id_ikey_size;
421         /*
422          * Size of a pointer to the next level (stored in index nodes), in
423          * bytes.
424          */
425         size_t       id_ptr_size;
426         /*
427          * Size of a record (stored in leaf nodes), in bytes.
428          */
429         size_t       id_rec_size;
430         /*
431          * Size of unused (by iam) space at the beginning of every non-root
432          * node, in bytes. Used for compatibility with ldiskfs.
433          */
434         size_t       id_node_gap;
435         /*
436          * Size of unused (by iam) space at the beginning of root node, in
437          * bytes. Used for compatibility with ldiskfs.
438          */
439         size_t       id_root_gap;
440
441         struct iam_operations           *id_ops;
442         struct iam_leaf_operations      *id_leaf_ops;
443 };
444
445 /*
446  * An instance of iam container.
447  */
448 struct iam_container {
449         /*
450          * Underlying flat file. IO against this object is issued to
451          * read/write nodes.
452          */
453         struct inode     *ic_object;
454         /*
455          * container flavor.
456          */
457         struct iam_descr *ic_descr;
458         /*
459          * read-write lock protecting index consistency.
460          */
461         struct rw_semaphore ic_sem;
462 };
463
464 /*
465  * description-specific part of iam_path. This is usually embedded into larger
466  * structure.
467  */
468 struct iam_path_descr {
469         /*
470          * Scratch-pad area for temporary keys.
471          */
472         struct iam_ikey *ipd_key_scratch[DX_SCRATCH_KEYS];
473 };
474
475 /*
476  * Structure to keep track of a path drilled through htree.
477  */
478 struct iam_path {
479         /*
480          * Parent container.
481          */
482         struct iam_container  *ip_container;
483         /*
484          * Number of index levels minus one.
485          */
486         int                    ip_indirect;
487         /*
488          * Nodes that top-to-bottom traversal passed through.
489          */
490         struct iam_frame       ip_frames[DX_MAX_TREE_HEIGHT];
491         /*
492          * Last filled frame in ->ip_frames. Refers to the 'twig' node (one
493          * immediately above leaf).
494          */
495         struct iam_frame      *ip_frame;
496         /*
497          * Leaf node: a child of ->ip_frame.
498          */
499         struct iam_leaf        ip_leaf;
500         /*
501          * Key searched for.
502          */
503         const struct iam_key  *ip_key_target;
504         const struct iam_ikey *ip_ikey_target;
505         /*
506          * Description-specific data.
507          */
508         struct iam_path_descr *ip_data;
509 };
510
511 struct ldiskfs_dx_hash_info;
512
513 /*
514  * Helper structure for legacy htrees.
515  */
516 struct iam_path_compat {
517         struct iam_path      ipc_path;
518         struct iam_container ipc_container;
519         __u32                 ipc_scratch[DX_SCRATCH_KEYS];
520         struct ldiskfs_dx_hash_info  *ipc_hinfo;
521         struct qstr          *ipc_qstr;
522         struct iam_path_descr ipc_descr;
523         struct ldiskfs_dx_hash_info   ipc_hinfo_area;
524 };
525
526 #define const_max(p, q) ((p > q) ? p : q)
527
528 enum {
529         DX_MAX_IKEY_SIZE   = 32, /* be generous */
530         /*
531          * Hack to avoid dynamic allocation and freeing of ipd.
532          */
533         DX_IPD_MAX_SIZE    = const_max(sizeof(struct iam_path_compat),
534                                        DX_MAX_IKEY_SIZE * DX_SCRATCH_KEYS +
535                                        sizeof(struct iam_path_descr))
536 };
537
538 /*
539  * iam cursor (iterator) api.
540  */
541
542 /*
543  * States of iterator state machine.
544  */
545 enum iam_it_state {
546         /* initial state */
547         IAM_IT_DETACHED,
548         /* iterator is above particular record in the container */
549         IAM_IT_ATTACHED,
550         /* iterator is positioned before record  */
551         IAM_IT_SKEWED
552 };
553
554 /*
555  * Flags controlling iterator functionality.
556  */
557 enum iam_it_flags {
558         /*
559          * this iterator will move (iam_it_next() will be called on it)
560          */
561         IAM_IT_MOVE  = (1 << 0),
562         /*
563          * tree can be updated through this iterator.
564          */
565         IAM_IT_WRITE = (1 << 1)
566 };
567
568 /*
569  * Iterator.
570  *
571  * Immediately after call to iam_it_init() iterator is in "detached"
572  * (IAM_IT_DETACHED) state: it is associated with given parent container, but
573  * doesn't point to any particular record in this container.
574  *
575  * After successful call to iam_it_get() and until corresponding call to
576  * iam_it_put() iterator is in one of "active" states: IAM_IT_ATTACHED or
577  * IAM_IT_SKEWED.
578  *
579  * Active iterator can move through records in a container (provided
580  * IAM_IT_MOVE permission) in a key order, can get record and key values as it
581  * passes over them, and can modify container (provided IAM_IT_WRITE
582  * permission).
583  *
584  * Iteration may reach the end of container, at which point iterator switches
585  * into IAM_IT_DETACHED state.
586  *
587  * Concurrency: iterators are supposed to be local to thread. Interfaces below
588  * do no internal serialization of access to the iterator fields.
589  *
590  * When in non-detached state, iterator keeps some container nodes pinned in
591  * memory and locked (that locking may be implemented at the container
592  * granularity though). In particular, clients may assume that pointers to
593  * records and keys obtained through iterator interface as valid until
594  * iterator is detached (except that they may be invalidated by sub-sequent
595  * operations done through the same iterator).
596  *
597  */
598 struct iam_iterator {
599         /*
600          * iterator flags, taken from enum iam_it_flags.
601          */
602         __u32                 ii_flags;
603         enum iam_it_state     ii_state;
604         /*
605          * path to the record. Valid in IAM_IT_ATTACHED, and IAM_IT_SKEWED
606          * states.
607          */
608         struct iam_path       ii_path;
609 };
610
611 void iam_path_init(struct iam_path *path, struct iam_container *c,
612                    struct iam_path_descr *pd);
613 void iam_path_fini(struct iam_path *path);
614 void iam_path_release(struct iam_path *path);
615
616 void iam_path_compat_init(struct iam_path_compat *path, struct inode *inode);
617 void iam_path_compat_fini(struct iam_path_compat *path);
618
619 struct iam_path_descr *iam_ipd_alloc(void *area, int keysize);
620 void iam_ipd_free(struct iam_path_descr *ipd);
621
622 int  iam_it_init(struct iam_iterator *it, struct iam_container *c, __u32 flags,
623                  struct iam_path_descr *pd);
624 void iam_it_fini(struct iam_iterator *it);
625 int iam_it_get(struct iam_iterator *it, const struct iam_key *k);
626 int iam_it_get_at(struct iam_iterator *it, const struct iam_key *k);
627 void iam_it_dup(struct iam_iterator *dst, const struct iam_iterator *src);
628 void iam_it_put(struct iam_iterator *it);
629 int iam_it_next(struct iam_iterator *it);
630 struct iam_rec *iam_it_rec_get(const struct iam_iterator *it);
631 int iam_it_rec_set(handle_t *h,
632                    struct iam_iterator *it, const struct iam_rec *r);
633 struct iam_key *iam_it_key_get(const struct iam_iterator *it);
634 int iam_it_key_size(const struct iam_iterator *it);
635 int iam_it_rec_insert(handle_t *h, struct iam_iterator *it,
636                       const struct iam_key *k, const struct iam_rec *r);
637 int iam_it_rec_delete(handle_t *h, struct iam_iterator *it);
638
639 typedef __u64 iam_pos_t;
640
641 iam_pos_t iam_it_store(const struct iam_iterator *it);
642 int iam_it_load(struct iam_iterator *it, iam_pos_t pos);
643
644 int iam_lookup(struct iam_container *c, const struct iam_key *k,
645                struct iam_rec *r, struct iam_path_descr *pd);
646 int iam_delete(handle_t *h, struct iam_container *c, const struct iam_key *k,
647                struct iam_path_descr *pd);
648 int iam_update(handle_t *h, struct iam_container *c, const struct iam_key *k,
649                const struct iam_rec *r, struct iam_path_descr *pd);
650 int iam_insert(handle_t *handle, struct iam_container *c,
651                const struct iam_key *k,
652                const struct iam_rec *r, struct iam_path_descr *pd);
653 /*
654  * Initialize container @c.
655  */
656 int iam_container_init(struct iam_container *c,
657                        struct iam_descr *descr, struct inode *inode);
658 /*
659  * Finalize container @c, release all resources.
660  */
661 void iam_container_fini(struct iam_container *c);
662
663 /*
664  * Determine container format.
665  */
666 int iam_container_setup(struct iam_container *c);
667
668 static inline struct iam_descr *iam_container_descr(struct iam_container *c)
669 {
670         return c->ic_descr;
671 }
672
673 static inline struct iam_descr *iam_path_descr(const struct iam_path *p)
674 {
675         return p->ip_container->ic_descr;
676 }
677
678 static inline struct inode *iam_path_obj(struct iam_path *p)
679 {
680         return p->ip_container->ic_object;
681 }
682
683 static inline void iam_ikeycpy(const struct iam_container *c,
684                                struct iam_ikey *k1, const struct iam_ikey *k2)
685 {
686         memcpy(k1, k2, c->ic_descr->id_ikey_size);
687 }
688
689 static inline size_t iam_entry_size(struct iam_path *p)
690 {
691         return iam_path_descr(p)->id_ikey_size + iam_path_descr(p)->id_ptr_size;
692 }
693
694 static inline struct iam_entry *iam_entry_shift(struct iam_path *p,
695                                                 struct iam_entry *entry,
696                                                 int shift)
697 {
698         void *e = entry;
699         return e + shift * iam_entry_size(p);
700 }
701
702 static inline struct iam_ikey *dx_get_ikey(struct iam_path *p,
703                                             struct iam_entry *entry,
704                                             struct iam_ikey *key)
705 {
706         return memcpy(key, entry, iam_path_descr(p)->id_ikey_size);
707 }
708
709 static inline struct iam_ikey *iam_ikey_at(struct iam_path *p,
710                                            struct iam_entry *entry)
711 {
712         return (struct iam_ikey *)entry;
713 }
714
715 static inline ptrdiff_t iam_entry_diff(struct iam_path *p,
716                                        struct iam_entry *e1,
717                                        struct iam_entry *e2)
718 {
719         ptrdiff_t diff;
720
721         diff = (void *)e1 - (void *)e2;
722         assert_corr(diff / iam_entry_size(p) * iam_entry_size(p) == diff);
723         return diff / iam_entry_size(p);
724 }
725
726 /*
727  * Helper for the frequent case, where key was already placed into @k1 by
728  * callback.
729  */
730 static inline void iam_ikeycpy0(const struct iam_container *c,
731                                 struct iam_ikey *k1, const struct iam_ikey *k2)
732 {
733         if (k1 != k2)
734                 iam_ikeycpy(c, k1, k2);
735 }
736
737 static inline int iam_ikeycmp(const struct iam_container *c,
738                               const struct iam_ikey *k1,
739                               const struct iam_ikey *k2)
740 {
741         return c->ic_descr->id_ops->id_ikeycmp(c, k1, k2);
742 }
743
744 static inline void *iam_entry_off(struct iam_entry *entry, size_t off)
745 {
746         return (void *)((char *)entry + off);
747 }
748
749 /*
750  * Leaf helpers.
751  */
752
753 static inline struct iam_path *iam_leaf_path(const struct iam_leaf *leaf)
754 {
755         return leaf->il_path;
756 }
757
758 static inline struct iam_container *
759 iam_leaf_container(const struct iam_leaf *leaf)
760 {
761         return iam_leaf_path(leaf)->ip_container;
762 }
763
764 static inline struct iam_descr *iam_leaf_descr(const struct iam_leaf *leaf)
765 {
766         return iam_leaf_container(leaf)->ic_descr;
767 }
768
769 static inline struct iam_leaf_operations *
770 iam_leaf_ops(const struct iam_leaf *leaf)
771 {
772         return iam_leaf_descr(leaf)->id_leaf_ops;
773 }
774
775 static inline void iam_reccpy(const struct iam_leaf *leaf,
776                               struct iam_rec *rec_dst)
777 {
778         iam_leaf_ops(leaf)->rec_get(leaf, rec_dst);
779 }
780
781 /*XXX These stuff put here, just because they are used by iam.c */
782 static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry)
783 {
784         u32 *addr;
785
786         addr = iam_entry_off(entry, iam_path_descr(p)->id_ikey_size);
787         return le32_to_cpu(get_unaligned(addr)) & 0x00ffffff;
788 }
789
790 static inline void dx_set_block(struct iam_path *p,
791                                 struct iam_entry *entry, unsigned value)
792 {
793         u32 *addr;
794
795         addr = iam_entry_off(entry, iam_path_descr(p)->id_ikey_size);
796         put_unaligned(cpu_to_le32(value), addr);
797 }
798
799 static inline void dx_set_ikey(struct iam_path *p, struct iam_entry *entry,
800                                const struct iam_ikey *key)
801 {
802         iam_ikeycpy(p->ip_container, iam_entry_off(entry, 0), key);
803 }
804
805 struct dx_map_entry
806 {
807         u32 hash;
808         u32 offs;
809 };
810
811 struct fake_dirent {
812         __le32 inode;
813         __le16 rec_len;
814         u8 name_len;
815         u8 file_type;
816 };
817
818 struct dx_countlimit {
819         __le16 limit;
820         __le16 count;
821 };
822
823 /*
824  * dx_root_info is laid out so that if it should somehow get overlaid by a
825  * dirent the two low bits of the hash version will be zero.  Therefore, the
826  * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
827  */
828
829 struct dx_root {
830         struct fake_dirent dot;
831         char dot_name[4];
832         struct fake_dirent dotdot;
833         char dotdot_name[4];
834         struct dx_root_info
835         {
836                 __le32 reserved_zero;
837                 u8 hash_version;
838                 u8 info_length; /* 8 */
839                 u8 indirect_levels;
840                 u8 unused_flags;
841         }
842         info;
843         struct {} entries[0];
844 };
845
846 struct dx_node
847 {
848         struct fake_dirent fake;
849         struct {} entries[0];
850 };
851
852
853 static inline unsigned dx_get_count(struct iam_entry *entries)
854 {
855         return le16_to_cpu(((struct dx_countlimit *) entries)->count);
856 }
857
858 static inline unsigned dx_get_limit(struct iam_entry *entries)
859 {
860         return le16_to_cpu(((struct dx_countlimit *) entries)->limit);
861 }
862
863 static inline void dx_set_count(struct iam_entry *entries, unsigned value)
864 {
865         ((struct dx_countlimit *) entries)->count = cpu_to_le16(value);
866 }
867
868 static inline unsigned dx_node_limit(struct iam_path *p)
869 {
870         struct iam_descr *param = iam_path_descr(p);
871         unsigned entry_space   = iam_path_obj(p)->i_sb->s_blocksize -
872                 param->id_node_gap;
873         return entry_space / (param->id_ikey_size + param->id_ptr_size);
874 }
875
876 static inline unsigned dx_root_limit(struct iam_path *p)
877 {
878         struct iam_descr *param = iam_path_descr(p);
879         unsigned limit = iam_path_obj(p)->i_sb->s_blocksize -
880                 param->id_root_gap;
881         limit /= (param->id_ikey_size + param->id_ptr_size);
882         if (limit == dx_node_limit(p))
883                 limit--;
884         return limit;
885 }
886
887
888 static inline struct iam_entry *dx_get_entries(struct iam_path *path,
889                                                void *data, int root)
890 {
891         struct iam_descr *param = iam_path_descr(path);
892         return data + (root ? param->id_root_gap : param->id_node_gap);
893 }
894
895
896 static inline struct iam_entry *dx_node_get_entries(struct iam_path *path,
897                                                     struct iam_frame *frame)
898 {
899         return dx_get_entries(path,
900                               frame->bh->b_data, frame == path->ip_frames);
901 }
902
903 static inline struct iam_ikey *iam_path_ikey(const struct iam_path *path,
904                                              int nr)
905 {
906         assert(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch));
907         return path->ip_data->ipd_key_scratch[nr];
908 }
909
910 static inline struct dynlock *path_dynlock(struct iam_path *path)
911 {
912         return &LDISKFS_I(iam_path_obj(path))->i_htree_lock;
913 }
914
915 static inline int iam_leaf_is_locked(const struct iam_leaf *leaf)
916 {
917         int result;
918
919         result = dynlock_is_locked(path_dynlock(leaf->il_path),
920                                    leaf->il_curidx);
921         if (!result)
922                 dump_stack();
923         return result;
924 }
925
926 static inline int iam_frame_is_locked(struct iam_path *path,
927                                       const struct iam_frame *frame)
928 {
929         int result;
930
931         result = dynlock_is_locked(path_dynlock(path), frame->curidx);
932         if (!result)
933                 dump_stack();
934         return result;
935 }
936
937 int dx_lookup_lock(struct iam_path *path,
938                    struct dynlock_handle **dl, enum dynlock_type lt);
939
940 void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
941                      u32 hash, u32 block);
942 int dx_index_is_compat(struct iam_path *path);
943
944 int ldiskfs_htree_next_block(struct inode *dir, __u32 hash,
945                           struct iam_path *path, __u32 *start_hash);
946
947 struct buffer_head *ldiskfs_append(handle_t *handle, struct inode *inode,
948                                 u32 *block, int *err);
949 int split_index_node(handle_t *handle, struct iam_path *path,
950                      struct dynlock_handle **lh);
951 struct ldiskfs_dir_entry_2 *split_entry(struct inode *dir,
952                                      struct ldiskfs_dir_entry_2 *de,
953                                      unsigned long ino, mode_t mode,
954                                      const char *name, int namelen);
955 struct ldiskfs_dir_entry_2 *find_insertion_point(struct inode *dir,
956                                               struct buffer_head *bh,
957                                               const char *name, int namelen);
958 struct ldiskfs_dir_entry_2 *move_entries(struct inode *dir,
959                                       struct ldiskfs_dx_hash_info *hinfo,
960                                       struct buffer_head **bh1,
961                                       struct buffer_head **bh2,
962                                       __u32 *delim_hash);
963
964 extern struct iam_descr iam_htree_compat_param;
965
966 struct dynlock_handle *dx_lock_htree(struct inode *dir, unsigned long value,
967                                      enum dynlock_type lt);
968 void dx_unlock_htree(struct inode *dir, struct dynlock_handle *lh);
969
970 /*
971  * external
972  */
973 void iam_container_write_lock(struct iam_container *c);
974 void iam_container_write_unlock(struct iam_container *c);
975
976 void iam_container_read_lock(struct iam_container *c);
977 void iam_container_read_unlock(struct iam_container *c);
978
979 int iam_index_next(struct iam_container *c, struct iam_path *p);
980 int iam_read_leaf(struct iam_path *p);
981
982 int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
983                   handle_t *handle, struct buffer_head **bh);
984 int iam_lvar_create(struct inode *obj, int keysize, int ptrsize,
985                            int recsize, handle_t *handle);
986 int iam_lfix_create(struct inode *obj, int keysize, int ptrsize,
987                            int recsize, handle_t *handle);
988
989 #ifndef swap
990 #define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
991 #endif
992
993 #ifdef DX_DEBUG
994 #define dxtrace(command) command
995 #else
996 #define dxtrace(command) 
997 #endif
998
999 #define BH_DXLock        25
1000 #define DX_DEBUG (1)
1001 #if DX_DEBUG
1002 static struct iam_lock_stats {
1003         unsigned dls_bh_lock;
1004         unsigned dls_bh_busy;
1005         unsigned dls_bh_again;
1006         unsigned dls_bh_full_again;
1007 } iam_lock_stats = { 0, };
1008 #define DX_DEVAL(x) x
1009 #else
1010 #define DX_DEVAL(x)
1011 #endif
1012
1013 static inline void iam_lock_bh(struct buffer_head volatile *bh)
1014 {
1015         DX_DEVAL(iam_lock_stats.dls_bh_lock++);
1016 #ifdef CONFIG_SMP
1017         while (test_and_set_bit(BH_DXLock, &bh->b_state)) {
1018                 DX_DEVAL(iam_lock_stats.dls_bh_busy++);
1019                 while (test_bit(BH_DXLock, &bh->b_state))
1020                         cpu_relax();
1021         }
1022 #endif
1023 }
1024
1025 static inline void iam_unlock_bh(struct buffer_head *bh)
1026 {
1027 #ifdef CONFIG_SMP
1028         smp_mb__before_clear_bit();
1029         clear_bit(BH_DXLock, &bh->b_state);
1030 #endif
1031 }
1032
1033
1034 void iam_insert_key(struct iam_path *path, struct iam_frame *frame,
1035                     const struct iam_ikey *key, iam_ptr_t ptr);
1036
1037 void iam_insert_key_lock(struct iam_path *path, struct iam_frame *frame,
1038                          const struct iam_ikey *key, iam_ptr_t ptr);
1039
1040
1041 int  iam_leaf_at_end(const struct iam_leaf *l);
1042 void iam_leaf_next(struct iam_leaf *folio);
1043 int iam_leaf_can_add(const struct iam_leaf *l,
1044                      const struct iam_key *k, const struct iam_rec *r);
1045
1046 struct iam_path *iam_leaf_path(const struct iam_leaf *leaf);
1047 struct iam_container *iam_leaf_container(const struct iam_leaf *leaf);
1048 struct iam_descr *iam_leaf_descr(const struct iam_leaf *leaf);
1049 struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf);
1050
1051
1052 int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
1053                   handle_t *h, struct buffer_head **bh);
1054
1055 /*
1056  * Container format.
1057  */
1058 struct iam_format {
1059         /*
1060          * Method called to recognize container format. Should return true iff
1061          * container @c conforms to this format. This method may do IO to read
1062          * container pages.
1063          *
1064          * If container is recognized, this method sets operation vectors
1065          * ->id_ops and ->id_leaf_ops in container description (c->ic_descr),
1066          * and fills other description fields.
1067          */
1068         int (*if_guess)(struct iam_container *c);
1069         /*
1070          * Linkage into global list of container formats.
1071          */
1072         struct list_head if_linkage;
1073 };
1074
1075 void iam_format_register(struct iam_format *fmt);
1076 int iam_root_limit(int rootgap, int blocksize, int size);
1077
1078 void iam_lfix_format_init(void);
1079 void iam_lvar_format_init(void);
1080 void iam_htree_format_init(void);
1081
1082 struct iam_private_info;
1083
1084 void ldiskfs_iam_release(struct file *filp, struct inode *inode);
1085
1086 int iam_uapi_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
1087                    unsigned long arg);
1088
1089 /* dir.c 
1090 #if LDISKFS_INVARIANT_ON
1091 extern int ldiskfs_check_dir_entry(const char *, struct inode *,
1092                                 struct ldiskfs_dir_entry_2 *,
1093                                 struct buffer_head *, unsigned long);
1094 #else
1095 static inline int ldiskfs_check_dir_entry(const char * function,
1096                                        struct inode * dir,
1097                                        struct ldiskfs_dir_entry_2 * de,
1098                                        struct buffer_head * bh,
1099                                        unsigned long offset)
1100 {
1101         return 1;
1102 }
1103 #endif
1104 */
1105
1106 /* __KERNEL__ */
1107 #endif
1108
1109 /*
1110  * User level API. Copy exists in lustre/lustre/tests/iam_ut.c
1111  */
1112
1113 struct iam_uapi_info {
1114         __u16 iui_keysize;
1115         __u16 iui_recsize;
1116         __u16 iui_ptrsize;
1117         __u16 iui_height;
1118         char  iui_fmt_name[DX_FMT_NAME_LEN];
1119 };
1120
1121 struct iam_uapi_op {
1122         void *iul_key;
1123         void *iul_rec;
1124 };
1125
1126 struct iam_uapi_it {
1127         struct iam_uapi_op iui_op;
1128         __u16              iui_state;
1129 };
1130
1131 enum iam_ioctl_cmd {
1132         IAM_IOC_INIT     = _IOW('i', 1, struct iam_uapi_info),
1133         IAM_IOC_GETINFO  = _IOR('i', 2, struct iam_uapi_info),
1134         IAM_IOC_INSERT   = _IOR('i', 3, struct iam_uapi_op),
1135         IAM_IOC_LOOKUP   = _IOWR('i', 4, struct iam_uapi_op),
1136         IAM_IOC_DELETE   = _IOR('i', 5, struct iam_uapi_op),
1137         IAM_IOC_IT_START = _IOR('i', 6, struct iam_uapi_it),
1138         IAM_IOC_IT_NEXT  = _IOW('i', 7, struct iam_uapi_it),
1139         IAM_IOC_IT_STOP  = _IOR('i', 8, struct iam_uapi_it),
1140
1141         IAM_IOC_POLYMORPH = _IOR('i', 9, unsigned long)
1142 };
1143
1144 /* __LINUX_LUSTRE_IAM_H__ */
1145 #endif