Skip to content

Commit

Permalink
erofs: add fiemap support with iomap
Browse files Browse the repository at this point in the history
This adds fiemap support for both uncompressed files and compressed
files by using iomap infrastructure.

Link: https://lore.kernel.org/r/20210813052931.203280-3-hsiangkao@linux.alibaba.com
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
  • Loading branch information
Gao Xiang committed Aug 18, 2021
1 parent d95ae5e commit eadcd6b
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 1 deletion.
15 changes: 14 additions & 1 deletion fs/erofs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/
#include "internal.h"
#include <linux/prefetch.h>
#include <linux/iomap.h>
#include <linux/dax.h>
#include <trace/events/erofs.h>

Expand Down Expand Up @@ -152,6 +151,20 @@ static const struct iomap_ops erofs_iomap_ops = {
.iomap_end = erofs_iomap_end,
};

int erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len)
{
if (erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout)) {
#ifdef CONFIG_EROFS_FS_ZIP
return iomap_fiemap(inode, fieinfo, start, len,
&z_erofs_iomap_report_ops);
#else
return -EOPNOTSUPP;
#endif
}
return iomap_fiemap(inode, fieinfo, start, len, &erofs_iomap_ops);
}

/*
* since we dont have write or truncate flows, so no inode
* locking needs to be held at the moment.
Expand Down
1 change: 1 addition & 0 deletions fs/erofs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ const struct inode_operations erofs_generic_iops = {
.getattr = erofs_getattr,
.listxattr = erofs_listxattr,
.get_acl = erofs_get_acl,
.fiemap = erofs_fiemap,
};

const struct inode_operations erofs_symlink_iops = {
Expand Down
5 changes: 5 additions & 0 deletions fs/erofs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/iomap.h>
#include "erofs_fs.h"

/* redefine pr_fmt "erofs: " */
Expand Down Expand Up @@ -363,6 +364,8 @@ struct erofs_map_blocks {
#define EROFS_GET_BLOCKS_FIEMAP 0x0002

/* zmap.c */
extern const struct iomap_ops z_erofs_iomap_report_ops;

#ifdef CONFIG_EROFS_FS_ZIP
int z_erofs_fill_inode(struct inode *inode);
int z_erofs_map_blocks_iter(struct inode *inode,
Expand All @@ -381,6 +384,8 @@ static inline int z_erofs_map_blocks_iter(struct inode *inode,
/* data.c */
extern const struct file_operations erofs_file_fops;
struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr);
int erofs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len);

/* inode.c */
static inline unsigned long erofs_inode_hash(erofs_nid_t nid)
Expand Down
1 change: 1 addition & 0 deletions fs/erofs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,5 @@ const struct inode_operations erofs_dir_iops = {
.getattr = erofs_getattr,
.listxattr = erofs_listxattr,
.get_acl = erofs_get_acl,
.fiemap = erofs_fiemap,
};
38 changes: 38 additions & 0 deletions fs/erofs/zmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,3 +675,41 @@ int z_erofs_map_blocks_iter(struct inode *inode,
DBG_BUGON(err < 0 && err != -ENOMEM);
return err;
}

static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset,
loff_t length, unsigned int flags,
struct iomap *iomap, struct iomap *srcmap)
{
int ret;
struct erofs_map_blocks map = { .m_la = offset };

ret = z_erofs_map_blocks_iter(inode, &map, EROFS_GET_BLOCKS_FIEMAP);
if (map.mpage)
put_page(map.mpage);
if (ret < 0)
return ret;

iomap->bdev = inode->i_sb->s_bdev;
iomap->offset = map.m_la;
iomap->length = map.m_llen;
if (map.m_flags & EROFS_MAP_MAPPED) {
iomap->type = IOMAP_MAPPED;
iomap->addr = map.m_pa;
} else {
iomap->type = IOMAP_HOLE;
iomap->addr = IOMAP_NULL_ADDR;
/*
* No strict rule how to describe extents for post EOF, yet
* we need do like below. Otherwise, iomap itself will get
* into an endless loop on post EOF.
*/
if (iomap->offset >= inode->i_size)
iomap->length = length + map.m_la - offset;
}
iomap->flags = 0;
return 0;
}

const struct iomap_ops z_erofs_iomap_report_ops = {
.iomap_begin = z_erofs_iomap_begin_report,
};

0 comments on commit eadcd6b

Please sign in to comment.