+ return iam_leaf_ops(leaf)->key_cmp(leaf, key);
+}
+
++#if EXT3_INVARIANT
+static int iam_leaf_check(struct iam_leaf *leaf);
+extern int dx_node_check(struct iam_path *p, struct iam_frame *f);
+
-+#if EXT3_INVARIANT
+static int iam_path_check(struct iam_path *p)
+{
+ int i;
}
/*
-@@ -800,598 +232,116 @@ struct stats dx_show_entries(struct dx_h
+@@ -800,598 +232,118 @@ struct stats dx_show_entries(struct dx_h
}
#endif /* DX_DEBUG */
- err = iam_leaf_init(path, &leaf);
- if (err)
- goto errout;
-+ err = param->id_ops->id_node_check(path, frame);
-+ if (err != 0)
-+ break;
++ if (EXT3_INVARIANT) {
++ err = param->id_ops->id_node_check(path, frame);
++ if (err != 0)
++ break;
++ }
- err = iam_leaf_lookup(path, &leaf, k);
- if (err)
+ }
+
+ frame->at = iam_entry_shift(path, p, -1);
-+ if (1) { // linear search cross check
++ if (EXT3_INVARIANT) { // linear search cross check
+ unsigned n = count - 1;
+ struct iam_entry *at;
+
/*
* This function increments the frame pointer to search the next leaf
* block, and reads in the necessary intervening nodes if the search
-@@ -1409,16 +359,15 @@ EXPORT_SYMBOL(iam_update);
+@@ -1409,16 +361,15 @@ EXPORT_SYMBOL(iam_update);
* If start_hash is non-null, it will be filled in with the starting
* hash of the next page.
*/
p = path->ip_frame;
/*
* Find the next leaf page by incrementing the frame pointer.
-@@ -1438,6 +387,10 @@ static int ext3_htree_next_block(struct
+@@ -1438,6 +389,10 @@ static int ext3_htree_next_block(struct
--p;
}
/*
* If the hash is 1, then continue only if the next page has a
* continuation hash of any value. This is used for readdir
-@@ -1445,19 +398,21 @@ static int ext3_htree_next_block(struct
+@@ -1445,19 +400,21 @@ static int ext3_htree_next_block(struct
* desired contiuation hash. If it doesn't, return since
* there's no point to read in the successive index pages.
*/
(iam_ptr_t)dx_get_block(path, p->at),
NULL, &bh);
if (err != 0)
-@@ -1465,12 +420,23 @@ static int ext3_htree_next_block(struct
+@@ -1465,12 +422,23 @@ static int ext3_htree_next_block(struct
++p;
brelse (p->bh);
p->bh = bh;
/*
* p is at least 6 bytes before the end of page
-@@ -1662,21 +628,30 @@ static void dx_sort_map (struct dx_map_e
+@@ -1662,21 +630,30 @@ static void dx_sort_map (struct dx_map_e
} while(more);
}
#endif
-@@ -1903,7 +878,8 @@ static struct buffer_head * ext3_dx_find
+@@ -1903,7 +880,8 @@ static struct buffer_head * ext3_dx_find
hash = hinfo.hash;
do {
block = dx_get_block(path, path->ip_frame->at);
NULL, &bh);
if (*err != 0)
goto errout;
-@@ -2093,22 +1069,69 @@ static struct ext3_dir_entry_2* dx_pack_
+@@ -2093,22 +1071,69 @@ static struct ext3_dir_entry_2* dx_pack_
return prev;
}
int err;
bh2 = ext3_append (handle, dir, &newblock, error);
-@@ -2133,35 +1156,9 @@ static struct ext3_dir_entry_2 *do_split
+@@ -2133,35 +1158,9 @@ static struct ext3_dir_entry_2 *do_split
if (err)
goto journal_error;
err = ext3_journal_dirty_metadata (handle, bh2);
if (err)
goto journal_error;
-@@ -2175,6 +1172,63 @@ errout:
+@@ -2175,6 +1174,63 @@ errout:
}
#endif
/*
* Add a new entry into a directory (leaf) block. If de is non-NULL,
-@@ -2194,34 +1248,16 @@ static int add_dirent_to_buf(handle_t *h
+@@ -2194,34 +1250,16 @@ static int add_dirent_to_buf(handle_t *h
struct inode *dir = dentry->d_parent->d_inode;
const char *name = dentry->d_name.name;
int namelen = dentry->d_name.len;
}
BUFFER_TRACE(bh, "get_write_access");
err = ext3_journal_get_write_access(handle, bh);
-@@ -2232,22 +1268,9 @@ static int add_dirent_to_buf(handle_t *h
+@@ -2232,22 +1270,9 @@ static int add_dirent_to_buf(handle_t *h
}
/* By now the buffer is marked for journaling */
/*
* XXX shouldn't update any times until successful
* completion of syscall, but too many callers depend
-@@ -2423,8 +1446,40 @@ static int ext3_add_entry (handle_t *han
+@@ -2423,8 +1448,40 @@ static int ext3_add_entry (handle_t *han
return add_dirent_to_buf(handle, dentry, inode, de, bh);
}
{
struct iam_entry *entries; /* old block contents */
-@@ -2432,10 +1487,17 @@ static int split_index_node(handle_t *ha
+@@ -2432,10 +1489,17 @@ static int split_index_node(handle_t *ha
struct iam_frame *frame, *safe;
struct buffer_head *bh_new[DX_MAX_TREE_HEIGHT] = {0};
u32 newblock[DX_MAX_TREE_HEIGHT] = {0};
frame = path->ip_frame;
entries = frame->entries;
-@@ -2474,7 +1536,8 @@ static int split_index_node(handle_t *ha
+@@ -2474,7 +1538,8 @@ static int split_index_node(handle_t *ha
for (frame = safe + 1, i = 0; i < nr_splet; ++i, ++frame) {
bh_new[i] = ext3_append (handle, dir, &newblock[i], &err);
if (!bh_new[i] ||
goto cleanup;
BUFFER_TRACE(frame->bh, "get_write_access");
err = ext3_journal_get_write_access(handle, frame->bh);
-@@ -2493,6 +1556,7 @@ static int split_index_node(handle_t *ha
+@@ -2493,6 +1558,7 @@ static int split_index_node(handle_t *ha
unsigned count;
int idx;
struct buffer_head *bh2;
entries = frame->entries;
count = dx_get_count(entries);
-@@ -2501,6 +1565,7 @@ static int split_index_node(handle_t *ha
+@@ -2501,6 +1567,7 @@ static int split_index_node(handle_t *ha
bh2 = bh_new[i];
entries2 = dx_get_entries(path, bh2->b_data, 0);
if (frame == path->ip_frames) {
/* splitting root node. Tricky point:
*
-@@ -2512,22 +1577,20 @@ static int split_index_node(handle_t *ha
+@@ -2512,22 +1579,20 @@ static int split_index_node(handle_t *ha
* capacity of the root node is smaller than that of
* non-root one.
*/
/* Shift frames in the path */
memmove(frames + 2, frames + 1,
-@@ -2536,49 +1599,61 @@ static int split_index_node(handle_t *ha
+@@ -2536,49 +1601,61 @@ static int split_index_node(handle_t *ha
frames[1].at = iam_entry_shift(path, entries2, idx);
frames[1].entries = entries = entries2;
frames[1].bh = bh2;
}
goto cleanup;
journal_error:
-@@ -2610,7 +1685,7 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -2610,7 +1687,7 @@ static int ext3_dx_add_entry(handle_t *h
size_t isize;
iam_path_compat_init(&cpath, dir);
err = dx_probe(dentry, NULL, &hinfo, path);
if (err != 0)
-@@ -2620,7 +1695,8 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -2620,7 +1697,8 @@ static int ext3_dx_add_entry(handle_t *h
/* XXX nikita: global serialization! */
isize = dir->i_size;
handle, &bh);
if (err != 0)
goto cleanup;
-@@ -2641,11 +1717,11 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -2641,11 +1719,11 @@ static int ext3_dx_add_entry(handle_t *h
goto cleanup;
/*copy split inode too*/
err = add_dirent_to_buf(handle, dentry, inode, de, bh);
goto cleanup2;
+Index: iam/include/linux/ext3_fs.h
+===================================================================
+--- iam.orig/include/linux/ext3_fs.h
++++ iam/include/linux/ext3_fs.h
+@@ -758,9 +758,7 @@ extern int ext3_should_retry_alloc(struc
+ extern void rsv_window_add(struct super_block *sb, struct reserve_window_node *rsv);
+
+ /* dir.c */
+-extern int ext3_check_dir_entry(const char *, struct inode *,
+- struct ext3_dir_entry_2 *,
+- struct buffer_head *, unsigned long);
++
+ extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash,
+ __u32 minor_hash,
+ struct ext3_dir_entry_2 *dirent);
Index: iam/include/linux/lustre_iam.h
===================================================================
--- iam.orig/include/linux/lustre_iam.h
static unsigned char ext3_filetype_table[] = {
DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
-@@ -305,12 +306,14 @@ static void free_rb_tree_fname(struct rb
+@@ -61,6 +62,7 @@ static unsigned char get_dtype(struct su
+ }
+
+
++#if EXT3_INVARIANT
+ int ext3_check_dir_entry (const char * function, struct inode * dir,
+ struct ext3_dir_entry_2 * de,
+ struct buffer_head * bh,
+@@ -90,6 +92,7 @@ int ext3_check_dir_entry (const char * f
+ rlen, de->name_len);
+ return error_msg == NULL ? 1 : 0;
+ }
++#endif
+
+ static int ext3_readdir(struct file * filp,
+ void * dirent, filldir_t filldir)
+@@ -305,12 +308,14 @@ static void free_rb_tree_fname(struct rb
root->rb_node = NULL;
}
if (!p)
return NULL;
p->root.rb_node = NULL;
-@@ -326,6 +329,7 @@ struct dir_private_info *create_dir_info
+@@ -326,6 +331,7 @@ struct dir_private_info *create_dir_info
void ext3_htree_free_dir_info(struct dir_private_info *p)
{
free_rb_tree_fname(&p->root);
struct iam_path *iam_leaf_path(const struct iam_leaf *leaf);
struct iam_container *iam_leaf_container(const struct iam_leaf *leaf);
-@@ -709,14 +844,79 @@ struct iam_descr *iam_leaf_descr(const s
+@@ -709,14 +844,95 @@ struct iam_descr *iam_leaf_descr(const s
struct iam_leaf_operations *iam_leaf_ops(const struct iam_leaf *leaf);
+int iam_uapi_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
+ unsigned long arg);
+
++/* dir.c */
++#if EXT3_INVARIANT
++extern int ext3_check_dir_entry(const char *, struct inode *,
++ struct ext3_dir_entry_2 *,
++ struct buffer_head *, unsigned long);
++#else
++static inline int ext3_check_dir_entry(const char * function,
++ struct inode * dir,
++ struct ldiskfs_dir_entry_2 * de,
++ struct buffer_head * bh,
++ unsigned long offset)
++{
++ return 1;
++}
++#endif
++
+/* __KERNEL__ */
+#endif
+