Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 47188d39 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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()
parents ad81f054 e7676a70
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
+10 −12
Original line number Diff line number Diff line
@@ -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 @@ static int __es_insert_extent(struct inode *inode, struct extent_status *newes)
}

/*
 * 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.
 */
+6 −6
Original line number Diff line number Diff line
@@ -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 @@ 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 (allocation)\n", inode->i_ino, retval,
			       map->m_len, __func__);
@@ -1642,7 +1642,7 @@ static int ext4_da_map_blocks(struct inode *inode, sector_t iblock,

#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;
+8 −3
Original line number Diff line number Diff line
@@ -4740,11 +4740,16 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
		 * 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;
+21 −14
Original line number Diff line number Diff line
@@ -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));
	}

	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)
Loading