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 */