mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
erofs: implement fscache-based data readahead
Implement fscache-based data readahead. Also registers an individual bdi for each erofs instance to enable readahead. Signed-off-by: Jeffle Xu <jefflexu@linux.alibaba.com> Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20220425122143.56815-21-jefflexu@linux.alibaba.com Acked-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
This commit is contained in:
parent
bd735bdaa6
commit
c665b394b9
2 changed files with 94 additions and 0 deletions
|
@ -162,12 +162,102 @@ out_unlock:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void erofs_fscache_unlock_folios(struct readahead_control *rac,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
while (len) {
|
||||||
|
struct folio *folio = readahead_folio(rac);
|
||||||
|
|
||||||
|
len -= folio_size(folio);
|
||||||
|
folio_mark_uptodate(folio);
|
||||||
|
folio_unlock(folio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void erofs_fscache_readahead(struct readahead_control *rac)
|
||||||
|
{
|
||||||
|
struct inode *inode = rac->mapping->host;
|
||||||
|
struct super_block *sb = inode->i_sb;
|
||||||
|
size_t len, count, done = 0;
|
||||||
|
erofs_off_t pos;
|
||||||
|
loff_t start, offset;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!readahead_count(rac))
|
||||||
|
return;
|
||||||
|
|
||||||
|
start = readahead_pos(rac);
|
||||||
|
len = readahead_length(rac);
|
||||||
|
|
||||||
|
do {
|
||||||
|
struct erofs_map_blocks map;
|
||||||
|
struct erofs_map_dev mdev;
|
||||||
|
|
||||||
|
pos = start + done;
|
||||||
|
map.m_la = pos;
|
||||||
|
|
||||||
|
ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
offset = start + done;
|
||||||
|
count = min_t(size_t, map.m_llen - (pos - map.m_la),
|
||||||
|
len - done);
|
||||||
|
|
||||||
|
if (!(map.m_flags & EROFS_MAP_MAPPED)) {
|
||||||
|
struct iov_iter iter;
|
||||||
|
|
||||||
|
iov_iter_xarray(&iter, READ, &rac->mapping->i_pages,
|
||||||
|
offset, count);
|
||||||
|
iov_iter_zero(count, &iter);
|
||||||
|
|
||||||
|
erofs_fscache_unlock_folios(rac, count);
|
||||||
|
ret = count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map.m_flags & EROFS_MAP_META) {
|
||||||
|
struct folio *folio = readahead_folio(rac);
|
||||||
|
|
||||||
|
ret = erofs_fscache_readpage_inline(folio, &map);
|
||||||
|
if (!ret) {
|
||||||
|
folio_mark_uptodate(folio);
|
||||||
|
ret = folio_size(folio);
|
||||||
|
}
|
||||||
|
|
||||||
|
folio_unlock(folio);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mdev = (struct erofs_map_dev) {
|
||||||
|
.m_deviceid = map.m_deviceid,
|
||||||
|
.m_pa = map.m_pa,
|
||||||
|
};
|
||||||
|
ret = erofs_map_dev(sb, &mdev);
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = erofs_fscache_read_folios(mdev.m_fscache->cookie,
|
||||||
|
rac->mapping, offset, count,
|
||||||
|
mdev.m_pa + (pos - map.m_la));
|
||||||
|
/*
|
||||||
|
* For the error cases, the folios will be unlocked when
|
||||||
|
* .readahead() returns.
|
||||||
|
*/
|
||||||
|
if (!ret) {
|
||||||
|
erofs_fscache_unlock_folios(rac, count);
|
||||||
|
ret = count;
|
||||||
|
}
|
||||||
|
} while (ret > 0 && ((done += ret) < len));
|
||||||
|
}
|
||||||
|
|
||||||
static const struct address_space_operations erofs_fscache_meta_aops = {
|
static const struct address_space_operations erofs_fscache_meta_aops = {
|
||||||
.readpage = erofs_fscache_meta_readpage,
|
.readpage = erofs_fscache_meta_readpage,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct address_space_operations erofs_fscache_access_aops = {
|
const struct address_space_operations erofs_fscache_access_aops = {
|
||||||
.readpage = erofs_fscache_readpage,
|
.readpage = erofs_fscache_readpage,
|
||||||
|
.readahead = erofs_fscache_readahead,
|
||||||
};
|
};
|
||||||
|
|
||||||
int erofs_fscache_register_cookie(struct super_block *sb,
|
int erofs_fscache_register_cookie(struct super_block *sb,
|
||||||
|
|
|
@ -658,6 +658,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
|
||||||
sbi->opt.fsid, true);
|
sbi->opt.fsid, true);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
err = super_setup_bdi(sb);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
} else {
|
} else {
|
||||||
if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
|
if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
|
||||||
erofs_err(sb, "failed to set erofs blksize");
|
erofs_err(sb, "failed to set erofs blksize");
|
||||||
|
|
Loading…
Add table
Reference in a new issue