Various regression and bug fixes for ext4.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABCAAGBQJR43U/AAoJENNvdpvBGATwdl4P+gI23RkFXTHKvd3XtmXLQojT ncRXVOAARuRZiMbiAOzXv/BDSkLHnOHw6fVLK5buFTLlpQ00tdlrd6ngui4NTe+v Qo0GUqL09iSMLEgZV0OwxV5EULPpYb/xQwfQNAqG3pQbUFq/JdxptBT7r/go/YnX bzWSDiMKeFQoIgH1/xDGXRrfcSdEbjewMfT7lXq+XWRlPyyJPjLnxzDGfJDaOLSR rCZJOsbCfxzwhBd2HFzH55CGGU4yoZ6O7qpsMoF1gjqUSJ2DmVhMV/NSspmTnKRd EZKDT7LK8c02UNdYzLPzPpRjAQfUWBgnh9R84Ake8Py2UHGommTyz6TqMmNTbW5Q EMRd461v+8bvIYnbe/tkT+CTTkC7lRapX6AYaq8k+MpLIWE1bmvX+bMRYOejTE4r jTgYUktzaVzx/4XdgT837vCbsFttixL3x62XelrkZoANw/m0+jgOn9mY5pjDFp8j Eq5wWJ8IsuxCofk/qQj5rOK7/3tFcdJULCoX8f3AB0vooAUKTXBYxYflfIeSgqeZ vlp0ymj588pimH3LM0Vs1BT/aGh0JninLIBk+hcb2YxC2NzvLO2pjSV8i+olBU+C Yq7MoakdT/FDTWp8WbbZm21C95Tj/zCfMCBSgC0k7LpQVM00ts87UdUgfAZPzI1w ZISZFy6O/zhPMFAZCxfV =qf2h -----END PGP SIGNATURE----- Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 Pull ext4 bugfixes from Ted Ts'o: "Various regression and bug fixes for ext4" * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: don't allow ext4_free_blocks() to fail due to ENOMEM ext4: fix spelling errors and a comment in extent_status tree ext4: rate limit printk in buffer_io_error() ext4: don't show usrquota/grpquota twice in /proc/mounts ext4: fix warning in ext4_evict_inode() ext4: fix ext4_get_group_number() ext4: silence warning in ext4_writepages()
This commit is contained in:
Коммит
47188d39b5
|
@ -38,8 +38,8 @@ ext4_group_t ext4_get_group_number(struct super_block *sb,
|
|||
ext4_group_t group;
|
||||
|
||||
if (test_opt2(sb, STD_GROUP_SIZE))
|
||||
group = (le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block) +
|
||||
block) >>
|
||||
group = (block -
|
||||
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) >>
|
||||
(EXT4_BLOCK_SIZE_BITS(sb) + EXT4_CLUSTER_BITS(sb) + 3);
|
||||
else
|
||||
ext4_get_group_no_and_offset(sb, block, &group, NULL);
|
||||
|
|
|
@ -439,7 +439,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
|
|||
*/
|
||||
if (!ext4_es_is_written(es) && !ext4_es_is_unwritten(es)) {
|
||||
if (in_range(es->es_lblk, ee_block, ee_len)) {
|
||||
pr_warn("ES insert assertation failed for "
|
||||
pr_warn("ES insert assertion failed for "
|
||||
"inode: %lu we can find an extent "
|
||||
"at block [%d/%d/%llu/%c], but we "
|
||||
"want to add an delayed/hole extent "
|
||||
|
@ -458,7 +458,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
|
|||
*/
|
||||
if (es->es_lblk < ee_block ||
|
||||
ext4_es_pblock(es) != ee_start + es->es_lblk - ee_block) {
|
||||
pr_warn("ES insert assertation failed for inode: %lu "
|
||||
pr_warn("ES insert assertion failed for inode: %lu "
|
||||
"ex_status [%d/%d/%llu/%c] != "
|
||||
"es_status [%d/%d/%llu/%c]\n", inode->i_ino,
|
||||
ee_block, ee_len, ee_start,
|
||||
|
@ -468,7 +468,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
|
|||
}
|
||||
|
||||
if (ee_status ^ es_status) {
|
||||
pr_warn("ES insert assertation failed for inode: %lu "
|
||||
pr_warn("ES insert assertion failed for inode: %lu "
|
||||
"ex_status [%d/%d/%llu/%c] != "
|
||||
"es_status [%d/%d/%llu/%c]\n", inode->i_ino,
|
||||
ee_block, ee_len, ee_start,
|
||||
|
@ -481,7 +481,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
|
|||
* that we don't want to add an written/unwritten extent.
|
||||
*/
|
||||
if (!ext4_es_is_delayed(es) && !ext4_es_is_hole(es)) {
|
||||
pr_warn("ES insert assertation failed for inode: %lu "
|
||||
pr_warn("ES insert assertion failed for inode: %lu "
|
||||
"can't find an extent at block %d but we want "
|
||||
"to add an written/unwritten extent "
|
||||
"[%d/%d/%llu/%llx]\n", inode->i_ino,
|
||||
|
@ -519,7 +519,7 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
|
|||
* We want to add a delayed/hole extent but this
|
||||
* block has been allocated.
|
||||
*/
|
||||
pr_warn("ES insert assertation failed for inode: %lu "
|
||||
pr_warn("ES insert assertion failed for inode: %lu "
|
||||
"We can find blocks but we want to add a "
|
||||
"delayed/hole extent [%d/%d/%llu/%llx]\n",
|
||||
inode->i_ino, es->es_lblk, es->es_len,
|
||||
|
@ -527,13 +527,13 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
|
|||
return;
|
||||
} else if (ext4_es_is_written(es)) {
|
||||
if (retval != es->es_len) {
|
||||
pr_warn("ES insert assertation failed for "
|
||||
pr_warn("ES insert assertion failed for "
|
||||
"inode: %lu retval %d != es_len %d\n",
|
||||
inode->i_ino, retval, es->es_len);
|
||||
return;
|
||||
}
|
||||
if (map.m_pblk != ext4_es_pblock(es)) {
|
||||
pr_warn("ES insert assertation failed for "
|
||||
pr_warn("ES insert assertion failed for "
|
||||
"inode: %lu m_pblk %llu != "
|
||||
"es_pblk %llu\n",
|
||||
inode->i_ino, map.m_pblk,
|
||||
|
@ -549,7 +549,7 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
|
|||
}
|
||||
} else if (retval == 0) {
|
||||
if (ext4_es_is_written(es)) {
|
||||
pr_warn("ES insert assertation failed for inode: %lu "
|
||||
pr_warn("ES insert assertion failed for inode: %lu "
|
||||
"We can't find the block but we want to add "
|
||||
"an written extent [%d/%d/%llu/%llx]\n",
|
||||
inode->i_ino, es->es_lblk, es->es_len,
|
||||
|
@ -632,10 +632,8 @@ out:
|
|||
}
|
||||
|
||||
/*
|
||||
* ext4_es_insert_extent() adds a space to a extent status tree.
|
||||
*
|
||||
* ext4_es_insert_extent is called by ext4_da_write_begin and
|
||||
* ext4_es_remove_extent.
|
||||
* ext4_es_insert_extent() adds information to an inode's extent
|
||||
* status tree.
|
||||
*
|
||||
* Return 0 on success, error code on failure.
|
||||
*/
|
||||
|
|
|
@ -465,7 +465,7 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
|
|||
if (es_map->m_lblk != map->m_lblk ||
|
||||
es_map->m_flags != map->m_flags ||
|
||||
es_map->m_pblk != map->m_pblk) {
|
||||
printk("ES cache assertation failed for inode: %lu "
|
||||
printk("ES cache assertion failed for inode: %lu "
|
||||
"es_cached ex [%d/%d/%llu/%x] != "
|
||||
"found ex [%d/%d/%llu/%x] retval %d flags %x\n",
|
||||
inode->i_ino, es_map->m_lblk, es_map->m_len,
|
||||
|
@ -558,7 +558,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
|
|||
|
||||
#ifdef ES_AGGRESSIVE_TEST
|
||||
if (retval != map->m_len) {
|
||||
printk("ES len assertation failed for inode: %lu "
|
||||
printk("ES len assertion failed for inode: %lu "
|
||||
"retval %d != map->m_len %d "
|
||||
"in %s (lookup)\n", inode->i_ino, retval,
|
||||
map->m_len, __func__);
|
||||
|
@ -659,7 +659,7 @@ found:
|
|||
|
||||
#ifdef ES_AGGRESSIVE_TEST
|
||||
if (retval != map->m_len) {
|
||||
printk("ES len assertation failed for inode: %lu "
|
||||
printk("ES len assertion failed for inode: %lu "
|
||||
"retval %d != map->m_len %d "
|
||||
"in %s (allocation)\n", inode->i_ino, retval,
|
||||
map->m_len, __func__);
|
||||
|
@ -1642,7 +1642,7 @@ add_delayed:
|
|||
|
||||
#ifdef ES_AGGRESSIVE_TEST
|
||||
if (retval != map->m_len) {
|
||||
printk("ES len assertation failed for inode: %lu "
|
||||
printk("ES len assertion failed for inode: %lu "
|
||||
"retval %d != map->m_len %d "
|
||||
"in %s (lookup)\n", inode->i_ino, retval,
|
||||
map->m_len, __func__);
|
||||
|
@ -2163,7 +2163,7 @@ static int mpage_map_and_submit_extent(handle_t *handle,
|
|||
|
||||
mpd->io_submit.io_end->offset =
|
||||
((loff_t)map->m_lblk) << inode->i_blkbits;
|
||||
while (map->m_len) {
|
||||
do {
|
||||
err = mpage_map_one_extent(handle, mpd);
|
||||
if (err < 0) {
|
||||
struct super_block *sb = inode->i_sb;
|
||||
|
@ -2201,7 +2201,7 @@ static int mpage_map_and_submit_extent(handle_t *handle,
|
|||
err = mpage_map_and_submit_buffers(mpd);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
} while (map->m_len);
|
||||
|
||||
/* Update on-disk size after IO is submitted */
|
||||
disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT;
|
||||
|
|
|
@ -4740,11 +4740,16 @@ do_more:
|
|||
* blocks being freed are metadata. these blocks shouldn't
|
||||
* be used until this transaction is committed
|
||||
*/
|
||||
retry:
|
||||
new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
|
||||
if (!new_entry) {
|
||||
ext4_mb_unload_buddy(&e4b);
|
||||
err = -ENOMEM;
|
||||
goto error_return;
|
||||
/*
|
||||
* We use a retry loop because
|
||||
* ext4_free_blocks() is not allowed to fail.
|
||||
*/
|
||||
cond_resched();
|
||||
congestion_wait(BLK_RW_ASYNC, HZ/50);
|
||||
goto retry;
|
||||
}
|
||||
new_entry->efd_start_cluster = bit;
|
||||
new_entry->efd_group = block_group;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
#include "ext4_jbd2.h"
|
||||
#include "xattr.h"
|
||||
|
@ -55,7 +56,7 @@ void ext4_exit_pageio(void)
|
|||
static void buffer_io_error(struct buffer_head *bh)
|
||||
{
|
||||
char b[BDEVNAME_SIZE];
|
||||
printk(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
|
||||
printk_ratelimited(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
|
||||
bdevname(bh->b_bdev, b),
|
||||
(unsigned long long)bh->b_blocknr);
|
||||
}
|
||||
|
@ -308,6 +309,7 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
|
|||
return io_end;
|
||||
}
|
||||
|
||||
/* BIO completion function for page writeback */
|
||||
static void ext4_end_bio(struct bio *bio, int error)
|
||||
{
|
||||
ext4_io_end_t *io_end = bio->bi_private;
|
||||
|
@ -318,18 +320,6 @@ static void ext4_end_bio(struct bio *bio, int error)
|
|||
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
|
||||
error = 0;
|
||||
|
||||
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
|
||||
/*
|
||||
* Link bio into list hanging from io_end. We have to do it
|
||||
* atomically as bio completions can be racing against each
|
||||
* other.
|
||||
*/
|
||||
bio->bi_private = xchg(&io_end->bio, bio);
|
||||
} else {
|
||||
ext4_finish_bio(bio);
|
||||
bio_put(bio);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
struct inode *inode = io_end->inode;
|
||||
|
||||
|
@ -341,7 +331,24 @@ static void ext4_end_bio(struct bio *bio, int error)
|
|||
(unsigned long long)
|
||||
bi_sector >> (inode->i_blkbits - 9));
|
||||
}
|
||||
ext4_put_io_end_defer(io_end);
|
||||
|
||||
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
|
||||
/*
|
||||
* Link bio into list hanging from io_end. We have to do it
|
||||
* atomically as bio completions can be racing against each
|
||||
* other.
|
||||
*/
|
||||
bio->bi_private = xchg(&io_end->bio, bio);
|
||||
ext4_put_io_end_defer(io_end);
|
||||
} else {
|
||||
/*
|
||||
* Drop io_end reference early. Inode can get freed once
|
||||
* we finish the bio.
|
||||
*/
|
||||
ext4_put_io_end_defer(io_end);
|
||||
ext4_finish_bio(bio);
|
||||
bio_put(bio);
|
||||
}
|
||||
}
|
||||
|
||||
void ext4_io_submit(struct ext4_io_submit *io)
|
||||
|
|
|
@ -1702,12 +1702,6 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
|
|||
|
||||
if (sbi->s_qf_names[GRPQUOTA])
|
||||
seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
|
||||
|
||||
if (test_opt(sb, USRQUOTA))
|
||||
seq_puts(seq, ",usrquota");
|
||||
|
||||
if (test_opt(sb, GRPQUOTA))
|
||||
seq_puts(seq, ",grpquota");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3624,10 +3618,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb));
|
||||
sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb));
|
||||
|
||||
/* Do we have standard group size of blocksize * 8 blocks ? */
|
||||
if (sbi->s_blocks_per_group == blocksize << 3)
|
||||
set_opt2(sb, STD_GROUP_SIZE);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
|
||||
sbi->s_def_hash_version = es->s_def_hash_version;
|
||||
|
@ -3697,6 +3687,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
|
|||
goto failed_mount;
|
||||
}
|
||||
|
||||
/* Do we have standard group size of clustersize * 8 blocks ? */
|
||||
if (sbi->s_blocks_per_group == clustersize << 3)
|
||||
set_opt2(sb, STD_GROUP_SIZE);
|
||||
|
||||
/*
|
||||
* Test whether we have more sectors than will fit in sector_t,
|
||||
* and whether the max offset is addressable by the page cache.
|
||||
|
|
Загрузка…
Ссылка в новой задаче