Эх сурвалжийг харах

ext4: Use helper function to access group descriptor and its fields

The descriptor size is variable, thus array indices are not generically
applicable. The larger group descriptors also contain e.g. high parts
of block numbers, which have to be read and written.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Stefan Brüns 8 жил өмнө
parent
commit
688d0e79f6

+ 65 - 60
fs/ext4/ext4_common.c

@@ -393,7 +393,7 @@ uint16_t ext4fs_checksum_update(uint32_t i)
 	uint16_t crc = 0;
 	uint16_t crc = 0;
 	__le32 le32_i = cpu_to_le32(i);
 	__le32 le32_i = cpu_to_le32(i);
 
 
-	desc = (struct ext2_block_group *)&fs->bgd[i];
+	desc = ext4fs_get_group_descriptor(fs, i);
 	if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
 	if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
 		int offset = offsetof(struct ext2_block_group, bg_checksum);
 		int offset = offsetof(struct ext2_block_group, bg_checksum);
 
 
@@ -933,39 +933,41 @@ uint32_t ext4fs_get_new_blk_no(void)
 	char *zero_buffer = zalloc(fs->blksz);
 	char *zero_buffer = zalloc(fs->blksz);
 	if (!journal_buffer || !zero_buffer)
 	if (!journal_buffer || !zero_buffer)
 		goto fail;
 		goto fail;
-	struct ext2_block_group *bgd = (struct ext2_block_group *)fs->gdtable;
 
 
 	if (fs->first_pass_bbmap == 0) {
 	if (fs->first_pass_bbmap == 0) {
 		for (i = 0; i < fs->no_blkgrp; i++) {
 		for (i = 0; i < fs->no_blkgrp; i++) {
-			if (le16_to_cpu(bgd[i].free_blocks)) {
-				if (le16_to_cpu(bgd[i].bg_flags) & EXT4_BG_BLOCK_UNINIT) {
-					uint16_t new_flags;
-					put_ext4((uint64_t)le32_to_cpu(bgd[i].block_id) * fs->blksz,
-						 zero_buffer, fs->blksz);
-					new_flags = le16_to_cpu(bgd[i].bg_flags) & ~EXT4_BG_BLOCK_UNINIT;
-					bgd[i].bg_flags = cpu_to_le16(new_flags);
+			struct ext2_block_group *bgd = NULL;
+			bgd = ext4fs_get_group_descriptor(fs, i);
+			if (ext4fs_bg_get_free_blocks(bgd, fs)) {
+				uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+				uint64_t b_bitmap_blk =
+					ext4fs_bg_get_block_id(bgd, fs);
+				if (bg_flags & EXT4_BG_BLOCK_UNINIT) {
 					memcpy(fs->blk_bmaps[i], zero_buffer,
 					memcpy(fs->blk_bmaps[i], zero_buffer,
 					       fs->blksz);
 					       fs->blksz);
+					put_ext4(b_bitmap_blk * fs->blksz,
+						 fs->blk_bmaps[i], fs->blksz);
+					bg_flags &= ~EXT4_BG_BLOCK_UNINIT;
+					ext4fs_bg_set_flags(bgd, bg_flags);
 				}
 				}
 				fs->curr_blkno =
 				fs->curr_blkno =
 				    _get_new_blk_no(fs->blk_bmaps[i]);
 				    _get_new_blk_no(fs->blk_bmaps[i]);
 				if (fs->curr_blkno == -1)
 				if (fs->curr_blkno == -1)
-					/* if block bitmap is completely fill */
+					/* block bitmap is completely filled */
 					continue;
 					continue;
 				fs->curr_blkno = fs->curr_blkno +
 				fs->curr_blkno = fs->curr_blkno +
 						(i * fs->blksz * 8);
 						(i * fs->blksz * 8);
 				fs->first_pass_bbmap++;
 				fs->first_pass_bbmap++;
-				ext4fs_bg_free_blocks_dec(&bgd[i]);
+				ext4fs_bg_free_blocks_dec(bgd);
 				ext4fs_sb_free_blocks_dec(fs->sb);
 				ext4fs_sb_free_blocks_dec(fs->sb);
-				status = ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[i].block_id) *
-							fs->sect_perblk, 0,
-							fs->blksz,
+				status = ext4fs_devread(b_bitmap_blk *
+							fs->sect_perblk,
+							0, fs->blksz,
 							journal_buffer);
 							journal_buffer);
 				if (status == 0)
 				if (status == 0)
 					goto fail;
 					goto fail;
 				if (ext4fs_log_journal(journal_buffer,
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[i].block_id)))
+						       b_bitmap_blk))
 					goto fail;
 					goto fail;
 				goto success;
 				goto success;
 			} else {
 			} else {
@@ -992,7 +994,9 @@ restart:
 		if (bg_idx >= fs->no_blkgrp)
 		if (bg_idx >= fs->no_blkgrp)
 			goto fail;
 			goto fail;
 
 
-		if (bgd[bg_idx].free_blocks == 0) {
+		struct ext2_block_group *bgd = NULL;
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		if (ext4fs_bg_get_free_blocks(bgd, fs) == 0) {
 			debug("block group %u is full. Skipping\n", bg_idx);
 			debug("block group %u is full. Skipping\n", bg_idx);
 			fs->curr_blkno = (bg_idx + 1) * blk_per_grp;
 			fs->curr_blkno = (bg_idx + 1) * blk_per_grp;
 			if (fs->blksz == 1024)
 			if (fs->blksz == 1024)
@@ -1000,13 +1004,14 @@ restart:
 			goto restart;
 			goto restart;
 		}
 		}
 
 
-		if (le16_to_cpu(bgd[bg_idx].bg_flags) & EXT4_BG_BLOCK_UNINIT) {
-			uint16_t new_flags;
-			put_ext4((uint64_t)le32_to_cpu(bgd[bg_idx].block_id) * fs->blksz,
-				 zero_buffer, fs->blksz);
+		uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+		uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+		if (bg_flags & EXT4_BG_BLOCK_UNINIT) {
 			memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
 			memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
-			new_flags = le16_to_cpu(bgd[bg_idx].bg_flags) & ~EXT4_BG_BLOCK_UNINIT;
-			bgd[bg_idx].bg_flags = cpu_to_le16(new_flags);
+			put_ext4(b_bitmap_blk * fs->blksz,
+				 zero_buffer, fs->blksz);
+			bg_flags &= ~EXT4_BG_BLOCK_UNINIT;
+			ext4fs_bg_set_flags(bgd, bg_flags);
 		}
 		}
 
 
 		if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx],
 		if (ext4fs_set_block_bmap(fs->curr_blkno, fs->blk_bmaps[bg_idx],
@@ -1019,19 +1024,16 @@ restart:
 
 
 		/* journal backup */
 		/* journal backup */
 		if (prev_bg_bitmap_index != bg_idx) {
 		if (prev_bg_bitmap_index != bg_idx) {
-			status = ext4fs_devread(
-						(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id)
-						* fs->sect_perblk,
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
 			if (status == 0)
 				goto fail;
 				goto fail;
-			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 				goto fail;
 
 
 			prev_bg_bitmap_index = bg_idx;
 			prev_bg_bitmap_index = bg_idx;
 		}
 		}
-		ext4fs_bg_free_blocks_dec(&bgd[bg_idx]);
+		ext4fs_bg_free_blocks_dec(bgd);
 		ext4fs_sb_free_blocks_dec(fs->sb);
 		ext4fs_sb_free_blocks_dec(fs->sb);
 		goto success;
 		goto success;
 	}
 	}
@@ -1059,46 +1061,49 @@ int ext4fs_get_new_inode_no(void)
 	char *zero_buffer = zalloc(fs->blksz);
 	char *zero_buffer = zalloc(fs->blksz);
 	if (!journal_buffer || !zero_buffer)
 	if (!journal_buffer || !zero_buffer)
 		goto fail;
 		goto fail;
-	struct ext2_block_group *bgd = (struct ext2_block_group *)fs->gdtable;
 	int has_gdt_chksum = le32_to_cpu(fs->sb->feature_ro_compat) &
 	int has_gdt_chksum = le32_to_cpu(fs->sb->feature_ro_compat) &
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM ? 1 : 0;
 		EXT4_FEATURE_RO_COMPAT_GDT_CSUM ? 1 : 0;
 
 
 	if (fs->first_pass_ibmap == 0) {
 	if (fs->first_pass_ibmap == 0) {
 		for (i = 0; i < fs->no_blkgrp; i++) {
 		for (i = 0; i < fs->no_blkgrp; i++) {
-			if (bgd[i].free_inodes) {
+			uint32_t free_inodes;
+			struct ext2_block_group *bgd = NULL;
+			bgd = ext4fs_get_group_descriptor(fs, i);
+			free_inodes = ext4fs_bg_get_free_inodes(bgd, fs);
+			if (free_inodes) {
+				uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+				uint64_t i_bitmap_blk =
+					ext4fs_bg_get_inode_id(bgd, fs);
 				if (has_gdt_chksum)
 				if (has_gdt_chksum)
-					bgd[i].bg_itable_unused =
-						bgd[i].free_inodes;
-				if (le16_to_cpu(bgd[i].bg_flags) & EXT4_BG_INODE_UNINIT) {
-					int new_flags;
-					put_ext4((uint64_t)le32_to_cpu(bgd[i].inode_id) * fs->blksz,
+					bgd->bg_itable_unused = free_inodes;
+				if (bg_flags & EXT4_BG_INODE_UNINIT) {
+					put_ext4(i_bitmap_blk * fs->blksz,
 						 zero_buffer, fs->blksz);
 						 zero_buffer, fs->blksz);
-					new_flags = le16_to_cpu(bgd[i].bg_flags) & ~EXT4_BG_INODE_UNINIT;
-					bgd[i].bg_flags = cpu_to_le16(new_flags);
+					bg_flags &= ~EXT4_BG_INODE_UNINIT;
+					ext4fs_bg_set_flags(bgd, bg_flags);
 					memcpy(fs->inode_bmaps[i],
 					memcpy(fs->inode_bmaps[i],
 					       zero_buffer, fs->blksz);
 					       zero_buffer, fs->blksz);
 				}
 				}
 				fs->curr_inode_no =
 				fs->curr_inode_no =
 				    _get_new_inode_no(fs->inode_bmaps[i]);
 				    _get_new_inode_no(fs->inode_bmaps[i]);
 				if (fs->curr_inode_no == -1)
 				if (fs->curr_inode_no == -1)
-					/* if block bitmap is completely fill */
+					/* inode bitmap is completely filled */
 					continue;
 					continue;
 				fs->curr_inode_no = fs->curr_inode_no +
 				fs->curr_inode_no = fs->curr_inode_no +
 							(i * inodes_per_grp);
 							(i * inodes_per_grp);
 				fs->first_pass_ibmap++;
 				fs->first_pass_ibmap++;
-				ext4fs_bg_free_inodes_dec(&bgd[i]);
+				ext4fs_bg_free_inodes_dec(bgd);
 				if (has_gdt_chksum)
 				if (has_gdt_chksum)
-					ext4fs_bg_itable_unused_dec(&bgd[i]);
+					ext4fs_bg_itable_unused_dec(bgd);
 				ext4fs_sb_free_inodes_dec(fs->sb);
 				ext4fs_sb_free_inodes_dec(fs->sb);
-				status = ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[i].inode_id) *
-							fs->sect_perblk, 0,
-							fs->blksz,
+				status = ext4fs_devread(i_bitmap_blk *
+							fs->sect_perblk,
+							0, fs->blksz,
 							journal_buffer);
 							journal_buffer);
 				if (status == 0)
 				if (status == 0)
 					goto fail;
 					goto fail;
 				if (ext4fs_log_journal(journal_buffer,
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[i].inode_id)))
+						       i_bitmap_blk))
 					goto fail;
 					goto fail;
 				goto success;
 				goto success;
 			} else
 			} else
@@ -1110,12 +1115,16 @@ restart:
 		fs->curr_inode_no++;
 		fs->curr_inode_no++;
 		/* get the blockbitmap index respective to blockno */
 		/* get the blockbitmap index respective to blockno */
 		ibmap_idx = fs->curr_inode_no / inodes_per_grp;
 		ibmap_idx = fs->curr_inode_no / inodes_per_grp;
-		if (le16_to_cpu(bgd[ibmap_idx].bg_flags) & EXT4_BG_INODE_UNINIT) {
-			int new_flags;
-			put_ext4((uint64_t)le32_to_cpu(bgd[ibmap_idx].inode_id) * fs->blksz,
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, ibmap_idx);
+		uint16_t bg_flags = ext4fs_bg_get_flags(bgd);
+		uint64_t i_bitmap_blk = ext4fs_bg_get_inode_id(bgd, fs);
+
+		if (bg_flags & EXT4_BG_INODE_UNINIT) {
+			put_ext4(i_bitmap_blk * fs->blksz,
 				 zero_buffer, fs->blksz);
 				 zero_buffer, fs->blksz);
-			new_flags = le16_to_cpu(bgd[ibmap_idx].bg_flags) & ~EXT4_BG_INODE_UNINIT;
-			bgd[ibmap_idx].bg_flags = cpu_to_le16(new_flags);
+			bg_flags &= ~EXT4_BG_INODE_UNINIT;
+			ext4fs_bg_set_flags(bgd, bg_flags);
 			memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer,
 			memcpy(fs->inode_bmaps[ibmap_idx], zero_buffer,
 				fs->blksz);
 				fs->blksz);
 		}
 		}
@@ -1130,22 +1139,18 @@ restart:
 
 
 		/* journal backup */
 		/* journal backup */
 		if (prev_inode_bitmap_index != ibmap_idx) {
 		if (prev_inode_bitmap_index != ibmap_idx) {
-			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(
-						(lbaint_t)le32_to_cpu(bgd[ibmap_idx].inode_id)
-						* fs->sect_perblk,
+			status = ext4fs_devread(i_bitmap_blk * fs->sect_perblk,
 						0, fs->blksz, journal_buffer);
 						0, fs->blksz, journal_buffer);
 			if (status == 0)
 			if (status == 0)
 				goto fail;
 				goto fail;
 			if (ext4fs_log_journal(journal_buffer,
 			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[ibmap_idx].inode_id)))
+						le32_to_cpu(bgd->inode_id)))
 				goto fail;
 				goto fail;
 			prev_inode_bitmap_index = ibmap_idx;
 			prev_inode_bitmap_index = ibmap_idx;
 		}
 		}
-		ext4fs_bg_free_inodes_dec(&bgd[ibmap_idx]);
+		ext4fs_bg_free_inodes_dec(bgd);
 		if (has_gdt_chksum)
 		if (has_gdt_chksum)
-			bgd[ibmap_idx].bg_itable_unused =
-					bgd[ibmap_idx].free_inodes;
+			bgd->bg_itable_unused = bgd->free_inodes;
 		ext4fs_sb_free_inodes_dec(fs->sb);
 		ext4fs_sb_free_inodes_dec(fs->sb);
 		goto success;
 		goto success;
 	}
 	}
@@ -1561,7 +1566,7 @@ int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
 		return 0;
 		return 0;
 
 
 	inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz;
 	inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz;
-	blkno = le32_to_cpu(blkgrp.inode_table_id) +
+	blkno = ext4fs_bg_get_inode_table_id(&blkgrp, fs) +
 	    (ino % le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	    (ino % le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	blkoff = (ino % inodes_per_block) * fs->inodesz;
 	/* Read the inode. */
 	/* Read the inode. */

+ 89 - 76
fs/ext4/ext4_write.c

@@ -53,21 +53,26 @@ static void ext4fs_update(void)
 	short i;
 	short i;
 	ext4fs_update_journal();
 	ext4fs_update_journal();
 	struct ext_filesystem *fs = get_fs();
 	struct ext_filesystem *fs = get_fs();
+	struct ext2_block_group *bgd = NULL;
 
 
 	/* update  super block */
 	/* update  super block */
 	put_ext4((uint64_t)(SUPERBLOCK_SIZE),
 	put_ext4((uint64_t)(SUPERBLOCK_SIZE),
 		 (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE);
 		 (struct ext2_sblock *)fs->sb, (uint32_t)SUPERBLOCK_SIZE);
 
 
-	/* update block groups */
+	/* update block bitmaps */
 	for (i = 0; i < fs->no_blkgrp; i++) {
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		fs->bgd[i].bg_checksum = cpu_to_le16(ext4fs_checksum_update(i));
-		put_ext4((uint64_t)le32_to_cpu(fs->bgd[i].block_id) * fs->blksz,
+		bgd = ext4fs_get_group_descriptor(fs, i);
+		bgd->bg_checksum = cpu_to_le16(ext4fs_checksum_update(i));
+		uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+		put_ext4(b_bitmap_blk * fs->blksz,
 			 fs->blk_bmaps[i], fs->blksz);
 			 fs->blk_bmaps[i], fs->blksz);
 	}
 	}
 
 
-	/* update inode table groups */
+	/* update inode bitmaps */
 	for (i = 0; i < fs->no_blkgrp; i++) {
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		put_ext4((uint64_t)le32_to_cpu(fs->bgd[i].inode_id) * fs->blksz,
+		bgd = ext4fs_get_group_descriptor(fs, i);
+		uint64_t i_bitmap_blk = ext4fs_bg_get_inode_id(bgd, fs);
+		put_ext4(i_bitmap_blk * fs->blksz,
 			 fs->inode_bmaps[i], fs->blksz);
 			 fs->inode_bmaps[i], fs->blksz);
 	}
 	}
 
 
@@ -85,15 +90,12 @@ static void ext4fs_update(void)
 int ext4fs_get_bgdtable(void)
 int ext4fs_get_bgdtable(void)
 {
 {
 	int status;
 	int status;
-	int grp_desc_size;
 	struct ext_filesystem *fs = get_fs();
 	struct ext_filesystem *fs = get_fs();
-	grp_desc_size = sizeof(struct ext2_block_group);
-	fs->no_blk_pergdt = (fs->no_blkgrp * grp_desc_size) / fs->blksz;
-	if ((fs->no_blkgrp * grp_desc_size) % fs->blksz)
-		fs->no_blk_pergdt++;
+	int gdsize_total = ROUND(fs->no_blkgrp * fs->gdsize, fs->blksz);
+	fs->no_blk_pergdt = gdsize_total / fs->blksz;
 
 
 	/* allocate memory for gdtable */
 	/* allocate memory for gdtable */
-	fs->gdtable = zalloc(fs->blksz * fs->no_blk_pergdt);
+	fs->gdtable = zalloc(gdsize_total);
 	if (!fs->gdtable)
 	if (!fs->gdtable)
 		return -ENOMEM;
 		return -ENOMEM;
 	/* read the group descriptor table */
 	/* read the group descriptor table */
@@ -130,8 +132,6 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 		printf("No memory\n");
 		printf("No memory\n");
 		return;
 		return;
 	}
 	}
-	/* get  block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 
 
 	/* deleting the single indirect block associated with inode */
 	/* deleting the single indirect block associated with inode */
 	if (inode->b.blocks.indir_block != 0) {
 	if (inode->b.blocks.indir_block != 0) {
@@ -144,18 +144,19 @@ static void delete_single_indirect_block(struct ext2_inode *inode)
 				bg_idx--;
 				bg_idx--;
 		}
 		}
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 		if (prev_bg_bmap_idx != bg_idx) {
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
 			status = ext4fs_devread(
 			status = ext4fs_devread(
-					   (lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-					   fs->sect_perblk, 0, fs->blksz,
-					   journal_buffer);
+					   b_bitmap_blk * fs->sect_perblk,
+					   0, fs->blksz, journal_buffer);
 			if (status == 0)
 			if (status == 0)
 				goto fail;
 				goto fail;
-			if (ext4fs_log_journal
-			    (journal_buffer, le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 			prev_bg_bmap_idx = bg_idx;
 		}
 		}
@@ -182,8 +183,6 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 		printf("No memory\n");
 		printf("No memory\n");
 		return;
 		return;
 	}
 	}
-	/* get the block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 
 
 	if (inode->b.blocks.double_indir_block != 0) {
 	if (inode->b.blocks.double_indir_block != 0) {
 		di_buffer = zalloc(fs->blksz);
 		di_buffer = zalloc(fs->blksz);
@@ -206,15 +205,18 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 				if (!remainder)
 				if (!remainder)
 					bg_idx--;
 					bg_idx--;
 			}
 			}
+			/* get  block group descriptor table */
+			bgd = ext4fs_get_group_descriptor(fs, bg_idx);
 			ext4fs_reset_block_bmap(le32_to_cpu(*di_buffer),
 			ext4fs_reset_block_bmap(le32_to_cpu(*di_buffer),
 					fs->blk_bmaps[bg_idx], bg_idx);
 					fs->blk_bmaps[bg_idx], bg_idx);
 			di_buffer++;
 			di_buffer++;
-			ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+			ext4fs_bg_free_blocks_inc(bgd);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			/* journal backup */
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 			if (prev_bg_bmap_idx != bg_idx) {
-				status = ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id)
+				uint64_t b_bitmap_blk =
+					ext4fs_bg_get_block_id(bgd, fs);
+				status = ext4fs_devread(b_bitmap_blk
 							* fs->sect_perblk, 0,
 							* fs->sect_perblk, 0,
 							fs->blksz,
 							fs->blksz,
 							journal_buffer);
 							journal_buffer);
@@ -222,7 +224,7 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 					goto fail;
 					goto fail;
 
 
 				if (ext4fs_log_journal(journal_buffer,
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[bg_idx].block_id)))
+						       b_bitmap_blk))
 					goto fail;
 					goto fail;
 				prev_bg_bmap_idx = bg_idx;
 				prev_bg_bmap_idx = bg_idx;
 			}
 			}
@@ -236,20 +238,20 @@ static void delete_double_indirect_block(struct ext2_inode *inode)
 			if (!remainder)
 			if (!remainder)
 				bg_idx--;
 				bg_idx--;
 		}
 		}
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 		if (prev_bg_bmap_idx != bg_idx) {
-			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread((lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-						fs->sect_perblk, 0, fs->blksz,
-						journal_buffer);
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
+						0, fs->blksz, journal_buffer);
 			if (status == 0)
 			if (status == 0)
 				goto fail;
 				goto fail;
 
 
-			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 			prev_bg_bmap_idx = bg_idx;
 		}
 		}
@@ -280,8 +282,6 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 		printf("No memory\n");
 		printf("No memory\n");
 		return;
 		return;
 	}
 	}
-	/* get block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 
 
 	if (inode->b.blocks.triple_indir_block != 0) {
 	if (inode->b.blocks.triple_indir_block != 0) {
 		tigp_buffer = zalloc(fs->blksz);
 		tigp_buffer = zalloc(fs->blksz);
@@ -320,13 +320,17 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 							bg_idx);
 							bg_idx);
 
 
 				tip_buffer++;
 				tip_buffer++;
-				ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+				/* get  block group descriptor table */
+				bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+				ext4fs_bg_free_blocks_inc(bgd);
 				ext4fs_sb_free_blocks_inc(fs->sb);
 				ext4fs_sb_free_blocks_inc(fs->sb);
 				/* journal backup */
 				/* journal backup */
 				if (prev_bg_bmap_idx != bg_idx) {
 				if (prev_bg_bmap_idx != bg_idx) {
+					uint64_t b_bitmap_blk =
+						ext4fs_bg_get_block_id(bgd, fs);
 					status =
 					status =
 					    ext4fs_devread(
 					    ext4fs_devread(
-							(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
+							b_bitmap_blk *
 							fs->sect_perblk, 0,
 							fs->sect_perblk, 0,
 							fs->blksz,
 							fs->blksz,
 							journal_buffer);
 							journal_buffer);
@@ -334,7 +338,7 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 						goto fail;
 						goto fail;
 
 
 					if (ext4fs_log_journal(journal_buffer,
 					if (ext4fs_log_journal(journal_buffer,
-							       le32_to_cpu(bgd[bg_idx].block_id)))
+							       b_bitmap_blk))
 						goto fail;
 						goto fail;
 					prev_bg_bmap_idx = bg_idx;
 					prev_bg_bmap_idx = bg_idx;
 				}
 				}
@@ -356,21 +360,24 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 						fs->blk_bmaps[bg_idx], bg_idx);
 						fs->blk_bmaps[bg_idx], bg_idx);
 
 
 			tigp_buffer++;
 			tigp_buffer++;
-			ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+			/* get  block group descriptor table */
+			bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+			ext4fs_bg_free_blocks_inc(bgd);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			ext4fs_sb_free_blocks_inc(fs->sb);
 			/* journal backup */
 			/* journal backup */
 			if (prev_bg_bmap_idx != bg_idx) {
 			if (prev_bg_bmap_idx != bg_idx) {
+				uint64_t b_bitmap_blk =
+					ext4fs_bg_get_block_id(bgd, fs);
 				memset(journal_buffer, '\0', fs->blksz);
 				memset(journal_buffer, '\0', fs->blksz);
-				status =
-				    ext4fs_devread(
-						   (lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-						   fs->sect_perblk, 0,
-						   fs->blksz, journal_buffer);
+				status = ext4fs_devread(b_bitmap_blk *
+							fs->sect_perblk, 0,
+							fs->blksz,
+							journal_buffer);
 				if (status == 0)
 				if (status == 0)
 					goto fail;
 					goto fail;
 
 
 				if (ext4fs_log_journal(journal_buffer,
 				if (ext4fs_log_journal(journal_buffer,
-							le32_to_cpu(bgd[bg_idx].block_id)))
+						       b_bitmap_blk))
 					goto fail;
 					goto fail;
 				prev_bg_bmap_idx = bg_idx;
 				prev_bg_bmap_idx = bg_idx;
 			}
 			}
@@ -385,20 +392,19 @@ static void delete_triple_indirect_block(struct ext2_inode *inode)
 				bg_idx--;
 				bg_idx--;
 		}
 		}
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
 		ext4fs_reset_block_bmap(blknr, fs->blk_bmaps[bg_idx], bg_idx);
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 		if (prev_bg_bmap_idx != bg_idx) {
-			memset(journal_buffer, '\0', fs->blksz);
-			status = ext4fs_devread(
-						(lbaint_t)le32_to_cpu(bgd[bg_idx].block_id) *
-						fs->sect_perblk, 0, fs->blksz,
-						journal_buffer);
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
+						0, fs->blksz, journal_buffer);
 			if (status == 0)
 			if (status == 0)
 				goto fail;
 				goto fail;
 
 
-			if (ext4fs_log_journal(journal_buffer,
-						le32_to_cpu(bgd[bg_idx].block_id)))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 			prev_bg_bmap_idx = bg_idx;
 		}
 		}
@@ -435,8 +441,6 @@ static int ext4fs_delete_file(int inodeno)
 	char *journal_buffer = zalloc(fs->blksz);
 	char *journal_buffer = zalloc(fs->blksz);
 	if (!journal_buffer)
 	if (!journal_buffer)
 		return -ENOMEM;
 		return -ENOMEM;
-	/* get the block group descriptor table */
-	bgd = (struct ext2_block_group *)fs->gdtable;
 	status = ext4fs_read_inode(ext4fs_root, inodeno, &inode);
 	status = ext4fs_read_inode(ext4fs_root, inodeno, &inode);
 	if (status == 0)
 	if (status == 0)
 		goto fail;
 		goto fail;
@@ -475,18 +479,19 @@ static int ext4fs_delete_file(int inodeno)
 					bg_idx);
 					bg_idx);
 		debug("EXT4 Block releasing %ld: %d\n", blknr, bg_idx);
 		debug("EXT4 Block releasing %ld: %d\n", blknr, bg_idx);
 
 
-		ext4fs_bg_free_blocks_inc(&bgd[bg_idx]);
+		/* get  block group descriptor table */
+		bgd = ext4fs_get_group_descriptor(fs, bg_idx);
+		ext4fs_bg_free_blocks_inc(bgd);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		ext4fs_sb_free_blocks_inc(fs->sb);
 		/* journal backup */
 		/* journal backup */
 		if (prev_bg_bmap_idx != bg_idx) {
 		if (prev_bg_bmap_idx != bg_idx) {
-			uint32_t bgd_blknr = le32_to_cpu(bgd[bg_idx].block_id);
-			status = ext4fs_devread((lbaint_t)bgd_blknr *
-						fs->sect_perblk,
+			uint64_t b_bitmap_blk = ext4fs_bg_get_block_id(bgd, fs);
+			status = ext4fs_devread(b_bitmap_blk * fs->sect_perblk,
 						0, fs->blksz,
 						0, fs->blksz,
 						journal_buffer);
 						journal_buffer);
 			if (status == 0)
 			if (status == 0)
 				goto fail;
 				goto fail;
-			if (ext4fs_log_journal(journal_buffer, bgd_blknr))
+			if (ext4fs_log_journal(journal_buffer, b_bitmap_blk))
 				goto fail;
 				goto fail;
 			prev_bg_bmap_idx = bg_idx;
 			prev_bg_bmap_idx = bg_idx;
 		}
 		}
@@ -499,7 +504,9 @@ static int ext4fs_delete_file(int inodeno)
 
 
 	/* get the block no */
 	/* get the block no */
 	inodeno--;
 	inodeno--;
-	blkno = le32_to_cpu(bgd[ibmap_idx].inode_table_id) +
+	/* get  block group descriptor table */
+	bgd = ext4fs_get_group_descriptor(fs, ibmap_idx);
+	blkno = ext4fs_bg_get_inode_table_id(bgd, fs) +
 		(inodeno % inode_per_grp) / inodes_per_block;
 		(inodeno % inode_per_grp) / inodes_per_block;
 
 
 	/* get the offset of the inode */
 	/* get the offset of the inode */
@@ -529,15 +536,15 @@ static int ext4fs_delete_file(int inodeno)
 	/* update the respective inode bitmaps */
 	/* update the respective inode bitmaps */
 	inodeno++;
 	inodeno++;
 	ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx);
 	ext4fs_reset_inode_bmap(inodeno, fs->inode_bmaps[ibmap_idx], ibmap_idx);
-	ext4fs_bg_free_inodes_inc(&bgd[ibmap_idx]);
+	ext4fs_bg_free_inodes_inc(bgd);
 	ext4fs_sb_free_inodes_inc(fs->sb);
 	ext4fs_sb_free_inodes_inc(fs->sb);
 	/* journal backup */
 	/* journal backup */
 	memset(journal_buffer, '\0', fs->blksz);
 	memset(journal_buffer, '\0', fs->blksz);
-	status = ext4fs_devread((lbaint_t)le32_to_cpu(bgd[ibmap_idx].inode_id) *
+	status = ext4fs_devread(ext4fs_bg_get_inode_id(bgd, fs) *
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 				fs->sect_perblk, 0, fs->blksz, journal_buffer);
 	if (status == 0)
 	if (status == 0)
 		goto fail;
 		goto fail;
-	if (ext4fs_log_journal(journal_buffer, le32_to_cpu(bgd[ibmap_idx].inode_id)))
+	if (ext4fs_log_journal(journal_buffer, ext4fs_bg_get_inode_id(bgd, fs)))
 		goto fail;
 		goto fail;
 
 
 	ext4fs_update();
 	ext4fs_update();
@@ -594,7 +601,6 @@ int ext4fs_init(void)
 		printf("Error in getting the block group descriptor table\n");
 		printf("Error in getting the block group descriptor table\n");
 		goto fail;
 		goto fail;
 	}
 	}
-	fs->bgd = (struct ext2_block_group *)fs->gdtable;
 
 
 	/* load all the available bitmap block of the partition */
 	/* load all the available bitmap block of the partition */
 	fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *));
 	fs->blk_bmaps = zalloc(fs->no_blkgrp * sizeof(char *));
@@ -607,9 +613,9 @@ int ext4fs_init(void)
 	}
 	}
 
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status =
-		    ext4fs_devread(
-				   (lbaint_t)le32_to_cpu(fs->bgd[i].block_id) *
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, i);
+		status = ext4fs_devread(ext4fs_bg_get_block_id(bgd, fs) *
 				   fs->sect_perblk, 0,
 				   fs->sect_perblk, 0,
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 				   fs->blksz, (char *)fs->blk_bmaps[i]);
 		if (status == 0)
 		if (status == 0)
@@ -627,8 +633,9 @@ int ext4fs_init(void)
 	}
 	}
 
 
 	for (i = 0; i < fs->no_blkgrp; i++) {
 	for (i = 0; i < fs->no_blkgrp; i++) {
-		status = ext4fs_devread(
-					(lbaint_t)le32_to_cpu(fs->bgd[i].inode_id) *
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, i);
+		status = ext4fs_devread(ext4fs_bg_get_inode_id(bgd, fs) *
 					fs->sect_perblk,
 					fs->sect_perblk,
 					0, fs->blksz,
 					0, fs->blksz,
 					(char *)fs->inode_bmaps[i]);
 					(char *)fs->inode_bmaps[i]);
@@ -642,10 +649,14 @@ int ext4fs_init(void)
 	 * with the  blockgroups freeblocks when improper
 	 * with the  blockgroups freeblocks when improper
 	 * reboot of a linux kernel
 	 * reboot of a linux kernel
 	 */
 	 */
-	for (i = 0; i < fs->no_blkgrp; i++)
-		real_free_blocks = real_free_blocks + le16_to_cpu(fs->bgd[i].free_blocks);
-	if (real_free_blocks != le32_to_cpu(fs->sb->free_blocks))
-		fs->sb->free_blocks = cpu_to_le32(real_free_blocks);
+	for (i = 0; i < fs->no_blkgrp; i++) {
+		struct ext2_block_group *bgd =
+			ext4fs_get_group_descriptor(fs, i);
+		real_free_blocks = real_free_blocks +
+			ext4fs_bg_get_free_blocks(bgd, fs);
+	}
+	if (real_free_blocks != ext4fs_sb_get_free_blocks(fs->sb))
+		ext4fs_sb_set_free_blocks(fs->sb, real_free_blocks);
 
 
 	return 0;
 	return 0;
 fail:
 fail:
@@ -711,7 +722,6 @@ void ext4fs_deinit(void)
 
 
 	free(fs->gdtable);
 	free(fs->gdtable);
 	fs->gdtable = NULL;
 	fs->gdtable = NULL;
-	fs->bgd = NULL;
 	/*
 	/*
 	 * reinitiliazed the global inode and
 	 * reinitiliazed the global inode and
 	 * block bitmap first execution check variables
 	 * block bitmap first execution check variables
@@ -826,6 +836,7 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	struct ext2_sblock *sblock = &(ext4fs_root->sblock);
 	struct ext2_sblock *sblock = &(ext4fs_root->sblock);
 	unsigned int inodes_per_block;
 	unsigned int inodes_per_block;
 	unsigned int ibmap_idx;
 	unsigned int ibmap_idx;
+	struct ext2_block_group *bgd = NULL;
 	struct ext_filesystem *fs = get_fs();
 	struct ext_filesystem *fs = get_fs();
 	ALLOC_CACHE_ALIGN_BUFFER(char, filename, 256);
 	ALLOC_CACHE_ALIGN_BUFFER(char, filename, 256);
 	memset(filename, 0x00, 256);
 	memset(filename, 0x00, 256);
@@ -903,7 +914,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 		goto fail;
 		goto fail;
 	ibmap_idx = inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
 	ibmap_idx = inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
 	inodeno--;
 	inodeno--;
-	itable_blkno = le32_to_cpu(fs->bgd[ibmap_idx].inode_table_id) +
+	bgd = ext4fs_get_group_descriptor(fs, ibmap_idx);
+	itable_blkno = ext4fs_bg_get_inode_table_id(bgd, fs) +
 			(inodeno % le32_to_cpu(sblock->inodes_per_group)) /
 			(inodeno % le32_to_cpu(sblock->inodes_per_group)) /
 			inodes_per_block;
 			inodes_per_block;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
 	blkoff = (inodeno % inodes_per_block) * fs->inodesz;
@@ -923,7 +935,8 @@ int ext4fs_write(const char *fname, unsigned char *buffer,
 	}
 	}
 	ibmap_idx = parent_inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
 	ibmap_idx = parent_inodeno / le32_to_cpu(ext4fs_root->sblock.inodes_per_group);
 	parent_inodeno--;
 	parent_inodeno--;
-	parent_itable_blkno = le32_to_cpu(fs->bgd[ibmap_idx].inode_table_id) +
+	bgd = ext4fs_get_group_descriptor(fs, ibmap_idx);
+	parent_itable_blkno = ext4fs_bg_get_inode_table_id(bgd, fs) +
 	    (parent_inodeno %
 	    (parent_inodeno %
 	     le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	     le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;
 	blkoff = (parent_inodeno % inodes_per_block) * fs->inodesz;

+ 0 - 1
include/ext4fs.h

@@ -98,7 +98,6 @@ struct ext_filesystem {
 	/* Superblock */
 	/* Superblock */
 	struct ext2_sblock *sb;
 	struct ext2_sblock *sb;
 	/* Block group descritpor table */
 	/* Block group descritpor table */
-	struct ext2_block_group *bgd;
 	char *gdtable;
 	char *gdtable;
 
 
 	/* Block Bitmap Related */
 	/* Block Bitmap Related */