Some bug fixes, and an update to the URL's for the final version of
Unicode 12.1.0. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEK2m5VNv+CHkogTfJ8vlZVpUNgaMFAlzg2qIACgkQ8vlZVpUN gaPYfgf+IadtbeBYbKcHQzw8OZ9UxyGv7+Havs523XzhdceiflpOCe3lpSFYuX6w 0CtRIWEOqFzQLRHUlX/sRywYLvrvg3irDuYJGTzny9MfPEI+tVCkYi877PPAOOR3 4xay7dF63mcCpmhRxgw1fLx5I/hYpzrDnw5dGe7jjgU6SrR5FpE2GmEmbfBW087W zAuRDkuTv03J791Kgpq4TAMNla9F2/oedq/2B0v43+TnKfYe1SEIDm3VusUvSfoI ++8CfRrRJ3D7vCmtFSuieFFb91HtHMqdv0gaad2cY1DfvJLVm7gP1uPL7QahA5Dq VfhvFfqshqN9Jizr6BqP5GPOj2J9cw== =QK+R -----END PGP SIGNATURE----- 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: "Some bug fixes, and an update to the URL's for the final version of Unicode 12.1.0" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: avoid panic during forced reboot due to aborted journal ext4: fix block validity checks for journal inodes using indirect blocks unicode: update to Unicode 12.1.0 final unicode: add missing check for an error return from utf8lookup() ext4: fix miscellaneous sparse warnings ext4: unsigned int compared against zero ext4: fix use-after-free in dx_release() ext4: fix data corruption caused by overlapping unaligned and aligned IO jbd2: fix potential double free ext4: zero out the unused memory region in the extent tree block
This commit is contained in:
Коммит
c4d36b63b2
|
@ -142,7 +142,8 @@ static int ext4_protect_reserved_inode(struct super_block *sb, u32 ino)
|
|||
struct inode *inode;
|
||||
struct ext4_sb_info *sbi = EXT4_SB(sb);
|
||||
struct ext4_map_blocks map;
|
||||
u32 i = 0, err = 0, num, n;
|
||||
u32 i = 0, num;
|
||||
int err = 0, n;
|
||||
|
||||
if ((ino < EXT4_ROOT_INO) ||
|
||||
(ino > le32_to_cpu(sbi->s_es->s_inodes_count)))
|
||||
|
@ -276,6 +277,11 @@ int ext4_check_blockref(const char *function, unsigned int line,
|
|||
__le32 *bref = p;
|
||||
unsigned int blk;
|
||||
|
||||
if (ext4_has_feature_journal(inode->i_sb) &&
|
||||
(inode->i_ino ==
|
||||
le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum)))
|
||||
return 0;
|
||||
|
||||
while (bref < p+max) {
|
||||
blk = le32_to_cpu(*bref++);
|
||||
if (blk &&
|
||||
|
|
|
@ -1035,6 +1035,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
|
|||
__le32 border;
|
||||
ext4_fsblk_t *ablocks = NULL; /* array of allocated blocks */
|
||||
int err = 0;
|
||||
size_t ext_size = 0;
|
||||
|
||||
/* make decision: where to split? */
|
||||
/* FIXME: now decision is simplest: at current extent */
|
||||
|
@ -1126,6 +1127,10 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
|
|||
le16_add_cpu(&neh->eh_entries, m);
|
||||
}
|
||||
|
||||
/* zero out unused area in the extent block */
|
||||
ext_size = sizeof(struct ext4_extent_header) +
|
||||
sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries);
|
||||
memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
|
||||
ext4_extent_block_csum_set(inode, neh);
|
||||
set_buffer_uptodate(bh);
|
||||
unlock_buffer(bh);
|
||||
|
@ -1205,6 +1210,11 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
|
|||
sizeof(struct ext4_extent_idx) * m);
|
||||
le16_add_cpu(&neh->eh_entries, m);
|
||||
}
|
||||
/* zero out unused area in the extent block */
|
||||
ext_size = sizeof(struct ext4_extent_header) +
|
||||
(sizeof(struct ext4_extent) * le16_to_cpu(neh->eh_entries));
|
||||
memset(bh->b_data + ext_size, 0,
|
||||
inode->i_sb->s_blocksize - ext_size);
|
||||
ext4_extent_block_csum_set(inode, neh);
|
||||
set_buffer_uptodate(bh);
|
||||
unlock_buffer(bh);
|
||||
|
@ -1270,6 +1280,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
|
|||
ext4_fsblk_t newblock, goal = 0;
|
||||
struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es;
|
||||
int err = 0;
|
||||
size_t ext_size = 0;
|
||||
|
||||
/* Try to prepend new index to old one */
|
||||
if (ext_depth(inode))
|
||||
|
@ -1295,9 +1306,11 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ext_size = sizeof(EXT4_I(inode)->i_data);
|
||||
/* move top-level index/leaf into new block */
|
||||
memmove(bh->b_data, EXT4_I(inode)->i_data,
|
||||
sizeof(EXT4_I(inode)->i_data));
|
||||
memmove(bh->b_data, EXT4_I(inode)->i_data, ext_size);
|
||||
/* zero out unused area in the extent block */
|
||||
memset(bh->b_data + ext_size, 0, inode->i_sb->s_blocksize - ext_size);
|
||||
|
||||
/* set size of new block */
|
||||
neh = ext_block_hdr(bh);
|
||||
|
|
|
@ -264,6 +264,13 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
|||
}
|
||||
|
||||
ret = __generic_file_write_iter(iocb, from);
|
||||
/*
|
||||
* Unaligned direct AIO must be the only IO in flight. Otherwise
|
||||
* overlapping aligned IO after unaligned might result in data
|
||||
* corruption.
|
||||
*/
|
||||
if (ret == -EIOCBQUEUED && unaligned_aio)
|
||||
ext4_unwritten_wait(inode);
|
||||
inode_unlock(inode);
|
||||
|
||||
if (ret > 0)
|
||||
|
|
|
@ -626,7 +626,7 @@ int ext4_getfsmap(struct super_block *sb, struct ext4_fsmap_head *head,
|
|||
{
|
||||
struct ext4_fsmap dkeys[2]; /* per-dev keys */
|
||||
struct ext4_getfsmap_dev handlers[EXT4_GETFSMAP_DEVS];
|
||||
struct ext4_getfsmap_info info = {0};
|
||||
struct ext4_getfsmap_info info = { NULL };
|
||||
int i;
|
||||
int error = 0;
|
||||
|
||||
|
|
|
@ -608,7 +608,7 @@ static int ext4_getfsmap_format(struct ext4_fsmap *xfm, void *priv)
|
|||
static int ext4_ioc_getfsmap(struct super_block *sb,
|
||||
struct fsmap_head __user *arg)
|
||||
{
|
||||
struct getfsmap_info info = {0};
|
||||
struct getfsmap_info info = { NULL };
|
||||
struct ext4_fsmap_head xhead = {0};
|
||||
struct fsmap_head head;
|
||||
bool aborted = false;
|
||||
|
|
|
@ -872,12 +872,15 @@ static void dx_release(struct dx_frame *frames)
|
|||
{
|
||||
struct dx_root_info *info;
|
||||
int i;
|
||||
unsigned int indirect_levels;
|
||||
|
||||
if (frames[0].bh == NULL)
|
||||
return;
|
||||
|
||||
info = &((struct dx_root *)frames[0].bh->b_data)->info;
|
||||
for (i = 0; i <= info->indirect_levels; i++) {
|
||||
/* save local copy, "info" may be freed after brelse() */
|
||||
indirect_levels = info->indirect_levels;
|
||||
for (i = 0; i <= indirect_levels; i++) {
|
||||
if (frames[i].bh == NULL)
|
||||
break;
|
||||
brelse(frames[i].bh);
|
||||
|
|
|
@ -699,7 +699,7 @@ void __ext4_abort(struct super_block *sb, const char *function,
|
|||
jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
|
||||
save_error_info(sb, function, line);
|
||||
}
|
||||
if (test_opt(sb, ERRORS_PANIC)) {
|
||||
if (test_opt(sb, ERRORS_PANIC) && !system_going_down()) {
|
||||
if (EXT4_SB(sb)->s_journal &&
|
||||
!(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
|
||||
return;
|
||||
|
@ -4661,7 +4661,7 @@ failed_mount:
|
|||
|
||||
#ifdef CONFIG_QUOTA
|
||||
for (i = 0; i < EXT4_MAXQUOTAS; i++)
|
||||
kfree(sbi->s_qf_names[i]);
|
||||
kfree(get_qf_name(sb, sbi, i));
|
||||
#endif
|
||||
ext4_blkdev_remove(sbi);
|
||||
brelse(bh);
|
||||
|
|
|
@ -2375,22 +2375,19 @@ static struct kmem_cache *jbd2_journal_head_cache;
|
|||
static atomic_t nr_journal_heads = ATOMIC_INIT(0);
|
||||
#endif
|
||||
|
||||
static int jbd2_journal_init_journal_head_cache(void)
|
||||
static int __init jbd2_journal_init_journal_head_cache(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
J_ASSERT(jbd2_journal_head_cache == NULL);
|
||||
J_ASSERT(!jbd2_journal_head_cache);
|
||||
jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
|
||||
sizeof(struct journal_head),
|
||||
0, /* offset */
|
||||
SLAB_TEMPORARY | SLAB_TYPESAFE_BY_RCU,
|
||||
NULL); /* ctor */
|
||||
retval = 0;
|
||||
if (!jbd2_journal_head_cache) {
|
||||
retval = -ENOMEM;
|
||||
printk(KERN_EMERG "JBD2: no memory for journal_head cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return retval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jbd2_journal_destroy_journal_head_cache(void)
|
||||
|
@ -2636,28 +2633,38 @@ static void __exit jbd2_remove_jbd_stats_proc_entry(void)
|
|||
|
||||
struct kmem_cache *jbd2_handle_cache, *jbd2_inode_cache;
|
||||
|
||||
static int __init jbd2_journal_init_handle_cache(void)
|
||||
static int __init jbd2_journal_init_inode_cache(void)
|
||||
{
|
||||
jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY);
|
||||
if (jbd2_handle_cache == NULL) {
|
||||
printk(KERN_EMERG "JBD2: failed to create handle cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
J_ASSERT(!jbd2_inode_cache);
|
||||
jbd2_inode_cache = KMEM_CACHE(jbd2_inode, 0);
|
||||
if (jbd2_inode_cache == NULL) {
|
||||
printk(KERN_EMERG "JBD2: failed to create inode cache\n");
|
||||
kmem_cache_destroy(jbd2_handle_cache);
|
||||
if (!jbd2_inode_cache) {
|
||||
pr_emerg("JBD2: failed to create inode cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init jbd2_journal_init_handle_cache(void)
|
||||
{
|
||||
J_ASSERT(!jbd2_handle_cache);
|
||||
jbd2_handle_cache = KMEM_CACHE(jbd2_journal_handle, SLAB_TEMPORARY);
|
||||
if (!jbd2_handle_cache) {
|
||||
printk(KERN_EMERG "JBD2: failed to create handle cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void jbd2_journal_destroy_inode_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(jbd2_inode_cache);
|
||||
jbd2_inode_cache = NULL;
|
||||
}
|
||||
|
||||
static void jbd2_journal_destroy_handle_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(jbd2_handle_cache);
|
||||
jbd2_handle_cache = NULL;
|
||||
kmem_cache_destroy(jbd2_inode_cache);
|
||||
jbd2_inode_cache = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2668,11 +2675,15 @@ static int __init journal_init_caches(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = jbd2_journal_init_revoke_caches();
|
||||
ret = jbd2_journal_init_revoke_record_cache();
|
||||
if (ret == 0)
|
||||
ret = jbd2_journal_init_revoke_table_cache();
|
||||
if (ret == 0)
|
||||
ret = jbd2_journal_init_journal_head_cache();
|
||||
if (ret == 0)
|
||||
ret = jbd2_journal_init_handle_cache();
|
||||
if (ret == 0)
|
||||
ret = jbd2_journal_init_inode_cache();
|
||||
if (ret == 0)
|
||||
ret = jbd2_journal_init_transaction_cache();
|
||||
return ret;
|
||||
|
@ -2680,9 +2691,11 @@ static int __init journal_init_caches(void)
|
|||
|
||||
static void jbd2_journal_destroy_caches(void)
|
||||
{
|
||||
jbd2_journal_destroy_revoke_caches();
|
||||
jbd2_journal_destroy_revoke_record_cache();
|
||||
jbd2_journal_destroy_revoke_table_cache();
|
||||
jbd2_journal_destroy_journal_head_cache();
|
||||
jbd2_journal_destroy_handle_cache();
|
||||
jbd2_journal_destroy_inode_cache();
|
||||
jbd2_journal_destroy_transaction_cache();
|
||||
jbd2_journal_destroy_slabs();
|
||||
}
|
||||
|
|
|
@ -178,33 +178,41 @@ static struct jbd2_revoke_record_s *find_revoke_record(journal_t *journal,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void jbd2_journal_destroy_revoke_caches(void)
|
||||
void jbd2_journal_destroy_revoke_record_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(jbd2_revoke_record_cache);
|
||||
jbd2_revoke_record_cache = NULL;
|
||||
}
|
||||
|
||||
void jbd2_journal_destroy_revoke_table_cache(void)
|
||||
{
|
||||
kmem_cache_destroy(jbd2_revoke_table_cache);
|
||||
jbd2_revoke_table_cache = NULL;
|
||||
}
|
||||
|
||||
int __init jbd2_journal_init_revoke_caches(void)
|
||||
int __init jbd2_journal_init_revoke_record_cache(void)
|
||||
{
|
||||
J_ASSERT(!jbd2_revoke_record_cache);
|
||||
J_ASSERT(!jbd2_revoke_table_cache);
|
||||
|
||||
jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s,
|
||||
SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY);
|
||||
if (!jbd2_revoke_record_cache)
|
||||
goto record_cache_failure;
|
||||
|
||||
if (!jbd2_revoke_record_cache) {
|
||||
pr_emerg("JBD2: failed to create revoke_record cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init jbd2_journal_init_revoke_table_cache(void)
|
||||
{
|
||||
J_ASSERT(!jbd2_revoke_table_cache);
|
||||
jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s,
|
||||
SLAB_TEMPORARY);
|
||||
if (!jbd2_revoke_table_cache)
|
||||
goto table_cache_failure;
|
||||
return 0;
|
||||
table_cache_failure:
|
||||
jbd2_journal_destroy_revoke_caches();
|
||||
record_cache_failure:
|
||||
if (!jbd2_revoke_table_cache) {
|
||||
pr_emerg("JBD2: failed to create revoke_table cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size)
|
||||
|
|
|
@ -42,9 +42,11 @@ int __init jbd2_journal_init_transaction_cache(void)
|
|||
0,
|
||||
SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
|
||||
NULL);
|
||||
if (transaction_cache)
|
||||
return 0;
|
||||
return -ENOMEM;
|
||||
if (!transaction_cache) {
|
||||
pr_emerg("JBD2: failed to create transaction cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jbd2_journal_destroy_transaction_cache(void)
|
||||
|
|
|
@ -5,29 +5,15 @@ The full set of files can be found here:
|
|||
|
||||
http://www.unicode.org/Public/12.1.0/ucd/
|
||||
|
||||
Note!
|
||||
|
||||
The URL's listed below are not stable. That's because Unicode 12.1.0
|
||||
has not been officially released yet; it is scheduled to be released
|
||||
on May 8, 2019. We taking Unicode 12.1.0 a few weeks early because it
|
||||
contains a new Japanese character which is required in order to
|
||||
specify Japenese dates after May 1, 2019, when Crown Prince Naruhito
|
||||
ascends to the Chrysanthemum Throne. (Isn't internationalization fun?
|
||||
The abdication of Emperor Akihito of Japan is requiring dozens of
|
||||
software packages to be updated with only a month's notice. :-)
|
||||
|
||||
We will update the URL's (and any needed changes to the checksums)
|
||||
after the final Unicode 12.1.0 is released.
|
||||
|
||||
Individual source links:
|
||||
|
||||
https://www.unicode.org/Public/12.1.0/ucd/CaseFolding-12.1.0d2.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/DerivedAge-12.1.0d3.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/extracted/DerivedCombiningClass-12.1.0d2.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/DerivedCoreProperties-12.1.0d2.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/NormalizationCorrections-12.1.0d1.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/NormalizationTest-12.1.0d3.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/UnicodeData-12.1.0d2.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/CaseFolding.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/DerivedAge.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/extracted/DerivedCombiningClass.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/DerivedCoreProperties.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/NormalizationCorrections.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/NormalizationTest.txt
|
||||
https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt
|
||||
|
||||
md5sums (verify by running "md5sum -c README.utf8data"):
|
||||
|
||||
|
|
|
@ -714,6 +714,8 @@ int utf8byte(struct utf8cursor *u8c)
|
|||
}
|
||||
|
||||
leaf = utf8lookup(u8c->data, u8c->hangul, u8c->s);
|
||||
if (!leaf)
|
||||
return -1;
|
||||
ccc = LEAF_CCC(leaf);
|
||||
}
|
||||
|
||||
|
|
|
@ -1318,7 +1318,7 @@ extern void __wait_on_journal (journal_t *);
|
|||
|
||||
/* Transaction cache support */
|
||||
extern void jbd2_journal_destroy_transaction_cache(void);
|
||||
extern int jbd2_journal_init_transaction_cache(void);
|
||||
extern int __init jbd2_journal_init_transaction_cache(void);
|
||||
extern void jbd2_journal_free_transaction(transaction_t *);
|
||||
|
||||
/*
|
||||
|
@ -1446,8 +1446,10 @@ static inline void jbd2_free_inode(struct jbd2_inode *jinode)
|
|||
/* Primary revoke support */
|
||||
#define JOURNAL_REVOKE_DEFAULT_HASH 256
|
||||
extern int jbd2_journal_init_revoke(journal_t *, int);
|
||||
extern void jbd2_journal_destroy_revoke_caches(void);
|
||||
extern int jbd2_journal_init_revoke_caches(void);
|
||||
extern void jbd2_journal_destroy_revoke_record_cache(void);
|
||||
extern void jbd2_journal_destroy_revoke_table_cache(void);
|
||||
extern int __init jbd2_journal_init_revoke_record_cache(void);
|
||||
extern int __init jbd2_journal_init_revoke_table_cache(void);
|
||||
|
||||
extern void jbd2_journal_destroy_revoke(journal_t *);
|
||||
extern int jbd2_journal_revoke (handle_t *, unsigned long long, struct buffer_head *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче