aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2010-05-16 20:00:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-05-16 20:00:00 -0400
commit2ed886852adfcb070bf350e66a0da0d98b2f3ab5 (patch)
treebcec0a1004f413b70087e2c43097892f87f21cc3 /fs/ext4/extents.c
parente35fd6609b2fee54484d520deccb8f18bf7d38f3 (diff)
ext4: Convert callers of ext4_get_blocks() to use ext4_map_blocks()
This saves a huge amount of stack space by avoiding unnecesary struct buffer_head's from being allocated on the stack. In addition, to make the code easier to understand, collapse and refactor ext4_get_block(), ext4_get_block_write(), noalloc_get_block_write(), into a single function. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c40
1 files changed, 17 insertions, 23 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 37f938789344..d6801eb7232b 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3667,13 +3667,12 @@ static void ext4_falloc_update_inode(struct inode *inode,
3667long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) 3667long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
3668{ 3668{
3669 handle_t *handle; 3669 handle_t *handle;
3670 ext4_lblk_t block;
3671 loff_t new_size; 3670 loff_t new_size;
3672 unsigned int max_blocks; 3671 unsigned int max_blocks;
3673 int ret = 0; 3672 int ret = 0;
3674 int ret2 = 0; 3673 int ret2 = 0;
3675 int retries = 0; 3674 int retries = 0;
3676 struct buffer_head map_bh; 3675 struct ext4_map_blocks map;
3677 unsigned int credits, blkbits = inode->i_blkbits; 3676 unsigned int credits, blkbits = inode->i_blkbits;
3678 3677
3679 /* 3678 /*
@@ -3687,13 +3686,13 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
3687 if (S_ISDIR(inode->i_mode)) 3686 if (S_ISDIR(inode->i_mode))
3688 return -ENODEV; 3687 return -ENODEV;
3689 3688
3690 block = offset >> blkbits; 3689 map.m_lblk = offset >> blkbits;
3691 /* 3690 /*
3692 * We can't just convert len to max_blocks because 3691 * We can't just convert len to max_blocks because
3693 * If blocksize = 4096 offset = 3072 and len = 2048 3692 * If blocksize = 4096 offset = 3072 and len = 2048
3694 */ 3693 */
3695 max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) 3694 max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
3696 - block; 3695 - map.m_lblk;
3697 /* 3696 /*
3698 * credits to insert 1 extent into extent tree 3697 * credits to insert 1 extent into extent tree
3699 */ 3698 */
@@ -3706,16 +3705,14 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
3706 } 3705 }
3707retry: 3706retry:
3708 while (ret >= 0 && ret < max_blocks) { 3707 while (ret >= 0 && ret < max_blocks) {
3709 block = block + ret; 3708 map.m_lblk = map.m_lblk + ret;
3710 max_blocks = max_blocks - ret; 3709 map.m_len = max_blocks = max_blocks - ret;
3711 handle = ext4_journal_start(inode, credits); 3710 handle = ext4_journal_start(inode, credits);
3712 if (IS_ERR(handle)) { 3711 if (IS_ERR(handle)) {
3713 ret = PTR_ERR(handle); 3712 ret = PTR_ERR(handle);
3714 break; 3713 break;
3715 } 3714 }
3716 map_bh.b_state = 0; 3715 ret = ext4_map_blocks(handle, inode, &map,
3717 ret = ext4_get_blocks(handle, inode, block,
3718 max_blocks, &map_bh,
3719 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT); 3716 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT);
3720 if (ret <= 0) { 3717 if (ret <= 0) {
3721#ifdef EXT4FS_DEBUG 3718#ifdef EXT4FS_DEBUG
@@ -3729,14 +3726,14 @@ retry:
3729 ret2 = ext4_journal_stop(handle); 3726 ret2 = ext4_journal_stop(handle);
3730 break; 3727 break;
3731 } 3728 }
3732 if ((block + ret) >= (EXT4_BLOCK_ALIGN(offset + len, 3729 if ((map.m_lblk + ret) >= (EXT4_BLOCK_ALIGN(offset + len,
3733 blkbits) >> blkbits)) 3730 blkbits) >> blkbits))
3734 new_size = offset + len; 3731 new_size = offset + len;
3735 else 3732 else
3736 new_size = (block + ret) << blkbits; 3733 new_size = (map.m_lblk + ret) << blkbits;
3737 3734
3738 ext4_falloc_update_inode(inode, mode, new_size, 3735 ext4_falloc_update_inode(inode, mode, new_size,
3739 buffer_new(&map_bh)); 3736 (map.m_flags & EXT4_MAP_NEW));
3740 ext4_mark_inode_dirty(handle, inode); 3737 ext4_mark_inode_dirty(handle, inode);
3741 ret2 = ext4_journal_stop(handle); 3738 ret2 = ext4_journal_stop(handle);
3742 if (ret2) 3739 if (ret2)
@@ -3765,42 +3762,39 @@ int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
3765 ssize_t len) 3762 ssize_t len)
3766{ 3763{
3767 handle_t *handle; 3764 handle_t *handle;
3768 ext4_lblk_t block;
3769 unsigned int max_blocks; 3765 unsigned int max_blocks;
3770 int ret = 0; 3766 int ret = 0;
3771 int ret2 = 0; 3767 int ret2 = 0;
3772 struct buffer_head map_bh; 3768 struct ext4_map_blocks map;
3773 unsigned int credits, blkbits = inode->i_blkbits; 3769 unsigned int credits, blkbits = inode->i_blkbits;
3774 3770
3775 block = offset >> blkbits; 3771 map.m_lblk = offset >> blkbits;
3776 /* 3772 /*
3777 * We can't just convert len to max_blocks because 3773 * We can't just convert len to max_blocks because
3778 * If blocksize = 4096 offset = 3072 and len = 2048 3774 * If blocksize = 4096 offset = 3072 and len = 2048
3779 */ 3775 */
3780 max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) 3776 max_blocks = ((EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits) -
3781 - block; 3777 map.m_lblk);
3782 /* 3778 /*
3783 * credits to insert 1 extent into extent tree 3779 * credits to insert 1 extent into extent tree
3784 */ 3780 */
3785 credits = ext4_chunk_trans_blocks(inode, max_blocks); 3781 credits = ext4_chunk_trans_blocks(inode, max_blocks);
3786 while (ret >= 0 && ret < max_blocks) { 3782 while (ret >= 0 && ret < max_blocks) {
3787 block = block + ret; 3783 map.m_lblk += ret;
3788 max_blocks = max_blocks - ret; 3784 map.m_len = (max_blocks -= ret);
3789 handle = ext4_journal_start(inode, credits); 3785 handle = ext4_journal_start(inode, credits);
3790 if (IS_ERR(handle)) { 3786 if (IS_ERR(handle)) {
3791 ret = PTR_ERR(handle); 3787 ret = PTR_ERR(handle);
3792 break; 3788 break;
3793 } 3789 }
3794 map_bh.b_state = 0; 3790 ret = ext4_map_blocks(handle, inode, &map,
3795 ret = ext4_get_blocks(handle, inode, block,
3796 max_blocks, &map_bh,
3797 EXT4_GET_BLOCKS_IO_CONVERT_EXT); 3791 EXT4_GET_BLOCKS_IO_CONVERT_EXT);
3798 if (ret <= 0) { 3792 if (ret <= 0) {
3799 WARN_ON(ret <= 0); 3793 WARN_ON(ret <= 0);
3800 printk(KERN_ERR "%s: ext4_ext_map_blocks " 3794 printk(KERN_ERR "%s: ext4_ext_map_blocks "
3801 "returned error inode#%lu, block=%u, " 3795 "returned error inode#%lu, block=%u, "
3802 "max_blocks=%u", __func__, 3796 "max_blocks=%u", __func__,
3803 inode->i_ino, block, max_blocks); 3797 inode->i_ino, map.m_lblk, map.m_len);
3804 } 3798 }
3805 ext4_mark_inode_dirty(handle, inode); 3799 ext4_mark_inode_dirty(handle, inode);
3806 ret2 = ext4_journal_stop(handle); 3800 ret2 = ext4_journal_stop(handle);