diff --git a/lustre/tests/it_test.c b/lustre/tests/it_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..a2e983493b1892316256b482ac54d0a7caf0a941
--- /dev/null
+++ b/lustre/tests/it_test.c
@@ -0,0 +1,558 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see [sun.com URL with a
+ * copy of GPLv2].
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ *
+ * lustre/tests/it_test.c
+ *
+ * Unit test tool for interval tree.
+ *
+ * Author: jay <jxiong@clusterfs.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <libcfs/kp30.h>
+#include <../ldlm/interval_tree.c>
+
+#define dprintf(fmt, args...) //printf(fmt, ##args)
+#define error(fmt, args...) do {                        \
+        fflush(stdout), fflush(stderr);                 \
+        fprintf(stderr, "\nError:" fmt, ##args);        \
+        abort();                                        \
+} while(0)
+
+#define __F(ext)         (ext)->start, (ext)->end
+#define __S              "["LPX64":"LPX64"]"
+
+#define ALIGN_SIZE       4096
+#define ALIGN_MASK       (~(ALIGN_SIZE - 1))
+
+static struct it_node {
+        struct interval_node node;
+        struct list_head list;
+        int hit, valid;
+} *it_array;
+static int it_count;
+CFS_LIST_HEAD(header);
+static unsigned long max_count = ULONG_MAX & ALIGN_MASK;
+static int have_wide_lock = 0;
+
+static void it_test_clear(void)
+{
+        int i = 0;
+        for (i = 0; i < it_count; i++)
+                it_array[i].hit = 0;
+}
+
+static enum interval_iter cb(struct interval_node *n, void *args)
+{
+        struct it_node *node = (struct it_node *)n;
+        static int count = 1;
+
+        if (node->hit == 1) {
+                dprintf("NODE "__S" has ever been accessed\n",
+                        __F(&n->in_extent));
+                return INTERVAL_ITER_CONT;
+                error("duplicate node accessing found\n");
+                return INTERVAL_ITER_STOP;
+        }
+        
+        if (node->valid == 0) {
+                error("A deleted node "__S" being accessed\n",
+                       __F(&n->in_extent));
+                return INTERVAL_ITER_STOP;
+        }
+
+        if (count++ == 8) {
+                dprintf("\n");
+                count = 1;
+        }
+        dprintf(""__S" ", __F(&n->in_extent));
+        fflush(stdout);
+
+        node->hit = 1;
+        return INTERVAL_ITER_CONT;
+}
+
+static int it_test_search(struct interval_node *root)
+{
+        struct it_node *n;
+        struct interval_node_extent ext;
+        int times = 10, i, err = 0;
+
+        while (times--) {
+                it_test_clear();
+                ext.start = (random() % max_count) & ALIGN_MASK;
+                ext.end = random() % (max_count - ext.start + 2) + ext.start;
+                ext.end &= ALIGN_MASK;
+                if (ext.end > max_count)
+                        ext.end = max_count;
+
+                dprintf("\n\nSearching the node overlapped "__S" ..\n",
+                        __F(&ext));
+
+                interval_search(root, &ext, cb, NULL);
+
+                dprintf("\nverifing ...");
+        
+                /* verify */
+                for (i = 0; i < it_count; i++) {
+                        n = &it_array[i];
+                        if (n->valid == 0)
+                                continue;
+
+                        if (extent_overlapped(&ext, &n->node.in_extent) && 
+                            n->hit == 0)
+                                error("node "__S" overlaps" __S","
+                                      "but never to be hit.\n", 
+                                      __F(&n->node.in_extent),
+                                      __F(&ext));
+
+                        if (!extent_overlapped(&ext, &n->node.in_extent) && 
+                            n->hit)
+                                error("node "__S" overlaps" __S", but hit.\n", 
+                                      __F(&n->node.in_extent),
+                                      __F(&ext));
+                }
+                if (err) error("search error\n");
+                dprintf("ok.\n");
+        }
+
+        return 0;
+}
+
+static int it_test_iterate(struct interval_node *root)
+{
+        int i;
+
+        dprintf("\n\nIterate testing start..\n");
+
+        it_test_clear();
+        interval_iterate(root, cb, NULL);
+
+        /* verify */
+        for (i = 0; i < it_count; i++) {
+                if (it_array[i].valid == 0)
+                        continue;
+                if (it_array[i].hit == 0)
+                        error("Node "__S" is not accessed\n",
+                              __F(&it_array[i].node.in_extent));
+        }
+
+        return 0;
+}
+
+static int it_test_iterate_reverse(struct interval_node *root)
+{
+        int i;
+
+        dprintf("\n\niterate reverse testing start..\n");
+        it_test_clear();
+        interval_iterate_reverse(root, cb, NULL);
+
+        /* verify */
+        for (i = 0; i < it_count; i++) {
+                if (it_array[i].valid == 0)
+                        continue;
+                if (it_array[i].hit == 0)
+                        error("Not every extent is accessed\n");
+        }
+
+        return 0;
+}
+
+static int it_test_find(struct interval_node *root)
+{
+        int idx;
+        struct interval_node_extent *ext;
+
+        dprintf("\ninterval_find testing start ..\n");
+        for (idx = 0; idx < it_count; idx++) {
+                if (it_array[idx].valid == 0)
+                        continue;
+
+                ext = &it_array[idx].node.in_extent;
+                dprintf("Try to find "__S"\n", __F(ext));
+                if (!interval_find(root, ext))
+                        error("interval_find, try to find "__S"\n", __F(ext));
+        }
+        return 0;
+}
+
+/* sanity test is tightly coupled with implementation, so when you changed
+ * the interval tree implementation, change this code also. */
+static enum interval_iter sanity_cb(struct interval_node *node, void *args)
+{
+        __u64 max_high = node->in_max_high;
+        struct interval_node *tmp, *parent;
+        int left = 1, has = 0, nr = 0;
+
+        parent = node->in_parent;
+        node->in_parent = NULL;
+        interval_for_each(tmp, node) {
+                if ((left && node_compare(tmp, node) > 0) ||
+                    (!left && node_compare(tmp, node) < 0))
+                        error("interval tree sanity test\n");
+
+                if (tmp->in_max_high > max_high) {
+                        dprintf("max high sanity check, max_high is %llu,"
+                                "child max_high: %llu"__S"\n",
+                                max_high, tmp->in_max_high,
+                                __F(&tmp->in_extent));
+                        goto err;
+                } else if (tmp->in_max_high == max_high) {
+                        has = 1;
+                }
+
+                if (tmp == node) {
+                        left = 0;
+                        continue;
+                }
+        }
+
+        if (!has) {
+                int count = 1;
+err:
+                dprintf("node"__S":%llu Child list:\n",
+                        node->in_extent.start,
+                        node->in_extent.end,
+                        node->in_max_high);
+
+                interval_for_each(tmp, node) {
+                        dprintf(""__S":%llu ",
+                                __F(&tmp->in_extent),
+                                tmp->in_max_high);
+                        if (count++ == 8) {
+                                dprintf("\n");
+                                count = 1;
+                        }
+                }
+
+                error("max high sanity check, has == %d\n", has);
+        }
+        node->in_parent = parent;
+
+        tmp = node;
+        while (tmp) {
+                if (node_is_black(tmp))
+                        nr++;
+                else if ((tmp->in_left && node_is_red(tmp->in_left)) ||
+                         (tmp->in_right && node_is_red(tmp->in_right)))
+                        error("wrong tree, a red node has red child\n");
+                tmp = tmp->in_left;
+        }
+
+        tmp = node;
+        while (tmp) {
+                if (node_is_black(tmp))
+                        nr--;
+                tmp = tmp->in_right;
+        }
+        if (nr)
+                error("wrong tree, unbalanced!\n");
+        
+        return 0;
+}
+
+static int it_test_sanity(struct interval_node *root)
+{
+        it_test_clear();
+        interval_iterate(root, sanity_cb, NULL);
+        return 0;
+}
+
+static int it_test_search_hole(struct interval_node *root)
+{
+        int i, count = 10;
+        struct interval_node_extent ext, ext2;
+        struct it_node *n;
+        __u64 low = 0, high = ~0;
+
+        do {
+                if (--count == 0)
+                        return 0;
+
+                ext.start = random() % max_count;
+                ext.end = ext.start;
+        } while (interval_is_overlapped(root, &ext));
+        ext2 = ext;
+
+        interval_expand(root, &ext, NULL);
+        dprintf("Extending "__S" to .."__S"\n", __F(&ext2), __F(&ext));
+        for (i = 0; i < it_count; i++) {
+                n = &it_array[i];
+                if (n->valid == 0)
+                        continue;
+
+                if (extent_overlapped(&ext, &n->node.in_extent)) {
+                        error("Extending "__S" to .."__S" overlaps node"__S"\n",
+                                __F(&ext2), __F(&ext), __F(&n->node.in_extent));
+                }
+
+                if (n->node.in_extent.end < ext2.start)
+                        low = max_u64(n->node.in_extent.end + 1, low);
+
+                if (n->node.in_extent.start > ext2.end)
+                        high = min_u64(n->node.in_extent.start - 1, high);
+        }
+
+        /* only expanding high right now */
+        if (ext2.start != ext.start || high != ext.end) {
+                ext2.start = low, ext2.end = high;
+                error("Real extending result:"__S", expected:"__S"\n",
+                       __F(&ext), __F(&ext2));
+        }
+
+        return 0;
+}
+
+static int contended_count = 0; 
+#define LOOP_COUNT 1000
+static enum interval_iter perf_cb(struct interval_node *n, void *args)
+{
+        unsigned long count = LOOP_COUNT;
+        while (count--);
+        contended_count++;
+        return INTERVAL_ITER_CONT;
+}
+
+static inline long tv_delta(struct timeval *s, struct timeval *e)
+{
+        long c = e->tv_sec - s->tv_sec;
+        c *= 1000;
+        c += (long int)(e->tv_usec - s->tv_usec) / 1000;
+        dprintf("\tStart: %lu:%lu -> End: %lu:%lu\n", 
+                s->tv_sec, s->tv_usec, e->tv_sec, e->tv_usec);
+        return c;
+}
+
+static int it_test_performance(struct interval_node *root, unsigned long len)
+{
+        int i = 0, interval_time, list_time;
+        struct interval_node_extent ext;
+        struct it_node *n;
+        struct timeval start, end;
+        unsigned long count;
+        
+        ext.start = (random() % (max_count - len)) & ALIGN_MASK;
+        ext.end = (ext.start + len) & ALIGN_MASK;
+        if (have_wide_lock) {
+                ext.start = (max_count - len) & ALIGN_MASK;
+                ext.end = max_count;
+        }
+
+        dprintf("Extent search"__S"\n", __F(&ext));
+
+        /* list */
+        contended_count = 0;
+        gettimeofday(&start, NULL);
+        list_for_each_entry(n, &header, list) {
+                if (extent_overlapped(&ext, &n->node.in_extent)) {
+                        count = LOOP_COUNT;
+                        while (count--);
+                        contended_count++;
+                }
+        }
+        gettimeofday(&end, NULL);
+        list_time = tv_delta(&start, &end);
+        i = contended_count;
+
+        /* interval */
+        contended_count = 0;
+        gettimeofday(&start, NULL);
+        interval_search(root, &ext, perf_cb, &contended_count);
+        gettimeofday(&end, NULL);
+        interval_time = tv_delta(&start, &end);
+
+        if (i != contended_count)
+                error("count of contended lock don't match(%d: %d)\n",
+                      i, contended_count);
+
+        printf("\tList vs Int. search: \n\t\t"
+               "(%d vs %d)ms, %d contended lock.\n",
+                list_time, interval_time, contended_count);
+
+        return 0;
+}
+
+static struct interval_node *it_test_helper(struct interval_node *root)
+{
+        int idx, count = 0;
+        struct it_node *n;
+
+        count = random() % it_count;
+        while (count--) {
+                idx = random() % it_count;
+                n = &it_array[idx];
+                if (n->valid) {
+                        if (!interval_find(root, &n->node.in_extent))
+                                error("Cannot find an existent node\n");
+                        dprintf("Erasing a node "__S"\n", 
+                                __F(&n->node.in_extent));
+                        interval_erase(&n->node, &root);
+                        n->valid = 0;
+                        list_del_init(&n->list);
+                } else {
+                        __u64 low, high;
+                        low = (random() % max_count) & ALIGN_MASK;
+                        high = ((random() % max_count + 1) & ALIGN_MASK) + low;
+                        if (high > max_count)
+                                high = max_count;
+                        interval_set(&n->node, low, high);
+                        while (interval_insert(&n->node, &root))
+                                interval_set(&n->node, low, ++high);
+                        dprintf("Adding a node "__S"\n", 
+                                __F(&n->node.in_extent));
+                        n->valid = 1;
+                        list_add(&n->list, &header);
+                }
+        }
+
+        return root;
+}
+
+static struct interval_node *it_test_init(int count)
+{
+        int i;
+        uint64_t high, low, len;
+        struct it_node *n;
+        struct interval_node *root = NULL;
+
+        it_count = count;
+        it_array = (struct it_node *)malloc(sizeof(struct it_node) * count);
+        if (it_array == NULL)
+                error("it_array == NULL, no memory\n");
+
+        have_wide_lock = 0;
+        for (i = 0; i < count; i++) {
+                n = &it_array[i];
+                do {
+                        low = (random() % max_count + 1) & ALIGN_MASK;
+                        len = (random() % 256 + 1) * ALIGN_SIZE;
+                        if (!have_wide_lock && !(random() % count)) {
+                                low = 0;
+                                len = max_count;
+                                have_wide_lock = 1;
+                        }
+                        high = low + (len & ALIGN_MASK);
+
+                        interval_set(&n->node, low, high);
+                } while (interval_insert(&n->node, &root));
+                n->hit = 0;
+                n->valid = 1;
+                if (i == 0)
+                        list_add_tail(&n->list, &header);
+                else
+                        list_add_tail(&n->list, &it_array[rand()%i].list);
+        }
+
+        return root;
+}
+
+static void it_test_fini(void)
+{
+        free(it_array);
+        it_array = NULL;
+        it_count = 0;
+        max_count = 0;
+}
+
+int main(int argc, char *argv[])
+{
+        int count = 5, perf = 0;
+        struct interval_node *root;
+        struct timeval tv;
+
+        gettimeofday(&tv, NULL);
+        srandom(tv.tv_usec);
+
+        if (argc == 2) {
+                if (strcmp(argv[1], "-p"))
+                        error("Unknow options, usage: %s [-p]\n", argv[0]);
+                perf = 1;
+                count = 1;
+        }
+
+        if (perf) {
+                int M = 1024 * 1024;
+                root = it_test_init(1000000);
+                printf("1M locks with 4K request size\n");
+                it_test_performance(root, 4096);
+                printf("1M locks with 128K request size\n");
+                it_test_performance(root, 128 * 1024);
+                printf("1M locks with 256K request size\n");
+                it_test_performance(root, 256 * 1024);
+                printf("1M locks with 1M request size\n");
+                it_test_performance(root, 1 * M);
+                printf("1M locks with 16M request size\n");
+                it_test_performance(root, 16 * M);
+                printf("1M locks with 32M request size\n");
+                it_test_performance(root, 32 * M);
+                printf("1M locks with 64M request size\n");
+                it_test_performance(root, 64 * M);
+                printf("1M locks with 128M request size\n");
+                it_test_performance(root, 128 * M);
+                printf("1M locks with 256M request size\n");
+                it_test_performance(root, 256 * M);
+                printf("1M locks with 512M request size\n");
+                it_test_performance(root, 512 * M);
+                printf("1M locks with 1G request size\n");
+                it_test_performance(root, 1024 * M);
+                printf("1M locks with 2G request size\n");
+                it_test_performance(root, 2048 * M);
+                printf("1M locks with 3G request size\n");
+                it_test_performance(root, 3072 * M);
+                printf("1M locks with 4G request size\n");
+                it_test_performance(root, max_count - 1);
+                it_test_fini();
+                return 0;
+        }
+
+        root = it_test_init(random() % 100000 + 1000);
+        while (count--) {
+                it_test_sanity(root);
+                it_test_iterate(root);
+                it_test_iterate_reverse(root);
+                it_test_find(root);
+                it_test_search_hole(root);
+                it_test_search(root);
+                root = it_test_helper(root);
+        }
+        it_test_fini();
+
+        return 0;
+}