From 7b63fff9b6c4a0ca3b80740f01f5bf0583b42aa9 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 7 Jul 2001 23:01:31 -0400 Subject: [PATCH] pass1b.c (pass1b, process_pass1b_block): Change the num_bad field calculation so that it only counts EA block entries as a single multiply claimed block (since once we clone the EA blocks for one inode, we fix the problem for all of the other inodes). Also, I moved the num_bad calculation from process_pass1b_block to the end of pass1b. This fixes a *significant* performance bug in pass1b which hit people who had to had a lot of multiply claimed blocks. (Can you say O(n**3) boys and girls? I knew you could... Fortunately, this case didn't happen that much in actual practice.) --- e2fsck/ChangeLog | 18 ++++++++++++++++++ e2fsck/pass1b.c | 35 +++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index dca31fc..55b14c7 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,5 +1,23 @@ 2001-07-07 Theodore Tso + * pass1b.c (pass1b, process_pass1b_block): Change the num_bad + field calculation so that it only counts EA block entries + as a single multiply claimed block (since once we clone + the EA blocks for one inode, we fix the problem for all of + the other inodes). Also, I moved the num_bad calculation + from process_pass1b_block to the end of pass1b. This + fixes a *significant* performance bug in pass1b which hit + people who had to had a lot of multiply claimed blocks. + (Can you say O(n**3) boys and girls? I knew you could... + Fortunately, this case didn't happen that much in actual + practice.) + + * pass1.c (e2fsck_pass1): Defer inodes which have an extended + attribute block for later processing to avoid extra seeks + across the disk. + (process_inode_cmp): If there is no indirect block, sort + by the extended attribute (i_file_acl) block. + * pass1b.c (clone_file_block): Fix bugs when cloning extended attribute blocks. Moved free of block_buf to after the code which clones the extattr block, and fixed logic for diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index a67d9fb..e156433 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -172,8 +172,10 @@ static void pass1b(e2fsck_t ctx, char *block_buf) ext2_inode_scan scan; struct process_block_struct pb; struct dup_inode *dp; + struct dup_block *q, *r; struct problem_context pctx; - + int i, ea_flag; + clear_problem_context(&pctx); fix_problem(ctx, PR_1B_PASS_HEADER, &pctx); @@ -236,6 +238,21 @@ static void pass1b(e2fsck_t ctx, char *block_buf) } ext2fs_close_inode_scan(scan); e2fsck_use_inode_shortcuts(ctx, 0); + /* + * Set the num_bad field + */ + for (q = dup_blk; q; q = q->next_block) { + i = 0; + ea_flag = 0; + for (r = q; r; r = r->next_inode) { + if (r->flags & FLAG_EXTATTR) { + if (ea_flag++) + continue; + } + i++; + } + q->num_bad = i; + } } static int process_pass1b_block(ext2_filsys fs, @@ -246,8 +263,7 @@ static int process_pass1b_block(ext2_filsys fs, void *priv_data) { struct process_block_struct *p; - struct dup_block *dp, *q, *r; - int i; + struct dup_block *dp, *q; e2fsck_t ctx; if (HOLE_BLKADDR(*block_nr)) @@ -286,15 +302,6 @@ static int process_pass1b_block(ext2_filsys fs, dup_blk = dp; } } - /* - * Set the num_bad field - */ - for (q = dup_blk; q; q = q->next_block) { - i = 0; - for (r = q; r; r = r->next_inode) - i++; - q->num_bad = i; - } return 0; } @@ -616,6 +623,10 @@ static int clone_file_block(ext2_filsys fs, return BLOCK_ABORT; } } +#if 0 + printf("Cloning block %u to %u\n", *block_nr, + new_block); +#endif retval = io_channel_read_blk(fs->io, *block_nr, 1, cs->buf); if (retval) { -- 1.8.3.1