diff options
author | Chao Yu <yuchao0@huawei.com> | 2016-05-09 07:56:30 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-05-11 12:56:35 -0400 |
commit | 46008c6d42328710f9beaf5c2b47dc92b1cc1a75 (patch) | |
tree | de93d87eaf6b9a77d97378fd5dea31d2990129e2 /fs/f2fs/f2fs.h | |
parent | 0fac558b96584799876498248020dc49a98bd131 (diff) |
f2fs: support in batch multi blocks preallocation
This patch introduces reserve_new_blocks to make preallocation of multi
blocks as in batch operation, so it can avoid lots of redundant
operation, result in better performance.
In virtual machine, with rotational device:
time fallocate -l 32G /mnt/f2fs/file
Before:
real 0m4.584s
user 0m0.000s
sys 0m4.580s
After:
real 0m0.292s
user 0m0.000s
sys 0m0.272s
In x86, with SSD:
time fallocate -l 500G $MNT/testfile
Before : 24.758 s
After : 1.604 s
Signed-off-by: Chao Yu <yuchao0@huawei.com>
[Jaegeuk Kim: fix bugs and add performance numbers measured in x86.]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/f2fs.h')
-rw-r--r-- | fs/f2fs/f2fs.h | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 052f5a8c96f1..1401c96724c6 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -1094,7 +1094,7 @@ static inline bool f2fs_has_xattr_block(unsigned int ofs) | |||
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, | 1096 | static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, |
1097 | struct inode *inode, blkcnt_t count) | 1097 | struct inode *inode, blkcnt_t *count) |
1098 | { | 1098 | { |
1099 | block_t valid_block_count; | 1099 | block_t valid_block_count; |
1100 | 1100 | ||
@@ -1106,14 +1106,19 @@ static inline bool inc_valid_block_count(struct f2fs_sb_info *sbi, | |||
1106 | } | 1106 | } |
1107 | #endif | 1107 | #endif |
1108 | valid_block_count = | 1108 | valid_block_count = |
1109 | sbi->total_valid_block_count + (block_t)count; | 1109 | sbi->total_valid_block_count + (block_t)(*count); |
1110 | if (unlikely(valid_block_count > sbi->user_block_count)) { | 1110 | if (unlikely(valid_block_count > sbi->user_block_count)) { |
1111 | spin_unlock(&sbi->stat_lock); | 1111 | *count = sbi->user_block_count - sbi->total_valid_block_count; |
1112 | return false; | 1112 | if (!*count) { |
1113 | spin_unlock(&sbi->stat_lock); | ||
1114 | return false; | ||
1115 | } | ||
1113 | } | 1116 | } |
1114 | inode->i_blocks += count; | 1117 | /* *count can be recalculated */ |
1115 | sbi->total_valid_block_count = valid_block_count; | 1118 | inode->i_blocks += *count; |
1116 | sbi->alloc_valid_block_count += (block_t)count; | 1119 | sbi->total_valid_block_count = |
1120 | sbi->total_valid_block_count + (block_t)(*count); | ||
1121 | sbi->alloc_valid_block_count += (block_t)(*count); | ||
1117 | spin_unlock(&sbi->stat_lock); | 1122 | spin_unlock(&sbi->stat_lock); |
1118 | return true; | 1123 | return true; |
1119 | } | 1124 | } |
@@ -1945,6 +1950,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *); | |||
1945 | void f2fs_submit_page_mbio(struct f2fs_io_info *); | 1950 | void f2fs_submit_page_mbio(struct f2fs_io_info *); |
1946 | void set_data_blkaddr(struct dnode_of_data *); | 1951 | void set_data_blkaddr(struct dnode_of_data *); |
1947 | void f2fs_update_data_blkaddr(struct dnode_of_data *, block_t); | 1952 | void f2fs_update_data_blkaddr(struct dnode_of_data *, block_t); |
1953 | int reserve_new_blocks(struct dnode_of_data *, blkcnt_t); | ||
1948 | int reserve_new_block(struct dnode_of_data *); | 1954 | int reserve_new_block(struct dnode_of_data *); |
1949 | int f2fs_get_block(struct dnode_of_data *, pgoff_t); | 1955 | int f2fs_get_block(struct dnode_of_data *, pgoff_t); |
1950 | ssize_t f2fs_preallocate_blocks(struct kiocb *, struct iov_iter *); | 1956 | ssize_t f2fs_preallocate_blocks(struct kiocb *, struct iov_iter *); |