diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-14 21:47:51 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-14 21:47:51 -0700 | 
| commit | 47188d39b5deeebf41f87a02af1b3935866364cf (patch) | |
| tree | 4e7a5b4e7edfe1fd425695af0270315f2682f5a4 /fs | |
| parent | ad81f0545ef01ea651886dddac4bef6cec930092 (diff) | |
| parent | e7676a704ee0a1ef71a6b23760b5a8f6896cb1a1 (diff) | |
| download | linux-47188d39b5deeebf41f87a02af1b3935866364cf.tar.bz2 | |
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()
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ext4/balloc.c | 4 | ||||
| -rw-r--r-- | fs/ext4/extents_status.c | 22 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 12 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 11 | ||||
| -rw-r--r-- | fs/ext4/page-io.c | 35 | ||||
| -rw-r--r-- | fs/ext4/super.c | 14 | 
6 files changed, 51 insertions, 47 deletions
| diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 58339393fa6e..ddd715e42a5c 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -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); diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index ee018d5f397e..4b8df7fbb10a 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -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.   */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0188e65e1f58..98b9bff92a8a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -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; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a9ff5e5137ca..4bbbf13bd743 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -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; diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 48786cdb5e6c..6625d210fb45 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -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) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 85b3dd60169b..bca26f34edf4 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -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. |