Skip to content

Commit 5cf0288

Browse files
Chi Zhilingnamjaejeon
authored andcommitted
exfat: support reuse buffer head for exfat_ent_get
This patch is part 2 of cached buffer head for exfat_ent_get, it introduces an argument for exfat_ent_get, and make sure this routine releases buffer head refcount when any error return. Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn> Reviewed-by: Yuezhang Mo <Yuezhang.Mo@sony.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
1 parent 967288e commit 5cf0288

3 files changed

Lines changed: 27 additions & 18 deletions

File tree

fs/exfat/cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ int exfat_get_cluster(struct inode *inode, unsigned int cluster,
287287
return -EIO;
288288
}
289289

290-
if (exfat_ent_get(sb, *dclus, &content))
290+
if (exfat_ent_get(sb, *dclus, &content, NULL))
291291
return -EIO;
292292

293293
*last_dclus = *dclus;

fs/exfat/exfat_fs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,13 +432,13 @@ int exfat_set_volume_dirty(struct super_block *sb);
432432
int exfat_clear_volume_dirty(struct super_block *sb);
433433

434434
/* fatent.c */
435-
#define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu)
435+
#define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu, NULL)
436436

437437
int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
438438
struct exfat_chain *p_chain, bool sync_bmap);
439439
int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain);
440440
int exfat_ent_get(struct super_block *sb, unsigned int loc,
441-
unsigned int *content);
441+
unsigned int *content, struct buffer_head **last);
442442
int exfat_ent_set(struct super_block *sb, unsigned int loc,
443443
unsigned int content);
444444
int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain,

fs/exfat/fatent.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,49 +88,58 @@ int exfat_ent_set(struct super_block *sb, unsigned int loc,
8888
return 0;
8989
}
9090

91+
/*
92+
* Caller must release the buffer_head if no error return.
93+
*/
9194
int exfat_ent_get(struct super_block *sb, unsigned int loc,
92-
unsigned int *content)
95+
unsigned int *content, struct buffer_head **last)
9396
{
9497
struct exfat_sb_info *sbi = EXFAT_SB(sb);
95-
int err;
9698

9799
if (!is_valid_cluster(sbi, loc)) {
98100
exfat_fs_error_ratelimit(sb,
99101
"invalid access to FAT (entry 0x%08x)",
100102
loc);
101-
return -EIO;
103+
goto err;
102104
}
103105

104-
err = __exfat_ent_get(sb, loc, content, NULL);
105-
if (err) {
106+
if (unlikely(__exfat_ent_get(sb, loc, content, last))) {
106107
exfat_fs_error_ratelimit(sb,
107-
"failed to access to FAT (entry 0x%08x, err:%d)",
108-
loc, err);
109-
return err;
108+
"failed to access to FAT (entry 0x%08x)",
109+
loc);
110+
goto err;
110111
}
111112

112-
if (*content == EXFAT_FREE_CLUSTER) {
113+
if (unlikely(*content == EXFAT_FREE_CLUSTER)) {
113114
exfat_fs_error_ratelimit(sb,
114115
"invalid access to FAT free cluster (entry 0x%08x)",
115116
loc);
116-
return -EIO;
117+
goto err;
117118
}
118119

119-
if (*content == EXFAT_BAD_CLUSTER) {
120+
if (unlikely(*content == EXFAT_BAD_CLUSTER)) {
120121
exfat_fs_error_ratelimit(sb,
121122
"invalid access to FAT bad cluster (entry 0x%08x)",
122123
loc);
123-
return -EIO;
124+
goto err;
124125
}
125126

126127
if (*content != EXFAT_EOF_CLUSTER && !is_valid_cluster(sbi, *content)) {
127128
exfat_fs_error_ratelimit(sb,
128129
"invalid access to FAT (entry 0x%08x) bogus content (0x%08x)",
129130
loc, *content);
130-
return -EIO;
131+
goto err;
131132
}
132133

133134
return 0;
135+
err:
136+
if (last) {
137+
brelse(*last);
138+
139+
/* Avoid double release */
140+
*last = NULL;
141+
}
142+
return -EIO;
134143
}
135144

136145
int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain,
@@ -299,7 +308,7 @@ int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
299308
do {
300309
count++;
301310
clu = next;
302-
if (exfat_ent_get(sb, clu, &next))
311+
if (exfat_ent_get(sb, clu, &next, NULL))
303312
return -EIO;
304313
} while (next != EXFAT_EOF_CLUSTER && count <= p_chain->size);
305314

@@ -490,7 +499,7 @@ int exfat_count_num_clusters(struct super_block *sb,
490499
count = 0;
491500
for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) {
492501
count++;
493-
if (exfat_ent_get(sb, clu, &clu))
502+
if (exfat_ent_get(sb, clu, &clu, NULL))
494503
return -EIO;
495504
if (clu == EXFAT_EOF_CLUSTER)
496505
break;

0 commit comments

Comments
 (0)