mirror of
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
synced 2024-11-27 20:14:46 +08:00
e2fsck: eliminate per-block cluster alignment check
scan_extent_node() did cluster alignment check for every block in an extent. This is unnecessary and significantly slows down the runtime when hugefile is used with bigalloc. Do cluster alignment check once for each extent. Google-Bug-Id: 36886699 Signed-off-by: Tahsin Erdogan <tahsin@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
parent
ed1e950f84
commit
d5d981a369
@ -648,4 +648,7 @@ unsigned long long get_memory_size(void);
|
||||
extern void e2fsck_clear_progbar(e2fsck_t ctx);
|
||||
extern int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
|
||||
float percent, unsigned int dpynum);
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
#endif /* _E2FSCK_H */
|
||||
|
121
e2fsck/pass1.c
121
e2fsck/pass1.c
@ -2155,14 +2155,20 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When cluster size is greater than one block, it is caller's responsibility
|
||||
* to make sure block parameter starts at a cluster boundary.
|
||||
*/
|
||||
static _INLINE_ void mark_blocks_used(e2fsck_t ctx, blk64_t block,
|
||||
unsigned int num)
|
||||
{
|
||||
if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num))
|
||||
ext2fs_mark_block_bitmap_range2(ctx->block_found_map, block, num);
|
||||
else
|
||||
while (num--)
|
||||
mark_block_used(ctx, block++);
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < num; i += EXT2FS_CLUSTER_RATIO(ctx->fs))
|
||||
mark_block_used(ctx, block + i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2562,8 +2568,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
|
||||
{
|
||||
struct ext2fs_extent extent;
|
||||
blk64_t blk, last_lblk;
|
||||
e2_blkcnt_t blockcnt;
|
||||
unsigned int i;
|
||||
unsigned int i, n;
|
||||
int is_dir, is_leaf;
|
||||
problem_t problem;
|
||||
struct ext2_extent_info info;
|
||||
@ -2828,50 +2833,29 @@ report_problem:
|
||||
}
|
||||
}
|
||||
alloc_later:
|
||||
while (is_dir && (++pb->last_db_block <
|
||||
(e2_blkcnt_t) extent.e_lblk)) {
|
||||
pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
|
||||
pb->ino, 0,
|
||||
pb->last_db_block);
|
||||
if (pctx->errcode) {
|
||||
pctx->blk = 0;
|
||||
pctx->num = pb->last_db_block;
|
||||
goto failed_add_dir_block;
|
||||
}
|
||||
}
|
||||
if (!ctx->fs->cluster_ratio_bits) {
|
||||
mark_blocks_used(ctx, extent.e_pblk, extent.e_len);
|
||||
pb->num_blocks += extent.e_len;
|
||||
}
|
||||
for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
|
||||
i < extent.e_len;
|
||||
blk++, blockcnt++, i++) {
|
||||
if (ctx->fs->cluster_ratio_bits &&
|
||||
!(pb->previous_block &&
|
||||
(EXT2FS_B2C(ctx->fs, blk) ==
|
||||
EXT2FS_B2C(ctx->fs, pb->previous_block)) &&
|
||||
(blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
|
||||
((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
|
||||
mark_block_used(ctx, blk);
|
||||
pb->num_blocks++;
|
||||
}
|
||||
if (has_unaligned_cluster_map(ctx, pb->previous_block,
|
||||
pb->last_block, blk,
|
||||
blockcnt)) {
|
||||
pctx->blk = blockcnt;
|
||||
pctx->blk2 = blk;
|
||||
fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
|
||||
mark_block_used(ctx, blk);
|
||||
mark_block_used(ctx, blk);
|
||||
}
|
||||
pb->last_block = blockcnt;
|
||||
pb->previous_block = blk;
|
||||
|
||||
if (is_dir) {
|
||||
pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
|
||||
if (is_dir) {
|
||||
while (++pb->last_db_block <
|
||||
(e2_blkcnt_t) extent.e_lblk) {
|
||||
pctx->errcode = ext2fs_add_dir_block2(
|
||||
ctx->fs->dblist,
|
||||
pb->ino, 0,
|
||||
pb->last_db_block);
|
||||
if (pctx->errcode) {
|
||||
pctx->blk = blk;
|
||||
pctx->num = blockcnt;
|
||||
pctx->blk = 0;
|
||||
pctx->num = pb->last_db_block;
|
||||
goto failed_add_dir_block;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < extent.e_len; i++) {
|
||||
pctx->errcode = ext2fs_add_dir_block2(
|
||||
ctx->fs->dblist,
|
||||
pctx->ino,
|
||||
extent.e_pblk + i,
|
||||
extent.e_lblk + i);
|
||||
if (pctx->errcode) {
|
||||
pctx->blk = extent.e_pblk + i;
|
||||
pctx->num = extent.e_lblk + i;
|
||||
failed_add_dir_block:
|
||||
fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
|
||||
/* Should never get here */
|
||||
@ -2879,9 +2863,46 @@ alloc_later:
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (extent.e_len > 0)
|
||||
pb->last_db_block = extent.e_lblk + extent.e_len - 1;
|
||||
}
|
||||
if (is_dir && extent.e_len > 0)
|
||||
pb->last_db_block = blockcnt - 1;
|
||||
if (has_unaligned_cluster_map(ctx, pb->previous_block,
|
||||
pb->last_block,
|
||||
extent.e_pblk,
|
||||
extent.e_lblk)) {
|
||||
for (i = 0; i < extent.e_len; i++) {
|
||||
pctx->blk = extent.e_lblk + i;
|
||||
pctx->blk2 = extent.e_pblk + i;
|
||||
fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
|
||||
mark_block_used(ctx, extent.e_pblk + i);
|
||||
mark_block_used(ctx, extent.e_pblk + i);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether first cluster got marked in previous iteration.
|
||||
*/
|
||||
if (ctx->fs->cluster_ratio_bits &&
|
||||
pb->previous_block &&
|
||||
(EXT2FS_B2C(ctx->fs, extent.e_pblk) ==
|
||||
EXT2FS_B2C(ctx->fs, pb->previous_block)))
|
||||
/* Set blk to the beginning of next cluster. */
|
||||
blk = EXT2FS_C2B(
|
||||
ctx->fs,
|
||||
EXT2FS_B2C(ctx->fs, extent.e_pblk) + 1);
|
||||
else
|
||||
/* Set blk to the beginning of current cluster. */
|
||||
blk = EXT2FS_C2B(ctx->fs,
|
||||
EXT2FS_B2C(ctx->fs, extent.e_pblk));
|
||||
|
||||
if (blk < extent.e_pblk + extent.e_len) {
|
||||
mark_blocks_used(ctx, blk,
|
||||
extent.e_pblk + extent.e_len - blk);
|
||||
n = DIV_ROUND_UP(extent.e_pblk + extent.e_len - blk,
|
||||
EXT2FS_CLUSTER_RATIO(ctx->fs));
|
||||
pb->num_blocks += n;
|
||||
}
|
||||
pb->last_block = extent.e_lblk + extent.e_len - 1;
|
||||
pb->previous_block = extent.e_pblk + extent.e_len - 1;
|
||||
start_block = pb->last_block = last_lblk;
|
||||
if (is_leaf && !is_dir &&
|
||||
|
@ -21,8 +21,6 @@
|
||||
#include "e2fsck.h"
|
||||
#include "problem.h"
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
static void check_block_bitmaps(e2fsck_t ctx);
|
||||
static void check_inode_bitmaps(e2fsck_t ctx);
|
||||
static void check_inode_end(e2fsck_t ctx);
|
||||
|
@ -13,8 +13,6 @@ Inode 17 logical block 0 (physical block 1186) violates cluster allocation rules
|
||||
Will fix in pass 1B.
|
||||
Inode 17 logical block 2 (physical block 1184) violates cluster allocation rules.
|
||||
Will fix in pass 1B.
|
||||
Inode 17, i_blocks is 32, should be 64. Fix? yes
|
||||
|
||||
Inode 18 logical block 3 (physical block 1201) violates cluster allocation rules.
|
||||
Will fix in pass 1B.
|
||||
Inode 18, i_blocks is 32, should be 64. Fix? yes
|
||||
@ -86,8 +84,6 @@ Inode 12, i_blocks is 64, should be 32. Fix? yes
|
||||
|
||||
Inode 16, i_blocks is 64, should be 32. Fix? yes
|
||||
|
||||
Inode 17, i_blocks is 64, should be 32. Fix? yes
|
||||
|
||||
Inode 18, i_blocks is 64, should be 32. Fix? yes
|
||||
|
||||
Pass 2: Checking directory structure
|
||||
|
Loading…
Reference in New Issue
Block a user