shithub: lwext4

Download patch

ref: 504fa350e718a379f4a0ae764a80d1d8dd1b959b
parent: ccba18d3c3ce3a690f45841c7a7d4143694512a5
author: gkostka <kostka.grzegorz@gmail.com>
date: Tue Oct 21 18:15:57 EDT 2014

Meta bg feature


--- a/lwext4/ext4_fs.c
+++ b/lwext4/ext4_fs.c
@@ -312,28 +312,7 @@
     return EOK;
 }
 
-uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr)
-{
-    ext4_assert(baddr);
-    if(ext4_get32(s, first_data_block))
-        baddr--;
 
-    return  baddr % ext4_get32(s, blocks_per_group);
-}
-
-
-
-uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
-    uint32_t bgid)
-{
-    if(ext4_get32(s, first_data_block))
-        index++;
-
-    return ext4_get32(s, blocks_per_group) * bgid + index;
-}
-
-
-
 /**@brief Initialize block bitmap in block group.
  * @param bg_ref Reference to block group
  * @return Error code
@@ -454,7 +433,27 @@
     return EOK;
 }
 
+static uint64_t ext4_fs_get_descriptor_block(struct ext4_sblock *s,
+        uint32_t bgid, uint32_t dsc_per_block)
+{
+    uint32_t first_meta_bg, dsc_id;
 
+    int has_super = 0;
+
+    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) ||
+            dsc_id < first_meta_bg)
+        return ext4_get32(s, first_data_block) + dsc_id + 1;
+
+    if (ext4_sb_is_super_in_bg(s, bgid))
+        has_super = 1;
+
+    return (has_super + ext4_fs_first_bg_block_no(s, bgid));
+}
+
+
 int ext4_fs_get_block_group_ref(struct ext4_fs *fs, uint32_t bgid,
     struct ext4_block_group_ref *ref)
 {
@@ -463,13 +462,11 @@
             ext4_sb_get_desc_size(&fs->sb);
 
     /* Block group descriptor table starts at the next block after superblock */
-    uint64_t block_id = ext4_get32(&fs->sb, first_data_block) + 1;
+    uint64_t block_id = ext4_fs_get_descriptor_block(&fs->sb, bgid,
+            dsc_per_block);
 
-    /* Find the block containing the descriptor we are looking for */
-    block_id += bgid / dsc_per_block;
     uint32_t offset = (bgid % dsc_per_block) *
             ext4_sb_get_desc_size(&fs->sb);
-
 
     int rc = ext4_block_get(fs->bdev, &ref->block, block_id);
     if (rc != EOK)
--- a/lwext4/ext4_fs.h
+++ b/lwext4/ext4_fs.h
@@ -48,6 +48,45 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+/**@brief Convert block address to relative index in block group.
+ * @param sb Superblock pointer
+ * @param baddr Block number to convert
+ * @return Relative number of block
+ */
+static inline uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s,
+        uint32_t baddr)
+{
+    ext4_assert(baddr);
+    if(ext4_get32(s, first_data_block))
+        baddr--;
+
+    return  baddr % ext4_get32(s, blocks_per_group);
+}
+
+
+/**@brief Convert relative block address in group to absolute address.
+ * @param s Superblock pointer
+ * @param index Relative block address
+ * @param bgid Block group
+ * @return Absolute block address
+ */
+static inline uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s,
+        uint32_t index, uint32_t bgid)
+{
+    if(ext4_get32(s, first_data_block))
+        index++;
+
+    return ext4_get32(s, blocks_per_group) * bgid + index;
+}
+
+/**@brief TODO: */
+static inline uint64_t ext4_fs_first_bg_block_no(struct ext4_sblock *s,
+        uint32_t bgid)
+{
+    return (uint64_t)bgid * ext4_get32(s, blocks_per_group) +
+            ext4_get32(s, first_data_block);
+}
+
 /**@brief Initialize filesystem and read all needed data.
  * @param fs Filesystem instance to be initialized
  * @param bdev Identifier if device with the filesystem
@@ -70,22 +109,6 @@
  * @return Error code
  */
 int ext4_fs_check_features(struct ext4_fs *fs, bool *read_only);
-
-/**@brief Convert block address to relative index in block group.
- * @param sb Superblock pointer
- * @param baddr Block number to convert
- * @return Relative number of block
- */
-uint32_t ext4_fs_baddr2_index_in_group(struct ext4_sblock *s, uint32_t baddr);
-
-/**@brief Convert relative block address in group to absolute address.
- * @param s Superblock pointer
- * @param index Relative block address
- * @param bgid Block group
- * @return Absolute block address
- */
-uint32_t ext4_fs_index_in_group2_baddr(struct ext4_sblock *s, uint32_t index,
-    uint32_t bgid);
 
 /**@brief Get reference to block group specified by index.
  * @param fs   Filesystem to find block group on
--- a/lwext4/ext4_super.h
+++ b/lwext4/ext4_super.h
@@ -156,6 +156,13 @@
     return 1 << to_le32(s->log_groups_per_flex);
 }
 
+/**@brief   Return first meta block group id.
+ * @param   s superblock descriptor
+ * @return  first meta_bg id */
+static inline uint32_t ext4_sb_first_meta_bg(struct ext4_sblock *s)
+{
+    return to_le32(s->first_meta_bg);
+}
 
 /**************************More complex functions****************************/