* [PATCH 1/2 v2] exfat: write multiple sectors at once
@ 2020-06-09 7:53 ` Tetsuhiro Kohada
2020-06-09 7:53 ` [PATCH 2/2] exfat: add error check when updating dir-entries Tetsuhiro Kohada
2020-06-09 8:49 ` [PATCH 1/2 v2] exfat: write multiple sectors at once Namjae Jeon
0 siblings, 2 replies; 3+ messages in thread
From: Tetsuhiro Kohada @ 2020-06-09 7:53 UTC (permalink / raw)
To: kohada.t2
Cc: kohada.tetsuhiro, mori.takahiro, motai.hirotaka, Namjae Jeon,
Namjae Jeon, Sungjong Seo, linux-fsdevel, linux-kernel
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@kernel.org>
Signed-off-by: Tetsuhiro Kohada <kohada.t2@gmail.com>
---
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);
+ 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
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] exfat: add error check when updating dir-entries
2020-06-09 7:53 ` [PATCH 1/2 v2] exfat: write multiple sectors at once Tetsuhiro Kohada
@ 2020-06-09 7:53 ` Tetsuhiro Kohada
2020-06-09 8:49 ` [PATCH 1/2 v2] exfat: write multiple sectors at once Namjae Jeon
1 sibling, 0 replies; 3+ messages in thread
From: Tetsuhiro Kohada @ 2020-06-09 7:53 UTC (permalink / raw)
To: kohada.t2
Cc: kohada.tetsuhiro, mori.takahiro, motai.hirotaka, Namjae Jeon,
Sungjong Seo, Namjae Jeon, linux-fsdevel, linux-kernel
Add error check when synchronously updating dir-entries.
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Suggested-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Tetsuhiro Kohada <kohada.t2@gmail.com>
---
Changes in v2:
- Split into 'write multiple sectors at once'
and 'add error check when updating dir-entries'
fs/exfat/dir.c | 3 ++-
fs/exfat/exfat_fs.h | 2 +-
fs/exfat/file.c | 5 ++++-
fs/exfat/inode.c | 8 +++++---
4 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 495884ccb352..3eb8386fb5f2 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -602,7 +602,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es)
es->modified = true;
}
-void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
+int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
{
int i, err = 0;
@@ -614,6 +614,7 @@ void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
for (i = 0; i < es->num_bh; i++)
err ? bforget(es->bh[i]):brelse(es->bh[i]);
kfree(es);
+ return err;
}
static int exfat_walk_fat_chain(struct super_block *sb,
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 935954da2e54..f4fa0e833486 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -462,7 +462,7 @@ struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es,
int num);
struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
struct exfat_chain *p_dir, int entry, unsigned int type);
-void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync);
+int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync);
int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir);
/* inode.c */
diff --git a/fs/exfat/file.c b/fs/exfat/file.c
index fce03f318787..37c8f04c1f8a 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -153,6 +153,7 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
struct timespec64 ts;
struct exfat_dentry *ep, *ep2;
struct exfat_entry_set_cache *es;
+ int err;
es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
ES_ALL_ENTRIES);
@@ -187,7 +188,9 @@ int __exfat_truncate(struct inode *inode, loff_t new_size)
}
exfat_update_dir_chksum_with_entry_set(es);
- exfat_free_dentry_set(es, inode_needs_sync(inode));
+ err = exfat_free_dentry_set(es, inode_needs_sync(inode));
+ if (err)
+ return err;
}
/* cut off from the FAT chain */
diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c
index ef7cf7a6d187..c0bfd1a586aa 100644
--- a/fs/exfat/inode.c
+++ b/fs/exfat/inode.c
@@ -77,8 +77,7 @@ static int __exfat_write_inode(struct inode *inode, int sync)
ep2->dentry.stream.size = ep2->dentry.stream.valid_size;
exfat_update_dir_chksum_with_entry_set(es);
- exfat_free_dentry_set(es, sync);
- return 0;
+ return exfat_free_dentry_set(es, sync);
}
int exfat_write_inode(struct inode *inode, struct writeback_control *wbc)
@@ -222,6 +221,7 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
if (ei->dir.dir != DIR_DELETED && modified) {
struct exfat_dentry *ep;
struct exfat_entry_set_cache *es;
+ int err;
es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry,
ES_ALL_ENTRIES);
@@ -240,7 +240,9 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
ep->dentry.stream.valid_size;
exfat_update_dir_chksum_with_entry_set(es);
- exfat_free_dentry_set(es, inode_needs_sync(inode));
+ err = exfat_free_dentry_set(es, inode_needs_sync(inode));
+ if (err)
+ return err;
} /* end of if != DIR_DELETED */
--
2.25.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* RE: [PATCH 1/2 v2] exfat: write multiple sectors at once
2020-06-09 7:53 ` [PATCH 1/2 v2] exfat: write multiple sectors at once Tetsuhiro Kohada
2020-06-09 7:53 ` [PATCH 2/2] exfat: add error check when updating dir-entries Tetsuhiro Kohada
@ 2020-06-09 8:49 ` Namjae Jeon
1 sibling, 0 replies; 3+ messages in thread
From: Namjae Jeon @ 2020-06-09 8:49 UTC (permalink / raw)
To: 'Tetsuhiro Kohada'
Cc: kohada.tetsuhiro, mori.takahiro, motai.hirotaka,
'Namjae Jeon', 'Sungjong Seo', linux-fsdevel,
linux-kernel
> 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@kernel.org>
> Signed-off-by: Tetsuhiro Kohada <kohada.t2@gmail.com>
> ---
> 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
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-06-09 8:49 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <CGME20200609075406epcas1p38bc47a52172f47af12d79275a751b4d9@epcas1p3.samsung.com>
2020-06-09 7:53 ` [PATCH 1/2 v2] exfat: write multiple sectors at once Tetsuhiro Kohada
2020-06-09 7:53 ` [PATCH 2/2] exfat: add error check when updating dir-entries Tetsuhiro Kohada
2020-06-09 8:49 ` [PATCH 1/2 v2] exfat: write multiple sectors at once Namjae Jeon
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.