Patch "exfat: support dynamic allocate bh for exfat_entry_set_cache" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    exfat: support dynamic allocate bh for exfat_entry_set_cache

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit bc71b2ede225e52d70c9b809b631aaf4fef463f2
Author: Yuezhang Mo <Yuezhang.Mo@xxxxxxxx>
Date:   Wed Nov 9 13:50:22 2022 +0800

    exfat: support dynamic allocate bh for exfat_entry_set_cache
    
    [ Upstream commit a3ff29a95fde16906304455aa8c0bd84eb770258 ]
    
    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 <Yuezhang.Mo@xxxxxxxx>
    Reviewed-by: Andy Wu <Andy.Wu@xxxxxxxx>
    Reviewed-by: Aoyama Wataru <wataru.aoyama@xxxxxxxx>
    Reviewed-by: Sungjong Seo <sj1557.seo@xxxxxxxxxxx>
    Signed-off-by: Namjae Jeon <linkinjeon@xxxxxxxxxx>
    Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length")
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 8e355c6efbeb7..0c51bc986b7a6 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -613,6 +613,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
 			bforget(es->bh[i]);
 		else
 			brelse(es->bh[i]);
+
+	if (IS_DYNAMIC_ES(es))
+		kfree(es->bh);
+
 	kfree(es);
 	return err;
 }
@@ -845,6 +849,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
 	/* byte offset in sector */
 	off = EXFAT_BLK_OFFSET(byte_offset, sb);
 	es->start_off = off;
+	es->bh = es->__bh;
 
 	/* sector offset in cluster */
 	sec = EXFAT_B_TO_BLK(byte_offset, sb);
@@ -864,6 +869,16 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
 	es->num_entries = num_entries;
 
 	num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb);
+	if (num_bh > ARRAY_SIZE(es->__bh)) {
+		es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL);
+		if (!es->bh) {
+			brelse(bh);
+			kfree(es);
+			return NULL;
+		}
+		es->bh[0] = bh;
+	}
+
 	for (i = 1; i < num_bh; i++) {
 		/* get the next sector */
 		if (exfat_is_last_sector_in_cluster(sbi, sec)) {
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index 8b4253a2e0586..efa7f116a835f 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -170,10 +170,13 @@ struct exfat_entry_set_cache {
 	bool modified;
 	unsigned int start_off;
 	int num_bh;
-	struct buffer_head *bh[DIR_CACHE_SIZE];
+	struct buffer_head *__bh[DIR_CACHE_SIZE];
+	struct buffer_head **bh;
 	unsigned int num_entries;
 };
 
+#define IS_DYNAMIC_ES(es)	((es)->__bh != (es)->bh)
+
 struct exfat_dir_entry {
 	struct exfat_chain dir;
 	int entry;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux