From fdbdea09b87dbd8e39c23286f22653e7641599ae Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 2 Jun 2001 04:26:26 +0000 Subject: [PATCH] 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. --- e2fsck/ChangeLog | 13 +++++++++++++ e2fsck/pass1.c | 50 +++++++++++++++++++++++++----------------------- e2fsck/pass2.c | 24 +++++++++++------------ e2fsck/problem.c | 5 +++++ e2fsck/problem.h | 3 +++ 5 files changed, 59 insertions(+), 36 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index f7830adf..6cec171e 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,16 @@ +2001-06-02 Theodore Tso + + * 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 * problem.c, problem.h: Change PR_0_JOURNAL_UNSUPP_INCOMPAT and diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 62aa08e2..f3ab6675 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -60,9 +60,9 @@ static int process_bad_block(ext2_filsys fs, blk_t *block_nr, 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 @@ static void check_size(e2fsck_t ctx, struct problem_context *pctx) 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 @@ void e2fsck_pass1(e2fsck_t ctx) 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 @@ void e2fsck_pass1(e2fsck_t ctx) } 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 @@ void e2fsck_pass1(e2fsck_t ctx) 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 @@ static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b) } /* - * 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 ca412726..13b398e1 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -680,22 +680,22 @@ extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, !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 fef814cf..a101821f 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -871,6 +871,11 @@ static const struct e2fsck_problem problem_table[] = { 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 b0b6d78f..5df40ef6 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -517,6 +517,9 @@ struct problem_context { /* 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 */