Skip to content

Commit

Permalink
exfat: do not sync parent dir if just update timestamp
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Andy Wu <[email protected]>
Reviewed-by: Aoyama Wataru <[email protected]>
Signed-off-by: Namjae Jeon <[email protected]>
  • Loading branch information
YuezhangMo authored and namjaejeon committed Dec 29, 2023
1 parent 3212153 commit ed12154
Showing 1 changed file with 8 additions and 11 deletions.
19 changes: 8 additions & 11 deletions namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ static int exfat_create(struct user_namespace *mnt_userns, 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);
Expand All @@ -571,7 +572,7 @@ static int exfat_create(struct user_namespace *mnt_userns, struct inode *dir,
#else
dir->i_ctime = dir->i_mtime = current_time(dir);
#endif
if (IS_DIRSYNC(dir))
if (IS_DIRSYNC(dir) && size != i_size_read(dir))
exfat_sync_inode(dir);
else
mark_inode_dirty(dir);
Expand Down Expand Up @@ -835,10 +836,7 @@ static int exfat_unlink(struct inode *dir, struct dentry *dentry)
#endif
exfat_truncate_atime(&dir->i_atime);
#endif
if (IS_DIRSYNC(dir))
exfat_sync_inode(dir);
else
mark_inode_dirty(dir);
mark_inode_dirty(dir);

clear_nlink(inode);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
Expand Down Expand Up @@ -873,6 +871,7 @@ static int exfat_mkdir(struct user_namespace *mnt_userns, 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);
Expand All @@ -892,7 +891,7 @@ static int exfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
#else
dir->i_ctime = dir->i_mtime = current_time(dir);
#endif
if (IS_DIRSYNC(dir))
if (IS_DIRSYNC(dir) && size != i_size_read(dir))
exfat_sync_inode(dir);
else
mark_inode_dirty(dir);
Expand Down Expand Up @@ -1331,6 +1330,7 @@ static int exfat_rename(struct user_namespace *mnt_userns,
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
Expand Down Expand Up @@ -1361,7 +1361,7 @@ static int exfat_rename(struct user_namespace *mnt_userns,
#else
exfat_truncate_atime(&new_dir->i_atime);
#endif
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);
Expand All @@ -1385,10 +1385,7 @@ static int exfat_rename(struct user_namespace *mnt_userns,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(6, 6, 0)
old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
#endif
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);
Expand Down

0 comments on commit ed12154

Please sign in to comment.