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

Commit 805937cf authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull ext4 fixes from Ted Ts'o:
 "Miscellaneous ext4 bug fixes for v3.14"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  jbd2: fix use after free in jbd2_journal_start_reserved()
  ext4: don't leave i_crtime.tv_sec uninitialized
  ext4: fix online resize with a non-standard blocks per group setting
  ext4: fix online resize with very large inode tables
  ext4: don't try to modify s_flags if the the file system is read-only
  ext4: fix error paths in swap_inode_boot_loader()
  ext4: fix xfstest generic/299 block validity failures
parents 87eeff79 92e3b405
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -771,6 +771,8 @@ do { \
	if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))		       \
	if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime))		       \
		(einode)->xtime.tv_sec = 				       \
		(einode)->xtime.tv_sec = 				       \
			(signed)le32_to_cpu((raw_inode)->xtime);	       \
			(signed)le32_to_cpu((raw_inode)->xtime);	       \
	else								       \
		(einode)->xtime.tv_sec = 0;				       \
	if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))	       \
	if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra))	       \
		ext4_decode_extra_time(&(einode)->xtime,		       \
		ext4_decode_extra_time(&(einode)->xtime,		       \
				       raw_inode->xtime ## _extra);	       \
				       raw_inode->xtime ## _extra);	       \
+1 −0
Original line number Original line Diff line number Diff line
@@ -3906,6 +3906,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
		} else
		} else
			err = ret;
			err = ret;
		map->m_flags |= EXT4_MAP_MAPPED;
		map->m_flags |= EXT4_MAP_MAPPED;
		map->m_pblk = newblock;
		if (allocated > map->m_len)
		if (allocated > map->m_len)
			allocated = map->m_len;
			allocated = map->m_len;
		map->m_len = allocated;
		map->m_len = allocated;
+2 −1
Original line number Original line Diff line number Diff line
@@ -140,7 +140,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
	handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
	handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
	if (IS_ERR(handle)) {
	if (IS_ERR(handle)) {
		err = -EINVAL;
		err = -EINVAL;
		goto swap_boot_out;
		goto journal_err_out;
	}
	}


	/* Protect extent tree against block allocations via delalloc */
	/* Protect extent tree against block allocations via delalloc */
@@ -198,6 +198,7 @@ static long swap_inode_boot_loader(struct super_block *sb,


	ext4_double_up_write_data_sem(inode, inode_bl);
	ext4_double_up_write_data_sem(inode, inode_bl);


journal_err_out:
	ext4_inode_resume_unlocked_dio(inode);
	ext4_inode_resume_unlocked_dio(inode);
	ext4_inode_resume_unlocked_dio(inode_bl);
	ext4_inode_resume_unlocked_dio(inode_bl);


+21 −13
Original line number Original line Diff line number Diff line
@@ -243,6 +243,7 @@ static int ext4_alloc_group_tables(struct super_block *sb,
	ext4_group_t group;
	ext4_group_t group;
	ext4_group_t last_group;
	ext4_group_t last_group;
	unsigned overhead;
	unsigned overhead;
	__u16 uninit_mask = (flexbg_size > 1) ? ~EXT4_BG_BLOCK_UNINIT : ~0;


	BUG_ON(flex_gd->count == 0 || group_data == NULL);
	BUG_ON(flex_gd->count == 0 || group_data == NULL);


@@ -266,7 +267,7 @@ next_group:
	src_group++;
	src_group++;
	for (; src_group <= last_group; src_group++) {
	for (; src_group <= last_group; src_group++) {
		overhead = ext4_group_overhead_blocks(sb, src_group);
		overhead = ext4_group_overhead_blocks(sb, src_group);
		if (overhead != 0)
		if (overhead == 0)
			last_blk += group_data[src_group - group].blocks_count;
			last_blk += group_data[src_group - group].blocks_count;
		else
		else
			break;
			break;
@@ -280,8 +281,7 @@ next_group:
		group = ext4_get_group_number(sb, start_blk - 1);
		group = ext4_get_group_number(sb, start_blk - 1);
		group -= group_data[0].group;
		group -= group_data[0].group;
		group_data[group].free_blocks_count--;
		group_data[group].free_blocks_count--;
		if (flexbg_size > 1)
		flex_gd->bg_flags[group] &= uninit_mask;
			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
	}
	}


	/* Allocate inode bitmaps */
	/* Allocate inode bitmaps */
@@ -292,22 +292,30 @@ next_group:
		group = ext4_get_group_number(sb, start_blk - 1);
		group = ext4_get_group_number(sb, start_blk - 1);
		group -= group_data[0].group;
		group -= group_data[0].group;
		group_data[group].free_blocks_count--;
		group_data[group].free_blocks_count--;
		if (flexbg_size > 1)
		flex_gd->bg_flags[group] &= uninit_mask;
			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
	}
	}


	/* Allocate inode tables */
	/* Allocate inode tables */
	for (; it_index < flex_gd->count; it_index++) {
	for (; it_index < flex_gd->count; it_index++) {
		if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk)
		unsigned int itb = EXT4_SB(sb)->s_itb_per_group;
		ext4_fsblk_t next_group_start;

		if (start_blk + itb > last_blk)
			goto next_group;
			goto next_group;
		group_data[it_index].inode_table = start_blk;
		group_data[it_index].inode_table = start_blk;
		group = ext4_get_group_number(sb, start_blk - 1);
		group = ext4_get_group_number(sb, start_blk);
		next_group_start = ext4_group_first_block_no(sb, group + 1);
		group -= group_data[0].group;
		group -= group_data[0].group;
		group_data[group].free_blocks_count -=
					EXT4_SB(sb)->s_itb_per_group;
		if (flexbg_size > 1)
			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;


		if (start_blk + itb > next_group_start) {
			flex_gd->bg_flags[group + 1] &= uninit_mask;
			overhead = start_blk + itb - next_group_start;
			group_data[group + 1].free_blocks_count -= overhead;
			itb -= overhead;
		}

		group_data[group].free_blocks_count -= itb;
		flex_gd->bg_flags[group] &= uninit_mask;
		start_blk += EXT4_SB(sb)->s_itb_per_group;
		start_blk += EXT4_SB(sb)->s_itb_per_group;
	}
	}


@@ -401,7 +409,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle,
		start = ext4_group_first_block_no(sb, group);
		start = ext4_group_first_block_no(sb, group);
		group -= flex_gd->groups[0].group;
		group -= flex_gd->groups[0].group;


		count2 = sb->s_blocksize * 8 - (block - start);
		count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start);
		if (count2 > count)
		if (count2 > count)
			count2 = count;
			count2 = count;


@@ -620,7 +628,7 @@ handle_ib:
			if (err)
			if (err)
				goto out;
				goto out;
			count = group_table_count[j];
			count = group_table_count[j];
			start = group_data[i].block_bitmap;
			start = (&group_data[i].block_bitmap)[j];
			block = start;
			block = start;
		}
		}


+13 −7
Original line number Original line Diff line number Diff line
@@ -3695,17 +3695,23 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
	for (i = 0; i < 4; i++)
	for (i = 0; i < 4; i++)
		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
		sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
	sbi->s_def_hash_version = es->s_def_hash_version;
	sbi->s_def_hash_version = es->s_def_hash_version;
	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
		i = le32_to_cpu(es->s_flags);
		i = le32_to_cpu(es->s_flags);
		if (i & EXT2_FLAGS_UNSIGNED_HASH)
		if (i & EXT2_FLAGS_UNSIGNED_HASH)
			sbi->s_hash_unsigned = 3;
			sbi->s_hash_unsigned = 3;
		else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
		else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
#ifdef __CHAR_UNSIGNED__
#ifdef __CHAR_UNSIGNED__
		es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
			if (!(sb->s_flags & MS_RDONLY))
				es->s_flags |=
					cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
			sbi->s_hash_unsigned = 3;
			sbi->s_hash_unsigned = 3;
#else
#else
		es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
			if (!(sb->s_flags & MS_RDONLY))
				es->s_flags |=
					cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
#endif
#endif
		}
		}
	}


	/* Handle clustersize */
	/* Handle clustersize */
	clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
	clustersize = BLOCK_SIZE << le32_to_cpu(es->s_log_cluster_size);
Loading