Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd2d4291 authored by Avantika Mathur's avatar Avantika Mathur Committed by Theodore Ts'o
Browse files

ext4: add ext4_group_t, and change all group variables to this type.



In many places variables for block group are of type int, which limits the
maximum number of block groups to 2^31.  Each block group can have up to
2^15 blocks, with a 4K block size,  and the max filesystem size is limited to
2^31 * (2^15 * 2^12) = 2^58  -- or 256 PB

This patch introduces a new type ext4_group_t, of type unsigned long, to
represent block group numbers in ext4.
All occurrences of block group variables are converted to type ext4_group_t.

Signed-off-by: default avatarAvantika Mathur <mathur@us.ibm.com>
parent bba90743
Loading
Loading
Loading
Loading
+33 −36
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
 * Calculate the block group number and offset, given a block number
 */
void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
		unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
		ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
{
	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
	ext4_grpblk_t offset;
@@ -46,7 +46,7 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
/* Initializes an uninitialized block bitmap if given, and returns the
 * number of blocks free in the group. */
unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
				int block_group, struct ext4_group_desc *gdp)
		 ext4_group_t block_group, struct ext4_group_desc *gdp)
{
	unsigned long start;
	int bit, bit_max;
@@ -60,7 +60,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
		 * essentially implementing a per-group read-only flag. */
		if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
			ext4_error(sb, __FUNCTION__,
				   "Checksum bad for group %u\n", block_group);
				  "Checksum bad for group %lu\n", block_group);
			gdp->bg_free_blocks_count = 0;
			gdp->bg_free_inodes_count = 0;
			gdp->bg_itable_unused = 0;
@@ -153,7 +153,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
 *			group descriptor
 */
struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
					     unsigned int block_group,
					     ext4_group_t block_group,
					     struct buffer_head ** bh)
{
	unsigned long group_desc;
@@ -164,7 +164,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
	if (block_group >= sbi->s_groups_count) {
		ext4_error (sb, "ext4_get_group_desc",
			    "block_group >= groups_count - "
			    "block_group = %d, groups_count = %lu",
			    "block_group = %lu, groups_count = %lu",
			    block_group, sbi->s_groups_count);

		return NULL;
@@ -176,7 +176,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
	if (!sbi->s_group_desc[group_desc]) {
		ext4_error (sb, "ext4_get_group_desc",
			    "Group descriptor not loaded - "
			    "block_group = %d, group_desc = %lu, desc = %lu",
			    "block_group = %lu, group_desc = %lu, desc = %lu",
			     block_group, group_desc, offset);
		return NULL;
	}
@@ -200,7 +200,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb,
 * Return buffer_head on success or NULL in case of failure.
 */
struct buffer_head *
read_block_bitmap(struct super_block *sb, unsigned int block_group)
read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
{
	struct ext4_group_desc * desc;
	struct buffer_head * bh = NULL;
@@ -227,7 +227,7 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
	if (!bh)
		ext4_error (sb, __FUNCTION__,
			    "Cannot read block bitmap - "
			    "block_group = %d, block_bitmap = %llu",
			    "block_group = %lu, block_bitmap = %llu",
			    block_group, bitmap_blk);
	return bh;
}
@@ -320,7 +320,7 @@ static void __rsv_window_dump(struct rb_root *root, int verbose,
 */
static int
goal_in_my_reservation(struct ext4_reserve_window *rsv, ext4_grpblk_t grp_goal,
			unsigned int group, struct super_block * sb)
			ext4_group_t group, struct super_block *sb)
{
	ext4_fsblk_t group_first_block, group_last_block;

@@ -540,7 +540,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb,
{
	struct buffer_head *bitmap_bh = NULL;
	struct buffer_head *gd_bh;
	unsigned long block_group;
	ext4_group_t block_group;
	ext4_grpblk_t bit;
	unsigned long i;
	unsigned long overflow;
@@ -920,9 +920,10 @@ claim_block(spinlock_t *lock, ext4_grpblk_t block, struct buffer_head *bh)
 * ext4_journal_release_buffer(), else we'll run out of credits.
 */
static ext4_grpblk_t
ext4_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
			struct buffer_head *bitmap_bh, ext4_grpblk_t grp_goal,
			unsigned long *count, struct ext4_reserve_window *my_rsv)
ext4_try_to_allocate(struct super_block *sb, handle_t *handle,
			ext4_group_t group, struct buffer_head *bitmap_bh,
			ext4_grpblk_t grp_goal, unsigned long *count,
			struct ext4_reserve_window *my_rsv)
{
	ext4_fsblk_t group_first_block;
	ext4_grpblk_t start, end;
@@ -1156,7 +1157,7 @@ static int find_next_reservable_window(
 */
static int alloc_new_reservation(struct ext4_reserve_window_node *my_rsv,
		ext4_grpblk_t grp_goal, struct super_block *sb,
		unsigned int group, struct buffer_head *bitmap_bh)
		ext4_group_t group, struct buffer_head *bitmap_bh)
{
	struct ext4_reserve_window_node *search_head;
	ext4_fsblk_t group_first_block, group_end_block, start_block;
@@ -1354,7 +1355,7 @@ static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv,
 */
static ext4_grpblk_t
ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
			unsigned int group, struct buffer_head *bitmap_bh,
			ext4_group_t group, struct buffer_head *bitmap_bh,
			ext4_grpblk_t grp_goal,
			struct ext4_reserve_window_node * my_rsv,
			unsigned long *count, int *errp)
@@ -1528,12 +1529,12 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
{
	struct buffer_head *bitmap_bh = NULL;
	struct buffer_head *gdp_bh;
	unsigned long group_no;
	int goal_group;
	ext4_group_t group_no;
	ext4_group_t goal_group;
	ext4_grpblk_t grp_target_blk;	/* blockgroup relative goal block */
	ext4_grpblk_t grp_alloc_blk;	/* blockgroup-relative allocated block*/
	ext4_fsblk_t ret_block;		/* filesyetem-wide allocated block */
	int bgi;			/* blockgroup iteration index */
	ext4_group_t bgi;			/* blockgroup iteration index */
	int fatal = 0, err;
	int performed_allocation = 0;
	ext4_grpblk_t free_blocks;	/* number of free blocks in a group */
@@ -1544,10 +1545,7 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
	struct ext4_reserve_window_node *my_rsv = NULL;
	struct ext4_block_alloc_info *block_i;
	unsigned short windowsz = 0;
#ifdef EXT4FS_DEBUG
	static int goal_hits, goal_attempts;
#endif
	unsigned long ngroups;
	ext4_group_t ngroups;
	unsigned long num = *count;

	*errp = -ENOSPC;
@@ -1743,9 +1741,6 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode,
	 * list of some description.  We don't know in advance whether
	 * the caller wants to use it as metadata or data.
	 */
	ext4_debug("allocating block %lu. Goal hits %d of %d.\n",
			ret_block, goal_hits, goal_attempts);

	spin_lock(sb_bgl_lock(sbi, group_no));
	if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))
		gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
@@ -1804,8 +1799,8 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
{
	ext4_fsblk_t desc_count;
	struct ext4_group_desc *gdp;
	int i;
	unsigned long ngroups = EXT4_SB(sb)->s_groups_count;
	ext4_group_t i;
	ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
#ifdef EXT4FS_DEBUG
	struct ext4_super_block *es;
	ext4_fsblk_t bitmap_count;
@@ -1829,7 +1824,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
			continue;

		x = ext4_count_free(bitmap_bh, sb->s_blocksize);
		printk("group %d: stored = %d, counted = %lu\n",
		printk(KERN_DEBUG "group %lu: stored = %d, counted = %lu\n",
			i, le16_to_cpu(gdp->bg_free_blocks_count), x);
		bitmap_count += x;
	}
@@ -1853,7 +1848,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb)
#endif
}

static inline int test_root(int a, int b)
static inline int test_root(ext4_group_t a, int b)
{
	int num = b;

@@ -1862,7 +1857,7 @@ static inline int test_root(int a, int b)
	return num == a;
}

static int ext4_group_sparse(int group)
static int ext4_group_sparse(ext4_group_t group)
{
	if (group <= 1)
		return 1;
@@ -1880,7 +1875,7 @@ static int ext4_group_sparse(int group)
 *	Return the number of blocks used by the superblock (primary or backup)
 *	in this group.  Currently this will be only 0 or 1.
 */
int ext4_bg_has_super(struct super_block *sb, int group)
int ext4_bg_has_super(struct super_block *sb, ext4_group_t group)
{
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
				EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
@@ -1889,18 +1884,20 @@ int ext4_bg_has_super(struct super_block *sb, int group)
	return 1;
}

static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, int group)
static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb,
					ext4_group_t group)
{
	unsigned long metagroup = group / EXT4_DESC_PER_BLOCK(sb);
	unsigned long first = metagroup * EXT4_DESC_PER_BLOCK(sb);
	unsigned long last = first + EXT4_DESC_PER_BLOCK(sb) - 1;
	ext4_group_t first = metagroup * EXT4_DESC_PER_BLOCK(sb);
	ext4_group_t last = first + EXT4_DESC_PER_BLOCK(sb) - 1;

	if (group == first || group == first + 1 || group == last)
		return 1;
	return 0;
}

static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, int group)
static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb,
					ext4_group_t group)
{
	if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
				EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) &&
@@ -1918,7 +1915,7 @@ static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, int group)
 *	(primary or backup) in this group.  In the future there may be a
 *	different number of descriptor blocks in each group.
 */
unsigned long ext4_bg_num_gdb(struct super_block *sb, int group)
unsigned long ext4_bg_num_gdb(struct super_block *sb, ext4_group_t group)
{
	unsigned long first_meta_bg =
			le32_to_cpu(EXT4_SB(sb)->s_es->s_first_meta_bg);
+5 −3
Original line number Diff line number Diff line
@@ -14,14 +14,16 @@ extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group,
extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group,
				       struct ext4_group_desc *gdp);
struct buffer_head *read_block_bitmap(struct super_block *sb,
				      unsigned int block_group);
				      ext4_group_t block_group);
extern unsigned ext4_init_block_bitmap(struct super_block *sb,
				       struct buffer_head *bh, int group,
				       struct buffer_head *bh,
				       ext4_group_t group,
				       struct ext4_group_desc *desc);
#define ext4_free_blocks_after_init(sb, group, desc)			\
		ext4_init_block_bitmap(sb, NULL, group, desc)
extern unsigned ext4_init_inode_bitmap(struct super_block *sb,
				       struct buffer_head *bh, int group,
				       struct buffer_head *bh,
				       ext4_group_t group,
				       struct ext4_group_desc *desc);
extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap);
#endif /* _LINUX_EXT4_GROUP_H */
+24 −22
Original line number Diff line number Diff line
@@ -64,8 +64,8 @@ void mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
}

/* Initializes an uninitialized inode bitmap */
unsigned ext4_init_inode_bitmap(struct super_block *sb,
				struct buffer_head *bh, int block_group,
unsigned ext4_init_inode_bitmap(struct super_block *sb, struct buffer_head *bh,
				ext4_group_t block_group,
				struct ext4_group_desc *gdp)
{
	struct ext4_sb_info *sbi = EXT4_SB(sb);
@@ -75,7 +75,7 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb,
	/* If checksum is bad mark all blocks and inodes use to prevent
	 * allocation, essentially implementing a per-group read-only flag. */
	if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
		ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n",
		ext4_error(sb, __FUNCTION__, "Checksum bad for group %lu\n",
			   block_group);
		gdp->bg_free_blocks_count = 0;
		gdp->bg_free_inodes_count = 0;
@@ -98,7 +98,7 @@ unsigned ext4_init_inode_bitmap(struct super_block *sb,
 * Return buffer_head of bitmap on success or NULL.
 */
static struct buffer_head *
read_inode_bitmap(struct super_block * sb, unsigned long block_group)
read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
{
	struct ext4_group_desc *desc;
	struct buffer_head *bh = NULL;
@@ -152,7 +152,7 @@ void ext4_free_inode (handle_t *handle, struct inode * inode)
	unsigned long ino;
	struct buffer_head *bitmap_bh = NULL;
	struct buffer_head *bh2;
	unsigned long block_group;
	ext4_group_t block_group;
	unsigned long bit;
	struct ext4_group_desc * gdp;
	struct ext4_super_block * es;
@@ -260,12 +260,12 @@ void ext4_free_inode (handle_t *handle, struct inode * inode)
 * For other inodes, search forward from the parent directory\'s block
 * group to find a free inode.
 */
static int find_group_dir(struct super_block *sb, struct inode *parent)
static ext4_group_t find_group_dir(struct super_block *sb, struct inode *parent)
{
	int ngroups = EXT4_SB(sb)->s_groups_count;
	ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
	unsigned int freei, avefreei;
	struct ext4_group_desc *desc, *best_desc = NULL;
	int group, best_group = -1;
	ext4_group_t group, best_group = -1;

	freei = percpu_counter_read_positive(&EXT4_SB(sb)->s_freeinodes_counter);
	avefreei = freei / ngroups;
@@ -314,12 +314,13 @@ static int find_group_dir(struct super_block *sb, struct inode *parent)
#define INODE_COST 64
#define BLOCK_COST 256

static int find_group_orlov(struct super_block *sb, struct inode *parent)
static ext4_group_t find_group_orlov(struct super_block *sb,
				      struct inode *parent)
{
	int parent_group = EXT4_I(parent)->i_block_group;
	ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
	struct ext4_sb_info *sbi = EXT4_SB(sb);
	struct ext4_super_block *es = sbi->s_es;
	int ngroups = sbi->s_groups_count;
	ext4_group_t ngroups = sbi->s_groups_count;
	int inodes_per_group = EXT4_INODES_PER_GROUP(sb);
	unsigned int freei, avefreei;
	ext4_fsblk_t freeb, avefreeb;
@@ -327,7 +328,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
	unsigned int ndirs;
	int max_debt, max_dirs, min_inodes;
	ext4_grpblk_t min_blocks;
	int group = -1, i;
	ext4_group_t group = -1, i;
	struct ext4_group_desc *desc;

	freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
@@ -340,7 +341,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
	if ((parent == sb->s_root->d_inode) ||
	    (EXT4_I(parent)->i_flags & EXT4_TOPDIR_FL)) {
		int best_ndir = inodes_per_group;
		int best_group = -1;
		ext4_group_t best_group = -1;

		get_random_bytes(&group, sizeof(group));
		parent_group = (unsigned)group % ngroups;
@@ -415,12 +416,13 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent)
	return -1;
}

static int find_group_other(struct super_block *sb, struct inode *parent)
static ext4_group_t find_group_other(struct super_block *sb,
					struct inode *parent)
{
	int parent_group = EXT4_I(parent)->i_block_group;
	int ngroups = EXT4_SB(sb)->s_groups_count;
	ext4_group_t parent_group = EXT4_I(parent)->i_block_group;
	ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count;
	struct ext4_group_desc *desc;
	int group, i;
	ext4_group_t group, i;

	/*
	 * Try to place the inode in its parent directory
@@ -487,7 +489,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
	struct super_block *sb;
	struct buffer_head *bitmap_bh = NULL;
	struct buffer_head *bh2;
	int group;
	ext4_group_t group;
	unsigned long ino = 0;
	struct inode * inode;
	struct ext4_group_desc * gdp = NULL;
@@ -583,7 +585,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
	    ino > EXT4_INODES_PER_GROUP(sb)) {
		ext4_error(sb, __FUNCTION__,
			   "reserved inode or inode > inodes count - "
			   "block_group = %d, inode=%lu", group,
			   "block_group = %lu, inode=%lu", group,
			   ino + group * EXT4_INODES_PER_GROUP(sb));
		err = -EIO;
		goto fail;
@@ -777,7 +779,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode)
struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
{
	unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
	unsigned long block_group;
	ext4_group_t block_group;
	int bit;
	struct buffer_head *bitmap_bh = NULL;
	struct inode *inode = NULL;
@@ -833,7 +835,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb)
{
	unsigned long desc_count;
	struct ext4_group_desc *gdp;
	int i;
	ext4_group_t i;
#ifdef EXT4FS_DEBUG
	struct ext4_super_block *es;
	unsigned long bitmap_count, x;
@@ -879,7 +881,7 @@ unsigned long ext4_count_free_inodes (struct super_block * sb)
unsigned long ext4_count_dirs (struct super_block * sb)
{
	unsigned long count = 0;
	int i;
	ext4_group_t i;

	for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) {
		struct ext4_group_desc *gdp = ext4_get_group_desc (sb, i, NULL);
+3 −2
Original line number Diff line number Diff line
@@ -2464,7 +2464,8 @@ void ext4_truncate(struct inode *inode)
static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb,
		unsigned long ino, struct ext4_iloc *iloc)
{
	unsigned long desc, group_desc, block_group;
	unsigned long desc, group_desc;
	ext4_group_t block_group;
	unsigned long offset;
	ext4_fsblk_t block;
	struct buffer_head *bh;
@@ -2551,7 +2552,7 @@ static int __ext4_get_inode_loc(struct inode *inode,
			struct ext4_group_desc *desc;
			int inodes_per_buffer;
			int inode_offset, i;
			int block_group;
			ext4_group_t block_group;
			int start;

			block_group = (inode->i_ino - 1) /
+6 −6
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ static int verify_group_input(struct super_block *sb,
	struct ext4_super_block *es = sbi->s_es;
	ext4_fsblk_t start = ext4_blocks_count(es);
	ext4_fsblk_t end = start + input->blocks_count;
	unsigned group = input->group;
	ext4_group_t group = input->group;
	ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
	unsigned overhead = ext4_bg_has_super(sb, group) ?
		(1 + ext4_bg_num_gdb(sb, group) +
@@ -357,7 +357,7 @@ static int verify_reserved_gdb(struct super_block *sb,
			       struct buffer_head *primary)
{
	const ext4_fsblk_t blk = primary->b_blocknr;
	const unsigned long end = EXT4_SB(sb)->s_groups_count;
	const ext4_group_t end = EXT4_SB(sb)->s_groups_count;
	unsigned three = 1;
	unsigned five = 5;
	unsigned seven = 7;
@@ -656,12 +656,12 @@ static void update_backups(struct super_block *sb,
			   int blk_off, char *data, int size)
{
	struct ext4_sb_info *sbi = EXT4_SB(sb);
	const unsigned long last = sbi->s_groups_count;
	const ext4_group_t last = sbi->s_groups_count;
	const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
	unsigned three = 1;
	unsigned five = 5;
	unsigned seven = 7;
	unsigned group;
	ext4_group_t group;
	int rest = sb->s_blocksize - size;
	handle_t *handle;
	int err = 0, err2;
@@ -716,7 +716,7 @@ static void update_backups(struct super_block *sb,
exit_err:
	if (err) {
		ext4_warning(sb, __FUNCTION__,
			     "can't update backup for group %d (err %d), "
			     "can't update backup for group %lu (err %d), "
			     "forcing fsck on next reboot", group, err);
		sbi->s_mount_state &= ~EXT4_VALID_FS;
		sbi->s_es->s_state &= cpu_to_le16(~EXT4_VALID_FS);
@@ -952,7 +952,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
		      ext4_fsblk_t n_blocks_count)
{
	ext4_fsblk_t o_blocks_count;
	unsigned long o_groups_count;
	ext4_group_t o_groups_count;
	ext4_grpblk_t last;
	ext4_grpblk_t add;
	struct buffer_head * bh;
Loading