Expand the inline data read & fiemap to support inline tail.

Signed-off-by: Wu Bo <bo...@vivo.com>
---
 fs/f2fs/data.c   | 31 ++++++++++++++++++++++++++++++-
 fs/f2fs/inline.c | 26 ++++++++++++--------------
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index cd13b5703228..476325a26d4e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1922,9 +1922,11 @@ int f2fs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
        u64 logical = 0, phys = 0, size = 0;
        u32 flags = 0;
        int ret = 0;
-       bool compr_cluster = false, compr_appended;
+       bool compr_cluster = false, compr_appended, inline_tail = false;
        unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
        unsigned int count_in_cluster = 0;
+       loff_t i_size = i_size_read(inode);
+       pgoff_t end_index = i_size >> PAGE_SHIFT;
        loff_t maxbytes;
 
        if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
@@ -1983,6 +1985,16 @@ int f2fs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
 
        /* HOLE */
        if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) {
+               /*
+                * There is a reserved space between address array and inline
+                * data. So it must meet this hole state before inline data.
+                */
+               if (f2fs_has_inline_tail(inode) && start_blk == end_index
+                               && f2fs_exist_data(inode)) {
+                       inline_tail = true;
+                       goto fill_extent;
+               }
+
                start_blk = next_pgofs;
 
                if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode,
@@ -2000,6 +2012,7 @@ int f2fs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                goto skip_fill;
        }
 
+fill_extent:
        if (size) {
                flags |= FIEMAP_EXTENT_MERGED;
                if (IS_ENCRYPTED(inode))
@@ -2013,6 +2026,13 @@ int f2fs_fiemap(struct inode *inode, struct 
fiemap_extent_info *fieinfo,
                size = 0;
        }
 
+       if (inline_tail) {
+               start = blks_to_bytes(inode, start_blk);
+               ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len);
+               if (ret != -EAGAIN)
+                       goto out;
+       }
+
        if (start_blk > last_blk)
                goto out;
 
@@ -2377,6 +2397,8 @@ static int f2fs_mpage_readpages(struct inode *inode,
 #endif
        unsigned nr_pages = rac ? readahead_count(rac) : 1;
        unsigned max_nr_pages = nr_pages;
+       loff_t i_size = i_size_read(inode);
+       pgoff_t end_index = i_size >> PAGE_SHIFT;
        pgoff_t index;
        int ret = 0;
 
@@ -2397,6 +2419,12 @@ static int f2fs_mpage_readpages(struct inode *inode,
 
                index = folio_index(folio);
 
+               if (f2fs_has_inline_tail(inode) && index == end_index &&
+                               f2fs_exist_data(inode)) {
+                       ret = f2fs_read_inline_data(inode, folio);
+                       goto out;
+               }
+
 #ifdef CONFIG_F2FS_FS_COMPRESSION
                if (!f2fs_compressed_file(inode))
                        goto read_single_page;
@@ -2462,6 +2490,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
                }
 #endif
        }
+out:
        if (bio)
                f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
        return ret;
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 2e63e9389fd7..30b18053e784 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -86,8 +86,6 @@ void f2fs_do_read_inline_data(struct folio *folio, struct 
page *ipage)
        if (folio_test_uptodate(folio))
                return;
 
-       f2fs_bug_on(F2FS_I_SB(inode), folio_index(folio));
-
        folio_zero_segment(folio, MAX_INLINE_DATA(inode), folio_size(folio));
 
        /* Copy the whole inline data block */
@@ -126,15 +124,12 @@ int f2fs_read_inline_data(struct inode *inode, struct 
folio *folio)
                return PTR_ERR(ipage);
        }
 
-       if (!f2fs_has_inline_data(inode)) {
+       if (!f2fs_has_inline_data(inode) && !f2fs_has_inline_tail(inode)) {
                f2fs_put_page(ipage, 1);
                return -EAGAIN;
        }
 
-       if (folio_index(folio))
-               folio_zero_segment(folio, 0, folio_size(folio));
-       else
-               f2fs_do_read_inline_data(folio, ipage);
+       f2fs_do_read_inline_data(folio, ipage);
 
        if (!folio_test_uptodate(folio))
                folio_mark_uptodate(folio);
@@ -814,7 +809,7 @@ int f2fs_read_inline_dir(struct file *file, struct 
dir_context *ctx,
 int f2fs_inline_data_fiemap(struct inode *inode,
                struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
 {
-       __u64 byteaddr, ilen;
+       __u64 byteaddr, ilen, offset;
        __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
                FIEMAP_EXTENT_LAST;
        struct node_info ni;
@@ -826,7 +821,8 @@ int f2fs_inline_data_fiemap(struct inode *inode,
                return PTR_ERR(ipage);
 
        if ((S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
-                               !f2fs_has_inline_data(inode)) {
+                               !f2fs_has_inline_data(inode) &&
+                               !f2fs_has_inline_tail(inode)) {
                err = -EAGAIN;
                goto out;
        }
@@ -836,12 +832,14 @@ int f2fs_inline_data_fiemap(struct inode *inode,
                goto out;
        }
 
-       ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode));
-       if (start >= ilen)
+       ilen = min_t(size_t, MAX_INLINE_DATA(inode),
+                       i_size_read(inode) & (PAGE_SIZE - 1));
+       offset = start & (PAGE_SIZE - 1);
+       if (offset >= ilen)
                goto out;
-       if (start + len < ilen)
-               ilen = start + len;
-       ilen -= start;
+       if (offset + len < ilen)
+               ilen = offset + len;
+       ilen -= offset;
 
        err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni, false);
        if (err)
-- 
2.35.3



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

Reply via email to