-Index: linux-2.6.9-full/include/linux/ext3_fs.h
+Index: iam/fs/ext3/inode.c
===================================================================
---- linux-2.6.9-full.orig/include/linux/ext3_fs.h 2006-08-09 17:56:39.000000000 +0400
-+++ linux-2.6.9-full/include/linux/ext3_fs.h 2006-08-22 12:36:22.000000000 +0400
-@@ -826,6 +826,7 @@ extern void ext3_put_super (struct super
- extern void ext3_write_super (struct super_block *);
- extern void ext3_write_super_lockfs (struct super_block *);
- extern void ext3_unlockfs (struct super_block *);
-+extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
- extern int ext3_remount (struct super_block *, int *, char *);
- extern int ext3_statfs (struct super_block *, struct kstatfs *);
-
-Index: linux-2.6.9-full/fs/ext3/super.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/super.c 2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/super.c 2006-08-09 17:56:40.000000000 +0400
-@@ -43,7 +43,7 @@ static int ext3_load_journal(struct supe
- unsigned long journal_devnum);
- static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
- int);
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
- struct ext3_super_block * es,
- int sync);
- static void ext3_mark_recovery_complete(struct super_block * sb,
-@@ -1991,7 +1991,7 @@ static int ext3_create_journal(struct su
- return 0;
- }
-
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
- struct ext3_super_block * es,
- int sync)
- {
-Index: linux-2.6.9-full/fs/ext3/namei.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/namei.c 2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/namei.c 2006-08-09 17:56:40.000000000 +0400
-@@ -1599,7 +1599,7 @@ static int ext3_delete_entry (handle_t *
- struct buffer_head * bh)
- {
- struct ext3_dir_entry_2 * de, * pde;
-- int i;
-+ int i, err;
-
- i = 0;
- pde = NULL;
-@@ -1609,7 +1609,9 @@ static int ext3_delete_entry (handle_t *
- return -EIO;
- if (de == de_del) {
- BUFFER_TRACE(bh, "get_write_access");
-- ext3_journal_get_write_access(handle, bh);
-+ err = ext3_journal_get_write_access(handle, bh);
-+ if (err)
-+ return err;
- if (pde)
- pde->rec_len =
- cpu_to_le16(le16_to_cpu(pde->rec_len) +
-Index: linux-2.6.9-full/fs/ext3/xattr.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/xattr.c 2006-06-01 14:58:48.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/xattr.c 2006-08-09 17:56:40.000000000 +0400
-@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
- {
- struct xattr_handler *handler = NULL;
-
-- if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
-+ if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
- handler = ext3_xattr_handler_map[name_index];
- return handler;
- }
-Index: linux-2.6.9-full/fs/ext3/inode.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/inode.c 2006-06-02 23:37:38.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/inode.c 2006-08-22 12:34:28.000000000 +0400
+--- iam.orig/fs/ext3/inode.c
++++ iam/fs/ext3/inode.c
@@ -1513,9 +1513,14 @@ out_stop:
if (end > inode->i_size) {
ei->i_disksize = end;
}
}
+Index: iam/fs/ext3/namei.c
+===================================================================
+--- iam.orig/fs/ext3/namei.c
++++ iam/fs/ext3/namei.c
+@@ -2473,7 +2473,7 @@ static int ext3_delete_entry (handle_t *
+ struct buffer_head * bh)
+ {
+ struct ext3_dir_entry_2 * de, * pde;
+- int i;
++ int i, err;
+
+ i = 0;
+ pde = NULL;
+@@ -2483,7 +2483,9 @@ static int ext3_delete_entry (handle_t *
+ return -EIO;
+ if (de == de_del) {
+ BUFFER_TRACE(bh, "get_write_access");
+- ext3_journal_get_write_access(handle, bh);
++ err = ext3_journal_get_write_access(handle, bh);
++ if (err)
++ return err;
+ if (pde)
+ pde->rec_len =
+ cpu_to_le16(le16_to_cpu(pde->rec_len) +
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -42,7 +42,7 @@
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+ int);
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+ struct ext3_super_block * es,
+ int sync);
+ static void ext3_mark_recovery_complete(struct super_block * sb,
+@@ -1987,7 +1987,7 @@ static int ext3_create_journal(struct su
+ return 0;
+ }
+
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+ struct ext3_super_block * es,
+ int sync)
+ {
+Index: iam/fs/ext3/xattr.c
+===================================================================
+--- iam.orig/fs/ext3/xattr.c
++++ iam/fs/ext3/xattr.c
+@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
+ {
+ struct xattr_handler *handler = NULL;
+
+- if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
++ if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
+ handler = ext3_xattr_handler_map[name_index];
+ return handler;
+ }
+Index: iam/include/linux/ext3_fs.h
+===================================================================
+--- iam.orig/include/linux/ext3_fs.h
++++ iam/include/linux/ext3_fs.h
+@@ -839,6 +839,7 @@ extern void ext3_put_super (struct super
+ extern void ext3_write_super (struct super_block *);
+ extern void ext3_write_super_lockfs (struct super_block *);
+ extern void ext3_unlockfs (struct super_block *);
++extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
+ extern int ext3_remount (struct super_block *, int *, char *);
+ extern int ext3_statfs (struct super_block *, struct kstatfs *);
+
Signed-off-by: Mingming Cao<cmm@us.ibm.com>
Acked-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
----
-
- fs/ext3/resize.c | 10 ++++++++++
- fs/ext3/super.c | 10 ++++++++++
- 2 files changed, 20 insertions(+)
-
-diff -puN fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/resize.c
---- devel/fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem 2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/resize.c 2006-05-22 14:10:56.000000000 -0700
-@@ -926,6 +926,16 @@ int ext3_group_extend(struct super_block
+Index: iam/fs/ext3/resize.c
+===================================================================
+--- iam.orig/fs/ext3/resize.c
++++ iam/fs/ext3/resize.c
+@@ -914,6 +914,16 @@ int ext3_group_extend(struct super_block
if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
return 0;
if (n_blocks_count < o_blocks_count) {
ext3_warning(sb, __FUNCTION__,
"can't shrink FS - resize aborted");
-diff -puN fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/super.c
---- devel/fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem 2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/super.c 2006-05-22 14:11:10.000000000 -0700
-@@ -1565,6 +1565,17 @@ static int ext3_fill_super (struct super
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -1530,6 +1530,17 @@ static int ext3_fill_super (struct super
goto failed_mount;
}
sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
le32_to_cpu(es->s_first_data_block) +
EXT3_BLOCKS_PER_GROUP(sb) - 1) /
-_
-Index: linux-2.6.9-full/include/linux/ext3_fs.h
+Index: iam/fs/ext3/inode.c
===================================================================
---- linux-2.6.9-full.orig/include/linux/ext3_fs.h 2006-08-09 17:56:39.000000000 +0400
-+++ linux-2.6.9-full/include/linux/ext3_fs.h 2006-08-22 12:36:22.000000000 +0400
-@@ -826,6 +826,7 @@ extern void ext3_put_super (struct super
- extern void ext3_write_super (struct super_block *);
- extern void ext3_write_super_lockfs (struct super_block *);
- extern void ext3_unlockfs (struct super_block *);
-+extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
- extern int ext3_remount (struct super_block *, int *, char *);
- extern int ext3_statfs (struct super_block *, struct kstatfs *);
-
-Index: linux-2.6.9-full/fs/ext3/super.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/super.c 2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/super.c 2006-08-09 17:56:40.000000000 +0400
-@@ -43,7 +43,7 @@ static int ext3_load_journal(struct supe
- unsigned long journal_devnum);
- static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
- int);
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
- struct ext3_super_block * es,
- int sync);
- static void ext3_mark_recovery_complete(struct super_block * sb,
-@@ -1991,7 +1991,7 @@ static int ext3_create_journal(struct su
- return 0;
- }
-
--static void ext3_commit_super (struct super_block * sb,
-+void ext3_commit_super (struct super_block * sb,
- struct ext3_super_block * es,
- int sync)
- {
-Index: linux-2.6.9-full/fs/ext3/namei.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/namei.c 2006-08-09 17:56:40.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/namei.c 2006-08-09 17:56:40.000000000 +0400
-@@ -1599,7 +1599,7 @@ static int ext3_delete_entry (handle_t *
- struct buffer_head * bh)
- {
- struct ext3_dir_entry_2 * de, * pde;
-- int i;
-+ int i, err;
-
- i = 0;
- pde = NULL;
-@@ -1609,7 +1609,9 @@ static int ext3_delete_entry (handle_t *
- return -EIO;
- if (de == de_del) {
- BUFFER_TRACE(bh, "get_write_access");
-- ext3_journal_get_write_access(handle, bh);
-+ err = ext3_journal_get_write_access(handle, bh);
-+ if (err)
-+ return err;
- if (pde)
- pde->rec_len =
- cpu_to_le16(le16_to_cpu(pde->rec_len) +
-Index: linux-2.6.9-full/fs/ext3/xattr.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/xattr.c 2006-06-01 14:58:48.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/xattr.c 2006-08-09 17:56:40.000000000 +0400
-@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
- {
- struct xattr_handler *handler = NULL;
-
-- if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
-+ if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
- handler = ext3_xattr_handler_map[name_index];
- return handler;
- }
-Index: linux-2.6.9-full/fs/ext3/inode.c
-===================================================================
---- linux-2.6.9-full.orig/fs/ext3/inode.c 2006-06-02 23:37:38.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/inode.c 2006-08-22 12:34:28.000000000 +0400
+--- iam.orig/fs/ext3/inode.c
++++ iam/fs/ext3/inode.c
@@ -1513,9 +1513,14 @@ out_stop:
if (end > inode->i_size) {
ei->i_disksize = end;
}
}
+Index: iam/fs/ext3/namei.c
+===================================================================
+--- iam.orig/fs/ext3/namei.c
++++ iam/fs/ext3/namei.c
+@@ -2473,7 +2473,7 @@ static int ext3_delete_entry (handle_t *
+ struct buffer_head * bh)
+ {
+ struct ext3_dir_entry_2 * de, * pde;
+- int i;
++ int i, err;
+
+ i = 0;
+ pde = NULL;
+@@ -2483,7 +2483,9 @@ static int ext3_delete_entry (handle_t *
+ return -EIO;
+ if (de == de_del) {
+ BUFFER_TRACE(bh, "get_write_access");
+- ext3_journal_get_write_access(handle, bh);
++ err = ext3_journal_get_write_access(handle, bh);
++ if (err)
++ return err;
+ if (pde)
+ pde->rec_len =
+ cpu_to_le16(le16_to_cpu(pde->rec_len) +
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -42,7 +42,7 @@
+ static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+ static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
+ int);
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+ struct ext3_super_block * es,
+ int sync);
+ static void ext3_mark_recovery_complete(struct super_block * sb,
+@@ -1987,7 +1987,7 @@ static int ext3_create_journal(struct su
+ return 0;
+ }
+
+-static void ext3_commit_super (struct super_block * sb,
++void ext3_commit_super (struct super_block * sb,
+ struct ext3_super_block * es,
+ int sync)
+ {
+Index: iam/fs/ext3/xattr.c
+===================================================================
+--- iam.orig/fs/ext3/xattr.c
++++ iam/fs/ext3/xattr.c
+@@ -132,7 +132,7 @@ ext3_xattr_handler(int name_index)
+ {
+ struct xattr_handler *handler = NULL;
+
+- if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX)
++ if (name_index > 0 && name_index < EXT3_XATTR_INDEX_MAX)
+ handler = ext3_xattr_handler_map[name_index];
+ return handler;
+ }
+Index: iam/include/linux/ext3_fs.h
+===================================================================
+--- iam.orig/include/linux/ext3_fs.h
++++ iam/include/linux/ext3_fs.h
+@@ -839,6 +839,7 @@ extern void ext3_put_super (struct super
+ extern void ext3_write_super (struct super_block *);
+ extern void ext3_write_super_lockfs (struct super_block *);
+ extern void ext3_unlockfs (struct super_block *);
++extern void ext3_commit_super (struct super_block *, struct ext3_super_block *, int);
+ extern int ext3_remount (struct super_block *, int *, char *);
+ extern int ext3_statfs (struct super_block *, struct kstatfs *);
+
===================================================================
--- iam.orig/fs/ext3/iam.c
+++ iam/fs/ext3/iam.c
-@@ -0,0 +1,1432 @@
+@@ -0,0 +1,1445 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+
+static void iam_leaf_fini(struct iam_leaf *leaf);
+
-+void iam_path_fini(struct iam_path *path)
++void iam_path_release(struct iam_path *path)
+{
+ int i;
+
-+ iam_leaf_fini(&path->ip_leaf);
+ for (i = 0; i < ARRAY_SIZE(path->ip_frames); i++) {
+ if (path->ip_frames[i].bh != NULL) {
+ brelse(path->ip_frames[i].bh);
+ }
+}
+
++void iam_path_fini(struct iam_path *path)
++{
++ iam_leaf_fini(&path->ip_leaf);
++ iam_path_release(path);
++}
++
+void iam_path_compat_init(struct iam_path_compat *path, struct inode *inode)
+{
+ int i;
+}
+EXPORT_SYMBOL(iam_it_put);
+
++static struct iam_ikey *iam_it_ikey_get(const struct iam_iterator *it,
++ struct iam_ikey *ikey);
+/*
+ * Move iterator one record right.
+ *
+ struct iam_path *path;
+ struct iam_leaf *leaf;
+ struct inode *obj;
++ do_corr(struct iam_ikey *ik_orig);
+
+ /* assert_corr(it->ii_flags&IAM_IT_MOVE); */
+ assert_corr(it_state(it) == IAM_IT_ATTACHED ||
+ leaf = &path->ip_leaf;
+ obj = iam_path_obj(path);
+
++ assert_corr(iam_leaf_is_locked(leaf));
++
+ result = 0;
++ do_corr(ik_orig = iam_it_ikey_get(it, iam_path_ikey(path, 2)));
+ if (it_before(it)) {
+ assert_corr(!iam_leaf_at_end(leaf));
+ it->ii_state = IAM_IT_ATTACHED;
+ do_corr(schedule());
+ /* advance index portion of the path */
+ result = iam_index_next(iam_it_container(it), path);
++ assert_corr(iam_leaf_is_locked(leaf));
+ if (result == 1) {
+ struct dynlock_handle *lh;
+ lh = dx_lock_htree(obj, path->ip_frame->leaf,
+ }
+ assert_corr(ergo(result == 0, it_state(it) == IAM_IT_ATTACHED));
+ assert_corr(ergo(result > 0, it_state(it) == IAM_IT_DETACHED));
++ assert_corr(ergo(result == 0, it_ikeycmp(it, ik_orig) >= 0));
+ return result;
+}
+EXPORT_SYMBOL(iam_it_next);
+ * Search container @c for record with key @k. If record is found, its data
+ * are moved into @r.
+ *
-+ * Return values: +ve: found, 0: not-found, -ve: error
++ * Return values: 0: found, -ENOENT: not-found, -ve: error
+ */
+int iam_lookup(struct iam_container *c, const struct iam_key *k,
+ struct iam_rec *r, struct iam_path_descr *pd)
BREAKPOINT();
return 0;
}
-@@ -241,12 +280,236 @@ struct stats dx_show_entries(struct dx_h
+@@ -241,12 +280,241 @@ struct stats dx_show_entries(struct dx_h
}
#endif /* DX_DEBUG */
+ */
+ result = 0;
+ for (scan = path->ip_frames; scan < bottom; ++scan) {
-+ if (search) {
-+ struct iam_entry *pos;
++ struct iam_entry *pos;
+
++ if (search) {
+ if (dx_check_fast(path, scan) == 0)
+ continue;
+
+ break;
+ }
+ scan->at = pos;
-+ } else if (scan->leaf != dx_get_block(path, scan->at)) {
-+ result = -EAGAIN;
-+ break;
++ } else {
++ pos = iam_entry_shift(path, scan->entries,
++ dx_get_count(scan->entries) - 1);
++ if (scan->at > pos ||
++ scan->leaf != dx_get_block(path, scan->at)) {
++ result = -EAGAIN;
++ break;
++ }
+ }
+ }
+
struct iam_descr *param;
struct iam_frame *frame;
-@@ -255,20 +518,19 @@ int dx_lookup(struct iam_path *path)
+@@ -255,20 +523,19 @@ int dx_lookup(struct iam_path *path)
param = iam_path_descr(path);
c = path->ip_container;
if (err != 0)
break;
-@@ -283,53 +545,83 @@ int dx_lookup(struct iam_path *path)
+@@ -283,53 +550,83 @@ int dx_lookup(struct iam_path *path)
break;
assert_inv(dx_node_check(path, frame));
/*
* Probe for a directory leaf block to search.
*
-@@ -339,7 +631,7 @@ int dx_lookup(struct iam_path *path)
+@@ -339,7 +636,7 @@ int dx_lookup(struct iam_path *path)
* check for this error code, and make sure it never gets reflected
* back to userspace.
*/
struct dx_hash_info *hinfo, struct iam_path *path)
{
int err;
-@@ -347,7 +639,7 @@ static int dx_probe(struct dentry *dentr
+@@ -347,7 +644,7 @@ static int dx_probe(struct dentry *dentr
assert_corr(path->ip_data != NULL);
ipc = container_of(path->ip_data, struct iam_path_compat, ipc_descr);
ipc->ipc_hinfo = hinfo;
assert_corr(dx_index_is_compat(path));
-@@ -356,6 +648,7 @@ static int dx_probe(struct dentry *dentr
+@@ -356,6 +653,7 @@ static int dx_probe(struct dentry *dentr
return err;
}
/*
* This function increments the frame pointer to search the next leaf
* block, and reads in the necessary intervening nodes if the search
-@@ -391,10 +684,13 @@ static int ext3_htree_advance(struct ino
+@@ -391,10 +689,16 @@ static int ext3_htree_advance(struct ino
* nodes need to be read.
*/
while (1) {
+ do_corr(schedule());
++ dx_lock_bh(p->bh);
p->at = iam_entry_shift(path, p->at, +1);
if (p->at < iam_entry_shift(path, p->entries,
- dx_get_count(p->entries)))
+ dx_get_count(p->entries))) {
+ p->leaf = dx_get_block(path, p->at);
++ dx_unlock_bh(p->bh);
break;
+ }
++ dx_unlock_bh(p->bh);
if (p == path->ip_frames)
return 0;
num_frames++;
-@@ -409,7 +705,7 @@ static int ext3_htree_advance(struct ino
+@@ -409,7 +713,7 @@ static int ext3_htree_advance(struct ino
* If the hash is 1, then continue only if the next page has a
* continuation hash of any value. This is used for readdir
* handling. Otherwise, check to see if the hash matches the
* there's no point to read in the successive index pages.
*/
iam_get_ikey(path, p->at, (struct iam_ikey *)&bhash);
-@@ -425,25 +721,91 @@ static int ext3_htree_advance(struct ino
+@@ -425,25 +729,126 @@ static int ext3_htree_advance(struct ino
* block so no check is necessary
*/
while (num_frames--) {
+ iam_ptr_t idx;
+
+ do_corr(schedule());
++ dx_lock_bh(p->bh);
+ idx = p->leaf = dx_get_block(path, p->at);
++ dx_unlock_bh(p->bh);
err = iam_path_descr(path)->id_ops->
- id_node_read(path->ip_container,
- (iam_ptr_t)dx_get_block(path, p->at),
++p;
- brelse (p->bh);
+ brelse(p->bh);
++ assert_corr(p->bh != bh);
p->bh = bh;
p->entries = dx_node_get_entries(path, p);
p->at = iam_entry_shift(path, p->entries, !compat);
++ assert_corr(p->curidx != idx);
+ p->curidx = idx;
++ dx_lock_bh(p->bh);
++ assert_corr(p->leaf != dx_get_block(path, p->at));
+ p->leaf = dx_get_block(path, p->at);
++ dx_unlock_bh(p->bh);
assert_inv(dx_node_check(path, p));
+ assert(dx_bug11027_check(path, p));
}
+{
+ struct iam_frame *f;
+
-+ for (f = path->ip_frame; f >= path->ip_frames; --f) {
++ for (f = path->ip_frame; f >= path->ip_frames; --f, ++lh) {
+ do_corr(schedule());
-+ *lh = dx_lock_htree(iam_path_obj(path), f->curidx, DLT_WRITE);
++ *lh = dx_lock_htree(iam_path_obj(path), f->curidx, DLT_READ);
+ if (*lh == NULL)
+ return -ENOMEM;
-+ lh++;
-+ if (f->at < iam_entry_shift(path, f->entries,
-+ dx_get_count(f->entries) - 1))
-+ return 1;
+ }
-+ return 0; /* end of index... */
++ return 0;
+}
+
+static int iam_index_advance(struct iam_path *path)
+ while (1) {
+ result = iam_index_lock(path, lh);
+ do_corr(schedule());
-+ if (result <= 0) /* error, or end of index... */
++ if (result < 0)
+ break;
-+
++
+ result = dx_check_full_path(path, 0);
+ if (result == 0 && cursor == path->ip_frame->leaf) {
+ result = iam_index_advance(path);
++
++ assert_corr(result == 0 ||
++ cursor != path->ip_frame->leaf);
+ break;
+ }
-+ dx_unlock_array(object, lh);
-+ iam_path_fini(path);
-+ do_corr(schedule());
-+ result = dx_lookup(path);
-+ while (path->ip_frame->leaf != cursor) {
++ do {
++ dx_unlock_array(object, lh);
++
++ iam_path_release(path);
+ do_corr(schedule());
-+ result = iam_index_advance(path);
-+ if (result <= 0)
++
++ result = dx_lookup(path);
++ if (result < 0)
+ break;
-+ }
++
++ while (path->ip_frame->leaf != cursor) {
++ do_corr(schedule());
++
++ result = iam_index_lock(path, lh);
++ do_corr(schedule());
++ if (result < 0)
++ break;
++
++ result = dx_check_full_path(path, 0);
++ if (result != 0)
++ break;
++
++ result = iam_index_advance(path);
++ if (result == 0) {
++ ext3_error(object->i_sb, __FUNCTION__,
++ "cannot find cursor: %u\n",
++ cursor);
++ result = -EIO;
++ }
++ if (result < 0)
++ break;
++ result = dx_check_full_path(path, 0);
++ if (result != 0)
++ break;
++ dx_unlock_array(object, lh);
++ }
++ } while (result == -EAGAIN);
++ if (result < 0)
++ break;
+ }
+ dx_unlock_array(object, lh);
+ return result;
}
int ext3_htree_next_block(struct inode *dir, __u32 hash,
-@@ -649,14 +1011,26 @@ void iam_insert_key(struct iam_path *pat
+@@ -649,14 +1054,26 @@ void iam_insert_key(struct iam_path *pat
struct iam_entry *new = iam_entry_shift(path, frame->at, +1);
int count = dx_get_count(entries);
}
void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
-@@ -882,7 +1256,7 @@ static struct buffer_head * ext3_dx_find
+@@ -882,7 +1299,7 @@ static struct buffer_head * ext3_dx_find
sb = dir->i_sb;
/* NFS may look up ".." - look at dx_root directory block */
if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
if (*err != 0)
return NULL;
} else {
-@@ -1114,7 +1488,7 @@ struct ext3_dir_entry_2 *move_entries(st
+@@ -1114,7 +1531,7 @@ struct ext3_dir_entry_2 *move_entries(st
hash2 = map[split].hash;
continued = hash2 == map[split - 1].hash;
dxtrace(printk("Split block %i at %x, %i/%i\n",
/* Fancy dance to stay within two buffers */
de2 = dx_move_dirents(data1, data2, map + split, count - split);
-@@ -1484,16 +1858,38 @@ static int shift_entries(struct iam_path
+@@ -1484,16 +1901,38 @@ static int shift_entries(struct iam_path
(char *) iam_entry_shift(path, entries, count1),
count2 * iam_entry_size(path));
{
struct iam_entry *entries; /* old block contents */
-@@ -1501,6 +1897,8 @@ int split_index_node(handle_t *handle, s
+@@ -1501,6 +1940,8 @@ int split_index_node(handle_t *handle, s
struct iam_frame *frame, *safe;
struct buffer_head *bh_new[DX_MAX_TREE_HEIGHT] = {0};
u32 newblock[DX_MAX_TREE_HEIGHT] = {0};
struct inode *dir = iam_path_obj(path);
struct iam_descr *descr;
int nr_splet;
-@@ -1523,12 +1921,14 @@ int split_index_node(handle_t *handle, s
+@@ -1523,12 +1964,14 @@ int split_index_node(handle_t *handle, s
* - first allocate all necessary blocks
*
* - insert pointers into them atomically.
dxtrace(printk("using %u of %u node entries\n",
dx_get_count(entries), dx_get_limit(entries)));
-@@ -1536,6 +1936,7 @@ int split_index_node(handle_t *handle, s
+@@ -1536,6 +1979,7 @@ int split_index_node(handle_t *handle, s
for (nr_splet = 0; frame >= path->ip_frames &&
dx_get_count(frame->entries) == dx_get_limit(frame->entries);
--frame, ++nr_splet) {
if (nr_splet == DX_MAX_TREE_HEIGHT) {
ext3_warning(dir->i_sb, __FUNCTION__,
"Directory index full!\n");
-@@ -1545,14 +1946,53 @@ int split_index_node(handle_t *handle, s
+@@ -1545,14 +1989,53 @@ int split_index_node(handle_t *handle, s
}
safe = frame;
BUFFER_TRACE(frame->bh, "get_write_access");
err = ext3_journal_get_write_access(handle, frame->bh);
if (err)
-@@ -1560,6 +2000,7 @@ int split_index_node(handle_t *handle, s
+@@ -1560,6 +2043,7 @@ int split_index_node(handle_t *handle, s
}
/* Add "safe" node to transaction too */
if (safe + 1 != path->ip_frames) {
err = ext3_journal_get_write_access(handle, safe->bh);
if (err)
goto journal_error;
-@@ -1596,16 +2037,21 @@ int split_index_node(handle_t *handle, s
+@@ -1596,16 +2080,21 @@ int split_index_node(handle_t *handle, s
assert_corr(i == 0);
/* Shift frames in the path */
memmove(frames + 2, frames + 1,
(sizeof path->ip_frames) - 2 * sizeof frames[0]);
-@@ -1613,18 +2059,22 @@ int split_index_node(handle_t *handle, s
+@@ -1613,18 +2102,22 @@ int split_index_node(handle_t *handle, s
frames[1].at = iam_entry_shift(path, entries2, idx);
frames[1].entries = entries = entries2;
frames[1].bh = bh2;
count = shift_entries(path, frame, count,
entries, entries2, newblock[i]);
/* Which index block gets the new entry? */
-@@ -1634,33 +2084,44 @@ int split_index_node(handle_t *handle, s
+@@ -1634,33 +2127,44 @@ int split_index_node(handle_t *handle, s
frame->at = iam_entry_shift(path, entries2,
idx - count + d);
frame->entries = entries = entries2;
if (nr_splet > 0) {
/*
* Log ->i_size modification.
-@@ -1674,6 +2135,12 @@ journal_error:
+@@ -1674,6 +2178,12 @@ journal_error:
ext3_std_error(dir->i_sb, err);
cleanup:
for (i = 0; i < ARRAY_SIZE(bh_new); ++i) {
if (bh_new[i] != NULL)
brelse(bh_new[i]);
-@@ -1695,18 +2162,18 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -1695,18 +2205,18 @@ static int ext3_dx_add_entry(handle_t *h
struct buffer_head * bh = NULL;
struct inode *dir = dentry->d_parent->d_inode;
struct ext3_dir_entry_2 *de;
isize = dir->i_size;
err = param->id_ops->id_node_read(path->ip_container,
-@@ -1726,7 +2193,7 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -1726,7 +2236,7 @@ static int ext3_dx_add_entry(handle_t *h
goto cleanup;
}
if (err)
goto cleanup;
-@@ -1736,12 +2203,14 @@ static int ext3_dx_add_entry(handle_t *h
+@@ -1736,12 +2246,14 @@ static int ext3_dx_add_entry(handle_t *h
goto cleanup;
assert_inv(dx_node_check(path, frame));
struct iam_path_descr ipc_descr;
struct dx_hash_info ipc_hinfo_area;
};
-@@ -848,7 +867,36 @@ static inline struct iam_ikey *iam_path_
+@@ -554,6 +573,7 @@ struct iam_iterator {
+ void iam_path_init(struct iam_path *path, struct iam_container *c,
+ struct iam_path_descr *pd);
+ void iam_path_fini(struct iam_path *path);
++void iam_path_release(struct iam_path *path);
+
+ void iam_path_compat_init(struct iam_path_compat *path, struct inode *inode);
+ void iam_path_compat_fini(struct iam_path_compat *path);
+@@ -848,7 +868,36 @@ static inline struct iam_ikey *iam_path_
return path->ip_data->ipd_key_scratch[nr];
}
void dx_insert_block(struct iam_path *path, struct iam_frame *frame,
u32 hash, u32 block);
int dx_index_is_compat(struct iam_path *path);
-@@ -858,7 +906,8 @@ int ext3_htree_next_block(struct inode *
+@@ -858,7 +907,8 @@ int ext3_htree_next_block(struct inode *
struct buffer_head *ext3_append(handle_t *handle, struct inode *inode,
u32 *block, int *err);
struct ext3_dir_entry_2 *split_entry(struct inode *dir,
struct ext3_dir_entry_2 *de,
unsigned long ino, mode_t mode,
-@@ -874,6 +923,10 @@ struct ext3_dir_entry_2 *move_entries(st
+@@ -874,6 +924,10 @@ struct ext3_dir_entry_2 *move_entries(st
extern struct iam_descr iam_htree_compat_param;
/*
* external
*/
-@@ -889,7 +942,7 @@ int iam_read_leaf(struct iam_path *p);
+@@ -889,7 +943,7 @@ int iam_read_leaf(struct iam_path *p);
int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
handle_t *handle, struct buffer_head **bh);
Signed-off-by: Mingming Cao<cmm@us.ibm.com>
Acked-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
----
-
- fs/ext3/resize.c | 10 ++++++++++
- fs/ext3/super.c | 10 ++++++++++
- 2 files changed, 20 insertions(+)
-
-diff -puN fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/resize.c
---- devel/fs/ext3/resize.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem 2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/resize.c 2006-05-22 14:10:56.000000000 -0700
-@@ -926,6 +926,16 @@ int ext3_group_extend(struct super_block
+Index: iam/fs/ext3/resize.c
+===================================================================
+--- iam.orig/fs/ext3/resize.c
++++ iam/fs/ext3/resize.c
+@@ -914,6 +914,16 @@ int ext3_group_extend(struct super_block
if (n_blocks_count == 0 || n_blocks_count == o_blocks_count)
return 0;
if (n_blocks_count < o_blocks_count) {
ext3_warning(sb, __FUNCTION__,
"can't shrink FS - resize aborted");
-diff -puN fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem fs/ext3/super.c
---- devel/fs/ext3/super.c~avoid-disk-sector_t-overflow-for-2tb-ext3-filesystem 2006-05-22 14:09:53.000000000 -0700
-+++ devel-akpm/fs/ext3/super.c 2006-05-22 14:11:10.000000000 -0700
-@@ -1565,6 +1565,17 @@ static int ext3_fill_super (struct super
+Index: iam/fs/ext3/super.c
+===================================================================
+--- iam.orig/fs/ext3/super.c
++++ iam/fs/ext3/super.c
+@@ -1530,6 +1530,17 @@ static int ext3_fill_super (struct super
goto failed_mount;
}
sbi->s_groups_count = (le32_to_cpu(es->s_blocks_count) -
le32_to_cpu(es->s_first_data_block) +
EXT3_BLOCKS_PER_GROUP(sb) - 1) /
-_