2001-07-07 Theodore Tso <tytso@valinux.com>
+ * 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
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);
}
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,
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))
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;
}
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) {