Index: iam/fs/ext3/Makefile
===================================================================
--- iam.orig/fs/ext3/Makefile 2006-05-31 20:24:32.000000000 +0400
-+++ iam/fs/ext3/Makefile 2006-06-28 01:37:26.000000000 +0400
++++ iam/fs/ext3/Makefile 2006-06-29 18:50:12.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-06-28 00:25:38.000000000 +0400
-@@ -0,0 +1,1229 @@
++++ iam/fs/ext3/iam.c 2006-06-28 22:46:13.000000000 +0400
+@@ -0,0 +1,1233 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ iam_leaf_ops(leaf)->rec_add(leaf, key, rec);
+}
+
-+static void iam_rec_del(struct iam_leaf *leaf)
++static void iam_rec_del(struct iam_leaf *leaf, int shift)
+{
-+ iam_leaf_ops(leaf)->rec_del(leaf);
++ iam_leaf_ops(leaf)->rec_del(leaf, shift);
+}
+
+int iam_leaf_at_end(const struct iam_leaf *leaf)
+
+static int iam_leaf_check(struct iam_leaf *leaf)
+{
++ return 1;
+ struct iam_lentry *orig;
+ struct iam_path *path;
+ struct iam_container *bag;
+ return result;
+
+ first = 1;
++ iam_leaf_start(leaf);
+ k0 = iam_path_ikey(path, 0);
+ k1 = iam_path_ikey(path, 1);
+ while (!iam_leaf_at_end(leaf)) {
+ iam_ikeycpy(bag, k0, k1);
+ iam_ikeycpy(bag, k1, iam_leaf_ikey(leaf, k1));
-+ if (!first && iam_ikeycmp(bag, k0, k1) > 0)
++ if (!first && iam_ikeycmp(bag, k0, k1) > 0) {
++ BREAKPOINT;
+ return 0;
++ }
+ first = 0;
+ iam_leaf_next(leaf);
+ }
+ * no compaction for now.
+ */
+ if (result == 0) {
-+ iam_rec_del(leaf);
++ iam_rec_del(leaf, it->ii_flags&IAM_IT_MOVE);
+ result = iam_txn_dirty(h, path, leaf->il_bh);
+ if (result == 0 && iam_leaf_at_end(leaf) &&
+ it->ii_flags&IAM_IT_MOVE) {
Index: iam/fs/ext3/iam_htree.c
===================================================================
--- iam.orig/fs/ext3/iam_htree.c 2004-04-06 17:27:52.000000000 +0400
-+++ iam/fs/ext3/iam_htree.c 2006-06-28 01:17:33.000000000 +0400
-@@ -0,0 +1,636 @@
++++ iam/fs/ext3/iam_htree.c 2006-06-28 22:18:53.000000000 +0400
+@@ -0,0 +1,645 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ found = NULL;
+ for (scan = getstart(l); scan < gettop(l); scan = entnext(scan)) {
+ if (scan != getent(l) && ent_is_live(scan) &&
-+ entcmp(l, getent(l), scan) > 0 &&
++ entcmp(l, getent(l), scan) < 0 &&
+ (found == NULL || entcmp(l, scan, found) < 0))
+ found = scan;
+ }
++ assert(ergo(found != NULL,
++ gethash(l, getent(l)) <= gethash(l, found)));
+ l->il_at = (void *)(found ? : gettop(l));
+}
+
+ assert(0);
+}
+
-+static int iam_htree_key_cmp(const struct iam_leaf *l, const struct iam_key *k)
++static int iam_htree_key_cmp(const struct iam_leaf *l,
++ const struct iam_key *k)
+{
-+ struct ext3_dir_entry_2 *hd;
+ const char *name;
-+ int result;
++ __u32 h0;
++ __u32 h1;
+
+ name = (const char *)k;
-+ hd = getent(l);
-+ assert(ent_is_live(hd));
+
-+ result = strncmp(hd->name, name, hd->name_len);
-+ if (result == 0 && strlen(name) < hd->name_len)
-+ result = -1;
-+ return result;
++ assert(ent_is_live(getent(l)));
++
++ h0 = gethash(l, getent(l));
++ h1 = hashname(l, name, strlen(name));
++
++ return h0 < h1 ? -1 : (h0 == h1 ? 0 : +1);
+}
+
+static void iam_htree_rec_set(struct iam_leaf *l, const struct iam_rec *r)
+ getent(l)->inode = cpu_to_le32(*ino);
+}
+
-+static void iam_htree_rec_add(struct iam_leaf *leaf,
-+ const struct iam_key *k, const struct iam_rec *r)
++static void iam_htree_rec_add(struct iam_leaf *leaf, const struct iam_key *k,
++ const struct iam_rec *r)
+{
+ struct ext3_dir_entry_2 *scan;
+ struct inode *dir;
+ leaf->il_at = (void *)scan;
+}
+
-+static void iam_htree_rec_del(struct iam_leaf *leaf)
++static void iam_htree_rec_del(struct iam_leaf *leaf, int shift)
+{
++ struct ext3_dir_entry_2 *orig;
+ struct ext3_dir_entry_2 *scan;
+ struct ext3_dir_entry_2 *prev;
+
+ assert(iam_leaf_at_rec(leaf));
+
-+ for (prev = NULL, scan = getstart(leaf); scan < getent(leaf);
++ orig = getent(leaf);
++
++ if (shift)
++ iam_htree_next(leaf);
++
++ for (prev = NULL, scan = getstart(leaf); scan < orig;
+ prev = scan, scan = entnext(scan))
+ ;
+
-+ assert(scan == getent(leaf));
++ assert(scan == orig);
+ if (prev != NULL) {
+ prev->rec_len = cpu_to_le16(le16_to_cpu(prev->rec_len) +
+ le16_to_cpu(scan->rec_len));
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-06-28 00:09:00.000000000 +0400
++++ iam/fs/ext3/iam_lfix.c 2006-06-28 21:18:56.000000000 +0400
@@ -0,0 +1,649 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ assert(iam_leaf_at_rec(leaf));
+}
+
-+static void iam_lfix_rec_del(struct iam_leaf *leaf)
++static void iam_lfix_rec_del(struct iam_leaf *leaf, int shift)
+{
+ struct iam_lentry *next, *end;
+ int count;
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-06-28 01:37:26.000000000 +0400
++++ iam/include/linux/lustre_iam.h 2006-06-29 18:50:12.000000000 +0400
@@ -1,9 +1,68 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
Index: iam/fs/ext3/Makefile
===================================================================
---- iam.orig/fs/ext3/Makefile 2006-06-28 01:37:26.000000000 +0400
-+++ iam/fs/ext3/Makefile 2006-06-28 01:37:26.000000000 +0400
+--- iam.orig/fs/ext3/Makefile 2006-06-29 18:50:12.000000000 +0400
++++ iam/fs/ext3/Makefile 2006-06-29 18:50:13.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/dir.c
===================================================================
---- iam.orig/fs/ext3/dir.c 2006-06-28 01:37:26.000000000 +0400
-+++ iam/fs/ext3/dir.c 2006-06-28 01:37:26.000000000 +0400
+--- iam.orig/fs/ext3/dir.c 2006-06-29 18:50:12.000000000 +0400
++++ iam/fs/ext3/dir.c 2006-06-29 18:50:13.000000000 +0400
@@ -28,6 +28,7 @@
#include <linux/smp_lock.h>
#include <linux/slab.h>
struct dir_private_info *p;
- p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL);
-+ p = ext3_iam_alloc_info(GFP_KERNEL);
++ p = (void *)ext3_iam_alloc_info(GFP_KERNEL);
if (!p)
return NULL;
p->root.rb_node = NULL;
(filp->f_version != inode->i_version)) {
Index: iam/fs/ext3/file.c
===================================================================
---- iam.orig/fs/ext3/file.c 2006-06-28 01:37:26.000000000 +0400
-+++ iam/fs/ext3/file.c 2006-06-28 01:37:26.000000000 +0400
+--- iam.orig/fs/ext3/file.c 2006-06-29 18:50:12.000000000 +0400
++++ iam/fs/ext3/file.c 2006-06-29 18:50:13.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-06-28 01:37:26.000000000 +0400
++++ iam/fs/ext3/iam-uapi.c 2006-06-29 18:50:13.000000000 +0400
@@ -0,0 +1,357 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+}
Index: iam/fs/ext3/ioctl.c
===================================================================
---- iam.orig/fs/ext3/ioctl.c 2006-06-28 01:37:26.000000000 +0400
-+++ iam/fs/ext3/ioctl.c 2006-06-28 01:37:26.000000000 +0400
+--- iam.orig/fs/ext3/ioctl.c 2006-06-29 18:50:12.000000000 +0400
++++ iam/fs/ext3/ioctl.c 2006-06-29 18:50:13.000000000 +0400
@@ -250,6 +250,6 @@ flags_err:
}
Index: iam/include/linux/lustre_iam.h
===================================================================
---- iam.orig/include/linux/lustre_iam.h 2006-06-28 01:37:26.000000000 +0400
-+++ iam/include/linux/lustre_iam.h 2006-06-28 01:37:26.000000000 +0400
+--- iam.orig/include/linux/lustre_iam.h 2006-06-29 18:50:12.000000000 +0400
++++ iam/include/linux/lustre_iam.h 2006-06-29 18:50:13.000000000 +0400
@@ -30,9 +30,6 @@
#ifndef __LINUX_LUSTRE_IAM_H__
#define __LINUX_LUSTRE_IAM_H__
/*
* linux/include/linux/lustre_iam.h
*/
-@@ -57,14 +54,20 @@ enum {
+@@ -57,14 +54,21 @@ enum {
* [2] reserved for leaf node operations.
*
* [3] reserved for index operations.
+ *
+ * [4] reserved for path->ip_ikey_target
++ *
*/
- DX_SCRATCH_KEYS = 4,
+ DX_SCRATCH_KEYS = 5,
/*
* Entry within index tree node. Consists of a key immediately followed
* (without padding) by a pointer to the child node.
-@@ -86,14 +89,21 @@ struct iam_entry_compat {
+@@ -86,14 +90,21 @@ struct iam_entry_compat {
*/
struct iam_key;
typedef __u64 iam_ptr_t;
/*
-@@ -123,6 +133,27 @@ struct iam_leaf {
+@@ -123,6 +134,27 @@ struct iam_leaf {
void *il_descr_data;
};
struct iam_operations {
/*
* Returns pointer (in the same sense as pointer in index entry) to
-@@ -131,11 +162,15 @@ struct iam_operations {
+@@ -131,11 +163,15 @@ struct iam_operations {
__u32 (*id_root_ptr)(struct iam_container *c);
/*
* Initialize new node (stored in @bh) that is going to be added into
* tree.
*/
-@@ -144,23 +179,33 @@ struct iam_operations {
+@@ -144,23 +180,33 @@ struct iam_operations {
int (*id_node_read)(struct iam_container *c, iam_ptr_t ptr,
handle_t *h, struct buffer_head **bh);
/*
struct iam_leaf_operations {
/*
* leaf operations.
-@@ -186,7 +231,8 @@ struct iam_leaf_operations {
+@@ -186,7 +232,8 @@ struct iam_leaf_operations {
void (*start)(struct iam_leaf *l);
/* more leaf to the next entry. */
void (*next)(struct iam_leaf *l);
* either pointer to the key stored in node, or copy key into
* @k buffer supplied by caller and return pointer to this
* buffer. The latter approach is used when keys in nodes are
-@@ -194,8 +240,10 @@ struct iam_leaf_operations {
+@@ -194,8 +241,10 @@ struct iam_leaf_operations {
* all).
*
* Caller should assume that returned pointer is only valid
/* return pointer to entry body. Pointer is valid while
corresponding leaf node is locked and pinned. */
struct iam_rec *(*rec)(const struct iam_leaf *l);
-@@ -203,6 +251,8 @@ struct iam_leaf_operations {
+@@ -203,6 +252,8 @@ struct iam_leaf_operations {
void (*key_set)(struct iam_leaf *l, const struct iam_key *k);
void (*rec_set)(struct iam_leaf *l, const struct iam_rec *r);
/*
* Search leaf @l for a record with key @k or for a place
* where such record is to be inserted.
-@@ -226,7 +276,8 @@ struct iam_leaf_operations {
+@@ -221,12 +272,13 @@ struct iam_leaf_operations {
+ /*
+ * remove rec for a leaf
+ */
+- void (*rec_del)(struct iam_leaf *l);
++ void (*rec_del)(struct iam_leaf *l, int shift);
+ /*
* split leaf node, moving some entries into @bh (the latter currently
* is assumed to be empty).
*/
};
struct iam_path *iam_leaf_path(const struct iam_leaf *leaf);
-@@ -241,6 +292,10 @@ struct iam_descr {
+@@ -241,6 +293,10 @@ struct iam_descr {
*/
size_t id_key_size;
/*
* Size of a pointer to the next level (stored in index nodes), in
* bytes.
*/
-@@ -264,6 +319,9 @@ struct iam_descr {
+@@ -264,6 +320,9 @@ struct iam_descr {
struct iam_leaf_operations *id_leaf_ops;
};
struct iam_container {
/*
* Underlying flat file. IO against this object is issued to
-@@ -284,7 +342,7 @@ struct iam_path_descr {
+@@ -284,7 +343,7 @@ struct iam_path_descr {
/*
* Scratch-pad area for temporary keys.
*/
};
/*
-@@ -316,6 +374,7 @@ struct iam_path {
+@@ -316,6 +375,7 @@ struct iam_path {
* Key searched for.
*/
const struct iam_key *ip_key_target;
/*
* Description-specific data.
*/
-@@ -334,6 +393,7 @@ struct iam_path_compat {
+@@ -334,6 +394,7 @@ struct iam_path_compat {
struct dx_hash_info *ipc_hinfo;
struct dentry *ipc_dentry;
struct iam_path_descr ipc_descr;
};
/*
-@@ -347,7 +407,9 @@ enum iam_it_state {
+@@ -347,7 +408,9 @@ enum iam_it_state {
/* initial state */
IAM_IT_DETACHED,
/* iterator is above particular record in the container */
};
/*
-@@ -355,7 +417,7 @@ enum iam_it_state {
+@@ -355,7 +418,7 @@ enum iam_it_state {
*/
enum iam_it_flags {
/*
*/
IAM_IT_MOVE = (1 << 0),
/*
-@@ -372,15 +434,26 @@ enum iam_it_flags {
+@@ -372,15 +435,26 @@ enum iam_it_flags {
* doesn't point to any particular record in this container.
*
* After successful call to iam_it_get() and until corresponding call to
*
*/
struct iam_iterator {
-@@ -390,7 +463,8 @@ struct iam_iterator {
+@@ -390,7 +464,8 @@ struct iam_iterator {
__u32 ii_flags;
enum iam_it_state ii_state;
/*
*/
struct iam_path ii_path;
};
-@@ -405,133 +479,24 @@ void iam_path_compat_fini(struct iam_pat
+@@ -405,133 +480,24 @@ void iam_path_compat_fini(struct iam_pat
struct iam_path_descr *iam_ipd_alloc(int keysize);
void iam_ipd_free(struct iam_path_descr *ipd);
int iam_it_load(struct iam_iterator *it, iam_pos_t pos);
int iam_lookup(struct iam_container *c, const struct iam_key *k,
-@@ -577,16 +542,65 @@ static inline struct inode *iam_path_obj
+@@ -577,16 +543,65 @@ static inline struct inode *iam_path_obj
return p->ip_container->ic_object;
}
}
static inline void iam_reccpy(const struct iam_path *p, struct iam_rec *rec_dst,
-@@ -604,7 +618,7 @@ static inline void *iam_entry_off(struct
+@@ -604,7 +619,7 @@ static inline void *iam_entry_off(struct
static inline unsigned dx_get_block(struct iam_path *p, struct iam_entry *entry)
{
return le32_to_cpu(*(u32*)iam_entry_off(entry,
& 0x00ffffff;
}
-@@ -612,21 +626,64 @@ static inline void dx_set_block(struct i
+@@ -612,21 +627,64 @@ static inline void dx_set_block(struct i
struct iam_entry *entry, unsigned value)
{
*(u32*)iam_entry_off(entry,
static inline unsigned dx_get_count(struct iam_entry *entries)
{
return le16_to_cpu(((struct dx_countlimit *) entries)->count);
-@@ -647,9 +704,18 @@ static inline unsigned dx_node_limit(str
+@@ -647,9 +705,18 @@ static inline unsigned dx_node_limit(str
struct iam_descr *param = iam_path_descr(p);
unsigned entry_space = iam_path_obj(p)->i_sb->s_blocksize -
param->id_node_gap;
static inline struct iam_entry *dx_get_entries(struct iam_path *path,
void *data, int root)
{
-@@ -665,7 +731,8 @@ static inline struct iam_entry *dx_node_
+@@ -665,7 +732,8 @@ static inline struct iam_entry *dx_node_
frame->bh->b_data, frame == path->ip_frames);
}
{
assert(0 <= nr && nr < ARRAY_SIZE(path->ip_data->ipd_key_scratch));
return path->ip_data->ipd_key_scratch[nr];
-@@ -674,6 +741,7 @@ static inline struct iam_key *iam_path_k
+@@ -674,6 +742,7 @@ static inline struct iam_key *iam_path_k
int dx_lookup(struct iam_path *path);
void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
u32 hash, u32 block);
int ext3_htree_next_block(struct inode *dir, __u32 hash,
struct iam_path *path, __u32 *start_hash);
-@@ -681,6 +749,21 @@ int ext3_htree_next_block(struct inode *
+@@ -681,6 +750,21 @@ int ext3_htree_next_block(struct inode *
struct buffer_head *ext3_append(handle_t *handle, struct inode *inode,
u32 *block, int *err);
int split_index_node(handle_t *handle, struct iam_path *path);
/*
* external
-@@ -698,10 +781,12 @@ int iam_node_read(struct iam_container *
+@@ -698,10 +782,12 @@ int iam_node_read(struct iam_container *
handle_t *handle, struct buffer_head **bh);
void iam_insert_key(struct iam_path *path, struct iam_frame *frame,
struct iam_path *iam_leaf_path(const struct iam_leaf *leaf);
struct iam_container *iam_leaf_container(const struct iam_leaf *leaf);
-@@ -709,14 +794,76 @@ struct iam_descr *iam_leaf_descr(const s
+@@ -709,14 +795,76 @@ struct iam_descr *iam_leaf_descr(const s
struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf);