Refactoring superblock features getters
[lwext4.git] / lwext4 / ext4_fs.c
index 06d6ea9a6762f3b96932acfa9b82917c536b25bd..cb2c91e54acc6d028f2e99745acd0da394b11ff9 100644 (file)
@@ -44,6 +44,7 @@
 #include "ext4_errno.h"
 #include "ext4_blockdev.h"
 #include "ext4_super.h"
+#include "ext4_crc32c.h"
 #include "ext4_debug.h"
 #include "ext4_block_group.h"
 #include "ext4_balloc.h"
@@ -127,72 +128,72 @@ int ext4_fs_fini(struct ext4_fs *fs)
 
 static void ext4_fs_debug_features_inc(uint32_t features_incompatible)
 {
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_COMPRESSION)
+       if (features_incompatible & EXT4_FINCOM_COMPRESSION)
                ext4_dbg(DEBUG_FS, DBG_NONE "compression\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_FILETYPE)
+       if (features_incompatible & EXT4_FINCOM_FILETYPE)
                ext4_dbg(DEBUG_FS, DBG_NONE "filetype\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_RECOVER)
+       if (features_incompatible & EXT4_FINCOM_RECOVER)
                ext4_dbg(DEBUG_FS, DBG_NONE "recover\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)
+       if (features_incompatible & EXT4_FINCOM_JOURNAL_DEV)
                ext4_dbg(DEBUG_FS, DBG_NONE "journal_dev\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_META_BG)
+       if (features_incompatible & EXT4_FINCOM_META_BG)
                ext4_dbg(DEBUG_FS, DBG_NONE "meta_bg\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_EXTENTS)
+       if (features_incompatible & EXT4_FINCOM_EXTENTS)
                ext4_dbg(DEBUG_FS, DBG_NONE "extents\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_64BIT)
+       if (features_incompatible & EXT4_FINCOM_64BIT)
                ext4_dbg(DEBUG_FS, DBG_NONE "64bit\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_MMP)
+       if (features_incompatible & EXT4_FINCOM_MMP)
                ext4_dbg(DEBUG_FS, DBG_NONE "mnp\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_FLEX_BG)
+       if (features_incompatible & EXT4_FINCOM_FLEX_BG)
                ext4_dbg(DEBUG_FS, DBG_NONE "flex_bg\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_EA_INODE)
+       if (features_incompatible & EXT4_FINCOM_EA_INODE)
                ext4_dbg(DEBUG_FS, DBG_NONE "ea_inode\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_DIRDATA)
+       if (features_incompatible & EXT4_FINCOM_DIRDATA)
                ext4_dbg(DEBUG_FS, DBG_NONE "dirdata\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_BG_USE_META_CSUM)
+       if (features_incompatible & EXT4_FINCOM_BG_USE_META_CSUM)
                ext4_dbg(DEBUG_FS, DBG_NONE "meta_csum\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_LARGEDIR)
+       if (features_incompatible & EXT4_FINCOM_LARGEDIR)
                ext4_dbg(DEBUG_FS, DBG_NONE "largedir\n");
-       if (features_incompatible & EXT4_FEATURE_INCOMPAT_INLINE_DATA)
+       if (features_incompatible & EXT4_FINCOM_INLINE_DATA)
                ext4_dbg(DEBUG_FS, DBG_NONE "inline_data\n");
 }
 static void ext4_fs_debug_features_comp(uint32_t features_compatible)
 {
-       if (features_compatible & EXT4_FEATURE_COMPAT_DIR_PREALLOC)
+       if (features_compatible & EXT4_FCOM_DIR_PREALLOC)
                ext4_dbg(DEBUG_FS, DBG_NONE "dir_prealloc\n");
-       if (features_compatible & EXT4_FEATURE_COMPAT_IMAGIC_INODES)
+       if (features_compatible & EXT4_FCOM_IMAGIC_INODES)
                ext4_dbg(DEBUG_FS, DBG_NONE "imagic_inodes\n");
-       if (features_compatible & EXT4_FEATURE_COMPAT_HAS_JOURNAL)
+       if (features_compatible & EXT4_FCOM_HAS_JOURNAL)
                ext4_dbg(DEBUG_FS, DBG_NONE "has_journal\n");
-       if (features_compatible & EXT4_FEATURE_COMPAT_EXT_ATTR)
+       if (features_compatible & EXT4_FCOM_EXT_ATTR)
                ext4_dbg(DEBUG_FS, DBG_NONE "ext_attr\n");
-       if (features_compatible & EXT4_FEATURE_COMPAT_RESIZE_INODE)
+       if (features_compatible & EXT4_FCOM_RESIZE_INODE)
                ext4_dbg(DEBUG_FS, DBG_NONE "resize_inode\n");
-       if (features_compatible & EXT4_FEATURE_COMPAT_DIR_INDEX)
+       if (features_compatible & EXT4_FCOM_DIR_INDEX)
                ext4_dbg(DEBUG_FS, DBG_NONE "dir_index\n");
 }
 
 static void ext4_fs_debug_features_ro(uint32_t features_ro)
 {
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER)
+       if (features_ro & EXT4_FRO_COM_SPARSE_SUPER)
                ext4_dbg(DEBUG_FS, DBG_NONE "sparse_super\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_LARGE_FILE)
+       if (features_ro & EXT4_FRO_COM_LARGE_FILE)
                ext4_dbg(DEBUG_FS, DBG_NONE "large_file\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_BTREE_DIR)
+       if (features_ro & EXT4_FRO_COM_BTREE_DIR)
                ext4_dbg(DEBUG_FS, DBG_NONE "btree_dir\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+       if (features_ro & EXT4_FRO_COM_HUGE_FILE)
                ext4_dbg(DEBUG_FS, DBG_NONE "huge_file\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
+       if (features_ro & EXT4_FRO_COM_GDT_CSUM)
                ext4_dbg(DEBUG_FS, DBG_NONE "gtd_csum\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
+       if (features_ro & EXT4_FRO_COM_DIR_NLINK)
                ext4_dbg(DEBUG_FS, DBG_NONE "dir_nlink\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)
+       if (features_ro & EXT4_FRO_COM_EXTRA_ISIZE)
                ext4_dbg(DEBUG_FS, DBG_NONE "extra_isize\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_QUOTA)
+       if (features_ro & EXT4_FRO_COM_QUOTA)
                ext4_dbg(DEBUG_FS, DBG_NONE "quota\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_BIGALLOC)
+       if (features_ro & EXT4_FRO_COM_BIGALLOC)
                ext4_dbg(DEBUG_FS, DBG_NONE "bigalloc\n");
-       if (features_ro & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
+       if (features_ro & EXT4_FRO_COM_METADATA_CSUM)
                ext4_dbg(DEBUG_FS, DBG_NONE "metadata_csum\n");
 }
 
@@ -216,7 +217,7 @@ int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only)
 
        /*Check features_incompatible*/
        v = (ext4_get32(&fs->sb, features_incompatible) &
-            (~CONFIG_FEATURE_INCOMPAT_SUPP));
+            (~CONFIG_SUPPORTED_FINCOM));
        if (v) {
                ext4_dbg(DEBUG_FS, DBG_ERROR
                                "sblock has unsupported features incompatible:\n");
@@ -226,7 +227,7 @@ int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only)
 
        /*Check features_read_only*/
        v = (ext4_get32(&fs->sb, features_read_only) &
-            (~CONFIG_FEATURE_RO_COMPAT_SUPP));
+            (~CONFIG_SUPPORTED_FRO_COM));
        if (v) {
                ext4_dbg(DEBUG_FS, DBG_WARN
                                "sblock has unsupported features read only:\n");
@@ -299,8 +300,7 @@ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)
            ext4_sb_get_desc_size(&bg_ref->fs->sb);
 
        bool flex_bg =
-               ext4_sb_has_feature_incompatible(&bg_ref->fs->sb,
-                                                EXT4_FEATURE_INCOMPAT_FLEX_BG);
+               ext4_sb_feature_incom(&bg_ref->fs->sb, EXT4_FINCOM_FLEX_BG);
 
        uint32_t inode_table_bcnt = inodes_per_group * inode_size / block_size;
 
@@ -313,8 +313,7 @@ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)
        memset(block_bitmap.data, 0, block_size);
 
        bit_max = ext4_sb_is_super_in_bg(&bg_ref->fs->sb, bg_ref->index);
-       if (!ext4_sb_has_feature_incompatible(&bg_ref->fs->sb,
-                                             EXT4_FEATURE_INCOMPAT_META_BG) ||
+       if (!ext4_sb_feature_incom(&bg_ref->fs->sb, EXT4_FINCOM_META_BG) ||
                        bg_ref->index < ext4_sb_first_meta_bg(&bg_ref->fs->sb) *
                        dsc_per_block) {
                if (bit_max) {
@@ -373,6 +372,11 @@ static int ext4_fs_init_block_bitmap(struct ext4_block_group_ref *bg_ref)
         ext4_fs_mark_bitmap_end(group_blocks, block_size * 8, block_bitmap.data);
        block_bitmap.dirty = true;
 
+       ext4_balloc_set_bitmap_csum(&bg_ref->fs->sb,
+                                   bg_ref->block_group,
+                                   block_bitmap.data);
+       bg_ref->dirty = true;
+
        /* Save bitmap */
        return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
 }
@@ -412,6 +416,11 @@ static int ext4_fs_init_inode_bitmap(struct ext4_block_group_ref *bg_ref)
 
        block_bitmap.dirty = true;
 
+       ext4_ialloc_set_bitmap_csum(&bg_ref->fs->sb,
+                                   bg_ref->block_group,
+                                   block_bitmap.data);
+       bg_ref->dirty = true;
+
        /* Save bitmap */
        return ext4_block_set(bg_ref->fs->bdev, &block_bitmap);
 }
@@ -470,8 +479,7 @@ static ext4_fsblk_t ext4_fs_get_descriptor_block(struct ext4_sblock *s,
        dsc_id = bgid / dsc_per_block;
        first_meta_bg = ext4_sb_first_meta_bg(s);
 
-       if (!ext4_sb_has_feature_incompatible(s,
-                                             EXT4_FEATURE_INCOMPAT_META_BG) ||
+       if (!ext4_sb_feature_incom(s, EXT4_FINCOM_META_BG) ||
            dsc_id < first_meta_bg)
                return ext4_get32(s, first_data_block) + dsc_id + 1;
 
@@ -545,6 +553,12 @@ int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
        return EOK;
 }
 
+/*
+ * BIG FAT NOTES:
+ *       Currently we do not verify the checksum of block_group_desc
+ *       and inode.
+ */
+
 /**@brief  Compute checksum of block group descriptor.
  * @param sb   Superblock
  * @param bgid Index of block group in the filesystem
@@ -558,8 +572,27 @@ static uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid,
        uint16_t crc = 0;
 
        /* Compute the checksum only if the filesystem supports it */
-       if (ext4_sb_has_feature_read_only(sb,
-                                         EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) {
+       if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {
+               /* Use metadata_csum algorithm instead */
+               uint32_t le32_bgid = to_le32(bgid);
+               uint32_t orig_checksum, checksum;
+
+               /* Preparation: temporarily set bg checksum to 0 */
+               orig_checksum = bg->checksum;
+               bg->checksum = 0;
+
+               /* First calculate crc32 checksum against fs uuid */
+               checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid));
+               /* Then calculate crc32 checksum against bgid */
+               checksum = ext4_crc32c(checksum, &le32_bgid,
+                                    sizeof(bgid));
+               /* Finally calculate crc32 checksum against block_group_desc */
+               checksum = ext4_crc32c(checksum, bg,
+                                    ext4_sb_get_desc_size(sb));
+               bg->checksum = orig_checksum;
+
+               crc = checksum & 0xFFFF;
+       } else if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_GDT_CSUM)) {
                uint8_t *base = (uint8_t *)bg;
                uint8_t *checksum = (uint8_t *)&bg->checksum;
 
@@ -583,8 +616,7 @@ static uint16_t ext4_fs_bg_checksum(struct ext4_sblock *sb, uint32_t bgid,
                offset += sizeof(bg->checksum);
 
                /* Checksum of the rest of block group descriptor */
-               if ((ext4_sb_has_feature_incompatible(
-                       sb, EXT4_FEATURE_INCOMPAT_64BIT)) &&
+               if ((ext4_sb_feature_incom(sb, EXT4_FINCOM_64BIT)) &&
                    (offset < ext4_sb_get_desc_size(sb)))
 
                        crc = ext4_bg_crc16(crc, ((uint8_t *)bg) + offset,
@@ -611,6 +643,51 @@ int ext4_fs_put_block_group_ref(struct ext4_block_group_ref *ref)
        return ext4_block_set(ref->fs->bdev, &ref->block);
 }
 
+static uint32_t ext4_fs_inode_checksum(struct ext4_inode_ref *inode_ref)
+{
+       uint32_t checksum = 0;
+       struct ext4_sblock *sb = &inode_ref->fs->sb;
+       uint16_t inode_size = ext4_get16(sb, inode_size);
+
+       if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM)) {
+               uint32_t orig_checksum;
+
+               uint32_t ino_index = to_le32(inode_ref->index);
+               uint32_t ino_gen =
+                       to_le32(ext4_inode_get_generation(inode_ref->inode));
+
+               /* Preparation: temporarily set bg checksum to 0 */
+               orig_checksum = ext4_inode_get_checksum(sb, inode_ref->inode);
+               ext4_inode_set_checksum(sb, inode_ref->inode, 0);
+
+               /* First calculate crc32 checksum against fs uuid */
+               checksum = ext4_crc32c(~0, sb->uuid, sizeof(sb->uuid));
+               /* Then calculate crc32 checksum against inode number
+                * and inode generation */
+               checksum = ext4_crc32c(checksum, &ino_index,
+                                    sizeof(ino_index));
+               checksum = ext4_crc32c(checksum, &ino_gen,
+                                    sizeof(ino_gen));
+               /* Finally calculate crc32 checksum against 
+                * the entire inode */
+               checksum = ext4_crc32c(checksum, inode_ref->inode,
+                               inode_size);
+               ext4_inode_set_checksum(sb, inode_ref->inode,
+                               orig_checksum);
+       }
+       return checksum;
+}
+
+static void ext4_fs_set_inode_checksum(struct ext4_inode_ref *inode_ref)
+{
+       struct ext4_sblock *sb = &inode_ref->fs->sb;
+       if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_METADATA_CSUM))
+               return;
+
+       ext4_inode_set_checksum(sb, inode_ref->inode,
+                               ext4_fs_inode_checksum(inode_ref));
+}
+
 int ext4_fs_get_inode_ref(struct ext4_fs *fs, uint32_t index,
                          struct ext4_inode_ref *ref)
 {
@@ -674,6 +751,7 @@ int ext4_fs_put_inode_ref(struct ext4_inode_ref *ref)
        /* Check if reference modified */
        if (ref->dirty) {
                /* Mark block dirty for writing changes to physical device */
+               ext4_fs_set_inode_checksum(ref);
                ref->block.dirty = true;
        }
 
@@ -692,8 +770,7 @@ void ext4_fs_inode_blocks_init(struct ext4_fs *fs, struct ext4_inode_ref *inode_
        (void)fs;
 #if CONFIG_EXTENT_ENABLE
        /* Initialize extents if needed */
-       if (ext4_sb_has_feature_incompatible(&fs->sb,
-                               EXT4_FEATURE_INCOMPAT_EXTENTS)) {
+       if (ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) {
                ext4_inode_set_flag(inode, EXT4_INODE_FLAG_EXTENTS);
 
                /* Initialize extent root header */
@@ -723,6 +800,7 @@ int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
 {
        /* Check if newly allocated i-node will be a directory */
        bool is_dir;
+       uint16_t inode_size = ext4_get16(&fs->sb, inode_size);
 
        is_dir = (filetype == EXT4_DIRENTRY_DIR);
 
@@ -774,6 +852,11 @@ int ext4_fs_alloc_inode(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref,
        ext4_inode_set_blocks_count(&fs->sb, inode, 0);
        ext4_inode_set_flags(inode, 0);
        ext4_inode_set_generation(inode, 0);
+       if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)
+               ext4_inode_set_extra_isize(inode,
+                               sizeof(struct ext4_inode) -
+                               ext4_offsetof(struct ext4_inode,
+                                       extra_isize));
 
        /* Reset blocks array. For symbolic link inode, just
         * fill in blocks with 0 */
@@ -797,8 +880,7 @@ int ext4_fs_free_inode(struct ext4_inode_ref *inode_ref)
        int rc;
 #if CONFIG_EXTENT_ENABLE
        /* For extents must be data block destroyed by other way */
-       if ((ext4_sb_has_feature_incompatible(&fs->sb,
-                                             EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+       if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) &&
            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
                /* Data structures are released during truncate operation... */
                goto finish;
@@ -929,6 +1011,112 @@ finish:
        return rc;
 }
 
+
+/**@brief Release data block from i-node
+ * @param inode_ref I-node to release block from
+ * @param iblock    Logical block to be released
+ * @return Error code
+ */
+static int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
+                               uint32_t iblock)
+{
+       ext4_fsblk_t fblock;
+
+       struct ext4_fs *fs = inode_ref->fs;
+
+       /* Extents are handled otherwise = there is not support in this function
+        */
+       ext4_assert(!(
+           ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS) &&
+           (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));
+
+       struct ext4_inode *inode = inode_ref->inode;
+
+       /* Handle simple case when we are dealing with direct reference */
+       if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
+               fblock = ext4_inode_get_direct_block(inode, iblock);
+
+               /* Sparse file */
+               if (fblock == 0)
+                       return EOK;
+
+               ext4_inode_set_direct_block(inode, iblock, 0);
+               return ext4_balloc_free_block(inode_ref, fblock);
+       }
+
+       /* Determine the indirection level needed to get the desired block */
+       unsigned int level = 0;
+       unsigned int i;
+       for (i = 1; i < 4; i++) {
+               if (iblock < fs->inode_block_limits[i]) {
+                       level = i;
+                       break;
+               }
+       }
+
+       if (level == 0)
+               return EIO;
+
+       /* Compute offsets for the topmost level */
+       uint64_t block_offset_in_level =
+           iblock - fs->inode_block_limits[level - 1];
+       ext4_fsblk_t current_block =
+           ext4_inode_get_indirect_block(inode, level - 1);
+       uint32_t offset_in_block =
+           block_offset_in_level / fs->inode_blocks_per_level[level - 1];
+
+       /*
+        * Navigate through other levels, until we find the block number
+        * or find null reference meaning we are dealing with sparse file
+        */
+       struct ext4_block block;
+
+       while (level > 0) {
+
+               /* Sparse check */
+               if (current_block == 0)
+                       return EOK;
+
+               int rc = ext4_block_get(fs->bdev, &block, current_block);
+               if (rc != EOK)
+                       return rc;
+
+               current_block =
+                   to_le32(((uint32_t *)block.data)[offset_in_block]);
+
+               /* Set zero if physical data block address found */
+               if (level == 1) {
+                       ((uint32_t *)block.data)[offset_in_block] = to_le32(0);
+                       block.dirty = true;
+               }
+
+               rc = ext4_block_set(fs->bdev, &block);
+               if (rc != EOK)
+                       return rc;
+
+               level--;
+
+               /*
+                * If we are on the last level, break here as
+                * there is no next level to visit
+                */
+               if (level == 0)
+                       break;
+
+               /* Visit the next level */
+               block_offset_in_level %= fs->inode_blocks_per_level[level];
+               offset_in_block = block_offset_in_level /
+                                 fs->inode_blocks_per_level[level - 1];
+       }
+
+       fblock = current_block;
+       if (fblock == 0)
+               return EOK;
+
+       /* Physical block is not referenced, it can be released */
+       return ext4_balloc_free_block(inode_ref, fblock);
+}
+
 int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size)
 {
        struct ext4_sblock *sb = &inode_ref->fs->sb;
@@ -967,8 +1155,7 @@ int ext4_fs_truncate_inode(struct ext4_inode_ref *inode_ref, uint64_t new_size)
                                    block_size;
        uint32_t diff_blocks_count = old_blocks_count - new_blocks_count;
 #if CONFIG_EXTENT_ENABLE
-       if ((ext4_sb_has_feature_incompatible(sb,
-                                             EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+       if ((ext4_sb_feature_incom(sb, EXT4_FINCOM_EXTENTS)) &&
            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
 
                /* Extents require special operation */
@@ -1106,8 +1293,7 @@ static int ext4_fs_get_inode_data_block_idx(struct ext4_inode_ref *inode_ref,
        (void)extent_create;
 #if CONFIG_EXTENT_ENABLE
        /* Handle i-node using extents */
-       if ((ext4_sb_has_feature_incompatible(&fs->sb,
-                                             EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+       if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) &&
            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
 
                ext4_fsblk_t current_fsblk;
@@ -1229,8 +1415,7 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
 
 #if CONFIG_EXTENT_ENABLE
        /* Handle inode using extents */
-       if ((ext4_sb_has_feature_incompatible(&fs->sb,
-                                             EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+       if ((ext4_sb_feature_incom(&fs->sb, EXT4_FINCOM_EXTENTS)) &&
            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
                /* Not reachable */
                return ENOTSUP;
@@ -1395,114 +1580,13 @@ static int ext4_fs_set_inode_data_block_index(struct ext4_inode_ref *inode_ref,
        return EOK;
 }
 
-int ext4_fs_release_inode_block(struct ext4_inode_ref *inode_ref,
-                               uint32_t iblock)
-{
-       ext4_fsblk_t fblock;
-
-       struct ext4_fs *fs = inode_ref->fs;
-
-       /* Extents are handled otherwise = there is not support in this function
-        */
-       ext4_assert(!(
-           ext4_sb_has_feature_incompatible(&fs->sb,
-                                            EXT4_FEATURE_INCOMPAT_EXTENTS) &&
-           (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))));
-
-       struct ext4_inode *inode = inode_ref->inode;
-
-       /* Handle simple case when we are dealing with direct reference */
-       if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) {
-               fblock = ext4_inode_get_direct_block(inode, iblock);
-
-               /* Sparse file */
-               if (fblock == 0)
-                       return EOK;
-
-               ext4_inode_set_direct_block(inode, iblock, 0);
-               return ext4_balloc_free_block(inode_ref, fblock);
-       }
-
-       /* Determine the indirection level needed to get the desired block */
-       unsigned int level = 0;
-       unsigned int i;
-       for (i = 1; i < 4; i++) {
-               if (iblock < fs->inode_block_limits[i]) {
-                       level = i;
-                       break;
-               }
-       }
-
-       if (level == 0)
-               return EIO;
-
-       /* Compute offsets for the topmost level */
-       uint64_t block_offset_in_level =
-           iblock - fs->inode_block_limits[level - 1];
-       ext4_fsblk_t current_block =
-           ext4_inode_get_indirect_block(inode, level - 1);
-       uint32_t offset_in_block =
-           block_offset_in_level / fs->inode_blocks_per_level[level - 1];
-
-       /*
-        * Navigate through other levels, until we find the block number
-        * or find null reference meaning we are dealing with sparse file
-        */
-       struct ext4_block block;
-
-       while (level > 0) {
-
-               /* Sparse check */
-               if (current_block == 0)
-                       return EOK;
-
-               int rc = ext4_block_get(fs->bdev, &block, current_block);
-               if (rc != EOK)
-                       return rc;
-
-               current_block =
-                   to_le32(((uint32_t *)block.data)[offset_in_block]);
-
-               /* Set zero if physical data block address found */
-               if (level == 1) {
-                       ((uint32_t *)block.data)[offset_in_block] = to_le32(0);
-                       block.dirty = true;
-               }
-
-               rc = ext4_block_set(fs->bdev, &block);
-               if (rc != EOK)
-                       return rc;
-
-               level--;
-
-               /*
-                * If we are on the last level, break here as
-                * there is no next level to visit
-                */
-               if (level == 0)
-                       break;
-
-               /* Visit the next level */
-               block_offset_in_level %= fs->inode_blocks_per_level[level];
-               offset_in_block = block_offset_in_level /
-                                 fs->inode_blocks_per_level[level - 1];
-       }
-
-       fblock = current_block;
-       if (fblock == 0)
-               return EOK;
-
-       /* Physical block is not referenced, it can be released */
-       return ext4_balloc_free_block(inode_ref, fblock);
-}
 
 int ext4_fs_append_inode_block(struct ext4_inode_ref *inode_ref,
                               ext4_fsblk_t *fblock, uint32_t *iblock)
 {
 #if CONFIG_EXTENT_ENABLE
        /* Handle extents separately */
-       if ((ext4_sb_has_feature_incompatible(&inode_ref->fs->sb,
-                                             EXT4_FEATURE_INCOMPAT_EXTENTS)) &&
+       if ((ext4_sb_feature_incom(&inode_ref->fs->sb, EXT4_FINCOM_EXTENTS)) &&
            (ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS))) {
                int rc;
                ext4_fsblk_t current_fsblk;
@@ -1577,8 +1661,7 @@ void ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref)
        ext4_inode_set_links_count(inode_ref->inode, link);
 
        bool is_dx =
-           ext4_sb_has_feature_compatible(&inode_ref->fs->sb,
-                                          EXT4_FEATURE_COMPAT_DIR_INDEX) &&
+           ext4_sb_feature_com(&inode_ref->fs->sb, EXT4_FCOM_DIR_INDEX) &&
            ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_INDEX);
 
        if (is_dx && link > 1) {
@@ -1587,7 +1670,7 @@ void ext4_fs_inode_links_count_inc(struct ext4_inode_ref *inode_ref)
 
                        uint32_t v =
                            ext4_get32(&inode_ref->fs->sb, features_read_only);
-                       v |= EXT4_FEATURE_RO_COMPAT_DIR_NLINK;
+                       v |= EXT4_FRO_COM_DIR_NLINK;
                        ext4_set32(&inode_ref->fs->sb, features_read_only, v);
                }
        }