--- /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;
+ }
+@@ -542,6 +543,7 @@
+ int i, j, k, tmp, alloctmp;
+ int bitmap_nr;
+ int fatal = 0, err;
++ int performed_allocation = 0;
+ struct super_block * sb;
+ struct ext3_group_desc * gdp;
+ struct ext3_super_block * es;
+@@ -575,6 +577,7 @@
+
+ ext3_debug ("goal=%lu.\n", goal);
+
++repeat:
+ /*
+ * First, test whether the goal block is free.
+ */
+@@ -644,8 +647,7 @@
+ }
+
+ /* No space left on the device */
+- unlock_super (sb);
+- return 0;
++ goto out;
+
+ search_back:
+ /*
+@@ -684,16 +686,28 @@
+ 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! */
+ J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data));
+ BUFFER_TRACE(bh, "setting bitmap bit");
+ ext3_set_bit(j, bh->b_data);
++ performed_allocation = 1;
+
+ #ifdef CONFIG_JBD_DEBUG
+ {
+@@ -815,6 +829,11 @@
+ ext3_std_error(sb, fatal);
+ }
+ unlock_super (sb);
++ /*
++ * Undo the block allocation
++ */
++ if (!performed_allocation)
++ DQUOT_FREE_BLOCK(inode, 1);
+ return 0;
+
+ }
+diff -ru lum-2.4.18-um30/fs/ext3/file.c uml-2.4.18-12.5/fs/ext3/file.c
+--- lum-2.4.18-um30/fs/ext3/file.c Thu Nov 15 14:37:55 2001
++++ uml-2.4.18-12.5/fs/ext3/file.c Thu Sep 19 13:40:11 2002
+@@ -61,19 +61,52 @@
+ static ssize_t
+ ext3_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+ {
++ int ret, err;
+ struct inode *inode = file->f_dentry->d_inode;
+
+- /*
+- * Nasty: if the file is subject to synchronous writes then we need
+- * to force generic_osync_inode() to call ext3_write_inode().
+- * We do that by marking the inode dirty. This adds much more
+- * computational expense than we need, but we're going to sync
+- * anyway.
+- */
+- if (IS_SYNC(inode) || (file->f_flags & O_SYNC))
+- mark_inode_dirty(inode);
++ ret = generic_file_write(file, buf, count, ppos);
+
+- return generic_file_write(file, buf, count, ppos);
++ /* Skip file flushing code if there was an error, or if nothing
++ was written. */
++ if (ret <= 0)
++ return ret;
++
++ /* If the inode is IS_SYNC, or is O_SYNC and we are doing
++ data-journaling, then we need to make sure that we force the
++ transaction to disk to keep all metadata uptodate
++ synchronously. */
++
++ if (file->f_flags & O_SYNC) {
++ /* If we are non-data-journaled, then the dirty data has
++ already been flushed to backing store by
++ generic_osync_inode, and the inode has been flushed
++ too if there have been any modifications other than
++ mere timestamp updates.
++
++ Open question --- do we care about flushing
++ timestamps too if the inode is IS_SYNC? */
++ if (!ext3_should_journal_data(inode))
++ return ret;
++
++ goto force_commit;
++ }
++
++ /* So we know that there has been no forced data flush. If the
++ inode is marked IS_SYNC, we need to force one ourselves. */
++ if (!IS_SYNC(inode))
++ return ret;
++
++ /* Open question #2 --- should we force data to disk here too?
++ If we don't, the only impact is that data=writeback
++ filesystems won't flush data to disk automatically on
++ IS_SYNC, only metadata (but historically, that is what ext2
++ has done.) */
++
++force_commit:
++ err = ext3_force_commit(inode->i_sb);
++ if (err)
++ return err;
++ return ret;
+ }
+
+ struct file_operations ext3_file_operations = {
+diff -ru lum-2.4.18-um30/fs/ext3/fsync.c uml-2.4.18-12.5/fs/ext3/fsync.c
+--- lum-2.4.18-um30/fs/ext3/fsync.c Tue Nov 20 22:34:13 2001
++++ uml-2.4.18-12.5/fs/ext3/fsync.c Thu Sep 19 13:40:11 2002
+@@ -62,7 +62,12 @@
+ * we'll end up waiting on them in commit.
+ */
+ ret = fsync_inode_buffers(inode);
+- ret |= fsync_inode_data_buffers(inode);
++
++ /* In writeback mode, we need to force out data buffers too. In
++ * the other modes, ext3_force_commit takes care of forcing out
++ * just the right data blocks. */
++ if (test_opt(inode->i_sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
++ ret |= fsync_inode_data_buffers(inode);
+
+ ext3_force_commit(inode->i_sb);
+
+diff -ru lum-2.4.18-um30/fs/ext3/ialloc.c uml-2.4.18-12.5/fs/ext3/ialloc.c
+--- lum-2.4.18-um30/fs/ext3/ialloc.c Mon Feb 25 12:38:08 2002
++++ uml-2.4.18-12.5/fs/ext3/ialloc.c Thu Sep 19 13:40:11 2002
+@@ -392,7 +392,7 @@
+
+ err = -ENOSPC;
+ if (!gdp)
+- goto fail;
++ goto out;
+
+ err = -EIO;
+ bitmap_nr = load_inode_bitmap (sb, i);
+@@ -523,9 +523,10 @@
+ return inode;
+
+ fail:
++ ext3_std_error(sb, err);
++out:
+ unlock_super(sb);
+ iput(inode);
+- ext3_std_error(sb, err);
+ return ERR_PTR(err);
+ }
+
+diff -ru lum-2.4.18-um30/fs/ext3/inode.c uml-2.4.18-12.5/fs/ext3/inode.c
+--- lum-2.4.18-um30/fs/ext3/inode.c Mon Feb 25 12:38:08 2002
++++ uml-2.4.18-12.5/fs/ext3/inode.c Thu Sep 19 13:40:11 2002
+@@ -412,6 +412,7 @@
+ return NULL;
+
+ changed:
++ brelse(bh);
+ *err = -EAGAIN;
+ goto no_block;
+ failure:
+@@ -581,8 +582,6 @@
+
+ parent = nr;
+ }
+- if (IS_SYNC(inode))
+- handle->h_sync = 1;
+ }
+ if (n == num)
+ return 0;
+@@ -950,11 +951,13 @@
+ }
+
+ static int walk_page_buffers( handle_t *handle,
++ struct inode *inode,
+ struct buffer_head *head,
+ unsigned from,
+ unsigned to,
+ int *partial,
+ int (*fn)( handle_t *handle,
++ struct inode *inode,
+ struct buffer_head *bh))
+ {
+ struct buffer_head *bh;
+@@ -972,7 +975,7 @@
+ *partial = 1;
+ continue;
+ }
+- err = (*fn)(handle, bh);
++ err = (*fn)(handle, inode, bh);
+ if (!ret)
+ ret = err;
+ }
+@@ -1005,7 +1008,7 @@
+ * write.
+ */
+
+-static int do_journal_get_write_access(handle_t *handle,
++static int do_journal_get_write_access(handle_t *handle, struct inode *inode,
+ struct buffer_head *bh)
+ {
+ return ext3_journal_get_write_access(handle, bh);
+@@ -1015,8 +1018,8 @@
+ unsigned from, unsigned to)
+ {
+ struct inode *inode = page->mapping->host;
+- handle_t *handle = ext3_journal_current_handle();
+ int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
++ handle_t *handle;
+
+ lock_kernel();
+ handle = ext3_journal_start(inode, needed_blocks);
+@@ -1031,7 +1034,7 @@
+ goto prepare_write_failed;
+
+ if (ext3_should_journal_data(inode)) {
+- ret = walk_page_buffers(handle, page->buffers,
++ ret = walk_page_buffers(handle, inode, page->buffers,
+ from, to, NULL, do_journal_get_write_access);
+ if (ret) {
+ /*
+@@ -1052,24 +1055,32 @@
+ return ret;
+ }
+
+-static int journal_dirty_sync_data(handle_t *handle, struct buffer_head *bh)
++static int journal_dirty_sync_data(handle_t *handle, struct inode *inode,
++ struct buffer_head *bh)
+ {
+- return ext3_journal_dirty_data(handle, bh, 0);
++ int ret = ext3_journal_dirty_data(handle, bh, 0);
++ if (bh->b_inode != inode)
++ buffer_insert_inode_data_queue(bh, inode);
++ return ret;
+ }
+
+ /*
+ * For ext3_writepage(). We also brelse() the buffer to account for
+ * the bget() which ext3_writepage() performs.
+ */
+-static int journal_dirty_async_data(handle_t *handle, struct buffer_head *bh)
++static int journal_dirty_async_data(handle_t *handle, struct inode *inode,
++ struct buffer_head *bh)
+ {
+ int ret = ext3_journal_dirty_data(handle, bh, 1);
++ if (bh->b_inode != inode)
++ buffer_insert_inode_data_queue(bh, inode);
+ __brelse(bh);
+ return ret;
+ }
+
+ /* For commit_write() in data=journal mode */
+-static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
++static int commit_write_fn(handle_t *handle, struct inode *inode,
++ struct buffer_head *bh)
+ {
+ set_bit(BH_Uptodate, &bh->b_state);
+ return ext3_journal_dirty_metadata(handle, bh);
+@@ -1104,7 +1115,7 @@
+ int partial = 0;
+ loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+
+- ret = walk_page_buffers(handle, page->buffers,
++ ret = walk_page_buffers(handle, inode, page->buffers,
+ from, to, &partial, commit_write_fn);
+ if (!partial)
+ SetPageUptodate(page);
+@@ -1114,7 +1125,7 @@
+ EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+ } else {
+ if (ext3_should_order_data(inode)) {
+- ret = walk_page_buffers(handle, page->buffers,
++ ret = walk_page_buffers(handle, inode, page->buffers,
+ from, to, NULL, journal_dirty_sync_data);
+ }
+ /* Be careful here if generic_commit_write becomes a
+@@ -1196,7 +1207,8 @@
+ return generic_block_bmap(mapping,block,ext3_get_block);
+ }
+
+-static int bget_one(handle_t *handle, struct buffer_head *bh)
++static int bget_one(handle_t *handle, struct inode *inode,
++ struct buffer_head *bh)
+ {
+ atomic_inc(&bh->b_count);
+ return 0;
+@@ -1295,7 +1307,7 @@
+ create_empty_buffers(page,
+ inode->i_dev, inode->i_sb->s_blocksize);
+ page_buffers = page->buffers;
+- walk_page_buffers(handle, page_buffers, 0,
++ walk_page_buffers(handle, inode, page_buffers, 0,
+ PAGE_CACHE_SIZE, NULL, bget_one);
+ }
+
+@@ -1313,7 +1325,7 @@
+
+ /* And attach them to the current transaction */
+ if (order_data) {
+- err = walk_page_buffers(handle, page_buffers,
++ err = walk_page_buffers(handle, inode, page_buffers,
+ 0, PAGE_CACHE_SIZE, NULL, journal_dirty_async_data);
+ if (!ret)
+ ret = err;
+@@ -1581,8 +1593,10 @@
+ }
+ ext3_mark_inode_dirty(handle, inode);
+ ext3_journal_test_restart(handle, inode);
+- BUFFER_TRACE(bh, "get_write_access");
+- ext3_journal_get_write_access(handle, bh);
++ if (bh) {
++ BUFFER_TRACE(bh, "retaking write access");
++ ext3_journal_get_write_access(handle, bh);
++ }
+ }
+
+ /*
+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;
+ }
+diff -ru lum-2.4.18-um30/fs/ext3/super.c uml-2.4.18-12.5/fs/ext3/super.c
+--- lum-2.4.18-um30/fs/ext3/super.c Fri Jul 12 17:59:37 2002
++++ uml-2.4.18-12.5/fs/ext3/super.c Thu Sep 19 13:40:11 2002
+@@ -1589,8 +1589,10 @@
+ journal_t *journal = EXT3_SB(sb)->s_journal;
+
+ /* Now we set up the journal barrier. */
++ unlock_super(sb);
+ journal_lock_updates(journal);
+ journal_flush(journal);
++ lock_super(sb);
+
+ /* Journal blocked and flushed, clear needs_recovery flag. */
+ EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
return -EIO;
/*
-@@ -275,8 +273,9 @@ void ext3_free_blocks (handle_t *handle,
+@@ -275,7 +273,7 @@ void ext3_free_blocks (handle_t *handle,
return;
}
lock_super (sb);
- es = sb->u.ext3_sb.s_es;
-- if (block < le32_to_cpu(es->s_first_data_block) ||
+ es = EXT3_SB(sb)->s_es;
-+ if (block < le32_to_cpu(es->s_first_data_block) ||
-+ block + count < 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 - "
-@@ -304,22 +303,11 @@ do_more:
+@@ -304,7 +302,7 @@ do_more:
if (bitmap_nr < 0)
goto error_return;
gdp = ext3_get_group_desc (sb, block_group, &gd_bh);
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.
-@@ -340,19 +328,29 @@ do_more:
+@@ -330,8 +328,8 @@ do_more:
if (err)
goto error_return;
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),
+@@ -341,7 +339,7 @@
+ 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_SB(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 +363,8 @@ do_more:
- #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++;
-@@ -410,12 +407,11 @@ do_more:
+ ext3_error(sb, __FUNCTION__,
+ "Freeing block in system zone - block = %lu",
+ block);
+@@ -410,8 +407,8 @@ do_more:
if (!err) err = ret;
/* And the superblock */
if (!err) err = ret;
if (overflow && !err) {
-- block += count;
- count = overflow;
- goto do_more;
- }
-@@ -564,17 +560,18 @@ int ext3_new_block (handle_t *handle, st
+@@ -564,12 +560,12 @@ int ext3_new_block (handle_t *handle, st
}
lock_super (sb);
!capable(CAP_SYS_RESOURCE)))
goto out;
- ext3_debug ("goal=%lu.\n", goal);
-
-+repeat:
- /*
- * First, test whether the goal block is free.
- */
@@ -598,7 +595,7 @@ int ext3_new_block (handle_t *handle, st
if (bitmap_nr < 0)
goto io_error;
if (fatal) goto out;
tmp = j + i * EXT3_BLOCKS_PER_GROUP(sb)
-@@ -684,10 +681,21 @@ got_block:
- 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! */
@@ -796,7 +804,7 @@ got_block:
if (!fatal) fatal = err;
i < EXT3_SB(inode->i_sb)->s_es->s_prealloc_dir_blocks;
i++) {
/*
-@@ -1015,8 +1018,8 @@ static int ext3_prepare_write(struct fil
- unsigned from, unsigned to)
- {
- struct inode *inode = page->mapping->host;
-- handle_t *handle = ext3_journal_current_handle();
- int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
-+ handle_t *handle;
-
- lock_kernel();
- handle = ext3_journal_start(inode, needed_blocks);
@@ -1131,8 +1134,8 @@ static int ext3_commit_write(struct file
kunmap(page);
}
}
- inode->u.ext3_i.i_disksize = inode->i_size;
+ EXT3_I(inode)->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:
--- ./fs/ext3/super.c.orig Fri Apr 12 10:27:49 2002
+++ ./fs/ext3/super.c Tue May 7 16:05:44 2002