]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsck: When repacking directories, leave slack space for more efficiency
authorTheodore Ts'o <tytso@mit.edu>
Wed, 24 Dec 2008 00:10:43 +0000 (19:10 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 25 Dec 2008 22:59:36 +0000 (17:59 -0500)
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>
e2fsck/e2fsck.c
e2fsck/e2fsck.conf.5.in
e2fsck/e2fsck.h
e2fsck/rehash.c
tests/f_h_badnode/expect.1
tests/f_h_badnode/expect.2
tests/f_h_badroot/expect.1
tests/f_h_badroot/expect.2
tests/f_h_reindex/expect.1
tests/f_h_reindex/expect.2

index 9f862ffab58c944870f81beff36206f931e96322..26f7b5e5831ce043ce7cf974a6005f3cb153fe5e 100644 (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)
index c66a7698afc694411646b810399a4a9cb02a2a45..6638a394072cbc3f7dd4cd54e5d2fbea1e15ee16 100644 (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] 
index 9b9161558895ca88311537771bb9e1c4236f3e71..a159f2a9305b1754c183748627ef3e82fb38726e 100644 (file)
@@ -289,6 +289,7 @@ struct e2fsck_struct {
         */
        int process_inode_size;
        int inode_buffer_blocks;
+       unsigned int htree_slack_percentage;
 
        /*
         * ext3 journal support
index 6c24bdd439e1f8350e70081e383e46f828f4095f..51c2993031ef29e9442f658979caaeb8fdb3d207 100644 (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;
 
index 44d4a7c54550a589110205cce8c0d2b25198196c..5aa3cda11dfbe41c236d22f074569e56716d3804 100644 (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
index 8a219978b5115abde33e0fd1bfa7704c0e84a6d1..b9dadb739fb05bbe2eeac0865149ff377f171a58 100644 (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
index 261000da80fcd6af9fa33b6eecaf7824d229c738..037942dba27126f03b92e1e632a29e1f0ef807b8 100644 (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
index 28f1d2aa20530386b9b681f166ab0d3fa3ac3b43..d5772c1eee3119903dad48fbec83ea3909a0ae50 100644 (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
index 451189356ebaf6e4bd9a1098818fc23f08322113..a2324d765039c07538ec1d68436f6c9134874e3d 100755 (executable)
@@ -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
index 99de4cfc4cf5d6e44ba611f17401c6c5b0b7cd3c..7f785afa47bd27ec495141aca32c548cada6e262 100644 (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