Hi Ted, Andreas and the list, After the bigalloc-feature is completed in ext4, we could have much more big size of block-group (also bigger continuous space), so larger extent size which is above 128MB is necessary, such as: struct ext4_extent_large { __le64 ee_block; /* first logical block extent covers */ __le64 ee_start; /* starting physical block */ __le32 ee_len; /* number of blocks covered by extent */ __le32 ee_flags; /* flags and future extension */ }; On the other hand, people who use ext4 in desktop environment may need more compact format like: struct ext4_extent_packed { __le32 ee_start_lo; __le16 ee_start_hi; __le16 ee_len; }; which they can fit 6 extents in the inode. Therefore, supporting multiple extent formats is the solution which satisfied both. My Plan: First, abstracting the operation on disk extent format out: struct ext4_ext_operation { __u16 (*ext_size) (void); /* the size of struct ext4_extent_### */ ext4_fsblk_t (*ext_pblock) (void *extent); void (*ext_store_pblock) (void *extent, __u64 pb); ext4_lblk_t (*ext_lblock) (void *extent); ext4_lblk_t (*ext_len) (void *extent); int (*is_uninit) (void *extent); void (*mark_uninit) (void *extent); void (*mark_init) (void *extent); __u16 (*idx_size) (void); ext4_fsblk_t (*idx_pblock) (void *idx); void (*idx_store_pblock) (void *idx, __u64 pb); ext4_lblk_t (*idx_lblock) (void *idx); }; We can use this single entry to handle different extent format through different implementation of ext4_ext_operation (choosing different implementation by different eh_magic number), and the extent format which is used now could be implemented like: static const struct ext4_ext_operation ext4_normal_eops= { .ext_size = ext4_ext_size, .ext_pblock = ext4_ext_pblock, .ext_store_pblock = ext4_ext_store_pblock, .ext_lblock = ext4_ext_lblock, .ext_len = ext4_ext_get_actual_len, .is_uninit = ext4_ext_is_uninitialized, .mark_uninit = ext4_ext_mark_uninitialized, .mark_init = ext4_ext_mark_initialized, .idx_size = ext4_idx_size, .idx_pblock = ext4_idx_pblock, .idx_store_pblock = ext4_idx_store_pblock, .idx_lblock = ext4_idx_lblock, }; For instance, the function ext4_ext_binsearch_idx() may look like: static void ext4_ext_binsearch_idx(struct inode *inode, struct ext4_ext_path *path, ext4_lblk_t block) { struct ext4_extent_header *eh = path->p_hdr; struct void *r, *l, *m; struct ext4_ext_operation *op = (struct ext4_ext_operation*)inode->private; l = (char *) (eh) + sizeof(struct ext4_extent_header) + op->idx_size(); r = l + (le16_to_cpu(eh)->eh_entries) * op->idx_size(); while (l <= r) { m = l + op->idx_size() * ((r - l) / op->idx_size())/ 2; if (block < op->idx_lblock(m)) r = m - op->idx_size(); else l = m + op->idx_size(); } path->p_idx = l - op->idx_size(); } The only problem is the performance regression caused by frequent function calls. Any suggestions will be appreciated. -- -- Best Regard Robin Dong -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html