Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit d97e060

Browse files
YuezhangMonamjaejeon
authored andcommitted
exfat: convert exfat_init_ext_entry() to use dentry cache
Before this conversion, in exfat_init_ext_entry(), to init the dentries in a dentry set, the sync times is equals the dentry number if 'dirsync' or 'sync' is enabled. That affects not only performance but also device life. After this conversion, only needs to be synchronized once if 'dirsync' or 'sync' is enabled. Signed-off-by: Yuezhang Mo <[email protected]> Reviewed-by: Andy Wu <[email protected]> Reviewed-by: Aoyama Wataru <[email protected]> Reviewed-by: Sungjong Seo <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
1 parent 4e1aa22 commit d97e060

File tree

3 files changed

+33
-77
lines changed

3 files changed

+33
-77
lines changed

fs/exfat/dir.c

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -532,46 +532,27 @@ static void exfat_free_benign_secondary_clusters(struct inode *inode,
532532
exfat_free_cluster(inode, &dir);
533533
}
534534

535-
int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
536-
int entry, int num_entries, struct exfat_uni_name *p_uniname)
535+
void exfat_init_ext_entry(struct exfat_entry_set_cache *es, int num_entries,
536+
struct exfat_uni_name *p_uniname)
537537
{
538-
struct super_block *sb = inode->i_sb;
539538
int i;
540539
unsigned short *uniname = p_uniname->name;
541540
struct exfat_dentry *ep;
542-
struct buffer_head *bh;
543-
int sync = IS_DIRSYNC(inode);
544-
545-
ep = exfat_get_dentry(sb, p_dir, entry, &bh);
546-
if (!ep)
547-
return -EIO;
548541

542+
ep = exfat_get_dentry_cached(es, ES_IDX_FILE);
549543
ep->dentry.file.num_ext = (unsigned char)(num_entries - 1);
550-
exfat_update_bh(bh, sync);
551-
brelse(bh);
552-
553-
ep = exfat_get_dentry(sb, p_dir, entry + 1, &bh);
554-
if (!ep)
555-
return -EIO;
556544

545+
ep = exfat_get_dentry_cached(es, ES_IDX_STREAM);
557546
ep->dentry.stream.name_len = p_uniname->name_len;
558547
ep->dentry.stream.name_hash = cpu_to_le16(p_uniname->name_hash);
559-
exfat_update_bh(bh, sync);
560-
brelse(bh);
561-
562-
for (i = EXFAT_FIRST_CLUSTER; i < num_entries; i++) {
563-
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh);
564-
if (!ep)
565-
return -EIO;
566548

549+
for (i = ES_IDX_FIRST_FILENAME; i < num_entries; i++) {
550+
ep = exfat_get_dentry_cached(es, i);
567551
exfat_init_name_entry(ep, uniname);
568-
exfat_update_bh(bh, sync);
569-
brelse(bh);
570552
uniname += EXFAT_FILE_NAME_LEN;
571553
}
572554

573-
exfat_update_dir_chksum(inode, p_dir, entry);
574-
return 0;
555+
exfat_update_dir_chksum_with_entry_set(es);
575556
}
576557

577558
void exfat_remove_entries(struct inode *inode, struct exfat_entry_set_cache *es,

fs/exfat/exfat_fs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,8 @@ unsigned int exfat_get_entry_type(struct exfat_dentry *p_entry);
483483
void exfat_init_dir_entry(struct exfat_entry_set_cache *es,
484484
unsigned int type, unsigned int start_clu,
485485
unsigned long long size, struct timespec64 *ts);
486-
int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir,
487-
int entry, int num_entries, struct exfat_uni_name *p_uniname);
486+
void exfat_init_ext_entry(struct exfat_entry_set_cache *es, int num_entries,
487+
struct exfat_uni_name *p_uniname);
488488
void exfat_remove_entries(struct inode *inode, struct exfat_entry_set_cache *es,
489489
int order);
490490
int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,

fs/exfat/namei.c

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -539,15 +539,12 @@ static int exfat_add_entry(struct inode *inode, const char *path,
539539
goto out;
540540

541541
exfat_init_dir_entry(&es, type, start_clu, clu_size, &ts);
542+
exfat_init_ext_entry(&es, num_entries, &uniname);
542543

543544
ret = exfat_put_dentry_set(&es, IS_DIRSYNC(inode));
544545
if (ret)
545546
goto out;
546547

547-
ret = exfat_init_ext_entry(inode, p_dir, dentry, num_entries, &uniname);
548-
if (ret)
549-
goto out;
550-
551548
info->dir = *p_dir;
552549
info->entry = dentry;
553550
info->flags = ALLOC_NO_FAT_CHAIN;
@@ -1018,8 +1015,7 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
10181015
int ret, num_new_entries;
10191016
struct exfat_dentry *epold, *epnew;
10201017
struct super_block *sb = inode->i_sb;
1021-
struct buffer_head *new_bh;
1022-
struct exfat_entry_set_cache old_es;
1018+
struct exfat_entry_set_cache old_es, new_es;
10231019
int sync = IS_DIRSYNC(inode);
10241020

10251021
num_new_entries = exfat_calc_num_entries(p_uniname);
@@ -1044,33 +1040,25 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
10441040
goto put_old_es;
10451041
}
10461042

1047-
epnew = exfat_get_dentry(sb, p_dir, newentry, &new_bh);
1048-
if (!epnew) {
1049-
ret = -EIO;
1043+
ret = exfat_get_empty_dentry_set(&new_es, sb, p_dir, newentry,
1044+
num_new_entries);
1045+
if (ret)
10501046
goto put_old_es;
1051-
}
10521047

1048+
epnew = exfat_get_dentry_cached(&new_es, ES_IDX_FILE);
10531049
*epnew = *epold;
10541050
if (exfat_get_entry_type(epnew) == TYPE_FILE) {
10551051
epnew->dentry.file.attr |= cpu_to_le16(EXFAT_ATTR_ARCHIVE);
10561052
ei->attr |= EXFAT_ATTR_ARCHIVE;
10571053
}
1058-
exfat_update_bh(new_bh, sync);
1059-
brelse(new_bh);
10601054

10611055
epold = exfat_get_dentry_cached(&old_es, ES_IDX_STREAM);
1062-
epnew = exfat_get_dentry(sb, p_dir, newentry + 1, &new_bh);
1063-
if (!epnew) {
1064-
ret = -EIO;
1065-
goto put_old_es;
1066-
}
1067-
1056+
epnew = exfat_get_dentry_cached(&new_es, ES_IDX_STREAM);
10681057
*epnew = *epold;
1069-
exfat_update_bh(new_bh, sync);
1070-
brelse(new_bh);
10711058

1072-
ret = exfat_init_ext_entry(inode, p_dir, newentry,
1073-
num_new_entries, p_uniname);
1059+
exfat_init_ext_entry(&new_es, num_new_entries, p_uniname);
1060+
1061+
ret = exfat_put_dentry_set(&new_es, sync);
10741062
if (ret)
10751063
goto put_old_es;
10761064

@@ -1084,11 +1072,7 @@ static int exfat_rename_file(struct inode *inode, struct exfat_chain *p_dir,
10841072
}
10851073

10861074
exfat_remove_entries(inode, &old_es, ES_IDX_FIRST_FILENAME + 1);
1087-
1088-
ret = exfat_init_ext_entry(inode, p_dir, oldentry,
1089-
num_new_entries, p_uniname);
1090-
if (ret)
1091-
goto put_old_es;
1075+
exfat_init_ext_entry(&old_es, num_new_entries, p_uniname);
10921076
}
10931077
return exfat_put_dentry_set(&old_es, sync);
10941078

@@ -1104,8 +1088,7 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
11041088
int ret, newentry, num_new_entries;
11051089
struct exfat_dentry *epmov, *epnew;
11061090
struct super_block *sb = inode->i_sb;
1107-
struct buffer_head *new_bh;
1108-
struct exfat_entry_set_cache mov_es;
1091+
struct exfat_entry_set_cache mov_es, new_es;
11091092

11101093
num_new_entries = exfat_calc_num_entries(p_uniname);
11111094
if (num_new_entries < 0)
@@ -1120,43 +1103,35 @@ static int exfat_move_file(struct inode *inode, struct exfat_chain *p_olddir,
11201103
if (ret)
11211104
return -EIO;
11221105

1123-
epmov = exfat_get_dentry_cached(&mov_es, ES_IDX_FILE);
1124-
epnew = exfat_get_dentry(sb, p_newdir, newentry, &new_bh);
1125-
if (!epnew) {
1126-
ret = -EIO;
1106+
ret = exfat_get_empty_dentry_set(&new_es, sb, p_newdir, newentry,
1107+
num_new_entries);
1108+
if (ret)
11271109
goto put_mov_es;
1128-
}
11291110

1111+
epmov = exfat_get_dentry_cached(&mov_es, ES_IDX_FILE);
1112+
epnew = exfat_get_dentry_cached(&new_es, ES_IDX_FILE);
11301113
*epnew = *epmov;
11311114
if (exfat_get_entry_type(epnew) == TYPE_FILE) {
11321115
epnew->dentry.file.attr |= cpu_to_le16(EXFAT_ATTR_ARCHIVE);
11331116
ei->attr |= EXFAT_ATTR_ARCHIVE;
11341117
}
1135-
exfat_update_bh(new_bh, IS_DIRSYNC(inode));
1136-
brelse(new_bh);
11371118

11381119
epmov = exfat_get_dentry_cached(&mov_es, ES_IDX_STREAM);
1139-
epnew = exfat_get_dentry(sb, p_newdir, newentry + 1, &new_bh);
1140-
if (!epnew) {
1141-
ret = -EIO;
1142-
goto put_mov_es;
1143-
}
1144-
1120+
epnew = exfat_get_dentry_cached(&new_es, ES_IDX_STREAM);
11451121
*epnew = *epmov;
1146-
exfat_update_bh(new_bh, IS_DIRSYNC(inode));
1147-
brelse(new_bh);
1148-
1149-
ret = exfat_init_ext_entry(inode, p_newdir, newentry, num_new_entries,
1150-
p_uniname);
1151-
if (ret)
1152-
return ret;
11531122

1123+
exfat_init_ext_entry(&new_es, num_new_entries, p_uniname);
11541124
exfat_remove_entries(inode, &mov_es, ES_IDX_FILE);
11551125

11561126
exfat_chain_set(&ei->dir, p_newdir->dir, p_newdir->size,
11571127
p_newdir->flags);
11581128

11591129
ei->entry = newentry;
1130+
1131+
ret = exfat_put_dentry_set(&new_es, IS_DIRSYNC(inode));
1132+
if (ret)
1133+
goto put_mov_es;
1134+
11601135
return exfat_put_dentry_set(&mov_es, IS_DIRSYNC(inode));
11611136

11621137
put_mov_es:

0 commit comments

Comments
 (0)