Skip to content

Commit fa55a0e

Browse files
jankaratytso
authored andcommitted
ext4: improve writepage credit estimate for files with indirect blocks
ext4_ind_trans_blocks() wrongly used 'chunk' argument to decide whether blocks mapped are logically contiguous. That is wrong since the argument informs whether the blocks are physically contiguous. As the blocks mapped are always logically contiguous and that's all ext4_ind_trans_blocks() cares about, just remove the 'chunk' argument. Reviewed-by: Zheng Liu <[email protected]> Signed-off-by: Jan Kara <[email protected]> Signed-off-by: "Theodore Ts'o" <[email protected]>
1 parent f2d50a6 commit fa55a0e

File tree

3 files changed

+11
-20
lines changed

3 files changed

+11
-20
lines changed

fs/ext4/ext4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2109,7 +2109,7 @@ extern ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
21092109
const struct iovec *iov, loff_t offset,
21102110
unsigned long nr_segs);
21112111
extern int ext4_ind_calc_metadata_amount(struct inode *inode, sector_t lblock);
2112-
extern int ext4_ind_trans_blocks(struct inode *inode, int nrblocks, int chunk);
2112+
extern int ext4_ind_trans_blocks(struct inode *inode, int nrblocks);
21132113
extern void ext4_ind_truncate(handle_t *, struct inode *inode);
21142114
extern int ext4_free_hole_blocks(handle_t *handle, struct inode *inode,
21152115
ext4_lblk_t first, ext4_lblk_t stop);

fs/ext4/indirect.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -779,27 +779,18 @@ int ext4_ind_calc_metadata_amount(struct inode *inode, sector_t lblock)
779779
return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1;
780780
}
781781

782-
int ext4_ind_trans_blocks(struct inode *inode, int nrblocks, int chunk)
782+
/*
783+
* Calculate number of indirect blocks touched by mapping @nrblocks logically
784+
* contiguous blocks
785+
*/
786+
int ext4_ind_trans_blocks(struct inode *inode, int nrblocks)
783787
{
784-
int indirects;
785-
786-
/* if nrblocks are contiguous */
787-
if (chunk) {
788-
/*
789-
* With N contiguous data blocks, we need at most
790-
* N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks,
791-
* 2 dindirect blocks, and 1 tindirect block
792-
*/
793-
return DIV_ROUND_UP(nrblocks,
794-
EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4;
795-
}
796788
/*
797-
* if nrblocks are not contiguous, worse case, each block touch
798-
* a indirect block, and each indirect block touch a double indirect
799-
* block, plus a triple indirect block
789+
* With N contiguous data blocks, we need at most
790+
* N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks,
791+
* 2 dindirect blocks, and 1 tindirect block
800792
*/
801-
indirects = nrblocks * 2 + 1;
802-
return indirects;
793+
return DIV_ROUND_UP(nrblocks, EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4;
803794
}
804795

805796
/*

fs/ext4/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4653,7 +4653,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
46534653
static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
46544654
{
46554655
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
4656-
return ext4_ind_trans_blocks(inode, nrblocks, chunk);
4656+
return ext4_ind_trans_blocks(inode, nrblocks);
46574657
return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
46584658
}
46594659

0 commit comments

Comments
 (0)