On Sun, Dec 13, 2020 at 08:27:13AM -0500, Jeff Layton wrote: > Peek at the upper layer's errseq_t at mount time for volatile mounts, > and record it in the per-sb info. In sync_fs, check for an error since > the recorded point and set it in the overlayfs superblock if there was > one. > > Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> > --- > fs/overlayfs/ovl_entry.h | 1 + > fs/overlayfs/super.c | 14 +++++++++++--- > 2 files changed, 12 insertions(+), 3 deletions(-) > > diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h > index 1b5a2094df8e..fcfcc3951973 100644 > --- a/fs/overlayfs/ovl_entry.h > +++ b/fs/overlayfs/ovl_entry.h > @@ -79,6 +79,7 @@ struct ovl_fs { > atomic_long_t last_ino; > /* Whiteout dentry cache */ > struct dentry *whiteout; > + errseq_t err_mark; > }; > > static inline struct vfsmount *ovl_upper_mnt(struct ovl_fs *ofs) > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c > index 290983bcfbb3..2985d2752970 100644 > --- a/fs/overlayfs/super.c > +++ b/fs/overlayfs/super.c > @@ -264,8 +264,13 @@ static int ovl_sync_fs(struct super_block *sb, int wait) > if (!ovl_upper_mnt(ofs)) > return 0; > > - if (!ovl_should_sync(ofs)) > - return 0; > + if (!ovl_should_sync(ofs)) { > + /* Propagate errors from upper to overlayfs */ > + ret = errseq_check(&upper_sb->s_wb_err, ofs->err_mark); > + errseq_set(&sb->s_wb_err, ret); > + return ret; > + } > + > /* > * Not called for sync(2) call or an emergency sync (SB_I_SKIP_SYNC). > * All the super blocks will be iterated, including upper_sb. > @@ -1945,8 +1950,11 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent) > > sb->s_stack_depth = ovl_upper_mnt(ofs)->mnt_sb->s_stack_depth; > sb->s_time_gran = ovl_upper_mnt(ofs)->mnt_sb->s_time_gran; > - > } > + > + if (ofs->config.ovl_volatile) > + ofs->err_mark = errseq_peek(&ovl_upper_mnt(ofs)->mnt_sb->s_wb_err); > + > oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers); > err = PTR_ERR(oe); > if (IS_ERR(oe)) > -- > 2.29.2 > I've tested this with the following scenarios, seems to work: Test: 1. Mount ext2 on /mnt/loop, and cause a writeback error 2. Verify syncfs on /mnt/loop shows error 3. Mount volatile filesystem 4. Create file on volatile filesystem, and verify that I can syncfs it without error --- Fork: 5a. Create a file on overlayfs, and generate a writeback error 6a. Syncfs overlayfs. 7a. Create a new file on overlayfs, and syncfs, and verify it returns error --- 5b. Create a file on loop back, and generate a writeback error 6b. Sync said file 7b. Verify syncfs on loop returns error once, and then success on next attempts 8b. Verify all syncfs on overlayfs now fail --- 5c. Create file on overlayfs, and generate a writeback error 6c. Sync overlayfs, and verify all syncs are failures 7c. Verify syncfs on loop fails once.