mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
A set of miscellaneous ext4 bug fixes for 3.18.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJUVAF/AAoJENNvdpvBGATwEbAQALNiAIChEyJTnQDkAQc2wqqn dv8NQmFr5aefc63A/+n/yJJGrQZtKs0ceh29ty5ksYLFXzUdc2ctFg6vBmllQfbz PQawAk2gOkF8zfVuqiQU7X+wTBpGmGXTa8HY+WJTtk0pBfhl+p0PDCYsWXMwZJ1D tAZpxJ4AmPc7A4hApWOvce6r7Xg24vZk/8UA93Tif9AkeY6VoN272Hx5b/UGmBHY RCEgpowuiIY38bghtLh5+T0J98/EQNof46cEHgGI9nIDZeXRzgvDojE5bLI0/IS/ K07MjYlm/WFWsLFkgNJkTiqEXgnji9BNYRF1xxUjMMBAR4+fnFLw9kXXgcETrPCx U7lHOhs8M2FK40cWhUDz/tukvL4S4lQwPEeqBPlRE8J5/twRyXHeZDp4F7LOobwq mk6AajSJlP+05XwXOuCx7Hcf9uxjw/IpqhBS5IZxy8Nn3T2guPlY9wMhYU1RYFws 54FeE76SJ8EDgjVK/txj7rgh11GggWsjsdXvftSElM2DsKsqYEOKAvDzvwmbm7eV dsFOlRB6B/X4UpiAC2MiPJynYg9TJ7LkVBzDZeZ/fbm7JhTqChSJDzapqdrmNPIY SQqwLmFXnHqaw6HNitZ5Bs+fD6nfvKqy85NeImxE3lhLWDuiTt77Y3o80IW30TgN 5bnuXq8Rkukrxs/VDvPq =kI6P -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
32e8fd2f8e
@ -3603,11 +3603,10 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
|
||||
}
|
||||
}
|
||||
|
||||
allocated = ext4_split_extent(handle, inode, ppath,
|
||||
&split_map, split_flag, flags);
|
||||
if (allocated < 0)
|
||||
err = allocated;
|
||||
|
||||
err = ext4_split_extent(handle, inode, ppath, &split_map, split_flag,
|
||||
flags);
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
out:
|
||||
/* If we have gotten a failure, don't zero out status tree */
|
||||
if (!err)
|
||||
|
@ -137,10 +137,10 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
iov_iter_truncate(from, sbi->s_bitmap_maxbytes - pos);
|
||||
}
|
||||
|
||||
iocb->private = &overwrite;
|
||||
if (o_direct) {
|
||||
blk_start_plug(&plug);
|
||||
|
||||
iocb->private = &overwrite;
|
||||
|
||||
/* check whether we do a DIO overwrite or not */
|
||||
if (ext4_should_dioread_nolock(inode) && !aio_mutex &&
|
||||
|
@ -887,6 +887,10 @@ got:
|
||||
struct buffer_head *block_bitmap_bh;
|
||||
|
||||
block_bitmap_bh = ext4_read_block_bitmap(sb, group);
|
||||
if (!block_bitmap_bh) {
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
BUFFER_TRACE(block_bitmap_bh, "get block bitmap access");
|
||||
err = ext4_journal_get_write_access(handle, block_bitmap_bh);
|
||||
if (err) {
|
||||
|
@ -4959,7 +4959,12 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
|
||||
if (val)
|
||||
ext4_set_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
|
||||
else {
|
||||
jbd2_journal_flush(journal);
|
||||
err = jbd2_journal_flush(journal);
|
||||
if (err < 0) {
|
||||
jbd2_journal_unlock_updates(journal);
|
||||
ext4_inode_resume_unlocked_dio(inode);
|
||||
return err;
|
||||
}
|
||||
ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
|
||||
}
|
||||
ext4_set_aops(inode);
|
||||
|
@ -1816,17 +1816,31 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
|
||||
hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
|
||||
hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
|
||||
ext4fs_dirhash(name, namelen, &hinfo);
|
||||
memset(frames, 0, sizeof(frames));
|
||||
frame = frames;
|
||||
frame->entries = entries;
|
||||
frame->at = entries;
|
||||
frame->bh = bh;
|
||||
bh = bh2;
|
||||
|
||||
ext4_handle_dirty_dx_node(handle, dir, frame->bh);
|
||||
ext4_handle_dirty_dirent_node(handle, dir, bh);
|
||||
retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
|
||||
if (retval)
|
||||
goto out_frames;
|
||||
retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
|
||||
if (retval)
|
||||
goto out_frames;
|
||||
|
||||
de = do_split(handle,dir, &bh, frame, &hinfo);
|
||||
if (IS_ERR(de)) {
|
||||
retval = PTR_ERR(de);
|
||||
goto out_frames;
|
||||
}
|
||||
dx_release(frames);
|
||||
|
||||
retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
|
||||
brelse(bh);
|
||||
return retval;
|
||||
out_frames:
|
||||
/*
|
||||
* Even if the block split failed, we have to properly write
|
||||
* out all the changes we did so far. Otherwise we can end up
|
||||
@ -1834,12 +1848,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
|
||||
*/
|
||||
ext4_mark_inode_dirty(handle, dir);
|
||||
dx_release(frames);
|
||||
return PTR_ERR(de);
|
||||
}
|
||||
dx_release(frames);
|
||||
|
||||
retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
|
||||
brelse(bh);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1081,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data,
|
||||
break;
|
||||
|
||||
if (meta_bg == 0)
|
||||
backup_block = group * bpg + blk_off;
|
||||
backup_block = ((ext4_fsblk_t)group) * bpg + blk_off;
|
||||
else
|
||||
backup_block = (ext4_group_first_block_no(sb, group) +
|
||||
ext4_bg_has_super(sb, group));
|
||||
|
@ -3526,6 +3526,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
||||
#ifdef CONFIG_EXT4_FS_POSIX_ACL
|
||||
set_opt(sb, POSIX_ACL);
|
||||
#endif
|
||||
/* don't forget to enable journal_csum when metadata_csum is enabled. */
|
||||
if (ext4_has_metadata_csum(sb))
|
||||
set_opt(sb, JOURNAL_CHECKSUM);
|
||||
|
||||
if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA)
|
||||
set_opt(sb, JOURNAL_DATA);
|
||||
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)
|
||||
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) &&
|
||||
!(sb->s_flags & MS_RDONLY))
|
||||
if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)))
|
||||
goto failed_mount3;
|
||||
goto failed_mount3a;
|
||||
|
||||
/*
|
||||
* 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)
|
||||
if (!test_opt(sb, NOLOAD) &&
|
||||
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
|
||||
if (ext4_load_journal(sb, es, journal_devnum))
|
||||
goto failed_mount3;
|
||||
goto failed_mount3a;
|
||||
} else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
|
||||
EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
|
||||
ext4_msg(sb, KERN_ERR, "required journal recovery "
|
||||
@ -4240,6 +4244,7 @@ failed_mount_wq:
|
||||
jbd2_journal_destroy(sbi->s_journal);
|
||||
sbi->s_journal = NULL;
|
||||
}
|
||||
failed_mount3a:
|
||||
ext4_es_unregister_shrinker(sbi);
|
||||
failed_mount3:
|
||||
del_timer_sync(&sbi->s_err_report);
|
||||
@ -4841,6 +4846,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
|
||||
goto restore_opts;
|
||||
}
|
||||
|
||||
if ((old_opts.s_mount_opt & EXT4_MOUNT_JOURNAL_CHECKSUM) ^
|
||||
test_opt(sb, JOURNAL_CHECKSUM)) {
|
||||
ext4_msg(sb, KERN_ERR, "changing journal_checksum "
|
||||
"during remount not supported");
|
||||
err = -EINVAL;
|
||||
goto restore_opts;
|
||||
}
|
||||
|
||||
if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
|
||||
if (test_opt2(sb, EXPLICIT_DELALLOC)) {
|
||||
ext4_msg(sb, KERN_ERR, "can't mount with "
|
||||
|
@ -92,6 +92,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/bio.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/hash.h>
|
||||
#endif
|
||||
|
||||
static struct kmem_cache *jbd2_revoke_record_cache;
|
||||
@ -130,16 +131,9 @@ static void flush_descriptor(journal_t *, struct buffer_head *, int, int);
|
||||
|
||||
/* Utility functions to maintain the revoke table */
|
||||
|
||||
/* Borrowed from buffer.c: this is a tried and tested block hash function */
|
||||
static inline int hash(journal_t *journal, unsigned long long block)
|
||||
{
|
||||
struct jbd2_revoke_table_s *table = journal->j_revoke;
|
||||
int hash_shift = table->hash_shift;
|
||||
int hash = (int)block ^ (int)((block >> 31) >> 1);
|
||||
|
||||
return ((hash << (hash_shift - 6)) ^
|
||||
(hash >> 13) ^
|
||||
(hash << (hash_shift - 12))) & (table->hash_size - 1);
|
||||
return hash_64(block, journal->j_revoke->hash_shift);
|
||||
}
|
||||
|
||||
static int insert_revoke_hash(journal_t *journal, unsigned long long blocknr,
|
||||
|
Loading…
Reference in New Issue
Block a user