Whamcloud - gitweb
Merge branch 'maint' into next
[tools/e2fsprogs.git] / lib / ext2fs / blknum.c
index 1f183f4..b3eef6c 100644 (file)
@@ -11,6 +11,7 @@
  * %End-Header%
  */
 
+#include "config.h"
 #include "ext2fs.h"
 
 /*
@@ -43,14 +44,34 @@ blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group)
 }
 
 /*
+ * Return the number of blocks in a group
+ */
+int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group)
+{
+       int num_blocks;
+
+       if (group == fs->group_desc_count - 1) {
+               num_blocks = (ext2fs_blocks_count(fs->super) -
+                               fs->super->s_first_data_block) %
+                             fs->super->s_blocks_per_group;
+               if (!num_blocks)
+                       num_blocks = fs->super->s_blocks_per_group;
+       } else
+               num_blocks = fs->super->s_blocks_per_group;
+
+       return num_blocks;
+}
+
+/*
  * Return the inode data block count
  */
 blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
                                        struct ext2_inode *inode)
 {
        return (inode->i_blocks |
-               (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
-               (__u64)inode->osd2.linux2.l_i_blocks_hi << 32 : 0)) -
+               ((fs->super->s_feature_ro_compat &
+                 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ?
+                (__u64) inode->osd2.linux2.l_i_blocks_hi << 32 : 0)) -
                (inode->i_file_acl ? fs->blocksize >> 9 : 0);
 }
 
@@ -61,7 +82,8 @@ blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
                                        struct ext2_inode *inode)
 {
        return (inode->i_blocks |
-               (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT ?
+               ((fs->super->s_feature_ro_compat &
+                 EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ?
                 (__u64)inode->osd2.linux2.l_i_blocks_hi << 32 : 0));
 }
 
@@ -162,7 +184,7 @@ void ext2fs_free_blocks_count_add(struct ext2_super_block *super, blk64_t blk)
  * do the swap there.
  */
 struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
-                                         struct ext2_group_desc *gdp,
+                                         struct opaque_ext2_group_desc *gdp,
                                          dgrp_t group)
 {
        if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT)
@@ -172,22 +194,41 @@ struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
                return (struct ext2_group_desc *) gdp + group;
 }
 
+/* Do the same but as an ext4 group desc for internal use here */
+static struct ext4_group_desc *ext4fs_group_desc(ext2_filsys fs,
+                                         struct opaque_ext2_group_desc *gdp,
+                                         dgrp_t group)
+{
+       return (struct ext4_group_desc *)ext2fs_group_desc(fs, gdp, group);
+}
+
+/*
+ * Return the block bitmap checksum of a group
+ */
+__u32 ext2fs_block_bitmap_checksum(ext2_filsys fs, dgrp_t group)
+{
+       struct ext4_group_desc *gdp;
+       __u32 csum;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       csum = gdp->bg_block_bitmap_csum_lo;
+       if (fs->super->s_desc_size >= EXT4_BG_BLOCK_BITMAP_CSUM_HI_LOCATION)
+               csum |= ((__u32)gdp->bg_block_bitmap_csum_hi << 16);
+       return csum;
+}
+
 /*
  * Return the block bitmap block of a group
  */
 blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               return gdp->bg_block_bitmap |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u64) gdp->bg_block_bitmap_hi << 32 : 0);
-       }
+       struct ext4_group_desc *gdp;
 
-       return fs->group_desc[group].bg_block_bitmap;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_block_bitmap |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u64)gdp->bg_block_bitmap_hi << 32 : 0);
 }
 
 /*
@@ -195,14 +236,27 @@ blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_block_bitmap = blk;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_block_bitmap_hi = (__u64) blk >> 32;
-       } else
-               fs->group_desc[group].bg_block_bitmap = blk;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_block_bitmap = blk;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_block_bitmap_hi = (__u64) blk >> 32;
+}
+
+/*
+ * Return the inode bitmap checksum of a group
+ */
+__u32 ext2fs_inode_bitmap_checksum(ext2_filsys fs, dgrp_t group)
+{
+       struct ext4_group_desc *gdp;
+       __u32 csum;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       csum = gdp->bg_inode_bitmap_csum_lo;
+       if (fs->super->s_desc_size >= EXT4_BG_INODE_BITMAP_CSUM_HI_END)
+               csum |= ((__u32)gdp->bg_inode_bitmap_csum_hi << 16);
+       return csum;
 }
 
 /*
@@ -210,17 +264,13 @@ void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
  */
 blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               return gdp->bg_inode_bitmap |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u64) gdp->bg_inode_bitmap_hi << 32 : 0);
-       }
-
-       return fs->group_desc[group].bg_inode_bitmap;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_inode_bitmap |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u64) gdp->bg_inode_bitmap_hi << 32 : 0);
 }
 
 /*
@@ -228,14 +278,12 @@ blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_inode_bitmap = blk;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_inode_bitmap_hi = (__u64) blk >> 32;
-       } else
-               fs->group_desc[group].bg_inode_bitmap = blk;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_inode_bitmap = blk;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_inode_bitmap_hi = (__u64) blk >> 32;
 }
 
 /*
@@ -243,17 +291,13 @@ void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
  */
 blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               return gdp->bg_inode_table |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u64) gdp->bg_inode_table_hi << 32 : 0);
-       }
+       struct ext4_group_desc *gdp;
 
-       return fs->group_desc[group].bg_inode_table;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_inode_table |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u64) gdp->bg_inode_table_hi << 32 : 0);
 }
 
 /*
@@ -261,14 +305,12 @@ blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_inode_table = blk;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_inode_table_hi = (__u64) blk >> 32;
-       } else
-               fs->group_desc[group].bg_inode_table = blk;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_inode_table = blk;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_inode_table_hi = (__u64) blk >> 32;
 }
 
 /*
@@ -276,17 +318,13 @@ void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
  */
 __u32 ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               return gdp->bg_free_blocks_count |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u32) gdp->bg_free_blocks_count_hi << 16 : 0);
-       }
-
-       return fs->group_desc[group].bg_free_blocks_count;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_free_blocks_count |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u32) gdp->bg_free_blocks_count_hi << 16 : 0);
 }
 
 /*
@@ -294,14 +332,13 @@ __u32 ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_free_blocks_count = n;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_free_blocks_count_hi = (__u32) n >> 16;
-       } else
-               fs->group_desc[group].bg_free_blocks_count = n;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_free_blocks_count = n;
+
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_free_blocks_count_hi = (__u32) n >> 16;
 }
 
 /*
@@ -309,17 +346,13 @@ void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
  */
 __u32 ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               return gdp->bg_free_inodes_count |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u32) gdp->bg_free_inodes_count_hi << 16 : 0);
-       }
-
-       return fs->group_desc[group].bg_free_inodes_count;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_free_inodes_count |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u32) gdp->bg_free_inodes_count_hi << 16 : 0);
 }
 
 /*
@@ -327,14 +360,12 @@ __u32 ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_free_inodes_count = n;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_free_inodes_count_hi = (__u32) n >> 16;
-       } else
-               fs->group_desc[group].bg_free_inodes_count = n;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_free_inodes_count = n;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_free_inodes_count_hi = (__u32) n >> 16;
 }
 
 /*
@@ -342,17 +373,13 @@ void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
  */
 __u32 ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               return gdp->bg_used_dirs_count |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u32) gdp->bg_used_dirs_count_hi << 16 : 0);
-       }
+       struct ext4_group_desc *gdp;
 
-       return fs->group_desc[group].bg_used_dirs_count;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_used_dirs_count |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u32) gdp->bg_used_dirs_count_hi << 16 : 0);
 }
 
 /*
@@ -360,14 +387,12 @@ __u32 ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_used_dirs_count = n;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_used_dirs_count_hi = (__u32) n >> 16;
-       } else
-               fs->group_desc[group].bg_used_dirs_count = n;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_used_dirs_count = n;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_used_dirs_count_hi = (__u32) n >> 16;
 }
 
 /*
@@ -375,17 +400,13 @@ void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group, __u32 n)
  */
 __u32 ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               return gdp->bg_itable_unused |
-                       (fs->super->s_feature_incompat
-                        & EXT4_FEATURE_INCOMPAT_64BIT ?
-                        (__u32) gdp->bg_itable_unused_hi << 16 : 0);
-       }
-
-       return fs->group_desc[group].bg_itable_unused;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_itable_unused |
+               (fs->super->s_feature_incompat
+                & EXT4_FEATURE_INCOMPAT_64BIT ?
+                (__u32) gdp->bg_itable_unused_hi << 16 : 0);
 }
 
 /*
@@ -393,14 +414,12 @@ __u32 ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group, __u32 n)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               gdp->bg_itable_unused = n;
-               if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
-                       gdp->bg_itable_unused_hi = (__u32) n >> 16;
-       } else
-               fs->group_desc[group].bg_itable_unused = n;
+       struct ext4_group_desc *gdp;
+
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_itable_unused = n;
+       if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               gdp->bg_itable_unused_hi = (__u32) n >> 16;
 }
 
 /*
@@ -408,93 +427,57 @@ void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group, __u32 n)
  */
 __u16 ext2fs_bg_flags(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               return gdp->bg_flags;
-       }
-
-       return fs->group_desc[group].bg_flags;
-}
-
-/*
- * Set the flags for this block group
- */
-void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
-{
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               gdp->bg_flags = bg_flags;
-               return;
-       }
+       struct ext4_group_desc *gdp;
 
-       fs->group_desc[group].bg_flags = bg_flags;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_flags;
 }
 
 /*
- * Clear the flags for this block group
+ * Zero out the flags for this block group
  */
-void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
+void ext2fs_bg_flags_zap(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               gdp->bg_flags = 0;
-               return;
-       }
+       struct ext4_group_desc *gdp;
 
-       fs->group_desc[group].bg_flags = 0;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_flags = 0;
+       return;
 }
 
 /*
  * Get the value of a particular flag for this block group
  */
-int ext2fs_bg_flag_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
+int ext2fs_bg_flags_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               return gdp->bg_flags & bg_flag;
-       }
-
-       return fs->group_desc[group].bg_flags & bg_flag;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_flags & bg_flag;
 }
 
 /*
- * Set a particular flag for this block group
+ * Set a flag or set of flags for this block group
  */
-void ext2fs_bg_flag_set(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
+void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               gdp->bg_flags |= bg_flag;
-               return;
-       }
-
-       fs->group_desc[group].bg_flags |= bg_flag;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_flags |= bg_flags;
+       return;
 }
 
 /*
- * Clear a particular flag for this block group
+ * Clear a flag or set of flags for this block group
  */
-void ext2fs_bg_flag_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
+void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
+       struct ext4_group_desc *gdp;
 
-               gdp->bg_flags &= ~bg_flag;
-               return;
-       }
-
-       fs->group_desc[group].bg_flags &= ~bg_flag;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_flags &= ~bg_flags;
+       return;
 }
 
 /*
@@ -502,14 +485,10 @@ void ext2fs_bg_flag_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flag)
  */
 __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-
-               return gdp->bg_checksum;
-       }
+       struct ext4_group_desc *gdp;
 
-       return fs->group_desc[group].bg_checksum;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       return gdp->bg_checksum;
 }
 
 /*
@@ -517,36 +496,33 @@ __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group)
  */
 void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum)
 {
-       if (fs->super->s_desc_size >= EXT2_MIN_DESC_SIZE_64BIT) {
-               struct ext4_group_desc *gdp;
-               gdp = (struct ext4_group_desc *) (fs->group_desc) + group;
-               
-               gdp->bg_checksum = checksum;
-               return;
-       }
+       struct ext4_group_desc *gdp;
 
-       fs->group_desc[group].bg_checksum = checksum;
+       gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+       gdp->bg_checksum = checksum;
+       return;
 }
 
 /*
  * Get the acl block of a file
- *
- * XXX Ignoring 64-bit file system flag - most places where this is
- * called don't have access to the fs struct, and the high bits should
- * be 0 in the non-64-bit case anyway.
  */
-blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode)
+blk64_t ext2fs_file_acl_block(ext2_filsys fs, const struct ext2_inode *inode)
 {
-       return (inode->i_file_acl |
-               (__u64) inode->osd2.linux2.l_i_file_acl_high << 32);
+       blk64_t blk = inode->i_file_acl;
+
+       if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               blk |= ((__u64) inode->osd2.linux2.l_i_file_acl_high) << 32;
+       return blk;
 }
 
 /*
  * Set the acl block of a file
  */
-void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk)
+void ext2fs_file_acl_block_set(ext2_filsys fs, struct ext2_inode *inode,
+                              blk64_t blk)
 {
        inode->i_file_acl = blk;
-       inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;
+       if (fs && fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+               inode->osd2.linux2.l_i_file_acl_high = (__u64) blk >> 32;
 }