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