2022-02-08 14:18 GMT+09:00, Yuezhang.Mo@xxxxxxxx <Yuezhang.Mo@xxxxxxxx>: Hi Yuezhang, > Before this commit, VolumeDirty will be cleared first in > writeback if 'dirsync' or 'sync' is not enabled. If the power > is suddenly cut off after cleaning VolumeDirty but other > updates are not written, the exFAT filesystem will not be able > to detect the power failure in the next mount. > > And VolumeDirty will be set again when updating the parent > directory. It means that BootSector will be written twice in each > writeback, that will shorten the life of the device. > > Reviewed-by: Andy.Wu <Andy.Wu@xxxxxxxx> > Reviewed-by: Aoyama, Wataru <wataru.aoyama@xxxxxxxx> > Signed-off-by: Yuezhang.Mo <Yuezhang.Mo@xxxxxxxx> > --- > fs/exfat/super.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/fs/exfat/super.c b/fs/exfat/super.c > index 8c9fb7dcec16..f4906c17475e 100644 > --- a/fs/exfat/super.c > +++ b/fs/exfat/super.c > @@ -25,6 +25,8 @@ > static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET; > static struct kmem_cache *exfat_inode_cachep; > > +static int __exfat_clear_volume_dirty(struct super_block *sb); > + > static void exfat_free_iocharset(struct exfat_sb_info *sbi) > { > if (sbi->options.iocharset != exfat_default_iocharset) > @@ -64,7 +66,7 @@ static int exfat_sync_fs(struct super_block *sb, int wait) > /* If there are some dirty buffers in the bdev inode */ > mutex_lock(&sbi->s_lock); > sync_blockdev(sb->s_bdev); > - if (exfat_clear_volume_dirty(sb)) > + if (__exfat_clear_volume_dirty(sb)) > err = -EIO; > mutex_unlock(&sbi->s_lock); > return err; > @@ -139,13 +141,21 @@ int exfat_set_volume_dirty(struct super_block *sb) > return exfat_set_vol_flags(sb, sbi->vol_flags | VOLUME_DIRTY); > } > > -int exfat_clear_volume_dirty(struct super_block *sb) > +static int __exfat_clear_volume_dirty(struct super_block *sb) > { > struct exfat_sb_info *sbi = EXFAT_SB(sb); > > return exfat_set_vol_flags(sb, sbi->vol_flags & ~VOLUME_DIRTY); > } > > +int exfat_clear_volume_dirty(struct super_block *sb) > +{ > + if (sb->s_flags & (SB_SYNCHRONOUS | SB_DIRSYNC)) How about moving exfat_clear_volume_dirty() to IS_DIRSYNC() check in each operations instead of this check? > + return __exfat_clear_volume_dirty(sb); > + > + return 0; > +} > + > static int exfat_show_options(struct seq_file *m, struct dentry *root) > { > struct super_block *sb = root->d_sb; > -- > 2.25.1