]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: add a way to check the theoretical maximum extent tree depth
authorDarrick J. Wong <darrick.wong@oracle.com>
Sun, 14 Dec 2014 02:13:40 +0000 (21:13 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 14 Dec 2014 02:13:40 +0000 (21:13 -0500)
Add an API so that client programs can discover a reasonable maximum
extent tree depth.  This will eventually be used by e2fsck as one of
the criteria to decide if an extent-based file should have its extent
tree rebuilt.

Turn some related magic numbers into constants while we're at it.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/ext2fs/ext2fs.h
lib/ext2fs/ext3_extents.h
lib/ext2fs/extent.c

index 5f6a514fb984c6356301065e06a011668d91bad7..42c4ce144689771526e6c0eedbe9f05e4597a2d7 100644 (file)
@@ -1218,6 +1218,7 @@ extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
 extern errcode_t ext2fs_extent_goto2(ext2_extent_handle_t handle,
                                     int leaf_level, blk64_t blk);
 extern errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle);
+size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle);
 
 /* fileio.c */
 extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
index 66c23fd69b4962d14b7414b118603e6382d30732..f73a3321877f2be7f0b27fab36ba026eea3857f1 100644 (file)
@@ -98,6 +98,8 @@ struct ext3_ext_path {
  */
 #define EXT_INIT_MAX_LEN       (1UL << 15)
 #define EXT_UNINIT_MAX_LEN     (EXT_INIT_MAX_LEN - 1)
+#define EXT_MAX_EXTENT_LBLK    (((__u64) 1 << 32) - 1)
+#define EXT_MAX_EXTENT_PBLK    (((__u64) 1 << 48) - 1)
 
 #define EXT_FIRST_EXTENT(__hdr__) \
        ((struct ext3_extent *) (((char *) (__hdr__)) +         \
index afb79c8d875e2e15e72585303a01368c78c72617..b1130f6fc19d5c2d11142dcc11110fb4055c1341 100644 (file)
@@ -1697,14 +1697,39 @@ errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle,
 
        info->curr_level = handle->level;
        info->max_depth = handle->max_depth;
-       info->max_lblk = ((__u64) 1 << 32) - 1;
-       info->max_pblk = ((__u64) 1 << 48) - 1;
-       info->max_len = (1UL << 15);
-       info->max_uninit_len = (1UL << 15) - 1;
+       info->max_lblk = EXT_MAX_EXTENT_LBLK;
+       info->max_pblk = EXT_MAX_EXTENT_PBLK;
+       info->max_len = EXT_INIT_MAX_LEN;
+       info->max_uninit_len = EXT_UNINIT_MAX_LEN;
 
        return 0;
 }
 
+static int ul_log2(unsigned long arg)
+{
+       int     l = 0;
+
+       arg >>= 1;
+       while (arg) {
+               l++;
+               arg >>= 1;
+       }
+       return l;
+}
+
+size_t ext2fs_max_extent_depth(ext2_extent_handle_t handle)
+{
+       size_t iblock_sz = sizeof(((struct ext2_inode *)NULL)->i_block);
+       size_t iblock_extents = (iblock_sz - sizeof(struct ext3_extent_header)) /
+                               sizeof(struct ext3_extent);
+       size_t extents_per_block = (handle->fs->blocksize -
+                                   sizeof(struct ext3_extent_header)) /
+                                  sizeof(struct ext3_extent);
+
+       return 1 + ((ul_log2(EXT_MAX_EXTENT_LBLK) - ul_log2(iblock_extents)) /
+                   ul_log2(extents_per_block));
+}
+
 #ifdef DEBUG
 /*
  * Override debugfs's prompt