[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAKYAXd_hF+xYXNiawCZLYmnha+wSUSUCEJTVBw8v6UDYfjPiUg@mail.gmail.com>
Date: Sat, 5 Mar 2022 15:03:30 +0900
From: Namjae Jeon <linkinjeon@...nel.org>
To: "Yuezhang.Mo@...y.com" <Yuezhang.Mo@...y.com>
Cc: "sj1557.seo@...sung.com" <sj1557.seo@...sung.com>,
"linux-fsdevel@...r.kernel.org" <linux-fsdevel@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] exfat: do not clear VolumeDirty in writeback
2022-02-08 14:18 GMT+09:00, Yuezhang.Mo@...y.com <Yuezhang.Mo@...y.com>:
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@...y.com>
> Reviewed-by: Aoyama, Wataru <wataru.aoyama@...y.com>
> Signed-off-by: Yuezhang.Mo <Yuezhang.Mo@...y.com>
> ---
> 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
Powered by blists - more mailing lists