aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-07-05 19:24:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-07-05 19:24:54 -0400
commit1c4c7159ed2468f3ac4ce5a7f08d79663d381a93 (patch)
treebca0b61fc4a04711e0322dd9eb4a2f3c55ddf4c5
parentd770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff)
parent7444a072c387a93ebee7066e8aee776954ab0e41 (diff)
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: "Bug fixes (all for stable kernels) for ext4: - address corner cases for indirect blocks->extent migration - fix reserved block accounting invalidate_page when page_size != block_size (i.e., ppc or 1k block size file systems) - fix deadlocks when a memcg is under heavy memory pressure - fix fencepost error in lazytime optimization" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: replace open coded nofail allocation in ext4_free_blocks() ext4: correctly migrate a file with a hole at the beginning ext4: be more strict when migrating to non-extent based file ext4: fix reservation release on invalidatepage for delalloc fs ext4: avoid deadlocks in the writeback path by using sb_getblk_gfp bufferhead: Add _gfp version for sb_getblk() ext4: fix fencepost error in lazytime optimization
-rw-r--r--fs/ext4/extents.c6
-rw-r--r--fs/ext4/inode.c22
-rw-r--r--fs/ext4/mballoc.c16
-rw-r--r--fs/ext4/migrate.c17
-rw-r--r--include/linux/buffer_head.h7
5 files changed, 47 insertions, 21 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index aadb72828834..2553aa8b608d 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -504,7 +504,7 @@ __read_extent_tree_block(const char *function, unsigned int line,
504 struct buffer_head *bh; 504 struct buffer_head *bh;
505 int err; 505 int err;
506 506
507 bh = sb_getblk(inode->i_sb, pblk); 507 bh = sb_getblk_gfp(inode->i_sb, pblk, __GFP_MOVABLE | GFP_NOFS);
508 if (unlikely(!bh)) 508 if (unlikely(!bh))
509 return ERR_PTR(-ENOMEM); 509 return ERR_PTR(-ENOMEM);
510 510
@@ -1089,7 +1089,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
1089 err = -EIO; 1089 err = -EIO;
1090 goto cleanup; 1090 goto cleanup;
1091 } 1091 }
1092 bh = sb_getblk(inode->i_sb, newblock); 1092 bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
1093 if (unlikely(!bh)) { 1093 if (unlikely(!bh)) {
1094 err = -ENOMEM; 1094 err = -ENOMEM;
1095 goto cleanup; 1095 goto cleanup;
@@ -1283,7 +1283,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
1283 if (newblock == 0) 1283 if (newblock == 0)
1284 return err; 1284 return err;
1285 1285
1286 bh = sb_getblk(inode->i_sb, newblock); 1286 bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
1287 if (unlikely(!bh)) 1287 if (unlikely(!bh))
1288 return -ENOMEM; 1288 return -ENOMEM;
1289 lock_buffer(bh); 1289 lock_buffer(bh);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 41f8e55afcd1..cecf9aa10811 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1323,7 +1323,7 @@ static void ext4_da_page_release_reservation(struct page *page,
1323 unsigned int offset, 1323 unsigned int offset,
1324 unsigned int length) 1324 unsigned int length)
1325{ 1325{
1326 int to_release = 0; 1326 int to_release = 0, contiguous_blks = 0;
1327 struct buffer_head *head, *bh; 1327 struct buffer_head *head, *bh;
1328 unsigned int curr_off = 0; 1328 unsigned int curr_off = 0;
1329 struct inode *inode = page->mapping->host; 1329 struct inode *inode = page->mapping->host;
@@ -1344,14 +1344,23 @@ static void ext4_da_page_release_reservation(struct page *page,
1344 1344
1345 if ((offset <= curr_off) && (buffer_delay(bh))) { 1345 if ((offset <= curr_off) && (buffer_delay(bh))) {
1346 to_release++; 1346 to_release++;
1347 contiguous_blks++;
1347 clear_buffer_delay(bh); 1348 clear_buffer_delay(bh);
1349 } else if (contiguous_blks) {
1350 lblk = page->index <<
1351 (PAGE_CACHE_SHIFT - inode->i_blkbits);
1352 lblk += (curr_off >> inode->i_blkbits) -
1353 contiguous_blks;
1354 ext4_es_remove_extent(inode, lblk, contiguous_blks);
1355 contiguous_blks = 0;
1348 } 1356 }
1349 curr_off = next_off; 1357 curr_off = next_off;
1350 } while ((bh = bh->b_this_page) != head); 1358 } while ((bh = bh->b_this_page) != head);
1351 1359
1352 if (to_release) { 1360 if (contiguous_blks) {
1353 lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); 1361 lblk = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
1354 ext4_es_remove_extent(inode, lblk, to_release); 1362 lblk += (curr_off >> inode->i_blkbits) - contiguous_blks;
1363 ext4_es_remove_extent(inode, lblk, contiguous_blks);
1355 } 1364 }
1356 1365
1357 /* If we have released all the blocks belonging to a cluster, then we 1366 /* If we have released all the blocks belonging to a cluster, then we
@@ -4344,7 +4353,12 @@ static void ext4_update_other_inodes_time(struct super_block *sb,
4344 int inode_size = EXT4_INODE_SIZE(sb); 4353 int inode_size = EXT4_INODE_SIZE(sb);
4345 4354
4346 oi.orig_ino = orig_ino; 4355 oi.orig_ino = orig_ino;
4347 ino = (orig_ino & ~(inodes_per_block - 1)) + 1; 4356 /*
4357 * Calculate the first inode in the inode table block. Inode
4358 * numbers are one-based. That is, the first inode in a block
4359 * (assuming 4k blocks and 256 byte inodes) is (n*16 + 1).
4360 */
4361 ino = ((orig_ino - 1) & ~(inodes_per_block - 1)) + 1;
4348 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) { 4362 for (i = 0; i < inodes_per_block; i++, ino++, buf += inode_size) {
4349 if (ino == orig_ino) 4363 if (ino == orig_ino)
4350 continue; 4364 continue;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index f6aedf88da43..34b610ea5030 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -4816,18 +4816,12 @@ do_more:
4816 /* 4816 /*
4817 * blocks being freed are metadata. these blocks shouldn't 4817 * blocks being freed are metadata. these blocks shouldn't
4818 * be used until this transaction is committed 4818 * be used until this transaction is committed
4819 *
4820 * We use __GFP_NOFAIL because ext4_free_blocks() is not allowed
4821 * to fail.
4819 */ 4822 */
4820 retry: 4823 new_entry = kmem_cache_alloc(ext4_free_data_cachep,
4821 new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS); 4824 GFP_NOFS|__GFP_NOFAIL);
4822 if (!new_entry) {
4823 /*
4824 * We use a retry loop because
4825 * ext4_free_blocks() is not allowed to fail.
4826 */
4827 cond_resched();
4828 congestion_wait(BLK_RW_ASYNC, HZ/50);
4829 goto retry;
4830 }
4831 new_entry->efd_start_cluster = bit; 4825 new_entry->efd_start_cluster = bit;
4832 new_entry->efd_group = block_group; 4826 new_entry->efd_group = block_group;
4833 new_entry->efd_count = count_clusters; 4827 new_entry->efd_count = count_clusters;
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index b52374e42102..6163ad21cb0e 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -620,6 +620,7 @@ int ext4_ind_migrate(struct inode *inode)
620 struct ext4_inode_info *ei = EXT4_I(inode); 620 struct ext4_inode_info *ei = EXT4_I(inode);
621 struct ext4_extent *ex; 621 struct ext4_extent *ex;
622 unsigned int i, len; 622 unsigned int i, len;
623 ext4_lblk_t start, end;
623 ext4_fsblk_t blk; 624 ext4_fsblk_t blk;
624 handle_t *handle; 625 handle_t *handle;
625 int ret; 626 int ret;
@@ -633,6 +634,14 @@ int ext4_ind_migrate(struct inode *inode)
633 EXT4_FEATURE_RO_COMPAT_BIGALLOC)) 634 EXT4_FEATURE_RO_COMPAT_BIGALLOC))
634 return -EOPNOTSUPP; 635 return -EOPNOTSUPP;
635 636
637 /*
638 * In order to get correct extent info, force all delayed allocation
639 * blocks to be allocated, otherwise delayed allocation blocks may not
640 * be reflected and bypass the checks on extent header.
641 */
642 if (test_opt(inode->i_sb, DELALLOC))
643 ext4_alloc_da_blocks(inode);
644
636 handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); 645 handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1);
637 if (IS_ERR(handle)) 646 if (IS_ERR(handle))
638 return PTR_ERR(handle); 647 return PTR_ERR(handle);
@@ -650,11 +659,13 @@ int ext4_ind_migrate(struct inode *inode)
650 goto errout; 659 goto errout;
651 } 660 }
652 if (eh->eh_entries == 0) 661 if (eh->eh_entries == 0)
653 blk = len = 0; 662 blk = len = start = end = 0;
654 else { 663 else {
655 len = le16_to_cpu(ex->ee_len); 664 len = le16_to_cpu(ex->ee_len);
656 blk = ext4_ext_pblock(ex); 665 blk = ext4_ext_pblock(ex);
657 if (len > EXT4_NDIR_BLOCKS) { 666 start = le32_to_cpu(ex->ee_block);
667 end = start + len - 1;
668 if (end >= EXT4_NDIR_BLOCKS) {
658 ret = -EOPNOTSUPP; 669 ret = -EOPNOTSUPP;
659 goto errout; 670 goto errout;
660 } 671 }
@@ -662,7 +673,7 @@ int ext4_ind_migrate(struct inode *inode)
662 673
663 ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); 674 ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
664 memset(ei->i_data, 0, sizeof(ei->i_data)); 675 memset(ei->i_data, 0, sizeof(ei->i_data));
665 for (i=0; i < len; i++) 676 for (i = start; i <= end; i++)
666 ei->i_data[i] = cpu_to_le32(blk++); 677 ei->i_data[i] = cpu_to_le32(blk++);
667 ext4_mark_inode_dirty(handle, inode); 678 ext4_mark_inode_dirty(handle, inode);
668errout: 679errout:
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 73b45225a7ca..e6797ded700e 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -317,6 +317,13 @@ sb_getblk(struct super_block *sb, sector_t block)
317 return __getblk_gfp(sb->s_bdev, block, sb->s_blocksize, __GFP_MOVABLE); 317 return __getblk_gfp(sb->s_bdev, block, sb->s_blocksize, __GFP_MOVABLE);
318} 318}
319 319
320
321static inline struct buffer_head *
322sb_getblk_gfp(struct super_block *sb, sector_t block, gfp_t gfp)
323{
324 return __getblk_gfp(sb->s_bdev, block, sb->s_blocksize, gfp);
325}
326
320static inline struct buffer_head * 327static inline struct buffer_head *
321sb_find_get_block(struct super_block *sb, sector_t block) 328sb_find_get_block(struct super_block *sb, sector_t block)
322{ 329{