> Write multiple sectors at once when updating dir-entries. > Add exfat_update_bhs() for that. It wait for write completion once instead of sector by sector. > It's only effective if sync enabled. > > Suggested-by: Namjae Jeon <linkinjeon@xxxxxxxxxx> > Signed-off-by: Tetsuhiro Kohada <kohada.t2@xxxxxxxxx> > --- > Changes in v2: > - Split into 'write multiple sectors at once' > and 'add error check when updating dir-entries' > > fs/exfat/dir.c | 12 +++++++----- > fs/exfat/exfat_fs.h | 1 + > fs/exfat/misc.c | 19 +++++++++++++++++++ > 3 files changed, 27 insertions(+), 5 deletions(-) > > diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index de43534aa299..495884ccb352 100644 > --- a/fs/exfat/dir.c > +++ b/fs/exfat/dir.c > @@ -604,13 +604,15 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) > > void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) { > - int i; > + int i, err = 0; > > - for (i = 0; i < es->num_bh; i++) { > - if (es->modified) > - exfat_update_bh(es->sb, es->bh[i], sync); > - brelse(es->bh[i]); > + if (es->modified) { > + set_bit(EXFAT_SB_DIRTY, &EXFAT_SB(es->sb)->s_state); I pointed out that setting EXFAT_SB_DIRTY can be merged into exfat_update_bhs() on previous thread. Is it unnecessary? > + err = exfat_update_bhs(es->bh, es->num_bh, sync); > } > + > + for (i = 0; i < es->num_bh; i++) > + err ? bforget(es->bh[i]):brelse(es->bh[i]); > kfree(es); > } > > diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 595f3117f492..935954da2e54 100644 > --- a/fs/exfat/exfat_fs.h > +++ b/fs/exfat/exfat_fs.h > @@ -515,6 +515,7 @@ void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts, > u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type); > u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type); void exfat_update_bh(struct > super_block *sb, struct buffer_head *bh, int sync); > +int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync); > void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, > unsigned int size, unsigned char flags); void exfat_chain_dup(struct exfat_chain *dup, > struct exfat_chain *ec); diff --git a/fs/exfat/misc.c b/fs/exfat/misc.c index > 17d41f3d3709..dc34968e99d3 100644 > --- a/fs/exfat/misc.c > +++ b/fs/exfat/misc.c > @@ -173,6 +173,25 @@ void exfat_update_bh(struct super_block *sb, struct buffer_head *bh, int sync) > sync_dirty_buffer(bh); > } > > +int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync) { > + int i, err = 0; > + > + for (i = 0; i < nr_bhs; i++) { > + set_buffer_uptodate(bhs[i]); > + mark_buffer_dirty(bhs[i]); > + if (sync) > + write_dirty_buffer(bhs[i], 0); > + } > + > + for (i = 0; i < nr_bhs && sync; i++) { > + wait_on_buffer(bhs[i]); > + if (!buffer_uptodate(bhs[i])) > + err = -EIO; > + } > + return err; > +} > + > void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, > unsigned int size, unsigned char flags) { > -- > 2.25.1