Index: iam/fs/ext3/Makefile
===================================================================
--- iam.orig/fs/ext3/Makefile 2006-05-31 20:24:32.000000000 +0400
-+++ iam/fs/ext3/Makefile 2006-05-31 20:28:15.000000000 +0400
++++ iam/fs/ext3/Makefile 2006-05-31 23:32:29.000000000 +0400
@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
Index: iam/fs/ext3/iam.c
===================================================================
--- iam.orig/fs/ext3/iam.c 2004-04-06 17:27:52.000000000 +0400
-+++ iam/fs/ext3/iam.c 2006-05-31 20:28:37.000000000 +0400
-@@ -0,0 +1,1023 @@
++++ iam/fs/ext3/iam.c 2006-05-31 22:34:57.000000000 +0400
+@@ -0,0 +1,1016 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+}
+
+/*
-+ * Initialize container @c, acquires additional reference on @inode.
++ * Initialize container @c.
+ */
+int iam_container_init(struct iam_container *c,
+ struct iam_descr *descr, struct inode *inode)
+{
+ memset(c, 0, sizeof *c);
+ c->ic_descr = descr;
-+ c->ic_object = igrab(inode);
-+ if (c->ic_object != NULL)
-+ return 0;
-+ else
-+ return -ENOENT;
++ c->ic_object = inode;
++ return 0;
+}
+EXPORT_SYMBOL(iam_container_init);
+
+ */
+void iam_container_fini(struct iam_container *c)
+{
-+ if (c->ic_object != NULL) {
-+ iput(c->ic_object);
-+ c->ic_object = NULL;
-+ }
+}
+EXPORT_SYMBOL(iam_container_fini);
+
Index: iam/fs/ext3/iam_lfix.c
===================================================================
--- iam.orig/fs/ext3/iam_lfix.c 2004-04-06 17:27:52.000000000 +0400
-+++ iam/fs/ext3/iam_lfix.c 2006-05-31 20:26:49.000000000 +0400
-@@ -0,0 +1,448 @@
++++ iam/fs/ext3/iam_lfix.c 2006-05-31 23:32:16.000000000 +0400
+@@ -0,0 +1,451 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ return (struct iam_key *)entry;
+}
+
++static struct iam_leaf_head *iam_get_head(const struct iam_leaf *l)
++{
++ return (struct iam_leaf_head *)l->il_bh->b_data;
++}
++
+static struct iam_lentry *iam_entries(const struct buffer_head *bh)
+{
+ return (void *)bh->b_data + sizeof(struct iam_leaf_head);
+
+static int lentry_count_get(const struct iam_leaf *leaf)
+{
-+ struct iam_lentry *lentry = leaf->il_entries;
-+ return le16_to_cpu(((struct iam_leaf_head *)lentry)->ill_count);
++ return le16_to_cpu(iam_get_head(leaf)->ill_count);
+}
+
+static void lentry_count_set(struct iam_leaf *leaf, unsigned count)
+{
-+ struct iam_lentry *lentry = leaf->il_entries;
-+ ((struct iam_leaf_head *)lentry)->ill_count = cpu_to_le16(count);
++ iam_get_head(leaf)->ill_count = cpu_to_le16(count);
+}
+
+/*This func is for flat key, for those keys,
+ count = lentry_count_get(l);
+ c = iam_leaf_container(l);
+
-+ p = iam_lfix_shift(l, l->il_entries, 1);
-+ q = iam_lfix_shift(l, l->il_entries, count - 1);
++ p = l->il_entries;
++ q = iam_lfix_shift(l, p, count - 1);
+
+ while (p <= q) {
+ m = iam_lfix_shift(l, p, iam_lfix_diff(l, q, p) / 2);
Index: iam/include/linux/lustre_iam.h
===================================================================
--- iam.orig/include/linux/lustre_iam.h 2006-05-31 20:24:32.000000000 +0400
-+++ iam/include/linux/lustre_iam.h 2006-05-31 20:28:15.000000000 +0400
++++ iam/include/linux/lustre_iam.h 2006-05-31 23:32:29.000000000 +0400
@@ -1,9 +1,68 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
};
/*
-@@ -172,34 +311,238 @@ struct iam_path {
+@@ -172,36 +311,240 @@ struct iam_path {
/*
* Leaf node: a child of ->ip_frame.
*/
-int iam_delete(handle_t *h, struct iam_container *c, struct iam_key *k);
-int iam_update(handle_t *h, struct iam_container *c, struct iam_key *k, struct iam_rec *r);
-int iam_insert(handle_t *handle, struct iam_container *c, struct iam_key *k, struct iam_rec *r);
-+/*
+ /*
+- * Initialize container @c, acquires additional reference on @inode.
+ * Flags controlling iterator functionality.
+ */
+enum iam_it_flags {
+int iam_insert(handle_t *handle, struct iam_container *c,
+ const struct iam_key *k,
+ struct iam_rec *r, struct iam_path_descr *pd);
- /*
- * Initialize container @c, acquires additional reference on @inode.
++/*
++ * Initialize container @c.
*/
+ int iam_container_init(struct iam_container *c,
+ struct iam_descr *descr, struct inode *inode);
@@ -210,3 +553,170 @@ int iam_container_init(struct iam_contai
*/
void iam_container_fini(struct iam_container *c);
Index: iam/fs/ext3/Makefile
===================================================================
---- iam.orig/fs/ext3/Makefile 2006-05-30 23:07:25.000000000 +0400
-+++ iam/fs/ext3/Makefile 2006-05-30 23:08:12.000000000 +0400
+--- iam.orig/fs/ext3/Makefile 2006-05-31 23:32:29.000000000 +0400
++++ iam/fs/ext3/Makefile 2006-05-31 23:32:36.000000000 +0400
@@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o
ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o
Index: iam/fs/ext3/file.c
===================================================================
---- iam.orig/fs/ext3/file.c 2006-05-30 23:07:25.000000000 +0400
-+++ iam/fs/ext3/file.c 2006-05-30 23:11:11.000000000 +0400
+--- iam.orig/fs/ext3/file.c 2006-05-31 23:32:29.000000000 +0400
++++ iam/fs/ext3/file.c 2006-05-31 23:32:36.000000000 +0400
@@ -23,6 +23,7 @@
#include <linux/jbd.h>
#include <linux/ext3_fs.h>
Index: iam/fs/ext3/iam-uapi.c
===================================================================
--- iam.orig/fs/ext3/iam-uapi.c 2004-04-06 17:27:52.000000000 +0400
-+++ iam/fs/ext3/iam-uapi.c 2006-05-31 19:02:37.000000000 +0400
-@@ -0,0 +1,233 @@
++++ iam/fs/ext3/iam-uapi.c 2006-05-31 23:32:36.000000000 +0400
+@@ -0,0 +1,246 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ return 0;
+}
+
-+static int putop(struct iam_uapi_op *op, struct iam_uapi_op *uop,
-+ struct iam_descr *des)
++enum outop_t {
++ KEY = 1 << 0,
++ REC = 1 << 1
++};
++
++static int outop(struct iam_uapi_op *op, struct iam_uapi_op *uop,
++ struct iam_descr *des, enum outop_t opt)
+{
+ int result;
+
-+ if (uop != NULL && copy_to_user((void __user *)uop->iul_rec,
-+ op->iul_rec, des->id_rec_size))
++ if (((opt & REC) && copy_to_user((void __user *)uop->iul_rec,
++ op->iul_rec, des->id_rec_size)) ||
++ ((opt & KEY) && copy_to_user((void __user *)uop->iul_key,
++ op->iul_key, des->id_key_size)))
+ result = -EFAULT;
+ else
+ result = 0;
++ return result;
++}
+
++static void putop(struct iam_uapi_op *op)
++{
+ kfree(op->iul_key);
+ kfree(op->iul_rec);
-+ return result;
+}
+
+static int getop(struct iam_uapi_op *op, struct iam_uapi_op *uop,
+ result = 0;
+ else {
+ result = -EFAULT;
-+ putop(op, NULL, NULL);
++ putop(op);
+ }
+ return result;
+}
+ } else if (cmd == IAM_IOC_INSERT || cmd == IAM_IOC_LOOKUP) {
+ result = getop(&u.op, &uop, des, arg);
+ if (result == 0) {
-+ int res2;
-+
+ result = iam_uapi_op(cmd, inode, filp, &u.op);
-+ res2 = putop(&u.op, &uop, des);
-+ result = result ? : res2;
++ if (cmd == IAM_IOC_LOOKUP) {
++ int res2;
++
++ res2 = outop(&u.op, &uop, des, KEY);
++ result = result ? : res2;
++ }
++ putop(&u.op);
+ }
+ } else
+ result = -EINVAL;
+}
Index: iam/include/linux/lustre_iam.h
===================================================================
---- iam.orig/include/linux/lustre_iam.h 2006-05-30 23:07:25.000000000 +0400
-+++ iam/include/linux/lustre_iam.h 2006-05-31 18:26:14.000000000 +0400
+--- iam.orig/include/linux/lustre_iam.h 2006-05-31 23:32:29.000000000 +0400
++++ iam/include/linux/lustre_iam.h 2006-05-31 23:32:36.000000000 +0400
@@ -30,9 +30,6 @@
#ifndef __LINUX_LUSTRE_IAM_H__
#define __LINUX_LUSTRE_IAM_H__
--- /dev/null
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * iam_ut.c
+ * iam unit-tests
+ *
+ * Copyright (c) 2006 Cluster File Systems, Inc.
+ * Author: Nikita Danilov <nikita@clusterfs.com>
+ *
+ * This file is part of the Lustre file system, http://www.lustre.org
+ * Lustre is a trademark of Cluster File Systems, Inc.
+ *
+ * You may have signed or agreed to another license before downloading
+ * this software. If so, you are bound by the terms and conditions
+ * of that agreement, and the following does not apply to you. See the
+ * LICENSE file included with this distribution for more information.
+ *
+ * If you did not agree to a different license, then this copy of Lustre
+ * is open source software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In either case, Lustre 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
+ * license text for more details.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+
+#include <libcfs/libcfs.h>
+
+enum {
+ /*
+ * Maximal format name length.
+ */
+ DX_FMT_NAME_LEN = 16
+};
+
+struct iam_uapi_info {
+ __u16 iui_keysize;
+ __u16 iui_recsize;
+ __u16 iui_ptrsize;
+ __u16 iui_height;
+ char iui_fmt_name[DX_FMT_NAME_LEN];
+};
+
+struct iam_uapi_op {
+ void *iul_key;
+ void *iul_rec;
+};
+
+enum iam_ioctl_cmd {
+ IAM_IOC_INIT = _IOW('i', 1, struct iam_uapi_info),
+ IAM_IOC_GETINFO = _IOR('i', 2, struct iam_uapi_info),
+ IAM_IOC_INSERT = _IOWR('i', 3, struct iam_uapi_op),
+ IAM_IOC_LOOKUP = _IOWR('i', 4, struct iam_uapi_op)
+};
+
+static void usage(void)
+{
+ printf("usage: iam_ut [-v] [-h] file\n");
+}
+
+static int insert(int fd, const void *key, const void *rec)
+{
+ int result;
+
+ struct iam_uapi_op op = {
+ .iul_key = key,
+ .iul_rec = rec
+ };
+ result = ioctl(fd, IAM_IOC_INSERT, &op);
+ if (result != 0)
+ fprintf(stderr, "ioctl(IAM_IOC_INSERT): %i (%m)\n", result);
+ return result;
+}
+
+static int lookup(int fd, const void *key, void *rec)
+{
+ int result;
+
+ struct iam_uapi_op op = {
+ .iul_key = key,
+ .iul_rec = rec
+ };
+ result = ioctl(fd, IAM_IOC_LOOKUP, &op);
+ if (result != 0)
+ fprintf(stderr, "ioctl(IAM_IOC_LOOKUP): %i (%m)\n", result);
+ return result;
+}
+
+static void print_rec(const unsigned char *rec, int nr)
+{
+ int i;
+
+ for (i = 0; i < nr; ++i)
+ printf("%c", rec[i]);
+ printf("| |");
+ for (i = 0; i < nr; ++i)
+ printf("%x", rec[i]);
+ printf("\n");
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ int fd;
+ int opt;
+ int blocksize = 4096;
+ int keysize = 8;
+ int recsize = 8;
+ int ptrsize = 4;
+ int verbose = 0;
+
+ char *name;
+ char rec[8];
+
+ struct iam_uapi_info ua;
+
+ do {
+ opt = getopt(argc, argv, "v");
+ switch (opt) {
+ case 'v':
+ verbose++;
+ case -1:
+ break;
+ case 'b':
+ /* blocksize = atoi(optarg); */
+ break;
+ case '?':
+ default:
+ fprintf(stderr, "Unable to parse options.");
+ case 'h':
+ usage();
+ return 0;
+ }
+ } while (opt != -1);
+
+ if (optind >= argc) {
+ fprintf(stderr, "filename missed\n");
+ usage();
+ return 1;
+ }
+ name = argv[optind];
+ fd = open(name, O_RDWR);
+ if (fd == -1) {
+ fprintf(stderr, "open(%s): (%m)", name);
+ return 1;
+ }
+ rc = ioctl(fd, IAM_IOC_INIT, &ua);
+ if (rc != 0) {
+ fprintf(stderr, "ioctl(IAM_IOC_INIT): %i (%m)", rc);
+ return 1;
+ }
+ rc = ioctl(fd, IAM_IOC_GETINFO, &ua);
+ if (rc != 0) {
+ fprintf(stderr, "ioctl(IAM_IOC_GETATTR): %i (%m)", rc);
+ return 1;
+ }
+
+ printf("keysize: %i, recsize: %i, ptrsize: %i, height: %i, name: %s\n",
+ ua.iui_keysize, ua.iui_recsize, ua.iui_ptrsize,
+ ua.iui_height, ua.iui_fmt_name);
+
+ rc = insert(fd, "RIVERRUN", "PALEFIRE");
+ if (rc != 0)
+ return 1;
+
+ rc = insert(fd, "DAEDALUS", "FINNEGAN");
+ if (rc != 0)
+ return 1;
+
+ rc = insert(fd, "DAEDALUS", "FINNEGAN");
+ if (errno != EEXIST) {
+ if (rc == 0)
+ fprintf(stderr, "Duplicate key not detected!\n");
+ return 1;
+ }
+
+ rc = lookup(fd, "RIVERRUN", rec);
+ if (rc != 0)
+ return 1;
+
+ print_rec(rec, 8);
+
+ return 0;
+}