
From: Stone Wang <stone_wang@sohu.com>

We found strange blocks layout in our mail server, after careful study, we
got the reason and tried to fix it.

On the very fist attempt to allocate a block to the newly-initialised inode,
if we are trying to add a block at logical file offset "1" then
ext2_find_goal() will incorrectly assume that this was a next_alloc_block
cache hit (because we think the previously-allocated block was at offset
zero).

Net result: why trying to extend a freshly-opened one-block file we end up
deciding to place the second file block at disk block "1", rather than going
off and calling ext2_find_near().

Fix it by checking that we actually do have something valid cached in
next_alloc_goal.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/ext2/inode.c |    2 +-
 25-akpm/fs/ext3/inode.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff -puN fs/ext2/inode.c~ext2-ext3-block-allocator-startup-fix fs/ext2/inode.c
--- 25/fs/ext2/inode.c~ext2-ext3-block-allocator-startup-fix	2005-01-23 01:04:56.907446968 -0800
+++ 25-akpm/fs/ext2/inode.c	2005-01-23 01:08:59.941500176 -0800
@@ -354,7 +354,7 @@ static inline int ext2_find_goal(struct 
 {
 	struct ext2_inode_info *ei = EXT2_I(inode);
 	write_lock(&ei->i_meta_lock);
-	if (block == ei->i_next_alloc_block + 1) {
+	if ((block == ei->i_next_alloc_block + 1) && ei->i_next_alloc_goal) {
 		ei->i_next_alloc_block++;
 		ei->i_next_alloc_goal++;
 	} 
diff -puN fs/ext3/inode.c~ext2-ext3-block-allocator-startup-fix fs/ext3/inode.c
--- 25/fs/ext3/inode.c~ext2-ext3-block-allocator-startup-fix	2005-01-23 01:04:56.909446664 -0800
+++ 25-akpm/fs/ext3/inode.c	2005-01-23 01:04:56.916445600 -0800
@@ -464,7 +464,7 @@ static int ext3_find_goal(struct inode *
 {
 	struct ext3_inode_info *ei = EXT3_I(inode);
 	/* Writer: ->i_next_alloc* */
-	if (block == ei->i_next_alloc_block + 1) {
+	if ((block == ei->i_next_alloc_block + 1)&& ei->i_next_alloc_goal) {
 		ei->i_next_alloc_block++;
 		ei->i_next_alloc_goal++;
 	}
_
