diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 62 |
1 files changed, 27 insertions, 35 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 23d9a44d721a..2b777e51b677 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -136,6 +136,8 @@ static void ext4_invalidatepage(struct page *page, unsigned int offset, | |||
136 | unsigned int length); | 136 | unsigned int length); |
137 | static int __ext4_journalled_writepage(struct page *page, unsigned int len); | 137 | static int __ext4_journalled_writepage(struct page *page, unsigned int len); |
138 | static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh); | 138 | static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh); |
139 | static int ext4_meta_trans_blocks(struct inode *inode, int lblocks, | ||
140 | int pextents); | ||
139 | 141 | ||
140 | /* | 142 | /* |
141 | * Test whether an inode is a fast symlink. | 143 | * Test whether an inode is a fast symlink. |
@@ -2203,28 +2205,25 @@ static int ext4_writepage(struct page *page, | |||
2203 | } | 2205 | } |
2204 | 2206 | ||
2205 | /* | 2207 | /* |
2206 | * This is called via ext4_da_writepages() to | 2208 | * mballoc gives us at most this number of blocks... |
2207 | * calculate the total number of credits to reserve to fit | 2209 | * XXX: That seems to be only a limitation of ext4_mb_normalize_request(). |
2208 | * a single extent allocation into a single transaction, | 2210 | * The rest of mballoc seems to handle chunks upto full group size. |
2209 | * ext4_da_writpeages() will loop calling this before | ||
2210 | * the block allocation. | ||
2211 | */ | 2211 | */ |
2212 | #define MAX_WRITEPAGES_EXTENT_LEN 2048 | ||
2212 | 2213 | ||
2214 | /* | ||
2215 | * Calculate the total number of credits to reserve for one writepages | ||
2216 | * iteration. This is called from ext4_da_writepages(). We map an extent of | ||
2217 | * upto MAX_WRITEPAGES_EXTENT_LEN blocks and then we go on and finish mapping | ||
2218 | * the last partial page. So in total we can map MAX_WRITEPAGES_EXTENT_LEN + | ||
2219 | * bpp - 1 blocks in bpp different extents. | ||
2220 | */ | ||
2213 | static int ext4_da_writepages_trans_blocks(struct inode *inode) | 2221 | static int ext4_da_writepages_trans_blocks(struct inode *inode) |
2214 | { | 2222 | { |
2215 | int max_blocks = EXT4_I(inode)->i_reserved_data_blocks; | 2223 | int bpp = ext4_journal_blocks_per_page(inode); |
2216 | |||
2217 | /* | ||
2218 | * With non-extent format the journal credit needed to | ||
2219 | * insert nrblocks contiguous block is dependent on | ||
2220 | * number of contiguous block. So we will limit | ||
2221 | * number of contiguous block to a sane value | ||
2222 | */ | ||
2223 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) && | ||
2224 | (max_blocks > EXT4_MAX_TRANS_DATA)) | ||
2225 | max_blocks = EXT4_MAX_TRANS_DATA; | ||
2226 | 2224 | ||
2227 | return ext4_chunk_trans_blocks(inode, max_blocks); | 2225 | return ext4_meta_trans_blocks(inode, |
2226 | MAX_WRITEPAGES_EXTENT_LEN + bpp - 1, bpp); | ||
2228 | } | 2227 | } |
2229 | 2228 | ||
2230 | /* | 2229 | /* |
@@ -4650,11 +4649,12 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
4650 | return 0; | 4649 | return 0; |
4651 | } | 4650 | } |
4652 | 4651 | ||
4653 | static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) | 4652 | static int ext4_index_trans_blocks(struct inode *inode, int lblocks, |
4653 | int pextents) | ||
4654 | { | 4654 | { |
4655 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) | 4655 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
4656 | return ext4_ind_trans_blocks(inode, nrblocks); | 4656 | return ext4_ind_trans_blocks(inode, lblocks); |
4657 | return ext4_ext_index_trans_blocks(inode, nrblocks, chunk); | 4657 | return ext4_ext_index_trans_blocks(inode, pextents); |
4658 | } | 4658 | } |
4659 | 4659 | ||
4660 | /* | 4660 | /* |
@@ -4668,7 +4668,8 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4668 | * | 4668 | * |
4669 | * Also account for superblock, inode, quota and xattr blocks | 4669 | * Also account for superblock, inode, quota and xattr blocks |
4670 | */ | 4670 | */ |
4671 | static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | 4671 | static int ext4_meta_trans_blocks(struct inode *inode, int lblocks, |
4672 | int pextents) | ||
4672 | { | 4673 | { |
4673 | ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb); | 4674 | ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb); |
4674 | int gdpblocks; | 4675 | int gdpblocks; |
@@ -4676,14 +4677,10 @@ static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4676 | int ret = 0; | 4677 | int ret = 0; |
4677 | 4678 | ||
4678 | /* | 4679 | /* |
4679 | * How many index blocks need to touch to modify nrblocks? | 4680 | * How many index blocks need to touch to map @lblocks logical blocks |
4680 | * The "Chunk" flag indicating whether the nrblocks is | 4681 | * to @pextents physical extents? |
4681 | * physically contiguous on disk | ||
4682 | * | ||
4683 | * For Direct IO and fallocate, they calls get_block to allocate | ||
4684 | * one single extent at a time, so they could set the "Chunk" flag | ||
4685 | */ | 4682 | */ |
4686 | idxblocks = ext4_index_trans_blocks(inode, nrblocks, chunk); | 4683 | idxblocks = ext4_index_trans_blocks(inode, lblocks, pextents); |
4687 | 4684 | ||
4688 | ret = idxblocks; | 4685 | ret = idxblocks; |
4689 | 4686 | ||
@@ -4691,12 +4688,7 @@ static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4691 | * Now let's see how many group bitmaps and group descriptors need | 4688 | * Now let's see how many group bitmaps and group descriptors need |
4692 | * to account | 4689 | * to account |
4693 | */ | 4690 | */ |
4694 | groups = idxblocks; | 4691 | groups = idxblocks + pextents; |
4695 | if (chunk) | ||
4696 | groups += 1; | ||
4697 | else | ||
4698 | groups += nrblocks; | ||
4699 | |||
4700 | gdpblocks = groups; | 4692 | gdpblocks = groups; |
4701 | if (groups > ngroups) | 4693 | if (groups > ngroups) |
4702 | groups = ngroups; | 4694 | groups = ngroups; |
@@ -4727,7 +4719,7 @@ int ext4_writepage_trans_blocks(struct inode *inode) | |||
4727 | int bpp = ext4_journal_blocks_per_page(inode); | 4719 | int bpp = ext4_journal_blocks_per_page(inode); |
4728 | int ret; | 4720 | int ret; |
4729 | 4721 | ||
4730 | ret = ext4_meta_trans_blocks(inode, bpp, 0); | 4722 | ret = ext4_meta_trans_blocks(inode, bpp, bpp); |
4731 | 4723 | ||
4732 | /* Account for data blocks for journalled mode */ | 4724 | /* Account for data blocks for journalled mode */ |
4733 | if (ext4_should_journal_data(inode)) | 4725 | if (ext4_should_journal_data(inode)) |