ext4: improve writepage credit estimate for files with indirect blocks
authorJan Kara <jack@suse.cz>
Tue, 4 Jun 2013 16:56:55 +0000 (12:56 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 4 Jun 2013 16:56:55 +0000 (12:56 -0400)
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 <wenqing.lz@taobao.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
fs/ext4/ext4.h
fs/ext4/indirect.c
fs/ext4/inode.c

index 46674058d2514513c76125f186ea3fb64a32fd5f..25e261da871f2184dbc89d487fbe08c034bd3689 100644 (file)
@@ -2109,7 +2109,7 @@ extern ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
                                const struct iovec *iov, loff_t offset,
                                unsigned long nr_segs);
 extern int ext4_ind_calc_metadata_amount(struct inode *inode, sector_t lblock);
-extern int ext4_ind_trans_blocks(struct inode *inode, int nrblocks, int chunk);
+extern int ext4_ind_trans_blocks(struct inode *inode, int nrblocks);
 extern void ext4_ind_truncate(handle_t *, struct inode *inode);
 extern int ext4_free_hole_blocks(handle_t *handle, struct inode *inode,
                                 ext4_lblk_t first, ext4_lblk_t stop);
index b8d5d351e24f64b1a5ee02bd90be59f5b19ce290..f7742f03cdcbea4a367115398ccd1d2df75dfa1e 100644 (file)
@@ -779,27 +779,18 @@ int ext4_ind_calc_metadata_amount(struct inode *inode, sector_t lblock)
        return (blk_bits / EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb)) + 1;
 }
 
-int ext4_ind_trans_blocks(struct inode *inode, int nrblocks, int chunk)
+/*
+ * Calculate number of indirect blocks touched by mapping @nrblocks logically
+ * contiguous blocks
+ */
+int ext4_ind_trans_blocks(struct inode *inode, int nrblocks)
 {
-       int indirects;
-
-       /* if nrblocks are contiguous */
-       if (chunk) {
-               /*
-                * With N contiguous data blocks, we need at most
-                * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks,
-                * 2 dindirect blocks, and 1 tindirect block
-                */
-               return DIV_ROUND_UP(nrblocks,
-                                   EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4;
-       }
        /*
-        * if nrblocks are not contiguous, worse case, each block touch
-        * a indirect block, and each indirect block touch a double indirect
-        * block, plus a triple indirect block
+        * With N contiguous data blocks, we need at most
+        * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks,
+        * 2 dindirect blocks, and 1 tindirect block
         */
-       indirects = nrblocks * 2 + 1;
-       return indirects;
+       return DIV_ROUND_UP(nrblocks, EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4;
 }
 
 /*
index 80c710ae470bf306f9fb35da2cf9d61ef1792573..23d9a44d721a56cf3959e4e6d2d8115f9565098a 100644 (file)
@@ -4653,7 +4653,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
 static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
 {
        if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
-               return ext4_ind_trans_blocks(inode, nrblocks, chunk);
+               return ext4_ind_trans_blocks(inode, nrblocks);
        return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
 }