Skip to content

Commit c665b39

Browse files
lostjefflehsiangkao
authored andcommitted
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 <[email protected]> Reviewed-by: Gao Xiang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Acked-by: Chao Yu <[email protected]> Signed-off-by: Gao Xiang <[email protected]>
1 parent bd735bd commit c665b39

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

fs/erofs/fscache.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,102 @@ static int erofs_fscache_readpage(struct file *file, struct page *page)
162162
return ret;
163163
}
164164

165+
static void erofs_fscache_unlock_folios(struct readahead_control *rac,
166+
size_t len)
167+
{
168+
while (len) {
169+
struct folio *folio = readahead_folio(rac);
170+
171+
len -= folio_size(folio);
172+
folio_mark_uptodate(folio);
173+
folio_unlock(folio);
174+
}
175+
}
176+
177+
static void erofs_fscache_readahead(struct readahead_control *rac)
178+
{
179+
struct inode *inode = rac->mapping->host;
180+
struct super_block *sb = inode->i_sb;
181+
size_t len, count, done = 0;
182+
erofs_off_t pos;
183+
loff_t start, offset;
184+
int ret;
185+
186+
if (!readahead_count(rac))
187+
return;
188+
189+
start = readahead_pos(rac);
190+
len = readahead_length(rac);
191+
192+
do {
193+
struct erofs_map_blocks map;
194+
struct erofs_map_dev mdev;
195+
196+
pos = start + done;
197+
map.m_la = pos;
198+
199+
ret = erofs_map_blocks(inode, &map, EROFS_GET_BLOCKS_RAW);
200+
if (ret)
201+
return;
202+
203+
offset = start + done;
204+
count = min_t(size_t, map.m_llen - (pos - map.m_la),
205+
len - done);
206+
207+
if (!(map.m_flags & EROFS_MAP_MAPPED)) {
208+
struct iov_iter iter;
209+
210+
iov_iter_xarray(&iter, READ, &rac->mapping->i_pages,
211+
offset, count);
212+
iov_iter_zero(count, &iter);
213+
214+
erofs_fscache_unlock_folios(rac, count);
215+
ret = count;
216+
continue;
217+
}
218+
219+
if (map.m_flags & EROFS_MAP_META) {
220+
struct folio *folio = readahead_folio(rac);
221+
222+
ret = erofs_fscache_readpage_inline(folio, &map);
223+
if (!ret) {
224+
folio_mark_uptodate(folio);
225+
ret = folio_size(folio);
226+
}
227+
228+
folio_unlock(folio);
229+
continue;
230+
}
231+
232+
mdev = (struct erofs_map_dev) {
233+
.m_deviceid = map.m_deviceid,
234+
.m_pa = map.m_pa,
235+
};
236+
ret = erofs_map_dev(sb, &mdev);
237+
if (ret)
238+
return;
239+
240+
ret = erofs_fscache_read_folios(mdev.m_fscache->cookie,
241+
rac->mapping, offset, count,
242+
mdev.m_pa + (pos - map.m_la));
243+
/*
244+
* For the error cases, the folios will be unlocked when
245+
* .readahead() returns.
246+
*/
247+
if (!ret) {
248+
erofs_fscache_unlock_folios(rac, count);
249+
ret = count;
250+
}
251+
} while (ret > 0 && ((done += ret) < len));
252+
}
253+
165254
static const struct address_space_operations erofs_fscache_meta_aops = {
166255
.readpage = erofs_fscache_meta_readpage,
167256
};
168257

169258
const struct address_space_operations erofs_fscache_access_aops = {
170259
.readpage = erofs_fscache_readpage,
260+
.readahead = erofs_fscache_readahead,
171261
};
172262

173263
int erofs_fscache_register_cookie(struct super_block *sb,

fs/erofs/super.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,10 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
658658
sbi->opt.fsid, true);
659659
if (err)
660660
return err;
661+
662+
err = super_setup_bdi(sb);
663+
if (err)
664+
return err;
661665
} else {
662666
if (!sb_set_blocksize(sb, EROFS_BLKSIZ)) {
663667
erofs_err(sb, "failed to set erofs blksize");

0 commit comments

Comments
 (0)