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