aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/extents.c16
-rw-r--r--fs/ext4/inode.c62
3 files changed, 35 insertions, 46 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 25e261da871f..2ebfcde5a156 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2596,8 +2596,7 @@ struct ext4_extent;
2596 2596
2597extern int ext4_ext_tree_init(handle_t *handle, struct inode *); 2597extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
2598extern int ext4_ext_writepage_trans_blocks(struct inode *, int); 2598extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
2599extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, 2599extern int ext4_ext_index_trans_blocks(struct inode *inode, int extents);
2600 int chunk);
2601extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, 2600extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
2602 struct ext4_map_blocks *map, int flags); 2601 struct ext4_map_blocks *map, int flags);
2603extern void ext4_ext_truncate(handle_t *, struct inode *); 2602extern void ext4_ext_truncate(handle_t *, struct inode *);
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 299ee9df546f..94283d06cace 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2328,17 +2328,15 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
2328} 2328}
2329 2329
2330/* 2330/*
2331 * How many index/leaf blocks need to change/allocate to modify nrblocks? 2331 * How many index/leaf blocks need to change/allocate to add @extents extents?
2332 * 2332 *
2333 * if nrblocks are fit in a single extent (chunk flag is 1), then 2333 * If we add a single extent, then in the worse case, each tree level
2334 * in the worse case, each tree level index/leaf need to be changed 2334 * index/leaf need to be changed in case of the tree split.
2335 * if the tree split due to insert a new extent, then the old tree
2336 * index/leaf need to be updated too
2337 * 2335 *
2338 * If the nrblocks are discontiguous, they could cause 2336 * If more extents are inserted, they could cause the whole tree split more
2339 * the whole tree split more than once, but this is really rare. 2337 * than once, but this is really rare.
2340 */ 2338 */
2341int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) 2339int ext4_ext_index_trans_blocks(struct inode *inode, int extents)
2342{ 2340{
2343 int index; 2341 int index;
2344 int depth; 2342 int depth;
@@ -2349,7 +2347,7 @@ int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
2349 2347
2350 depth = ext_depth(inode); 2348 depth = ext_depth(inode);
2351 2349
2352 if (chunk) 2350 if (extents <= 1)
2353 index = depth * 2; 2351 index = depth * 2;
2354 else 2352 else
2355 index = depth * 3; 2353 index = depth * 3;
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);
137static int __ext4_journalled_writepage(struct page *page, unsigned int len); 137static int __ext4_journalled_writepage(struct page *page, unsigned int len);
138static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh); 138static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh);
139static 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 */
2213static int ext4_da_writepages_trans_blocks(struct inode *inode) 2221static 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
4653static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) 4652static 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 */
4671static int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) 4671static 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))