Skip to content

Commit a3ff29a

Browse files
YuezhangMonamjaejeon
authored andcommitted
exfat: support dynamic allocate bh for exfat_entry_set_cache
In special cases, a file or a directory may occupied more than 19 directory entries, pre-allocating 3 bh is not enough. Such as - Support vendor secondary directory entry in the future. - Since file directory entry is damaged, the SecondaryCount field is bigger than 18. So this commit supports dynamic allocation of bh. 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 f83d8a3 commit a3ff29a

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

fs/exfat/dir.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
615615
bforget(es->bh[i]);
616616
else
617617
brelse(es->bh[i]);
618+
619+
if (IS_DYNAMIC_ES(es))
620+
kfree(es->bh);
621+
618622
kfree(es);
619623
return err;
620624
}
@@ -847,6 +851,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
847851
/* byte offset in sector */
848852
off = EXFAT_BLK_OFFSET(byte_offset, sb);
849853
es->start_off = off;
854+
es->bh = es->__bh;
850855

851856
/* sector offset in cluster */
852857
sec = EXFAT_B_TO_BLK(byte_offset, sb);
@@ -866,6 +871,16 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
866871
es->num_entries = num_entries;
867872

868873
num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb);
874+
if (num_bh > ARRAY_SIZE(es->__bh)) {
875+
es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL);
876+
if (!es->bh) {
877+
brelse(bh);
878+
kfree(es);
879+
return NULL;
880+
}
881+
es->bh[0] = bh;
882+
}
883+
869884
for (i = 1; i < num_bh; i++) {
870885
/* get the next sector */
871886
if (exfat_is_last_sector_in_cluster(sbi, sec)) {

fs/exfat/exfat_fs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,14 @@ struct exfat_entry_set_cache {
185185
struct super_block *sb;
186186
unsigned int start_off;
187187
int num_bh;
188-
struct buffer_head *bh[DIR_CACHE_SIZE];
188+
struct buffer_head *__bh[DIR_CACHE_SIZE];
189+
struct buffer_head **bh;
189190
unsigned int num_entries;
190191
bool modified;
191192
};
192193

194+
#define IS_DYNAMIC_ES(es) ((es)->__bh != (es)->bh)
195+
193196
struct exfat_dir_entry {
194197
struct exfat_chain dir;
195198
int entry;

0 commit comments

Comments
 (0)