diff options
| -rw-r--r-- | fs/ext4/extents.c | 6 | ||||
| -rw-r--r-- | fs/ext4/inode.c | 22 | ||||
| -rw-r--r-- | fs/ext4/mballoc.c | 16 | ||||
| -rw-r--r-- | fs/ext4/migrate.c | 17 | ||||
| -rw-r--r-- | include/linux/buffer_head.h | 7 |
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); |
| 668 | errout: | 679 | errout: |
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 | |||
| 321 | static inline struct buffer_head * | ||
| 322 | sb_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 | |||
| 320 | static inline struct buffer_head * | 327 | static inline struct buffer_head * |
| 321 | sb_find_get_block(struct super_block *sb, sector_t block) | 328 | sb_find_get_block(struct super_block *sb, sector_t block) |
| 322 | { | 329 | { |
