]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
e2fsprogs: add support for 3-level htree
authorArtem Blagodarenko <artem.blagodarenko@seagate.com>
Wed, 15 Feb 2017 17:43:15 +0000 (20:43 +0300)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 13 Apr 2017 15:53:35 +0000 (11:53 -0400)
The INCOMPAT_LARGEDIR feature allows larger directories to
be created, both with directory sizes over 2GB and and a
maximum htree depth of 3 instead of the current limit of 2.
These features are needed in order to exceed the currently
limit of approximately 10M entries in a single directory
for 4KB blocksize (~100k for 1KB).

debugfs, e2fsck, ext2fs, mke2fs and tune2fs support is
added.

Signed-off-by: Alexey Lyashkov <alexey.lyashkov@seagate.com>
Signed-off-by: Artem Blagodarenko <artem.blagodarenko@seagate.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
e2fsck/pass1.c
e2fsck/pass2.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2fs.h
misc/mke2fs.c
misc/tune2fs.c

index b2b84aacb91072e0095d8f914e857861ec1640c7..f60424d2d9da53fa2e466c211e2ce7763f271f1b 100644 (file)
@@ -1715,7 +1715,8 @@ void e2fsck_pass1(e2fsck_t ctx)
                }
 
                if (inode->i_faddr || frag || fsize ||
-                   (LINUX_S_ISDIR(inode->i_mode) && inode->i_size_high))
+                   (!ext2fs_has_feature_largedir(fs->super) &&
+                   (LINUX_S_ISDIR(inode->i_mode) && inode->i_size_high)))
                        mark_inode_bad(ctx, ino);
                if ((fs->super->s_creator_os != EXT2_OS_HURD) &&
                    !ext2fs_has_feature_64bit(fs->super) &&
@@ -2468,7 +2469,7 @@ static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
                return 1;
 
        pctx->num = root->indirect_levels;
-       if ((root->indirect_levels > 1) &&
+       if ((root->indirect_levels > ext2_dir_htree_level(fs)) &&
            fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
                return 1;
 
index ff24019f79bc245c834cc3be616e0de6d8c14db9..013b82e833612186e282f7a335b901cfc5dd1d7b 100644 (file)
@@ -1058,7 +1058,8 @@ inline_read_fail:
                        dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
                        if ((root->reserved_zero ||
                             root->info_length < 8 ||
-                            root->indirect_levels > 1) &&
+                            root->indirect_levels >=
+                            ext2_dir_htree_level(fs)) &&
                            fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
                                clear_htree(ctx, ino);
                                dx_dir->numblocks = 0;
@@ -1811,7 +1812,7 @@ int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
                } else
                        not_fixed++;
        }
-       if (inode.i_size_high &&
+       if (inode.i_size_high && !ext2fs_has_feature_largedir(fs->super) &&
            LINUX_S_ISDIR(inode.i_mode)) {
                if (fix_problem(ctx, PR_2_DIR_SIZE_HIGH_ZERO, &pctx)) {
                        inode.i_size_high = 0;
index 195e3668e9f414cac36df2bd57f58f76d308db0a..66b7058c3993900b0a70ac8550458ef1a6d1c082 100644 (file)
@@ -921,7 +921,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,                4, ENCRYPT)
 
 #define EXT2_FEATURE_COMPAT_SUPP       0
 #define EXT2_FEATURE_INCOMPAT_SUPP    (EXT2_FEATURE_INCOMPAT_FILETYPE| \
-                                      EXT4_FEATURE_INCOMPAT_MMP)
+                                      EXT4_FEATURE_INCOMPAT_MMP| \
+                                      EXT4_FEATURE_INCOMPAT_LARGEDIR)
 #define EXT2_FEATURE_RO_COMPAT_SUPP    (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
index 8ff49ca669a8bf670c5038c110f0abe95ed10739..f8ec9175d59f1337bfccee0be7ab012aabe33641 100644 (file)
@@ -588,7 +588,8 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT4_FEATURE_INCOMPAT_64BIT|\
                                         EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
                                         EXT4_FEATURE_INCOMPAT_ENCRYPT|\
-                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED)
+                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED|\
+                                        EXT4_FEATURE_INCOMPAT_LARGEDIR)
 
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
                                         EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
@@ -1927,6 +1928,18 @@ _INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
        return (blk_t) ext2fs_inode_data_blocks2(fs, inode);
 }
 
+/* htree levels for ext4 */
+#define EXT4_HTREE_LEVEL_COMPAT 2
+#define EXT4_HTREE_LEVEL       3
+
+static inline unsigned int ext2_dir_htree_level(ext2_filsys fs)
+{
+       if (ext2fs_has_feature_largedir(fs->super))
+               return EXT4_HTREE_LEVEL;
+
+       return EXT4_HTREE_LEVEL_COMPAT;
+}
+
 /*
  * This is an efficient, overflow safe way of calculating ceil((1.0 * a) / b)
  */
index 49c6e94d03de532ca2496c2145e224de8ac3ad56..b157006ae71f23fb4a1b7ece15c42431acefb08f 100644 (file)
@@ -1081,7 +1081,8 @@ static __u32 ok_features[3] = {
                EXT4_FEATURE_INCOMPAT_64BIT|
                EXT4_FEATURE_INCOMPAT_INLINE_DATA|
                EXT4_FEATURE_INCOMPAT_ENCRYPT |
-               EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+               EXT4_FEATURE_INCOMPAT_CSUM_SEED |
+               EXT4_FEATURE_INCOMPAT_LARGEDIR,
        /* R/O compat */
        EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
                EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
index f1bad60602045e77bae8e7a55be90dd7194267b0..68891be71f642143899dd8cc13e699f8fd7a9676 100644 (file)
@@ -156,7 +156,8 @@ static __u32 ok_features[3] = {
                EXT4_FEATURE_INCOMPAT_MMP |
                EXT4_FEATURE_INCOMPAT_64BIT |
                EXT4_FEATURE_INCOMPAT_ENCRYPT |
-               EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+               EXT4_FEATURE_INCOMPAT_CSUM_SEED |
+               EXT4_FEATURE_INCOMPAT_LARGEDIR,
        /* R/O compat */
        EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
                EXT4_FEATURE_RO_COMPAT_HUGE_FILE|