diff options
author | Theodore Ts'o <tytso@mit.edu> | 2010-05-16 20:00:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-05-16 20:00:00 -0400 |
commit | 2ed886852adfcb070bf350e66a0da0d98b2f3ab5 (patch) | |
tree | bcec0a1004f413b70087e2c43097892f87f21cc3 /fs/ext4/extents.c | |
parent | e35fd6609b2fee54484d520deccb8f18bf7d38f3 (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.c | 40 |
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, | |||
3667 | long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len) | 3667 | long 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 | } |
3707 | retry: | 3706 | retry: |
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); |