Skip to content

Commit 6422cde

Browse files
committed
erofs: use buffered I/O for file-backed mounts by default
For many use cases (e.g. container images are just fetched from remote), performance will be impacted if underlay page cache is up-to-date but direct i/o flushes dirty pages first. Instead, let's use buffered I/O by default to keep in sync with loop devices and add a (re)mount option to explicitly give a try to use direct I/O if supported by the underlying files. The container startup time is improved as below: [workload] docker.io/library/workpress:latest unpack 1st run non-1st runs EROFS snapshotter buffered I/O file 4.586404265s 0.308s 0.198s EROFS snapshotter direct I/O file 4.581742849s 2.238s 0.222s EROFS snapshotter loop 4.596023152s 0.346s 0.201s Overlayfs snapshotter 5.382851037s 0.206s 0.214s Fixes: fb17675 ("erofs: add file-backed mount support") Cc: Derek McGowan <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Gao Xiang <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f8d920a commit 6422cde

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

fs/erofs/fileio.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct erofs_fileio_rq {
99
struct bio_vec bvecs[BIO_MAX_VECS];
1010
struct bio bio;
1111
struct kiocb iocb;
12+
struct super_block *sb;
1213
};
1314

1415
struct erofs_fileio {
@@ -52,8 +53,9 @@ static void erofs_fileio_rq_submit(struct erofs_fileio_rq *rq)
5253
rq->iocb.ki_pos = rq->bio.bi_iter.bi_sector << SECTOR_SHIFT;
5354
rq->iocb.ki_ioprio = get_current_ioprio();
5455
rq->iocb.ki_complete = erofs_fileio_ki_complete;
55-
rq->iocb.ki_flags = (rq->iocb.ki_filp->f_mode & FMODE_CAN_ODIRECT) ?
56-
IOCB_DIRECT : 0;
56+
if (test_opt(&EROFS_SB(rq->sb)->opt, DIRECT_IO) &&
57+
rq->iocb.ki_filp->f_mode & FMODE_CAN_ODIRECT)
58+
rq->iocb.ki_flags = IOCB_DIRECT;
5759
iov_iter_bvec(&iter, ITER_DEST, rq->bvecs, rq->bio.bi_vcnt,
5860
rq->bio.bi_iter.bi_size);
5961
ret = vfs_iocb_iter_read(rq->iocb.ki_filp, &rq->iocb, &iter);
@@ -68,6 +70,7 @@ static struct erofs_fileio_rq *erofs_fileio_rq_alloc(struct erofs_map_dev *mdev)
6870

6971
bio_init(&rq->bio, NULL, rq->bvecs, BIO_MAX_VECS, REQ_OP_READ);
7072
rq->iocb.ki_filp = mdev->m_dif->file;
73+
rq->sb = mdev->m_sb;
7174
return rq;
7275
}
7376

fs/erofs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ struct erofs_sb_info {
176176
#define EROFS_MOUNT_POSIX_ACL 0x00000020
177177
#define EROFS_MOUNT_DAX_ALWAYS 0x00000040
178178
#define EROFS_MOUNT_DAX_NEVER 0x00000080
179+
#define EROFS_MOUNT_DIRECT_IO 0x00000100
179180

180181
#define clear_opt(opt, option) ((opt)->mount_opt &= ~EROFS_MOUNT_##option)
181182
#define set_opt(opt, option) ((opt)->mount_opt |= EROFS_MOUNT_##option)

fs/erofs/super.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,14 +364,8 @@ static void erofs_default_options(struct erofs_sb_info *sbi)
364364
}
365365

366366
enum {
367-
Opt_user_xattr,
368-
Opt_acl,
369-
Opt_cache_strategy,
370-
Opt_dax,
371-
Opt_dax_enum,
372-
Opt_device,
373-
Opt_fsid,
374-
Opt_domain_id,
367+
Opt_user_xattr, Opt_acl, Opt_cache_strategy, Opt_dax, Opt_dax_enum,
368+
Opt_device, Opt_fsid, Opt_domain_id, Opt_directio,
375369
Opt_err
376370
};
377371

@@ -398,6 +392,7 @@ static const struct fs_parameter_spec erofs_fs_parameters[] = {
398392
fsparam_string("device", Opt_device),
399393
fsparam_string("fsid", Opt_fsid),
400394
fsparam_string("domain_id", Opt_domain_id),
395+
fsparam_flag_no("directio", Opt_directio),
401396
{}
402397
};
403398

@@ -511,6 +506,16 @@ static int erofs_fc_parse_param(struct fs_context *fc,
511506
errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
512507
break;
513508
#endif
509+
case Opt_directio:
510+
#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
511+
if (result.boolean)
512+
set_opt(&sbi->opt, DIRECT_IO);
513+
else
514+
clear_opt(&sbi->opt, DIRECT_IO);
515+
#else
516+
errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name);
517+
#endif
518+
break;
514519
default:
515520
return -ENOPARAM;
516521
}
@@ -948,6 +953,8 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root)
948953
seq_puts(seq, ",dax=always");
949954
if (test_opt(opt, DAX_NEVER))
950955
seq_puts(seq, ",dax=never");
956+
if (erofs_is_fileio_mode(sbi) && test_opt(opt, DIRECT_IO))
957+
seq_puts(seq, ",directio");
951958
#ifdef CONFIG_EROFS_FS_ONDEMAND
952959
if (sbi->fsid)
953960
seq_printf(seq, ",fsid=%s", sbi->fsid);

0 commit comments

Comments
 (0)