lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri,  7 Aug 2015 12:51:14 +0200
From:	Jan Kara <jack@...e.com>
To:	linux-ext4@...r.kernel.org
Cc:	Ted Tso <tytso@....edu>,
	"Darrick J. Wong" <darrick.wong@...cle.com>,
	Jan Kara <jack@...e.com>
Subject: [PATCH 04/19] ext2fs: Implement ext2fs_allocate_group_table2()

Implement ext2fs_allocate_group_table2() which marks blocks also in
fs->block_map unconditionally and which always updates allocation
statistics.

Signed-off-by: Jan Kara <jack@...e.com>
---
 lib/ext2fs/alloc_tables.c | 93 ++++++++++++++++++++++++++++++++++-------------
 lib/ext2fs/ext2fs.h       |  7 ++++
 2 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
index 3e1952fa63e8..9eedd7712be9 100644
--- a/lib/ext2fs/alloc_tables.c
+++ b/lib/ext2fs/alloc_tables.c
@@ -81,19 +81,59 @@ static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
 	return first_free;
 }
 
-errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
-				      ext2fs_block_bitmap bmap)
+static void update_block_bitmap_stats(ext2_filsys fs, blk64_t blk, int len,
+				      unsigned long flags)
+{
+	if (flags & EXT2FS_ALLOC_TABLE_UPDATE_STATS) {
+		ext2fs_block_alloc_stats_range(fs, blk, len, +1);
+		if (!(flags & EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP))
+			ext2fs_unmark_block_bitmap_range2(fs->block_map, blk,
+							  len);
+	} else if (flags & EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP) {
+		dgrp_t g, end;
+
+		ext2fs_mark_block_bitmap_range2(fs->block_map, blk, len);
+		/*
+		 * It's an overkill to assume more than two groups can be
+		 * touched but the code is easy to understand this way.
+		 */
+		end = ext2fs_group_of_blk2(fs, blk + len - 1);
+		for (g = ext2fs_group_of_blk2(fs, blk); g <= end; g++) {
+			if (ext2fs_bg_flags_test(fs, g, EXT2_BG_BLOCK_UNINIT)) {
+				ext2fs_bg_flags_clear(fs, g,
+						      EXT2_BG_BLOCK_UNINIT);
+				ext2fs_group_desc_csum_set(fs, g);
+			}
+		}
+	}
+}
+
+/*
+ * Allocate group metadata (bitmaps, inode table) if not present. If
+ * reserve_bmap is set, we use that as a bitmap of blocks free for allocation
+ * (and update used blocks there as well as in fs->block_map).
+ */
+errcode_t ext2fs_allocate_group_table2(ext2_filsys fs, dgrp_t group,
+				       ext2fs_block_bitmap reserve_bmap,
+				       unsigned long flags)
 {
 	errcode_t	retval;
 	blk64_t		group_blk, start_blk, last_blk, new_blk;
 	dgrp_t		last_grp = 0;
 	int		rem_grps = 0, flexbg_size = 0, table_offset = 0;
+	ext2fs_block_bitmap bmap;
 
 	group_blk = ext2fs_group_first_block2(fs, group);
 	last_blk = ext2fs_group_last_block2(fs, group);
 
-	if (!bmap)
+	if (reserve_bmap == fs->block_map)
+		reserve_bmap = NULL;
+
+	if (!reserve_bmap) {
 		bmap = fs->block_map;
+		flags |= EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP;
+	} else
+		bmap = reserve_bmap;
 
 	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
 				      EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
@@ -153,15 +193,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 					last_blk, 1, bmap, &new_blk);
 		if (retval)
 			return retval;
-		ext2fs_mark_block_bitmap2(bmap, new_blk);
 		ext2fs_block_bitmap_loc_set(fs, group, new_blk);
-		if (flexbg_size) {
-			dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
-			ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
-			ext2fs_free_blocks_count_add(fs->super, -1);
-			ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
-			ext2fs_group_desc_csum_set(fs, gr);
-		}
+		update_block_bitmap_stats(fs, new_blk, 1, flags);
+		if (reserve_bmap)
+			ext2fs_mark_block_bitmap2(bmap, new_blk);
 	}
 
 	if (flexbg_size) {
@@ -186,15 +221,10 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 					 last_blk, 1, bmap, &new_blk);
 		if (retval)
 			return retval;
-		ext2fs_mark_block_bitmap2(bmap, new_blk);
 		ext2fs_inode_bitmap_loc_set(fs, group, new_blk);
-		if (flexbg_size) {
-			dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
-			ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
-			ext2fs_free_blocks_count_add(fs->super, -1);
-			ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
-			ext2fs_group_desc_csum_set(fs, gr);
-		}
+		update_block_bitmap_stats(fs, new_blk, 1, flags);
+		if (reserve_bmap)
+			ext2fs_mark_block_bitmap2(bmap, new_blk);
 	}
 
 	/*
@@ -223,18 +253,29 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 						bmap, &new_blk);
 		if (retval)
 			return retval;
-		if (flexbg_size)
-			ext2fs_block_alloc_stats_range(fs, new_blk,
-				       fs->inode_blocks_per_group, +1);
-		else
-			ext2fs_mark_block_bitmap_range2(fs->block_map,
-					new_blk, fs->inode_blocks_per_group);
 		ext2fs_inode_table_loc_set(fs, group, new_blk);
+		update_block_bitmap_stats(fs, new_blk,
+					  fs->inode_blocks_per_group, flags);
+		if (reserve_bmap)
+			ext2fs_mark_block_bitmap_range2(bmap,
+					new_blk, fs->inode_blocks_per_group);
 	}
 	ext2fs_group_desc_csum_set(fs, group);
 	return 0;
 }
 
+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+				      ext2fs_block_bitmap bmap)
+{
+	unsigned long flags = 0;
+
+	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+                                      EXT4_FEATURE_INCOMPAT_FLEX_BG))
+		flags |= EXT2FS_ALLOC_TABLE_UPDATE_STATS;
+
+	return ext2fs_allocate_group_table2(fs, group, bmap, flags);
+}
+
 errcode_t ext2fs_allocate_tables(ext2_filsys fs)
 {
 	errcode_t	retval;
@@ -248,7 +289,7 @@ errcode_t ext2fs_allocate_tables(ext2_filsys fs)
 	for (i = 0; i < fs->group_desc_count; i++) {
 		if (fs->progress_ops && fs->progress_ops->update)
 			(fs->progress_ops->update)(fs, &progress, i);
-		retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
+		retval = ext2fs_allocate_group_table(fs, i, 0);
 		if (retval)
 			return retval;
 	}
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 13cbe567b19c..3eda8d1f4ad3 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -713,6 +713,13 @@ void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
 extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
 extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 					     ext2fs_block_bitmap bmap);
+/* Update allocation statistics */
+#define EXT2FS_ALLOC_TABLE_UPDATE_STATS		0x0001
+/* Set fs->block_map in addition to provided bmap */
+#define EXT2FS_ALLOC_TABLE_SET_BLOCK_BITMAP	0x0002
+extern errcode_t ext2fs_allocate_group_table2(ext2_filsys fs, dgrp_t group,
+					      ext2fs_block_bitmap bmap,
+					      unsigned long flags);
 
 /* badblocks.c */
 extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists