ChangeLog, pass1.c, pass2.c, problem.c, problem.h:
  pass1.c (mark_inode_bad): Replace alloc_bad_map with a function which
  	sets the bit in the bad inode bitmap.
  	(e2fsck_pass1): Check for fast symlinks with an invalid size, and set
  	the bad inode map in that case.
  pass2.c (e2fsck_process_bad_inode): Check for fast symlinks with an
  	invalid size and prompt the user if the inode should be cleared.
  problem.h, problem.c (PR_2_SYMLINK_SIZE): Added new problem code.

diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index f7830ad..6cec171 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,16 @@
+2001-06-02  Theodore Tso  <tytso@valinux.com>
+
+	* pass1.c (mark_inode_bad): Replace alloc_bad_map with a function
+		which sets the bit in the bad inode bitmap.
+		(e2fsck_pass1): Check for fast symlinks with an invalid
+		size, and set the bad inode map in that case.
+
+	* pass2.c (e2fsck_process_bad_inode): Check for fast symlinks with
+		an invalid size and prompt the user if the inode should be
+		cleared.
+
+	* problem.h, problem.c (PR_2_SYMLINK_SIZE): Added new problem code.
+
 2001-06-01  Theodore Tso  <tytso@valinux.com>
 
 	* problem.c, problem.h: Change PR_0_JOURNAL_UNSUPP_INCOMPAT and
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 62aa08e..f3ab667 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -60,9 +60,9 @@
 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 			 char *block_buf);
 static void mark_table_blocks(e2fsck_t ctx);
-static void alloc_bad_map(e2fsck_t ctx);
 static void alloc_bb_map(e2fsck_t ctx);
 static void alloc_imagic_map(e2fsck_t ctx);
+static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
 static void handle_fs_bad_blocks(e2fsck_t ctx);
 static void process_inodes(e2fsck_t ctx, char *block_buf);
 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
@@ -170,13 +170,14 @@
 	     LINUX_S_ISCHR(inode->i_mode) ||
 	     LINUX_S_ISFIFO(inode->i_mode) ||
 	     LINUX_S_ISSOCK(inode->i_mode)) && 
-	    !inode->i_size)
+	    !inode->i_size || !inode->i_size_high)
 		return;
 	
 	if(!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
 		return;
 	
 	inode->i_size = 0;
+	inode->i_size_high = 0;
 	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
 }
 	
@@ -520,11 +521,8 @@
 		
 		if (inode.i_faddr || frag || fsize
 		    || inode.i_file_acl ||
-		    (LINUX_S_ISDIR(inode.i_mode) && inode.i_dir_acl)) {
-			if (!ctx->inode_bad_map)
-				alloc_bad_map(ctx);
-			ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
-		}
+		    (LINUX_S_ISDIR(inode.i_mode) && inode.i_dir_acl))
+			mark_inode_bad(ctx, ino);
 		if (inode.i_flags & EXT2_IMAGIC_FL) {
 			if (imagic_fs) {
 				if (!ctx->inode_imagic_map)
@@ -560,6 +558,9 @@
 		} else if (LINUX_S_ISLNK (inode.i_mode)) {
 			ctx->fs_symlinks_count++;
 			if (!inode.i_blocks) {
+				if (inode.i_size_high ||
+				    (inode.i_size > EXT2_N_BLOCKS*4))
+					mark_inode_bad(ctx, ino);
 				ctx->fs_fast_symlinks_count++;
 				goto next;
 			}
@@ -574,11 +575,8 @@
 			check_immutable(ctx, &pctx);
 			check_size(ctx, &pctx);
 			ctx->fs_sockets_count++;
-		} else {
-			if (!ctx->inode_bad_map)
-				alloc_bad_map(ctx);
-			ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
-		}
+		} else
+			mark_inode_bad(ctx, ino);
 		if (inode.i_block[EXT2_IND_BLOCK])
 			ctx->fs_ind_count++;
 		if (inode.i_block[EXT2_DIND_BLOCK])
@@ -764,25 +762,29 @@
 }
 
 /*
- * This procedure will allocate the inode bad map table
+ * Mark an inode as being bad in some what
  */
-static void alloc_bad_map(e2fsck_t ctx)
+static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
 {
 	struct		problem_context pctx;
+
+	if (!ctx->inode_bad_map) {
+		clear_problem_context(&pctx);
 	
-	clear_problem_context(&pctx);
-	
-	pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, _("bad inode map"),
-					      &ctx->inode_bad_map);
-	if (pctx.errcode) {
-		pctx.num = 3;
-		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
-		/* Should never get here */
-		ctx->flags |= E2F_FLAG_ABORT;
-		return;
+		pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
+			    _("bad inode map"), &ctx->inode_bad_map);
+		if (pctx.errcode) {
+			pctx.num = 3;
+			fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
+			/* Should never get here */
+			ctx->flags |= E2F_FLAG_ABORT;
+			return;
+		}
 	}
+	ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
 }
 
+
 /*
  * This procedure will allocate the inode "bb" (badblock) map table
  */
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index ca41272..13b398e 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -680,22 +680,22 @@
 	    !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
 	    !(LINUX_S_ISSOCK(inode.i_mode)))
 		problem = PR_2_BAD_MODE;
-
-	if (LINUX_S_ISCHR(inode.i_mode)
-	    && !e2fsck_pass1_check_device_inode(&inode))
+	else if (LINUX_S_ISCHR(inode.i_mode)
+		 && !e2fsck_pass1_check_device_inode(&inode))
 		problem = PR_2_BAD_CHAR_DEV;
-		
-	if (LINUX_S_ISBLK(inode.i_mode)
-	    && !e2fsck_pass1_check_device_inode(&inode))
+	else if (LINUX_S_ISBLK(inode.i_mode)
+		 && !e2fsck_pass1_check_device_inode(&inode))
 		problem = PR_2_BAD_BLOCK_DEV;
-
-	if (LINUX_S_ISFIFO(inode.i_mode)
-	    && !e2fsck_pass1_check_device_inode(&inode))
+	else if (LINUX_S_ISFIFO(inode.i_mode)
+		 && !e2fsck_pass1_check_device_inode(&inode))
 		problem = PR_2_BAD_FIFO;
-		
-	if (LINUX_S_ISSOCK(inode.i_mode)
-	    && !e2fsck_pass1_check_device_inode(&inode))
+	else if (LINUX_S_ISSOCK(inode.i_mode)
+		 && !e2fsck_pass1_check_device_inode(&inode))
 		problem = PR_2_BAD_SOCKET;
+	else if (LINUX_S_ISLNK(inode.i_mode)
+		 && (inode.i_size_high ||
+		     (inode.i_size > EXT2_N_BLOCKS*4)))
+		problem = PR_2_SYMLINK_SIZE;
 
 	if (problem) {
 		if (fix_problem(ctx, problem, &pctx)) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index fef814c..a101821 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -871,6 +871,11 @@
 	  N_("@E has a zero-length name\n"),
 	  PROMPT_CLEAR, 0 },
 
+	/* Invalid fast symlink size */
+	{ PR_2_SYMLINK_SIZE,
+	  N_("@i %i (%Q) is a fast symlink with an invalid size (%Is)\n"),
+	  PROMPT_CLEAR, 0 },
+
 	/* Pass 3 errors */
 
 	/* Pass 3: Checking directory connectivity */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index b0b6d78..5df40ef 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -517,6 +517,9 @@
 /* Directory filename can't be zero-length  */
 #define PR_2_NULL_NAME		0x020030
 
+/* Invalid fast symlink size */
+#define PR_2_SYMLINK_SIZE	0x020031
+
 /*
  * Pass 3 errors
  */