zte's code,first commit

Change-Id: I9a04da59e459a9bc0d67f101f700d9d7dc8d681b
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c
new file mode 100644
index 0000000..9f3d4e0
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c
@@ -0,0 +1,245 @@
+/*
+ * alloc_tables.c --- Allocate tables for a newly initialized
+ * filesystem.  Used by mke2fs when initializing a filesystem
+ *
+ * Copyright (C) 1996 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <time.h>
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include "ext2_fs.h"
+#include "ext2fs.h"
+#include "ext2fsP.h"
+
+/*
+ * This routine searches for free blocks that can allocate a full
+ * group of bitmaps or inode tables for a flexbg group.  Returns the
+ * block number with a correct offset were the bitmaps and inode
+ * tables can be allocated continously and in order.
+ */
+static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
+			     ext2fs_block_bitmap bmap, int rem_grp,
+			     int elem_size)
+{
+	int		flexbg, flexbg_size, size;
+	blk64_t		last_blk, first_free = 0;
+	dgrp_t	       	last_grp;
+
+	flexbg_size = 1 << fs->super->s_log_groups_per_flex;
+	flexbg = group / flexbg_size;
+	size = rem_grp * elem_size;
+
+	if (size > (int) (fs->super->s_blocks_per_group / 8))
+		size = (int) fs->super->s_blocks_per_group / 8;
+
+	/*
+	 * Don't do a long search if the previous block
+	 * search is still valid.
+	 */
+	if (start_blk && ext2fs_test_block_bitmap_range2(bmap, start_blk,
+							 elem_size))
+		return start_blk;
+
+	start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg);
+	last_grp = group | (flexbg_size - 1);
+	if (last_grp > fs->group_desc_count-1)
+		last_grp = fs->group_desc_count-1;
+	last_blk = ext2fs_group_last_block2(fs, last_grp);
+
+	/* Find the first available block */
+	if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, size,
+				    bmap, &first_free) == 0)
+		return first_free;
+
+	if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, elem_size,
+				   bmap, &first_free) == 0)
+		return first_free;
+
+	if (ext2fs_get_free_blocks2(fs, 0, last_blk, elem_size, bmap,
+				    &first_free) == 0)
+		return first_free;
+
+	return first_free;
+}
+
+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
+				      ext2fs_block_bitmap bmap)
+{
+	unsigned int	j;
+	errcode_t	retval;
+	blk64_t		group_blk, start_blk, last_blk, new_blk, blk;
+	dgrp_t		last_grp = 0;
+	int		rem_grps = 0, flexbg_size = 0;
+
+	group_blk = ext2fs_group_first_block2(fs, group);
+	last_blk = ext2fs_group_last_block2(fs, group);
+
+	if (!bmap)
+		bmap = fs->block_map;
+
+	if (EXT2_HAS_INCOMPAT_FEATURE(fs->super,
+				      EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
+	    fs->super->s_log_groups_per_flex) {
+		flexbg_size = 1 << fs->super->s_log_groups_per_flex;
+		last_grp = group | (flexbg_size - 1);
+		if (last_grp > fs->group_desc_count-1)
+			last_grp = fs->group_desc_count-1;
+		rem_grps = last_grp - group + 1;
+	}
+
+	/*
+	 * Allocate the block and inode bitmaps, if necessary
+	 */
+	if (fs->stride) {
+		retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
+						 1, bmap, &start_blk);
+		if (retval)
+			return retval;
+		start_blk += fs->inode_blocks_per_group;
+		start_blk += ((fs->stride * group) %
+			      (last_blk - start_blk + 1));
+		if (start_blk >= last_blk)
+			start_blk = group_blk;
+	} else
+		start_blk = group_blk;
+
+	if (flexbg_size) {
+		blk64_t prev_block = 0;
+
+		if (group % flexbg_size)
+			prev_block = ext2fs_block_bitmap_loc(fs, group - 1) + 1;
+		start_blk = flexbg_offset(fs, group, prev_block, bmap,
+					  rem_grps, 1);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
+	}
+
+	if (!ext2fs_block_bitmap_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+						 1, bmap, &new_blk);
+		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+			retval = ext2fs_get_free_blocks2(fs, group_blk,
+					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);
+		}
+	}
+
+	if (flexbg_size) {
+		blk64_t prev_block = 0;
+		if (group % flexbg_size)
+			prev_block = ext2fs_inode_bitmap_loc(fs, group - 1) + 1;
+		else
+			prev_block = ext2fs_block_bitmap_loc(fs, group) +
+				flexbg_size;
+		start_blk = flexbg_offset(fs, group, prev_block, bmap,
+					  rem_grps, 1);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
+	}
+
+	if (!ext2fs_inode_bitmap_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+						 1, bmap, &new_blk);
+		if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+			retval = ext2fs_get_free_blocks2(fs, group_blk,
+					 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);
+		}
+	}
+
+	/*
+	 * Allocate the inode table
+	 */
+	if (flexbg_size) {
+		blk64_t prev_block = 0;
+
+		if (group % flexbg_size)
+			prev_block = ext2fs_inode_table_loc(fs, group - 1) +
+				fs->inode_blocks_per_group;
+		else
+			prev_block = ext2fs_inode_bitmap_loc(fs, group) +
+				flexbg_size;
+
+		group_blk = flexbg_offset(fs, group, prev_block, bmap,
+					  rem_grps, fs->inode_blocks_per_group);
+		last_blk = ext2fs_group_last_block2(fs, last_grp);
+	}
+
+	if (!ext2fs_inode_table_loc(fs, group)) {
+		retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
+						fs->inode_blocks_per_group,
+						bmap, &new_blk);
+		if (retval)
+			return retval;
+		for (j=0, blk = new_blk;
+		     j < fs->inode_blocks_per_group;
+		     j++, blk++) {
+			ext2fs_mark_block_bitmap2(bmap, blk);
+			if (flexbg_size) {
+				dgrp_t gr = ext2fs_group_of_blk2(fs, 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);
+			}
+		}
+		ext2fs_inode_table_loc_set(fs, group, new_blk);
+	}
+	ext2fs_group_desc_csum_set(fs, group);
+	return 0;
+}
+
+errcode_t ext2fs_allocate_tables(ext2_filsys fs)
+{
+	errcode_t	retval;
+	dgrp_t		i;
+	struct ext2fs_numeric_progress_struct progress;
+
+	ext2fs_numeric_progress_init(fs, &progress, NULL,
+				     fs->group_desc_count);
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		ext2fs_numeric_progress_update(fs, &progress, i);
+		retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
+		if (retval)
+			return retval;
+	}
+	ext2fs_numeric_progress_close(fs, &progress, NULL);
+	return 0;
+}
+