f2fs: support SEEK_DATA and SEEK_HOLE for compression files
authorDaeho Jeong <daehojeong@google.com>
Thu, 15 Feb 2024 20:16:33 +0000 (12:16 -0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 27 Feb 2024 17:41:15 +0000 (09:41 -0800)
Fix to support SEEK_DATA and SEEK_HOLE for compression files

Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/file.c

index 767d16c74bb60b948da61888762775b8f11085d6..f830f88a025d69c12099f372afbdefe19a545969 100644 (file)
@@ -394,9 +394,20 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
        return f2fs_do_sync_file(file, start, end, datasync, false);
 }
 
-static bool __found_offset(struct address_space *mapping, block_t blkaddr,
-                               pgoff_t index, int whence)
+static bool __found_offset(struct address_space *mapping,
+               struct dnode_of_data *dn, pgoff_t index, int whence)
 {
+       block_t blkaddr = f2fs_data_blkaddr(dn);
+       struct inode *inode = mapping->host;
+       bool compressed_cluster = false;
+
+       if (f2fs_compressed_file(inode)) {
+               block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page,
+                   ALIGN_DOWN(dn->ofs_in_node, F2FS_I(inode)->i_cluster_size));
+
+               compressed_cluster = first_blkaddr == COMPRESS_ADDR;
+       }
+
        switch (whence) {
        case SEEK_DATA:
                if (__is_valid_data_blkaddr(blkaddr))
@@ -404,8 +415,12 @@ static bool __found_offset(struct address_space *mapping, block_t blkaddr,
                if (blkaddr == NEW_ADDR &&
                    xa_get_mark(&mapping->i_pages, index, PAGECACHE_TAG_DIRTY))
                        return true;
+               if (compressed_cluster)
+                       return true;
                break;
        case SEEK_HOLE:
+               if (compressed_cluster)
+                       return false;
                if (blkaddr == NULL_ADDR)
                        return true;
                break;
@@ -474,7 +489,7 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
                                goto fail;
                        }
 
-                       if (__found_offset(file->f_mapping, blkaddr,
+                       if (__found_offset(file->f_mapping, &dn,
                                                        pgofs, whence)) {
                                f2fs_put_dnode(&dn);
                                goto found;