From: Andreas Dilger Date: Fri, 7 Feb 2020 01:09:41 +0000 (-0700) Subject: e2fsck: reduce memory usage for many directories X-Git-Tag: archive/debian/1.45.6-1~1^2~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=abeb84e31d69d97669da0785e5f53587438e76ed;hp=f7c8ea2067e811f17bd5c9706f7dbf65dadcfca1;p=thirdparty%2Fe2fsprogs.git e2fsck: reduce memory usage for many directories Pack struct dx_dir_info and dx_dirblock_info properly in memory, to avoid holes, and fields are not larger than necessary. This reduces the memory needed for each hashed dir, according to pahole(1) from: struct dx_dir_info { /* size: 32, cachelines: 1, members: 6 */ /* sum members: 26, holes: 1, sum holes: 2 */ /* padding: 4 */ }; struct dx_dirblock_info { /* size: 56, cachelines: 1, members: 9 */ /* sum members: 48, holes: 2, sum holes: 8 */ /* last cacheline: 56 bytes */ }; to 8 bytes less for each directory and directory block, and leaves space for future use if needed (e.g. larger numblocks): struct dx_dir_info { /* size: 24, cachelines: 1, members: 6 */ /* sum members: 20, holes: 1, sum holes: 4 */ /* bit holes: 1, sum bit holes: 7 bits */ }; struct dx_dirblock_info { /* size: 48, cachelines: 1, members: 9 */ }; Signed-off-by: Andreas Dilger Lustre-bug-id: https://jira.whamcloud.com/browse/LU-13197 Signed-off-by: Theodore Ts'o --- diff --git a/e2fsck/dx_dirinfo.c b/e2fsck/dx_dirinfo.c index f0f6084dd..caca3e307 100644 --- a/e2fsck/dx_dirinfo.c +++ b/e2fsck/dx_dirinfo.c @@ -73,11 +73,10 @@ void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, struct ext2_inode *inode, dir->ino = ino; dir->numblocks = num_blocks; dir->hashversion = 0; - dir->casefolded_hash = inode->i_flags & EXT4_CASEFOLD_FL; + dir->casefolded_hash = !!(inode->i_flags & EXT4_CASEFOLD_FL); dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks * sizeof (struct dx_dirblock_info), "dx_block info array"); - } /* diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 5e7db42c2..feb605c7b 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -104,12 +104,12 @@ struct dir_info { * directories which contain a hash tree index. */ struct dx_dir_info { - ext2_ino_t ino; /* Inode number */ - int numblocks; /* number of blocks */ - int hashversion; - short depth; /* depth of tree */ - struct dx_dirblock_info *dx_block; /* Array of size numblocks */ - int casefolded_hash; + ext2_ino_t ino; /* Inode number */ + short depth; /* depth of tree (15 bits) */ + __u8 hashversion; + __u8 casefolded_hash:1; + blk_t numblocks; /* number of blocks in dir */ + struct dx_dirblock_info *dx_block; /* Array of size numblocks */ }; #define DX_DIRBLOCK_ROOT 1 @@ -120,8 +120,8 @@ struct dx_dir_info { struct dx_dirblock_info { int type; - blk64_t phys; int flags; + blk64_t phys; blk64_t parent; blk64_t previous; ext2_dirhash_t min_hash; diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index ce3f4ca1f..b691417e0 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -71,8 +71,8 @@ static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry2 *dir_blocks_info, char *buf, struct problem_context *pctx); static void clear_htree(e2fsck_t ctx, ext2_ino_t ino); -static int htree_depth(struct dx_dir_info *dx_dir, - struct dx_dirblock_info *dx_db); +static short htree_depth(struct dx_dir_info *dx_dir, + struct dx_dirblock_info *dx_db); static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b); struct check_dir_struct { @@ -132,7 +132,7 @@ void e2fsck_pass2(e2fsck_t ctx) struct dx_dirblock_info *dx_db; int b; ext2_ino_t i; - int depth; + short depth; problem_t code; int bad_dir; int (*check_dir_func)(ext2_filsys fs, @@ -311,10 +311,10 @@ cleanup: } #define MAX_DEPTH 32000 -static int htree_depth(struct dx_dir_info *dx_dir, - struct dx_dirblock_info *dx_db) +static short htree_depth(struct dx_dir_info *dx_dir, + struct dx_dirblock_info *dx_db) { - int depth = 0; + short depth = 0; while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) { dx_db = &dx_dir->dx_block[dx_db->parent];