shithub: lwext4

Download patch

ref: f8d3ad62601edc9ef3ab539522854e5349f93c2f
parent: a7423d5e9195369d137c6adfe20e45826e161215
author: gkostka <kostka.grzegorz@gmail.com>
date: Fri Oct 24 18:45:36 EDT 2014

Support for flex_bg

--- a/lwext4/ext4_balloc.c
+++ b/lwext4/ext4_balloc.c
@@ -165,6 +165,7 @@
 int ext4_balloc_free_blocks(struct ext4_inode_ref *inode_ref, uint32_t first,
     uint32_t count)
 {
+    int rc = EOK;
     struct ext4_fs *fs = inode_ref->fs;
     struct ext4_sblock *sb = &fs->sb;
 
@@ -172,66 +173,93 @@
     uint32_t block_group_first =
             ext4_balloc_get_bgid_of_block(sb, first);
 
-    ext4_assert(block_group_first ==
-    		ext4_balloc_get_bgid_of_block(sb, first + count - 1));
+    /* Compute indexes */
+    uint32_t block_group_last =
+            ext4_balloc_get_bgid_of_block(sb, first + count - 1);
 
+    if(!ext4_sb_has_feature_incompatible(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)){
+        /*It is not possible withot flex_bg that blocks are continuous
+         * and and last block belongs to other bg.*/
+        ext4_assert(block_group_first ==
+                ext4_balloc_get_bgid_of_block(sb, first + count - 1));
+    }
+
     /* Load block group reference */
     struct ext4_block_group_ref bg_ref;
-    int rc = ext4_fs_get_block_group_ref(fs, block_group_first, &bg_ref);
-    if (rc != EOK)
-        return rc;
+    while(block_group_first <= block_group_last){
 
-    uint32_t index_in_group_first =
-            ext4_fs_baddr2_index_in_group(sb, first);
+        rc = ext4_fs_get_block_group_ref(fs, block_group_first, &bg_ref);
+        if (rc != EOK)
+            return rc;
 
-    /* Load block with bitmap */
-    uint32_t bitmap_block_addr =
-            ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
+        uint32_t index_in_group_first =
+                ext4_fs_baddr2_index_in_group(sb, first);
 
-    struct ext4_block bitmap_block;
+        /* Load block with bitmap */
+        uint32_t bitmap_block_addr =
+                ext4_bg_get_block_bitmap(bg_ref.block_group, sb);
 
-    rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
-    if (rc != EOK){
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
+        struct ext4_block bitmap_block;
 
-    /* Modify bitmap */
-    ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, count);
-    bitmap_block.dirty = true;
+        rc = ext4_block_get(fs->bdev, &bitmap_block, bitmap_block_addr);
+        if (rc != EOK){
+            ext4_fs_put_block_group_ref(&bg_ref);
+            return rc;
+        }
 
-    /* Release block with bitmap */
-    rc = ext4_block_set(fs->bdev, &bitmap_block);
-    if (rc != EOK) {
-        ext4_fs_put_block_group_ref(&bg_ref);
-        return rc;
-    }
+        uint32_t free_cnt = ext4_sb_get_block_size(sb) * 8 - index_in_group_first;
 
-    uint32_t block_size = ext4_sb_get_block_size(sb);
+        /*If last block, free only count blocks*/
+        free_cnt = count > free_cnt ? free_cnt : count;
 
-    /* Update superblock free blocks count */
-    uint64_t sb_free_blocks =
-            ext4_sb_get_free_blocks_cnt(sb);
-    sb_free_blocks += count;
-    ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
+        /* Modify bitmap */
+        ext4_bmap_bits_free(bitmap_block.data, index_in_group_first, free_cnt);
+        bitmap_block.dirty = true;
 
-    /* Update inode blocks count */
-    uint64_t ino_blocks =
-            ext4_inode_get_blocks_count(sb, inode_ref->inode);
-    ino_blocks -= count * (block_size / EXT4_INODE_BLOCK_SIZE);
-    ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
-    inode_ref->dirty = true;
+        count -= free_cnt;
+        first += free_cnt;
 
-    /* Update block group free blocks count */
-    uint32_t free_blocks =
-            ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
-    free_blocks += count;
-    ext4_bg_set_free_blocks_count(bg_ref.block_group,
-        sb, free_blocks);
-    bg_ref.dirty = true;
+        /* Release block with bitmap */
+        rc = ext4_block_set(fs->bdev, &bitmap_block);
+        if (rc != EOK) {
+            ext4_fs_put_block_group_ref(&bg_ref);
+            return rc;
+        }
 
-    /* Release block group reference */
-    return ext4_fs_put_block_group_ref(&bg_ref);
+        uint32_t block_size = ext4_sb_get_block_size(sb);
+
+        /* Update superblock free blocks count */
+        uint64_t sb_free_blocks =
+                ext4_sb_get_free_blocks_cnt(sb);
+        sb_free_blocks += free_cnt;
+        ext4_sb_set_free_blocks_cnt(sb, sb_free_blocks);
+
+        /* Update inode blocks count */
+        uint64_t ino_blocks =
+                ext4_inode_get_blocks_count(sb, inode_ref->inode);
+        ino_blocks -= free_cnt * (block_size / EXT4_INODE_BLOCK_SIZE);
+        ext4_inode_set_blocks_count(sb, inode_ref->inode, ino_blocks);
+        inode_ref->dirty = true;
+
+        /* Update block group free blocks count */
+        uint32_t free_blocks =
+                ext4_bg_get_free_blocks_count(bg_ref.block_group, sb);
+        free_blocks += free_cnt;
+        ext4_bg_set_free_blocks_count(bg_ref.block_group,
+                sb, free_blocks);
+        bg_ref.dirty = true;
+
+        /* Release block group reference */
+        rc = ext4_fs_put_block_group_ref(&bg_ref);
+        if(rc != EOK)
+            break;
+
+        block_group_first++;
+    }
+
+    /*All blocks should be released*/
+    ext4_assert(count == 0);
+    return rc;
 }
 
 
--- a/lwext4/ext4_types.h
+++ b/lwext4/ext4_types.h
@@ -59,7 +59,7 @@
     uint32_t free_inodes_count;         /* Free inodes count */
     uint32_t first_data_block;          /* First Data Block */
     uint32_t log_block_size;            /* Block size */
-    uint32_t log_frag_size;             /* Obsoleted fragment size */
+    uint32_t log_cluster_size;          /* Obsoleted fragment size */
     uint32_t blocks_per_group;          /* Number of blocks per group */
     uint32_t frags_per_group;           /* Obsoleted fragments per group */
     uint32_t inodes_per_group;          /* Number of inodes per group */
@@ -261,6 +261,7 @@
             (EXT4_FEATURE_INCOMPAT_FILETYPE         | \
             EXT4_FEATURE_INCOMPAT_META_BG           | \
             EXT4_FEATURE_INCOMPAT_EXTENTS           | \
+            EXT4_FEATURE_INCOMPAT_FLEX_BG           | \
             EXT4_FEATURE_INCOMPAT_64BIT)
 
 #define EXT4_FEATURE_RO_COMPAT_SUPP                   \
@@ -285,8 +286,7 @@
 #if 0
 /*TODO: Features incompatible to implement*/
 #define EXT4_FEATURE_INCOMPAT_SUPP
-                     EXT4_FEATURE_INCOMPAT_FLEX_BG| \
-                     EXT4_FEATURE_INCOMPAT_INLINE_DATA)
+                     (EXT4_FEATURE_INCOMPAT_INLINE_DATA)
 
 /*TODO: Features read only to implement*/
 #define EXT4_FEATURE_RO_COMPAT_SUPP