--- /dev/null
+diff -ru lum-2.4.18-um30/fs/ext3/balloc.c uml-2.4.18-12.5/fs/ext3/balloc.c
+--- lum-2.4.18-um30/fs/ext3/balloc.c Mon Feb 25 12:38:08 2002
++++ uml-2.4.18-12.5/fs/ext3/balloc.c Thu Sep 19 13:40:11 2002
+@@ -276,7 +276,8 @@
+ }
+ lock_super (sb);
+ es = sb->u.ext3_sb.s_es;
+- if (block < le32_to_cpu(es->s_first_data_block) ||
++ if (block < le32_to_cpu(es->s_first_data_block) ||
++ block + count < block ||
+ (block + count) > le32_to_cpu(es->s_blocks_count)) {
+ ext3_error (sb, "ext3_free_blocks",
+ "Freeing blocks not in datazone - "
+@@ -309,17 +310,6 @@
+ if (!gdp)
+ goto error_return;
+
+- if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) ||
+- in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) ||
+- in_range (block, le32_to_cpu(gdp->bg_inode_table),
+- sb->u.ext3_sb.s_itb_per_group) ||
+- in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table),
+- sb->u.ext3_sb.s_itb_per_group))
+- ext3_error (sb, "ext3_free_blocks",
+- "Freeing blocks in system zones - "
+- "Block = %lu, count = %lu",
+- block, count);
+-
+ /*
+ * We are about to start releasing blocks in the bitmap,
+ * so we need undo access.
+@@ -345,14 +335,24 @@
+ if (err)
+ goto error_return;
+
+- for (i = 0; i < count; i++) {
++ for (i = 0; i < count; i++, block++) {
++ if (block == le32_to_cpu(gdp->bg_block_bitmap) ||
++ block == le32_to_cpu(gdp->bg_inode_bitmap) ||
++ in_range(block, le32_to_cpu(gdp->bg_inode_table),
++ sb->u.ext2_sb.s_itb_per_group)) {
++ ext3_error(sb, __FUNCTION__,
++ "Freeing block in system zone - block = %lu",
++ block);
++ continue;
++ }
++
+ /*
+ * An HJ special. This is expensive...
+ */
+ #ifdef CONFIG_JBD_DEBUG
+ {
+ struct buffer_head *debug_bh;
+- debug_bh = sb_get_hash_table(sb, block + i);
++ debug_bh = sb_get_hash_table(sb, block);
+ if (debug_bh) {
+ BUFFER_TRACE(debug_bh, "Deleted!");
+ if (!bh2jh(bitmap_bh)->b_committed_data)
+@@ -365,9 +365,8 @@
+ #endif
+ BUFFER_TRACE(bitmap_bh, "clear bit");
+ if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) {
+- ext3_error (sb, __FUNCTION__,
+- "bit already cleared for block %lu",
+- block + i);
++ ext3_error(sb, __FUNCTION__,
++ "bit already cleared for block %lu", block);
+ BUFFER_TRACE(bitmap_bh, "bit already cleared");
+ } else {
+ dquot_freed_blocks++;
+@@ -415,7 +417,6 @@
+ if (!err) err = ret;
+
+ if (overflow && !err) {
+- block += count;
+ count = overflow;
+ goto do_more;
+ }
+@@ -575,6 +577,7 @@
+
+ ext3_debug ("goal=%lu.\n", goal);
+
++repeat:
+ /*
+ * First, test whether the goal block is free.
+ */
+@@ -684,16 +686,21 @@
+ if (tmp == le32_to_cpu(gdp->bg_block_bitmap) ||
+ tmp == le32_to_cpu(gdp->bg_inode_bitmap) ||
+ in_range (tmp, le32_to_cpu(gdp->bg_inode_table),
+- sb->u.ext3_sb.s_itb_per_group))
+- ext3_error (sb, "ext3_new_block",
+- "Allocating block in system zone - "
+- "block = %u", tmp);
++ EXT3_SB(sb)->s_itb_per_group)) {
++ ext3_error(sb, __FUNCTION__,
++ "Allocating block in system zone - block = %u", tmp);
++
++ /* Note: This will potentially use up one of the handle's
++ * buffer credits. Normally we have way too many credits,
++ * so that is OK. In _very_ rare cases it might not be OK.
++ * We will trigger an assertion if we run out of credits,
++ * and we will have to do a full fsck of the filesystem -
++ * better than randomly corrupting filesystem metadata.
++ */
++ ext3_set_bit(j, bh->b_data);
++ goto repeat;
++ }
++
+
+ /* The superblock lock should guard against anybody else beating
+ * us to this point! */
+diff -ru lum-2.4.18-um30/fs/ext3/namei.c uml-2.4.18-12.5/fs/ext3/namei.c
+--- lum-2.4.18-um30/fs/ext3/namei.c Fri Nov 9 15:25:04 2001
++++ uml-2.4.18-12.5/fs/ext3/namei.c Thu Sep 19 13:40:11 2002
+@@ -354,8 +355,8 @@
+ */
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL;
+- ext3_mark_inode_dirty(handle, dir);
+ dir->i_version = ++event;
++ ext3_mark_inode_dirty(handle, dir);
+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
+ ext3_journal_dirty_metadata(handle, bh);
+ brelse(bh);
+@@ -464,8 +465,8 @@
+ inode->i_op = &ext3_file_inode_operations;
+ inode->i_fop = &ext3_file_operations;
+ inode->i_mapping->a_ops = &ext3_aops;
+- ext3_mark_inode_dirty(handle, inode);
+ err = ext3_add_nondir(handle, dentry, inode);
++ ext3_mark_inode_dirty(handle, inode);
+ }
+ ext3_journal_stop(handle, dir);
+ return err;
+@@ -489,8 +490,8 @@
+ err = PTR_ERR(inode);
+ if (!IS_ERR(inode)) {
+ init_special_inode(inode, mode, rdev);
+- ext3_mark_inode_dirty(handle, inode);
+ err = ext3_add_nondir(handle, dentry, inode);
++ ext3_mark_inode_dirty(handle, inode);
+ }
+ ext3_journal_stop(handle, dir);
+ return err;
+@@ -933,8 +934,8 @@
+ inode->i_size = l-1;
+ }
+ inode->u.ext3_i.i_disksize = inode->i_size;
+- ext3_mark_inode_dirty(handle, inode);
+ err = ext3_add_nondir(handle, dentry, inode);
++ ext3_mark_inode_dirty(handle, inode);
+ out_stop:
+ ext3_journal_stop(handle, dir);
+ return err;
+@@ -970,8 +971,8 @@
+ ext3_inc_count(handle, inode);
+ atomic_inc(&inode->i_count);
+
+- ext3_mark_inode_dirty(handle, inode);
+ err = ext3_add_nondir(handle, dentry, inode);
++ ext3_mark_inode_dirty(handle, inode);
+ ext3_journal_stop(handle, dir);
+ return err;
+ }