diff mbox series

[v1,10/11] exfat: do not sync parent dir if just update timestamp

Message ID tencent_C819A7DB899F09F0693C9C36BA8CA422FA0A@qq.com (mailing list archive)
State New
Headers show
Series [v1,01/11] exfat: add __exfat_get_dentry_set() helper | expand

Commit Message

Yuezhang Mo Dec. 8, 2023, 11:23 a.m. UTC
From: Yuezhang Mo <Yuezhang.Mo@sony.com>

When sync or dir_sync is enabled, there is no need to sync the
parent directory's inode if only for updating its timestamp.

1. If an unexpected power failure occurs, the timestamp of the
   parent directory is not updated to the storage, which has no
   impact on the user.

2. The number of writes will be greatly reduced, which can not
   only improve performance, but also prolong device life.

Signed-off-by: Yuezhang Mo <Yuezhang.Mo@sony.com>
Reviewed-by: Andy Wu <Andy.Wu@sony.com>
Reviewed-by: Aoyama Wataru <wataru.aoyama@sony.com>
---
 fs/exfat/namei.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

Comments

Namjae Jeon Dec. 22, 2023, 5:08 a.m. UTC | #1
2023-12-08 20:23 GMT+09:00, yuezhang.mo@foxmail.com <yuezhang.mo@foxmail.com>:
> From: Yuezhang Mo <Yuezhang.Mo@sony.com>
>
> When sync or dir_sync is enabled, there is no need to sync the
> parent directory's inode if only for updating its timestamp.
>
> 1. If an unexpected power failure occurs, the timestamp of the
>    parent directory is not updated to the storage, which has no
>    impact on the user.
Well, Why do you think timestamp sync of parent dir is not important ?
>
> 2. The number of writes will be greatly reduced, which can not
>    only improve performance, but also prolong device life.
How much does this have on your measurement results?
Yuezhang.Mo@sony.com Dec. 24, 2023, 2:58 p.m. UTC | #2
> From: Namjae Jeon <linkinjeon@kernel.org>
> Sent: Friday, December 22, 2023 1:09 PM
> > From: Yuezhang Mo <mailto:Yuezhang.Mo@sony.com>
> >
> > When sync or dir_sync is enabled, there is no need to sync the parent
> > directory's inode if only for updating its timestamp.
> >
> > 1. If an unexpected power failure occurs, the timestamp of the
> >    parent directory is not updated to the storage, which has no
> >    impact on the user.
> Well, Why do you think timestamp sync of parent dir is not important ?

If the size of the parent directory does not change (only the timestamp of
the parent directory needs to be synchronized), synchronizing the dentry
set of the parent directory is not as important as synchronizing the dentry
set of the target file.

In the case of a large number of file operations, skipping the synchronization
of the parent directory timestamp can allow the file operations to be
completed faster and shorten the file operation completion time. The risk of
user data loss is greater if there is a possibility of unexpected power outage
and the process is not completed for a long time.

By skipping the synchronization of the parent directory timestamp, even if
the parent directory timestamp is not updated due to an unexpected power
outage, the file operation will still be successful.

> >
> > 2. The number of writes will be greatly reduced, which can not
> >    only improve performance, but also prolong device life.
> How much does this have on your measurement results?

I did not measure the improvements brought by this patch alone,
the improvements brought by this patch set are listed in [0/11].

If without this patch, 2 dentry sets(the target file dentry set and the parent
dir dentry set) will be sync in a file operation.

If with this patch, 1 dentry set(the target file dentry set) will be sync in a
file operation, the parent dir dentry set will not be sync in most case.

So this patch reduces metadata synchronization by nearly half.
diff mbox series

Patch

diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
index 79e3fc9d6e19..b33497845a06 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -547,6 +547,7 @@  static int exfat_create(struct mnt_idmap *idmap, struct inode *dir,
 	struct exfat_dir_entry info;
 	loff_t i_pos;
 	int err;
+	loff_t size = i_size_read(dir);
 
 	mutex_lock(&EXFAT_SB(sb)->s_lock);
 	exfat_set_volume_dirty(sb);
@@ -557,7 +558,7 @@  static int exfat_create(struct mnt_idmap *idmap, struct inode *dir,
 
 	inode_inc_iversion(dir);
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
-	if (IS_DIRSYNC(dir))
+	if (IS_DIRSYNC(dir) && size != i_size_read(dir))
 		exfat_sync_inode(dir);
 	else
 		mark_inode_dirty(dir);
@@ -801,10 +802,7 @@  static int exfat_unlink(struct inode *dir, struct dentry *dentry)
 	inode_inc_iversion(dir);
 	simple_inode_init_ts(dir);
 	exfat_truncate_inode_atime(dir);
-	if (IS_DIRSYNC(dir))
-		exfat_sync_inode(dir);
-	else
-		mark_inode_dirty(dir);
+	mark_inode_dirty(dir);
 
 	clear_nlink(inode);
 	simple_inode_init_ts(inode);
@@ -825,6 +823,7 @@  static int exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
 	struct exfat_chain cdir;
 	loff_t i_pos;
 	int err;
+	loff_t size = i_size_read(dir);
 
 	mutex_lock(&EXFAT_SB(sb)->s_lock);
 	exfat_set_volume_dirty(sb);
@@ -835,7 +834,7 @@  static int exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
 
 	inode_inc_iversion(dir);
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
-	if (IS_DIRSYNC(dir))
+	if (IS_DIRSYNC(dir) && size != i_size_read(dir))
 		exfat_sync_inode(dir);
 	else
 		mark_inode_dirty(dir);
@@ -1239,6 +1238,7 @@  static int exfat_rename(struct mnt_idmap *idmap,
 	struct super_block *sb = old_dir->i_sb;
 	loff_t i_pos;
 	int err;
+	loff_t size = i_size_read(new_dir);
 
 	/*
 	 * The VFS already checks for existence, so for local filesystems
@@ -1260,7 +1260,7 @@  static int exfat_rename(struct mnt_idmap *idmap,
 	simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
 	EXFAT_I(new_dir)->i_crtime = current_time(new_dir);
 	exfat_truncate_inode_atime(new_dir);
-	if (IS_DIRSYNC(new_dir))
+	if (IS_DIRSYNC(new_dir) && size != i_size_read(new_dir))
 		exfat_sync_inode(new_dir);
 	else
 		mark_inode_dirty(new_dir);
@@ -1281,10 +1281,7 @@  static int exfat_rename(struct mnt_idmap *idmap,
 	}
 
 	inode_inc_iversion(old_dir);
-	if (IS_DIRSYNC(old_dir))
-		exfat_sync_inode(old_dir);
-	else
-		mark_inode_dirty(old_dir);
+	mark_inode_dirty(old_dir);
 
 	if (new_inode) {
 		exfat_unhash_inode(new_inode);