ChangeLog, pass1b.c:
  pass1b.c (clone_file_block): Don't clear the dup_map flag if the block
  	also shares data with the fs metadata when the count drops to 1, since
  	the block should still be cloned, as fs metadata isn't included in the
  	count.
ChangeLog, pass3.c:
  pass3.c (adjust_inode_count): Fix bug where we didn't keep the
  	internal and external inode counts in sync when we decremented an
  	inode whose link count was already zero.  Now we skip incrementing or
  	decrementing both link counts if we would cause an overflow condition.
  	(expand_dir, expand_dir_proc): Change where we update the inode block
  	count and size files so that the block count field is updated
  	correctly when we create an indirect block.

diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index 44e7f47..a75e47d 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,4 +1,22 @@
-1999-07-18  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+1999-09-07    <tytso@rsts-11.mit.edu>
+
+	* pass3.c (adjust_inode_count): Fix bug where we didn't keep the
+		internal and external inode counts in sync when we
+		decremented an inode whose link count was already zero.
+		Now we skip incrementing or decrementing both link counts
+		if we would cause an overflow condition.
+		(expand_dir, expand_dir_proc): Change where we update the
+		inode block count and size files so that the block count
+		field is updated correctly when we create an indirect block.
+
+1999-08-02    <tytso@valinux.com>
+
+	* pass1b.c (clone_file_block): Don't clear the dup_map flag if
+		the block also shares data with the fs metadata when
+		the count drops to 1, since the block should still be
+		cloned, as fs metadata isn't included in the count.
+
+1999-07-18  Theodore Ts'o  <tytso@valinux.com>
 
 	* Release of E2fsprogs 1.15
 
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index df787e8..957a9ee 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -601,7 +601,9 @@
 				return BLOCK_ABORT;
 			}
 			p->num_bad--;
-			if (p->num_bad == 1)
+			if (p->num_bad == 1 &&
+			    !ext2fs_test_block_bitmap(ctx->block_illegal_map,
+						      *block_nr))
 				ext2fs_unmark_block_bitmap(ctx->block_dup_map,
 							   *block_nr);
 			*block_nr = new_block;
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 2e4bfe2..a336835 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -1,7 +1,7 @@
 /*
  * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
  *
- * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Theodore Ts'o.
  *
  * %Begin-Header%
  * This file may be redistributed under the terms of the GNU Public
@@ -538,16 +538,25 @@
 	       inode.i_links_count);
 #endif
 
-	inode.i_links_count += adj;
 	if (adj == 1) {
 		ext2fs_icount_increment(ctx->inode_count, ino, 0);
+		if (inode.i_links_count == (__u16) ~0)
+			return 0;
 		ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
-	} else {
+		inode.i_links_count++;
+	} else if (adj == -1) {
 		ext2fs_icount_decrement(ctx->inode_count, ino, 0);
+		if (inode.i_links_count == 0)
+			return 0;
 		ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
+		inode.i_links_count--;
+	} else {
+		/* Should never happen */
+		printf("Debug error in e2fsck adjust_inode_count, "
+		       "should never happen.\n");
+		exit(1);
 	}
 	
-
 	retval = ext2fs_write_inode(fs, ino, &inode);
 	if (retval)
 		return retval;
@@ -635,9 +644,10 @@
  */
 
 struct expand_dir_struct {
-	int	done;
-	errcode_t	err;
-	e2fsck_t	ctx;
+	int			done;
+	int			newblocks;
+	errcode_t		err;
+	e2fsck_t		ctx;
 };
 
 static int expand_dir_proc(ext2_filsys fs,
@@ -690,6 +700,8 @@
 	ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
 	ext2fs_mark_block_bitmap(fs->block_map, new_blk);
 	ext2fs_mark_bb_dirty(fs);
+	es->newblocks++;
+	
 	if (es->done)
 		return (BLOCK_CHANGED | BLOCK_ABORT);
 	else
@@ -711,13 +723,14 @@
 	 * them.
 	 */
 	e2fsck_read_bitmaps(ctx);
-	
+
 	retval = ext2fs_check_directory(fs, dir);
 	if (retval)
 		return retval;
 	
 	es.done = 0;
 	es.err = 0;
+	es.newblocks = 0;
 	es.ctx = ctx;
 	
 	retval = ext2fs_block_iterate(fs, dir, BLOCK_FLAG_APPEND,
@@ -736,7 +749,7 @@
 		return retval;
 	
 	inode.i_size += fs->blocksize;
-	inode.i_blocks += fs->blocksize / 512;
+	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
 
 	e2fsck_write_inode(ctx, dir, &inode, "expand_directory");