[f2fs-dev] [PATCH] f2fs: skip preallocation for mapped buffered overwrites
Wenjie Qi <[email protected]>
| Newsgroups | net.sourceforge.lists.linux-f2fs-devel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
For a full-block buffered overwrite, PRE_AIO does not reserve a block if the target range is already mapped. It still walks the dnode path under the node_change read lock. Skip PRE_AIO when the write is within i_size and the read extent cache covers the whole range with valid data blocks. Assisted-by: Codex:gpt-5.5 Signed-off-by: Wenjie Qi <[email protected]> --- QEMU test on a 1GiB F2FS scratch image: - mapped 4K overwrite: PRE_AIO traces 20000 -> 0, about 10.2 -> 2.0 us/write. - sparse in-i_size hole write miss case: PRE_AIO traces stayed 8192 -> 8192, median 7.71 -> 7.95 us/write. fs/f2fs/file.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4b52c56d71f0..cb03df086ff3 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -5007,6 +5007,32 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from) return count; } +static bool f2fs_prealloc_mapped_overwrite(struct inode *inode, + loff_t pos, size_t count, + const struct f2fs_map_blocks *map) +{ + struct extent_info ei = {}; + loff_t size = i_size_read(inode); + pgoff_t start = map->m_lblk; + pgoff_t end = start + map->m_len; + pgoff_t ei_end; + + if (pos >= size || count > size - pos) + return false; + if (f2fs_has_inline_data(inode) || f2fs_compressed_file(inode) || + f2fs_is_atomic_file(inode) || IS_DEVICE_ALIASING(inode)) + return false; + if (end < start) + return false; + if (!f2fs_lookup_read_extent_cache(inode, start, &ei)) + return false; + if (!__is_valid_data_blkaddr(ei.blk)) + return false; + + ei_end = (pgoff_t)ei.fofs + ei.len; + return start >= ei.fofs && end <= ei_end; +} + /* * Preallocate blocks for a write request, if it is possible and helpful to do * so. Returns a positive number if blocks may have been preallocated, 0 if no @@ -5061,6 +5087,9 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter, else return 0; + if (!dio && f2fs_prealloc_mapped_overwrite(inode, pos, count, &map)) + return 0; + if (!IS_DEVICE_ALIASING(inode)) map.m_may_create = true; if (dio) { _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel