e2fsck: When repacking directories, leave slack space for more efficiency

If the directory is packed with no slack space, as soon as any new
directory entries are added, leaf nodes end up getting split and
directory ends up getting very inefficient.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
bitmap-optimize
Theodore Ts'o 2008-12-23 19:10:43 -05:00
parent d5a74ff10b
commit 7dca4c88f1
10 changed files with 42 additions and 14 deletions

View File

@ -32,6 +32,7 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret)
context->process_inode_size = 256;
context->ext_attr_ver = 2;
context->blocks_per_page = 1;
context->htree_slack_percentage = 255;
time_env = getenv("E2FSCK_TIME");
if (time_env)

View File

@ -100,6 +100,13 @@ buggy distributions do not correct this before running e2fsck. If this
option is set to a boolean value of true, we attempt to work around this
situation by allowing the superblock last write time, last mount time,
and last check time to be in the future by up to 24 hours.
.TP
.I clear_test_fs_flag
This boolean relation controls whether or not
.BR e2fsck (8)
will offer to clear
the test_fs flag if the ext4 filesystem is available on the system. It
defaults to true.
.TP
.I defer_check_on_battery
This boolean relation controls whether or not the interval between
@ -107,10 +114,15 @@ filesystem checks (either based on time or number of mounts) should
be doubled if the system is running on battery. It defaults to
true.
.TP
.I clear_test_fs_flag
This boolean relation controls whether or not e2fsck will offer to clear
the test_fs flag if the ext4 filesystem is available on the system. It
defaults to true.
.I indexed_dir_slack_percentage
When
.BR e2fsck (8)
repacks a indexed directory, reserve the specified percentage of
empty space in each leaf nodes so that a few new entries can
be added to the directory without splitting leaf nodes, so that
the average fill ratio of directories can be maintained at a
higher, more efficient level. This relation defaults to 20
percent.
.SH THE [problems] STANZA
Each tag in the
.I [problems]

View File

@ -289,6 +289,7 @@ struct e2fsck_struct {
*/
int process_inode_size;
int inode_buffer_blocks;
unsigned int htree_slack_percentage;
/*
* ext3 journal support

View File

@ -397,17 +397,27 @@ static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
}
static errcode_t copy_dir_entries(ext2_filsys fs,
static errcode_t copy_dir_entries(e2fsck_t ctx,
struct fill_dir_struct *fd,
struct out_dir *outdir)
{
ext2_filsys fs = ctx->fs;
errcode_t retval;
char *block_start;
struct hash_entry *ent;
struct ext2_dir_entry *dirent;
int i, rec_len, left;
ext2_dirhash_t prev_hash;
int offset;
int offset, slack;
if (ctx->htree_slack_percentage == 255) {
profile_get_uint(ctx->profile, "options",
"indexed_dir_slack_percentage",
0, 20,
&ctx->htree_slack_percentage);
if (ctx->htree_slack_percentage > 100)
ctx->htree_slack_percentage = 20;
}
outdir->max = 0;
retval = alloc_size_dir(fs, outdir,
@ -422,6 +432,10 @@ static errcode_t copy_dir_entries(ext2_filsys fs,
return retval;
dirent = (struct ext2_dir_entry *) block_start;
left = fs->blocksize;
slack = fd->compress ? 12 :
(fs->blocksize * ctx->htree_slack_percentage)/100;
if (slack < 12)
slack = 12;
for (i=0; i < fd->num_array; i++) {
ent = fd->harray + i;
if (ent->dir->inode == 0)
@ -449,7 +463,7 @@ static errcode_t copy_dir_entries(ext2_filsys fs,
memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
offset += rec_len;
left -= rec_len;
if (left < 12) {
if (left < slack) {
dirent->rec_len += left;
offset += left;
left = 0;
@ -750,7 +764,7 @@ resort:
* Copy the directory entries. In a htree directory these
* will become the leaf nodes.
*/
retval = copy_dir_entries(fs, &fd, &outdir);
retval = copy_dir_entries(ctx, &fd, &outdir);
if (retval)
goto errout;

View File

@ -14,5 +14,5 @@ Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 47730/100192 files (0.0% non-contiguous), 13377/31745 blocks
test_filesys: 47730/100192 files (0.0% non-contiguous), 13551/31745 blocks
Exit status is 1

View File

@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 47730/100192 files (0.0% non-contiguous), 13377/31745 blocks
test_filesys: 47730/100192 files (0.0% non-contiguous), 13551/31745 blocks
Exit status is 0

View File

@ -36,5 +36,5 @@ Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 1921/100080 files (0.0% non-contiguous), 13642/15361 blocks
test_filesys: 1921/100080 files (0.0% non-contiguous), 13646/15361 blocks
Exit status is 1

View File

@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 1921/100080 files (0.0% non-contiguous), 13642/15361 blocks
test_filesys: 1921/100080 files (0.0% non-contiguous), 13646/15361 blocks
Exit status is 0

View File

@ -954,5 +954,5 @@ Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 30514/32000 files (0.0% non-contiguous), 5558/8000 blocks
test_filesys: 30514/32000 files (0.0% non-contiguous), 5669/8000 blocks
Exit status is 1

View File

@ -3,5 +3,5 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
test_filesys: 30514/32000 files (0.0% non-contiguous), 5558/8000 blocks
test_filesys: 30514/32000 files (0.0% non-contiguous), 5669/8000 blocks
Exit status is 0