Skip to content

Commit 32e8fd2

Browse files
committed
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bugfixes from Ted Ts'o: "A set of miscellaneous ext4 bug fixes for 3.18" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: make ext4_ext_convert_to_initialized() return proper number of blocks ext4: bail early when clearing inode journal flag fails ext4: bail out from make_indexed_dir() on first error jbd2: use a better hash function for the revoke table ext4: prevent bugon on race between write/fcntl ext4: remove extent status procfs files if journal load fails ext4: disallow changing journal_csum option during remount ext4: enable journal checksum when metadata checksum feature enabled ext4: fix oops when loading block bitmap failed ext4: fix overflow when updating superblock backups after resize
2 parents e2488ab + ae9e9c6 commit 32e8fd2

File tree

8 files changed

+51
-28
lines changed

8 files changed

+51
-28
lines changed

fs/ext4/extents.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3603,11 +3603,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
36033603
}
36043604
}
36053605

3606-
allocated = ext4_split_extent(handle, inode, ppath,
3607-
&split_map, split_flag, flags);
3608-
if (allocated < 0)
3609-
err = allocated;
3610-
3606+
err = ext4_split_extent(handle, inode, ppath, &split_map, split_flag,
3607+
flags);
3608+
if (err > 0)
3609+
err = 0;
36113610
out:
36123611
/* If we have gotten a failure, don't zero out status tree */
36133612
if (!err)

fs/ext4/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
137137
iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos);
138138
}
139139

140+
iocb->private = &overwrite;
140141
if (o_direct) {
141142
blk_start_plug(&plug);
142143

143-
iocb->private = &overwrite;
144144

145145
/* check whether we do a DIO overwrite or not */
146146
if (ext4_should_dioread_nolock(inode) && !aio_mutex &&

fs/ext4/ialloc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,10 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
887887
struct buffer_head *block_bitmap_bh;
888888

889889
block_bitmap_bh = ext4_read_block_bitmap(sb, group);
890+
if (!block_bitmap_bh) {
891+
err = -EIO;
892+
goto out;
893+
}
890894
BUFFER_TRACE(block_bitmap_bh, "get block bitmap access");
891895
err = ext4_journal_get_write_access(handle, block_bitmap_bh);
892896
if (err) {

fs/ext4/inode.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4959,7 +4959,12 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
49594959
if (val)
49604960
ext4_set_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
49614961
else {
4962-
jbd2_journal_flush(journal);
4962+
err = jbd2_journal_flush(journal);
4963+
if (err < 0) {
4964+
jbd2_journal_unlock_updates(journal);
4965+
ext4_inode_resume_unlocked_dio(inode);
4966+
return err;
4967+
}
49634968
ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
49644969
}
49654970
ext4_set_aops(inode);

fs/ext4/namei.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,31 +1816,39 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
18161816
hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
18171817
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
18181818
ext4fs_dirhash(name, namelen, &hinfo);
1819+
memset(frames, 0, sizeof(frames));
18191820
frame = frames;
18201821
frame->entries = entries;
18211822
frame->at = entries;
18221823
frame->bh = bh;
18231824
bh = bh2;
18241825

1825-
ext4_handle_dirty_dx_node(handle, dir, frame->bh);
1826-
ext4_handle_dirty_dirent_node(handle, dir, bh);
1826+
retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
1827+
if (retval)
1828+
goto out_frames;
1829+
retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
1830+
if (retval)
1831+
goto out_frames;
18271832

18281833
de = do_split(handle,dir, &bh, frame, &hinfo);
18291834
if (IS_ERR(de)) {
1830-
/*
1831-
* Even if the block split failed, we have to properly write
1832-
* out all the changes we did so far. Otherwise we can end up
1833-
* with corrupted filesystem.
1834-
*/
1835-
ext4_mark_inode_dirty(handle, dir);
1836-
dx_release(frames);
1837-
return PTR_ERR(de);
1835+
retval = PTR_ERR(de);
1836+
goto out_frames;
18381837
}
18391838
dx_release(frames);
18401839

18411840
retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
18421841
brelse(bh);
18431842
return retval;
1843+
out_frames:
1844+
/*
1845+
* Even if the block split failed, we have to properly write
1846+
* out all the changes we did so far. Otherwise we can end up
1847+
* with corrupted filesystem.
1848+
*/
1849+
ext4_mark_inode_dirty(handle, dir);
1850+
dx_release(frames);
1851+
return retval;
18441852
}
18451853

18461854
/*

fs/ext4/resize.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data,
10811081
break;
10821082

10831083
if (meta_bg == 0)
1084-
backup_block = group * bpg + blk_off;
1084+
backup_block = ((ext4_fsblk_t)group) * bpg + blk_off;
10851085
else
10861086
backup_block = (ext4_group_first_block_no(sb, group) +
10871087
ext4_bg_has_super(sb, group));

fs/ext4/super.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,6 +3526,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
35263526
#ifdef CONFIG_EXT4_FS_POSIX_ACL
35273527
set_opt(sb, POSIX_ACL);
35283528
#endif
3529+
/* don't forget to enable journal_csum when metadata_csum is enabled. */
3530+
if (ext4_has_metadata_csum(sb))
3531+
set_opt(sb, JOURNAL_CHECKSUM);
3532+
35293533
if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
35303534
set_opt(sb, JOURNAL_DATA);
35313535
else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED)
@@ -3943,7 +3947,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
39433947
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) &&
39443948
!(sb->s_flags & MS_RDONLY))
39453949
if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
3946-
goto failed_mount3;
3950+
goto failed_mount3a;
39473951

39483952
/*
39493953
* The first inode we look at is the journal inode. Don't try
@@ -3952,7 +3956,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
39523956
if (!test_opt(sb, NOLOAD) &&
39533957
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
39543958
if (ext4_load_journal(sb, es, journal_devnum))
3955-
goto failed_mount3;
3959+
goto failed_mount3a;
39563960
} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
39573961
EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
39583962
ext4_msg(sb, KERN_ERR, "required journal recovery "
@@ -4240,6 +4244,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42404244
jbd2_journal_destroy(sbi->s_journal);
42414245
sbi->s_journal = NULL;
42424246
}
4247+
failed_mount3a:
42434248
ext4_es_unregister_shrinker(sbi);
42444249
failed_mount3:
42454250
del_timer_sync(&sbi->s_err_report);
@@ -4841,6 +4846,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
48414846
goto restore_opts;
48424847
}
48434848

4849+
if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^
4850+
test_opt(sb, JOURNAL_CHECKSUM)) {
4851+
ext4_msg(sb, KERN_ERR, "changing journal_checksum "
4852+
"during remount not supported");
4853+
err = -EINVAL;
4854+
goto restore_opts;
4855+
}
4856+
48444857
if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
48454858
if (test_opt2(sb, EXPLICIT_DELALLOC)) {
48464859
ext4_msg(sb, KERN_ERR, "can't mount with "

fs/jbd2/revoke.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#include <linux/init.h>
9393
#include <linux/bio.h>
9494
#include <linux/log2.h>
95+
#include <linux/hash.h>
9596
#endif
9697

9798
static struct kmem_cache *jbd2_revoke_record_cache;
@@ -130,16 +131,9 @@ static void flush_descriptor(journal_t *, struct buffer_head *, int, int);
130131

131132
/* Utility functions to maintain the revoke table */
132133

133-
/* Borrowed from buffer.c: this is a tried and tested block hash function */
134134
static inline int hash(journal_t *journal, unsigned long long block)
135135
{
136-
struct jbd2_revoke_table_s *table = journal->j_revoke;
137-
int hash_shift = table->hash_shift;
138-
int hash = (int)block ^ (int)((block >> 31) >> 1);
139-
140-
return ((hash << (hash_shift - 6)) ^
141-
(hash >> 13) ^
142-
(hash << (hash_shift - 12))) & (table->hash_size - 1);
136+
return hash_64(block, journal->j_revoke->hash_shift);
143137
}
144138

145139
static int insert_revoke_hash(journal_t *journal, unsigned long long blocknr,

0 commit comments

Comments
 (0)