aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2015-03-22 22:33:37 -0400
committerJaegeuk Kim <jaegeuk@kernel.org>2015-04-10 18:08:52 -0400
commitdf6136ef5533421e68ea7ff9c33d5b2ac9005ff9 (patch)
treef9540d994fdc893ba9a1d0c5fdfdcee982fd7ae7 /fs/f2fs
parent75342797988a0f9ebec400a2dde8d4de581c4079 (diff)
f2fs: preallocate fallocated blocks for direct IO
Normally, due to DIO_SKIP_HOLES flag is set by default, blockdev_direct_IO in f2fs_direct_IO tries to skip DIO in holes when writing inside i_size, this makes us falling back to buffered IO which shows lower performance. So in commit 59b802e5a453 ("f2fs: allocate data blocks in advance for f2fs_direct_IO"), we improve perfromance by allocating data blocks in advance if we meet holes no matter in i_size or not, since with it we can avoid falling back to buffered IO. But we forget to consider for unwritten fallocated block in this commit. This patch tries to fix it for fallocate case, this helps to improve performance. Test result: Storage info: sandisk ultra 64G micro sd card. touch /mnt/f2fs/file truncate -s 67108864 /mnt/f2fs/file fallocate -o 0 -l 67108864 /mnt/f2fs/file time dd if=/dev/zero of=/mnt/f2fs/file bs=1M count=64 conv=notrunc oflag=direct Time before applying the patch: 67108864 bytes (67 MB) copied, 36.16 s, 1.9 MB/s real 0m36.162s user 0m0.000s sys 0m0.180s Time after applying the patch: 67108864 bytes (67 MB) copied, 27.7776 s, 2.4 MB/s real 0m27.780s user 0m0.000s sys 0m0.036s Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs')
-rw-r--r--fs/f2fs/data.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 8a940e518be8..614e444e5297 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1126,16 +1126,23 @@ static int __allocate_data_block(struct dnode_of_data *dn)
1126 1126
1127 if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC))) 1127 if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
1128 return -EPERM; 1128 return -EPERM;
1129
1130 dn->data_blkaddr = datablock_addr(dn->node_page, dn->ofs_in_node);
1131 if (dn->data_blkaddr == NEW_ADDR)
1132 goto alloc;
1133
1129 if (unlikely(!inc_valid_block_count(sbi, dn->inode, 1))) 1134 if (unlikely(!inc_valid_block_count(sbi, dn->inode, 1)))
1130 return -ENOSPC; 1135 return -ENOSPC;
1131 1136
1137alloc:
1132 get_node_info(sbi, dn->nid, &ni); 1138 get_node_info(sbi, dn->nid, &ni);
1133 set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); 1139 set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
1134 1140
1135 if (dn->ofs_in_node == 0 && dn->inode_page == dn->node_page) 1141 if (dn->ofs_in_node == 0 && dn->inode_page == dn->node_page)
1136 seg = CURSEG_DIRECT_IO; 1142 seg = CURSEG_DIRECT_IO;
1137 1143
1138 allocate_data_block(sbi, NULL, NULL_ADDR, &dn->data_blkaddr, &sum, seg); 1144 allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
1145 &sum, seg);
1139 1146
1140 /* direct IO doesn't use extent cache to maximize the performance */ 1147 /* direct IO doesn't use extent cache to maximize the performance */
1141 set_data_blkaddr(dn); 1148 set_data_blkaddr(dn);
@@ -1175,7 +1182,7 @@ static void __allocate_data_blocks(struct inode *inode, loff_t offset,
1175 block_t blkaddr; 1182 block_t blkaddr;
1176 1183
1177 blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node); 1184 blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node);
1178 if (blkaddr == NULL_ADDR) { 1185 if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) {
1179 if (__allocate_data_block(&dn)) 1186 if (__allocate_data_block(&dn))
1180 goto sync_out; 1187 goto sync_out;
1181 allocated = true; 1188 allocated = true;