Many files:
  pass4.c (e2fsck_pass4): If an inode is set in the inode_imagic_map
  	bitmap, don't check to see if it is disconnected from the inode tree
  	(because it almost certainly will be).  Free inode_imagic_map at the
  	end of pass 4.
  pass2.c (check_dir_block, check_filetype): If the FILETYPE feature is
  	set, check the directory entry's filetype information field, and
  	fix/set it if necessary.  (e2fsck_pass2): Free the inode_reg_map
  	bitmap at the end of pass 2.
  pass1.c (e2fsck_pass1, alloc_imagic_map): Allocate and fill in
  	information for inode_reg_map and inode_imagic_map, which indicates
  	which inodes are regular files and AFS inodes, respectively.
  	Since only the master superblock is written during a restart, force
  	that superblock to be used after a restart; otherwise changes to the
  	block group descriptors end up getting ignored.
  problem.c, problemP.h: If e2fsck is run -n, make def_yn variable be 0
  	for "no".  Add support for a new flag, PR_NO_NOMSG, which supresses
  	the problem message if e2fsck is run with the -n option.
  problem.c, problem.h (PR_2_SET_FILETYPE, PR_2_BAD_FILETYPE): Add new
  	problem codes.
  message.c (expand_dirent_expression): Add support for %dt which prints
  	the dirent type information.
  e2fsck.c (e2fsck_reset_context): Free new bitmaps (inode_reg_map and
  	inode_imagic_map).
  e2fsck.h (e2fsck_t): Add new inode_reg_map and inode_magic_map to the
  	context structure.
ChangeLog, nt_io.c:
  nt_io.c: New file which supports I/O under Windows NT.
ChangeLog, gen_uuid_nt.c:
  gen_uuid_nt.c: New file which creates a UUID under Windows NT.
Many files:
  Add support for non-Unix compiles

diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog
index 28960be..0fc1540 100644
--- a/e2fsck/ChangeLog
+++ b/e2fsck/ChangeLog
@@ -1,3 +1,43 @@
+1999-10-21    <tytso@valinux.com>
+
+	* pass4.c (e2fsck_pass4): If an inode is set in the
+		inode_imagic_map bitmap, don't check to see if it is
+		disconnected from the inode tree (because it almost
+		certainly will be).  Free inode_imagic_map at the end of
+		pass 4.
+
+	* pass2.c (check_dir_block, check_filetype): If the FILETYPE
+		feature is set, check the directory entry's filetype
+		information field, and fix/set it if necessary.
+		(e2fsck_pass2): Free the inode_reg_map bitmap at the end
+		of pass 2.
+
+	* pass1.c (e2fsck_pass1, alloc_imagic_map): Allocate and fill in
+		information for inode_reg_map and inode_imagic_map, which
+		indicates which inodes are regular files and AFS inodes,
+		respectively.
+		Since only the master superblock is written during a
+		restart, force that superblock to be used after a restart;
+		otherwise changes to the block group descriptors end up
+		getting ignored.
+
+	* problem.c, problemP.h: If e2fsck is run -n, make def_yn variable
+		be 0 for "no".  Add support for a new flag, PR_NO_NOMSG,
+		which supresses the problem message if e2fsck is run with
+		the -n option.
+
+	* problem.c, problem.h (PR_2_SET_FILETYPE, PR_2_BAD_FILETYPE): Add
+		new problem codes.
+
+	* message.c (expand_dirent_expression): Add support for %dt which
+		prints the dirent type information.
+
+	* e2fsck.c (e2fsck_reset_context): Free new bitmaps (inode_reg_map
+		and inode_imagic_map).
+
+	* e2fsck.h (e2fsck_t): Add new inode_reg_map and inode_magic_map
+		to the context structure.
+	
 1999-09-24    <tytso@valinux.com>
 
 	* unix.c (PRS), util.c (ask_yn): Add #ifdef's to make
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index 3cfca69..3028c87 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -50,6 +50,10 @@
 		ext2fs_free_inode_bitmap(ctx->inode_dir_map);
 		ctx->inode_dir_map = 0;
 	}
+	if (ctx->inode_reg_map) {
+		ext2fs_free_inode_bitmap(ctx->inode_reg_map);
+		ctx->inode_dir_map = 0;
+	}
 	if (ctx->block_found_map) {
 		ext2fs_free_block_bitmap(ctx->block_found_map);
 		ctx->block_found_map = 0;
@@ -75,6 +79,10 @@
 		ext2fs_free_inode_bitmap(ctx->inode_bad_map);
 		ctx->inode_bad_map = 0;
 	}
+	if (ctx->inode_imagic_map) {
+		ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
+		ctx->inode_imagic_map = 0;
+	}
 
 	/*
 	 * Clear the array of invalid meta-data flags
diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h
index 86b411c..83f0889 100644
--- a/e2fsck/e2fsck.h
+++ b/e2fsck/e2fsck.h
@@ -143,6 +143,8 @@
 	ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */
 	ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */
 	ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */
+	ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */
+	ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/
 
 	ext2fs_block_bitmap block_found_map; /* Blocks which are in use */
 	ext2fs_block_bitmap block_dup_map; /* Blks referenced more than once */
diff --git a/e2fsck/message.c b/e2fsck/message.c
index 8bb11df..a129f86 100644
--- a/e2fsck/message.c
+++ b/e2fsck/message.c
@@ -20,6 +20,7 @@
  * 	%dn	<dirent>->name		string
  * 	%dr	<dirent>->rec_len
  * 	%dl	<dirent>->name_len
+ * 	%dt	<dirent>->filetype
  * 	%D	<dir> 			inode number
  * 	%g	<group>			integer
  * 	%i	<ino>			inode number
@@ -301,6 +302,9 @@
 	case 'l':
 		printf("%u", dirent->name_len & 0xFF);
 		break;
+	case 't':
+		printf("%u", dirent->name_len >> 8);
+		break;
 	default:
 	no_dirent:
 		printf("%%D%c", ch);
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index cebc82c..c7475f9 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -19,8 +19,10 @@
  *
  * 	- A bitmap of which inodes are in use.		(inode_used_map)
  * 	- A bitmap of which inodes are directories.	(inode_dir_map)
+ * 	- A bitmap of which inodes are regular files.	(inode_reg_map)
  * 	- A bitmap of which inodes have bad fields.	(inode_bad_map)
  * 	- A bitmap of which inodes are in bad blocks.	(inode_bb_map)
+ * 	- A bitmap of which inodes are imagic inodes.	(inode_imagic_map)
  * 	- A bitmap of which blocks are in use.		(block_found_map)
  * 	- A bitmap of which blocks are in use by two inodes	(block_dup_map)
  * 	- The data blocks of the directory inodes.	(dir_map)
@@ -60,6 +62,7 @@
 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 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);
@@ -199,6 +202,15 @@
 		ctx->flags |= E2F_FLAG_ABORT;
 		return;
 	}
+	pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
+						    "regular file inode map",
+					      &ctx->inode_reg_map);
+	if (pctx.errcode) {
+		pctx.num = 6;
+		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
+		ctx->flags |= E2F_FLAG_ABORT;
+		return;
+	}
 	pctx.errcode = ext2fs_allocate_block_bitmap(fs, "in-use block map",
 					      &ctx->block_found_map);
 	if (pctx.errcode) {
@@ -405,14 +417,20 @@
 				alloc_bad_map(ctx);
 			ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
 		}
+		if (inode.i_flags & EXT2_IMAGIC_FL) {
+			if (!ctx->inode_imagic_map)
+				alloc_imagic_map(ctx);
+			ext2fs_mark_inode_bitmap(ctx->inode_imagic_map, ino);
+		}
 		
 		if (LINUX_S_ISDIR(inode.i_mode)) {
 			ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
 			e2fsck_add_dir_info(ctx, ino, 0);
 			ctx->fs_directory_count++;
-		} else if (LINUX_S_ISREG (inode.i_mode))
+		} else if (LINUX_S_ISREG (inode.i_mode)) {
+			ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
 			ctx->fs_regular_count++;
-		else if (LINUX_S_ISCHR (inode.i_mode) &&
+		} else if (LINUX_S_ISCHR (inode.i_mode) &&
 			 e2fsck_pass1_check_device_inode(&inode))
 			ctx->fs_chardev_count++;
 		else if (LINUX_S_ISBLK (inode.i_mode) &&
@@ -485,6 +503,13 @@
 		handle_fs_bad_blocks(ctx);
 
 	if (ctx->flags & E2F_FLAG_RESTART) {
+		/*
+		 * Only the master copy of the superblock and block
+		 * group descriptors are going to be written during a
+		 * restart, so set the superblock to be used to be the
+		 * master superblock.
+		 */
+		ctx->use_superblock = 0;
 		unwind_pass1(fs);
 		goto endit;
 	}
@@ -649,6 +674,26 @@
 }
 
 /*
+ * This procedure will allocate the inode imagic table
+ */
+static void alloc_imagic_map(e2fsck_t ctx)
+{
+	struct		problem_context pctx;
+	
+	clear_problem_context(&pctx);
+	pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
+					      "imagic inode map",
+					      &ctx->inode_imagic_map);
+	if (pctx.errcode) {
+		pctx.num = 5;
+		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
+		/* Should never get here */
+		ctx->flags |= E2F_FLAG_ABORT;
+		return;
+	}
+}
+
+/*
  * Marks a block as in use, setting the dup_map if it's been set
  * already.  Called by process_block and process_bad_block.
  *
@@ -729,6 +774,7 @@
 		inode->i_dtime = time(0);
 		e2fsck_write_inode(ctx, ino, inode, "check_blocks");
 		ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
+		ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
 		ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
 		/*
 		 * The inode was probably partially accounted for
@@ -752,6 +798,7 @@
 			inode->i_dtime = time(0);
 			e2fsck_write_inode(ctx, ino, inode, "check_blocks");
 			ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
+			ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
 			ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
 			ctx->fs_directory_count--;
 			pb.is_dir = 0;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index 37114e3..2eec914 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -38,11 +38,18 @@
  *
  * Pass 2 frees the following data structures
  * 	- The inode_bad_map bitmap
+ * 	- The inode_reg_map bitmap
  */
 
 #include "e2fsck.h"
 #include "problem.h"
 
+#ifdef NO_INLINE_FUNCS
+#define _INLINE_
+#else
+#define _INLINE_ inline
+#endif
+
 /*
  * Keeps track of how many times an inode is referenced.
  */
@@ -134,6 +141,10 @@
 		ext2fs_free_inode_bitmap(ctx->inode_bad_map);
 		ctx->inode_bad_map = 0;
 	}
+	if (ctx->inode_reg_map) {
+		ext2fs_free_inode_bitmap(ctx->inode_reg_map);
+		ctx->inode_reg_map = 0;
+	}
 #ifdef RESOURCE_TRACK
 	if (ctx->options & E2F_OPT_TIME2) {
 		e2fsck_clear_progbar(ctx);
@@ -268,6 +279,57 @@
 	return ret;
 }
 
+/*
+ * Check the directory filetype (if present)
+ */
+static _INLINE_ int check_filetype(e2fsck_t ctx,
+		      struct ext2_dir_entry *dirent,
+		      ino_t dir_ino, struct problem_context *pctx)
+{
+	int	filetype = dirent->name_len >> 8;
+	int	should_be = EXT2_FT_UNKNOWN;
+	struct ext2_inode	inode;
+
+	if (!(ctx->fs->super->s_feature_incompat &
+	      EXT2_FEATURE_INCOMPAT_FILETYPE))
+		return 0;
+
+	if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
+		should_be = EXT2_FT_DIR;
+	} else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
+					    dirent->inode)) {
+		should_be = EXT2_FT_REG_FILE;
+	} else if (ctx->inode_bad_map &&
+		   ext2fs_test_inode_bitmap(ctx->inode_bad_map,
+					    dirent->inode))
+		should_be = 0;
+	else {
+		e2fsck_read_inode(ctx, dirent->inode, &inode,
+				  "check_filetype");
+		if (LINUX_S_ISCHR (inode.i_mode))
+			should_be = EXT2_FT_CHRDEV;
+		else if (LINUX_S_ISBLK (inode.i_mode))
+			should_be = EXT2_FT_BLKDEV;
+		else if (LINUX_S_ISLNK (inode.i_mode))
+			should_be = EXT2_FT_SYMLINK;
+		else if (LINUX_S_ISFIFO (inode.i_mode))
+			should_be = EXT2_FT_FIFO;
+		else if (LINUX_S_ISSOCK (inode.i_mode))
+			should_be = EXT2_FT_SOCK;
+	}
+	if (filetype == should_be)
+		return 0;
+	pctx->num = should_be;
+
+	if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
+			pctx) == 0)
+		return 0;
+			
+	dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
+	return 1;
+}
+
+
 static int check_dir_block(ext2_filsys fs,
 			   struct ext2_db_entry *db,
 			   void *priv_data)
@@ -465,6 +527,9 @@
 		if (check_name(ctx, dirent, ino, &cd->pctx))
 			dir_modified++;
 
+		if (check_filetype(ctx, dirent, ino, &cd->pctx))
+			dir_modified++;
+
 		/*
 		 * If this is a directory, then mark its parent in its
 		 * dir_info structure.  If the parent field is already
diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c
index 264b1c7..92721bd 100644
--- a/e2fsck/pass4.c
+++ b/e2fsck/pass4.c
@@ -10,6 +10,7 @@
  *
  * Pass 4 frees the following data structures:
  * 	- A bitmap of which inodes are in bad blocks.	(inode_bb_map)
+ * 	- A bitmap of which inodes are imagic inodes.	(inode_imagic_map)
  */
 
 #include "e2fsck.h"
@@ -117,6 +118,8 @@
 		    (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
 			continue;
 		if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
+		    (ctx->inode_imagic_map &&
+		     ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
 		    (ctx->inode_bb_map &&
 		     ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
 			continue;
@@ -151,6 +154,7 @@
 	ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
 	ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
 	ext2fs_free_inode_bitmap(ctx->inode_bb_map);
+	ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
 	ctx->inode_bb_map = 0;
 #ifdef RESOURCE_TRACK
 	if (ctx->options & E2F_OPT_TIME2) {
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index e7a0dc6..3a54926 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -693,6 +693,16 @@
 	  "@i %i (%Q) is an @I socket.\n",
 	  PROMPT_CLEAR, 0 },
 
+	/* Directory filetype not set */
+	{ PR_2_SET_FILETYPE,
+	  "Setting filetype for @E to %N.\n",
+	  PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
+
+	/* Directory filetype incorrect */
+	{ PR_2_BAD_FILETYPE,
+	  "@E has an incorrect filetype (was %dt, should be %N)\n",
+	  PROMPT_FIX, 0 },
+
 	/* Pass 3 errors */
 
 	/* Pass 3: Checking directory connectivity */
@@ -1038,7 +1048,9 @@
 		printf("Unhandled error code (%d)!\n", code);
 		return 0;
 	}
-	def_yn = (ptr->flags & PR_NO_DEFAULT) ? 0 : 1;
+	def_yn = 1;
+	if ((ptr->flags & PR_NO_DEFAULT) || (ctx->options & E2F_OPT_NO))
+		def_yn= 0;
 
 	/*
 	 * Do special latch processing.  This is where we ask the
@@ -1060,6 +1072,9 @@
 	if ((ptr->flags & PR_PREEN_NOMSG) &&
 	    (ctx->options & E2F_OPT_PREEN))
 		suppress++;
+	if ((ptr->flags & PR_NO_NOMSG) &&
+	    (ctx->options & E2F_OPT_NO))
+		suppress++;
 	if (!suppress) {
 		message = ptr->e2p_description;
 		if (ctx->options & E2F_OPT_PREEN) {
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 1e21440..ddbc717 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -411,6 +411,12 @@
 /* Illegal socket */
 #define PR_2_BAD_SOCKET		0x020026
 
+/* Directory filetype not set */
+#define PR_2_SET_FILETYPE	0x020027
+
+/* Directory filetype incorrect */
+#define PR_2_BAD_FILETYPE	0x020028
+
 /*
  * Pass 3 errors
  */
diff --git a/e2fsck/problemP.h b/e2fsck/problemP.h
index ceb7bd3..7c75fc6 100644
--- a/e2fsck/problemP.h
+++ b/e2fsck/problemP.h
@@ -33,4 +33,5 @@
 				/* ask another */
 #define PR_PREEN_NOMSG	0x0200	/* Don't print a message if we're preening */
 #define PR_NOCOLLATE	0x0400	/* Don't collate answers for this latch */
+#define PR_NO_NOMSG	0x0800	/* Don't print a message if e2fsck -n */