Skip to content

Commit 805937c

Browse files
committed
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
2 parents 87eeff7 + 92e3b40 commit 805937c

File tree

6 files changed

+43
-23
lines changed

6 files changed

+43
-23
lines changed

fs/ext4/ext4.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ do { \
771771
if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime)) \
772772
(einode)->xtime.tv_sec = \
773773
(signed)le32_to_cpu((raw_inode)->xtime); \
774+
else \
775+
(einode)->xtime.tv_sec = 0; \
774776
if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \
775777
ext4_decode_extra_time(&(einode)->xtime, \
776778
raw_inode->xtime ## _extra); \

fs/ext4/extents.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3906,6 +3906,7 @@ ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
39063906
} else
39073907
err = ret;
39083908
map->m_flags |= EXT4_MAP_MAPPED;
3909+
map->m_pblk = newblock;
39093910
if (allocated > map->m_len)
39103911
allocated = map->m_len;
39113912
map->m_len = allocated;

fs/ext4/ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
140140
handle = ext4_journal_start(inode_bl, EXT4_HT_MOVE_EXTENTS, 2);
141141
if (IS_ERR(handle)) {
142142
err = -EINVAL;
143-
goto swap_boot_out;
143+
goto journal_err_out;
144144
}
145145

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

199199
ext4_double_up_write_data_sem(inode, inode_bl);
200200

201+
journal_err_out:
201202
ext4_inode_resume_unlocked_dio(inode);
202203
ext4_inode_resume_unlocked_dio(inode_bl);
203204

fs/ext4/resize.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ static int ext4_alloc_group_tables(struct super_block *sb,
243243
ext4_group_t group;
244244
ext4_group_t last_group;
245245
unsigned overhead;
246+
__u16 uninit_mask = (flexbg_size > 1) ? ~EXT4_BG_BLOCK_UNINIT : ~0;
246247

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

@@ -266,7 +267,7 @@ static int ext4_alloc_group_tables(struct super_block *sb,
266267
src_group++;
267268
for (; src_group <= last_group; src_group++) {
268269
overhead = ext4_group_overhead_blocks(sb, src_group);
269-
if (overhead != 0)
270+
if (overhead == 0)
270271
last_blk += group_data[src_group - group].blocks_count;
271272
else
272273
break;
@@ -280,8 +281,7 @@ static int ext4_alloc_group_tables(struct super_block *sb,
280281
group = ext4_get_group_number(sb, start_blk - 1);
281282
group -= group_data[0].group;
282283
group_data[group].free_blocks_count--;
283-
if (flexbg_size > 1)
284-
flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
284+
flex_gd->bg_flags[group] &= uninit_mask;
285285
}
286286

287287
/* Allocate inode bitmaps */
@@ -292,22 +292,30 @@ static int ext4_alloc_group_tables(struct super_block *sb,
292292
group = ext4_get_group_number(sb, start_blk - 1);
293293
group -= group_data[0].group;
294294
group_data[group].free_blocks_count--;
295-
if (flexbg_size > 1)
296-
flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
295+
flex_gd->bg_flags[group] &= uninit_mask;
297296
}
298297

299298
/* Allocate inode tables */
300299
for (; it_index < flex_gd->count; it_index++) {
301-
if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk)
300+
unsigned int itb = EXT4_SB(sb)->s_itb_per_group;
301+
ext4_fsblk_t next_group_start;
302+
303+
if (start_blk + itb > last_blk)
302304
goto next_group;
303305
group_data[it_index].inode_table = start_blk;
304-
group = ext4_get_group_number(sb, start_blk - 1);
306+
group = ext4_get_group_number(sb, start_blk);
307+
next_group_start = ext4_group_first_block_no(sb, group + 1);
305308
group -= group_data[0].group;
306-
group_data[group].free_blocks_count -=
307-
EXT4_SB(sb)->s_itb_per_group;
308-
if (flexbg_size > 1)
309-
flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
310309

310+
if (start_blk + itb > next_group_start) {
311+
flex_gd->bg_flags[group + 1] &= uninit_mask;
312+
overhead = start_blk + itb - next_group_start;
313+
group_data[group + 1].free_blocks_count -= overhead;
314+
itb -= overhead;
315+
}
316+
317+
group_data[group].free_blocks_count -= itb;
318+
flex_gd->bg_flags[group] &= uninit_mask;
311319
start_blk += EXT4_SB(sb)->s_itb_per_group;
312320
}
313321

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

404-
count2 = sb->s_blocksize * 8 - (block - start);
412+
count2 = EXT4_BLOCKS_PER_GROUP(sb) - (block - start);
405413
if (count2 > count)
406414
count2 = count;
407415

@@ -620,7 +628,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
620628
if (err)
621629
goto out;
622630
count = group_table_count[j];
623-
start = group_data[i].block_bitmap;
631+
start = (&group_data[i].block_bitmap)[j];
624632
block = start;
625633
}
626634

fs/ext4/super.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3695,16 +3695,22 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
36953695
for (i = 0; i < 4; i++)
36963696
sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
36973697
sbi->s_def_hash_version = es->s_def_hash_version;
3698-
i = le32_to_cpu(es->s_flags);
3699-
if (i & EXT2_FLAGS_UNSIGNED_HASH)
3700-
sbi->s_hash_unsigned = 3;
3701-
else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
3698+
if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
3699+
i = le32_to_cpu(es->s_flags);
3700+
if (i & EXT2_FLAGS_UNSIGNED_HASH)
3701+
sbi->s_hash_unsigned = 3;
3702+
else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) {
37023703
#ifdef __CHAR_UNSIGNED__
3703-
es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
3704-
sbi->s_hash_unsigned = 3;
3704+
if (!(sb->s_flags & MS_RDONLY))
3705+
es->s_flags |=
3706+
cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH);
3707+
sbi->s_hash_unsigned = 3;
37053708
#else
3706-
es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
3709+
if (!(sb->s_flags & MS_RDONLY))
3710+
es->s_flags |=
3711+
cpu_to_le32(EXT2_FLAGS_SIGNED_HASH);
37073712
#endif
3713+
}
37083714
}
37093715

37103716
/* Handle clustersize */

fs/jbd2/transaction.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,11 +514,13 @@ int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
514514
* similarly constrained call sites
515515
*/
516516
ret = start_this_handle(journal, handle, GFP_NOFS);
517-
if (ret < 0)
517+
if (ret < 0) {
518518
jbd2_journal_free_reserved(handle);
519+
return ret;
520+
}
519521
handle->h_type = type;
520522
handle->h_line_no = line_no;
521-
return ret;
523+
return 0;
522524
}
523525
EXPORT_SYMBOL(jbd2_journal_start_reserved);
524526

0 commit comments

Comments
 (0)