This patch supports to map continuous holes or preallocated addresses
to improve performace of lookuping mapping info during read DIO.

[testcase 1]
xfs_io -f /mnt/f2fs/hole -c "truncate 1m" -c "fsync"
xfs_io -d /mnt/f2fs/hole -c "pread -b 1m 0 1m"

[before]
f2fs_direct_IO_enter: dev = (253,16), ino = 6 pos = 0 len = 1048576 ki_flags = 
20000 ki_ioprio = 0 rw = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 0, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 1, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 2, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 3, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 4, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 5, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 6, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 7, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 8, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 9, start blkaddr = 0x0, 
len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 3, 
err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 10, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 11, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 12, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 13, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 14, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 15, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 16, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
......
f2fs_direct_IO_exit: dev = (253,16), ino = 6 pos = 0 len = 1048576 rw = 0 ret = 
1048576

[after]
f2fs_direct_IO_enter: dev = (253,16), ino = 6 pos = 0 len = 1048576 ki_flags = 
20000 ki_ioprio = 0 rw = 0
f2fs_map_blocks: dev = (253,16), ino = 6, file offset = 0, start blkaddr = 0x0, 
len = 0x100, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag = 
3, err = 0
f2fs_direct_IO_exit: dev = (253,16), ino = 6 pos = 0 len = 1048576 rw = 0 ret = 
1048576

[testcase 2]
xfs_io -f /mnt/f2fs/preallocated -c "falloc 0 1m" -c "fsync"
xfs_io -d /mnt/f2fs/preallocated -c "pread -b 1m 0 1m"

[before]
f2fs_direct_IO_enter: dev = (253,16), ino = 11 pos = 0 len = 1048576 ki_flags = 
20000 ki_ioprio = 0 rw = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 0, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 1, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 2, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 3, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 4, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 5, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 6, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 7, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 8, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 9, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 10, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 11, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 12, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 13, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 14, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 15, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 16, start blkaddr = 
0x0, len = 0x0, flags = 0, seg_type = 1, may_create = 0, multidevice = 0, flag 
= 3, err = 0
......
f2fs_direct_IO_exit: dev = (253,16), ino = 11 pos = 0 len = 1048576 rw = 0 ret 
= 1048576

[after]
f2fs_direct_IO_enter: dev = (253,16), ino = 11 pos = 0 len = 1048576 ki_flags = 
20000 ki_ioprio = 0 rw = 0
f2fs_map_blocks: dev = (253,16), ino = 11, file offset = 0, start blkaddr = 
0xffffffff, len = 0x100, flags = 4, seg_type = 1, may_create = 0, multidevice = 
0, flag = 3, err = 0
f2fs_direct_IO_exit: dev = (253,16), ino = 11 pos = 0 len = 1048576 rw = 0 ret 
= 1048576

Signed-off-by: Chao Yu <c...@kernel.org>
---
 fs/f2fs/data.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 9c000ca4f808..47e9b1bddb9b 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1521,6 +1521,9 @@ static bool map_is_mergeable(struct f2fs_sb_info *sbi,
                return true;
        if (flag == F2FS_GET_BLOCK_PRE_DIO)
                return true;
+       if (flag == F2FS_GET_BLOCK_DIO &&
+               map->m_pblk == NULL_ADDR && blkaddr == NULL_ADDR)
+               return true;
        return false;
 }
 
@@ -1645,6 +1648,10 @@ int f2fs_map_blocks(struct inode *inode, struct 
f2fs_map_blocks *map, int flag)
                                goto sync_out;
                        }
                        break;
+               case F2FS_GET_BLOCK_DIO:
+                       if (map->m_next_pgofs)
+                               *map->m_next_pgofs = pgofs + 1;
+                       break;
                default:
                        /* for defragment case */
                        if (map->m_next_pgofs)
@@ -1663,7 +1670,8 @@ int f2fs_map_blocks(struct inode *inode, struct 
f2fs_map_blocks *map, int flag)
                /* reserved delalloc block should be mapped for fiemap. */
                if (blkaddr == NEW_ADDR)
                        map->m_flags |= F2FS_MAP_DELALLOC;
-               map->m_flags |= F2FS_MAP_MAPPED;
+               if (flag != F2FS_GET_BLOCK_DIO || !is_hole)
+                       map->m_flags |= F2FS_MAP_MAPPED;
 
                map->m_pblk = blkaddr;
                map->m_len = 1;
@@ -4192,12 +4200,13 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t 
offset, loff_t length,
         * We should never see delalloc or compressed extents here based on
         * prior flushing and checks.
         */
-       if (WARN_ON_ONCE(map.m_pblk == NEW_ADDR))
-               return -EINVAL;
        if (WARN_ON_ONCE(map.m_pblk == COMPRESS_ADDR))
                return -EINVAL;
 
        if (map.m_flags & F2FS_MAP_MAPPED) {
+               if (WARN_ON_ONCE(map.m_pblk == NEW_ADDR))
+                       return -EINVAL;
+
                iomap->length = blks_to_bytes(inode, map.m_len);
                iomap->type = IOMAP_MAPPED;
                iomap->flags |= IOMAP_F_MERGED;
@@ -4206,9 +4215,17 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t 
offset, loff_t length,
        } else {
                if (flags & IOMAP_WRITE)
                        return -ENOTBLK;
-               iomap->length = blks_to_bytes(inode, next_pgofs) -
-                               iomap->offset;
-               iomap->type = IOMAP_HOLE;
+
+               if (map.m_pblk == NULL_ADDR) {
+                       iomap->length = blks_to_bytes(inode, next_pgofs) -
+                                                               iomap->offset;
+                       iomap->type = IOMAP_HOLE;
+               } else if (map.m_pblk == NEW_ADDR) {
+                       iomap->length = blks_to_bytes(inode, map.m_len);
+                       iomap->type = IOMAP_UNWRITTEN;
+               } else {
+                       f2fs_bug_on(F2FS_I_SB(inode), 1);
+               }
                iomap->addr = IOMAP_NULL_ADDR;
        }
 
-- 
2.40.1



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to