Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'exfat-for-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat

Pull exfat updates from Namjae Jeon:

- Improved compatibility issue with exfat from some camera vendors.

- Do not need to release root inode on error path.

* tag 'exfat-for-5.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
exfat: handle wrong stream entry size in exfat_readdir()
exfat: avoid incorrectly releasing for root inode

+6 -4
+5 -3
fs/exfat/dir.c
··· 63 63 static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry) 64 64 { 65 65 int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext; 66 - unsigned int type, clu_offset; 66 + unsigned int type, clu_offset, max_dentries; 67 67 sector_t sector; 68 68 struct exfat_chain dir, clu; 69 69 struct exfat_uni_name uni_name; ··· 86 86 87 87 dentries_per_clu = sbi->dentries_per_clu; 88 88 dentries_per_clu_bits = ilog2(dentries_per_clu); 89 + max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES, 90 + (u64)sbi->num_clusters << dentries_per_clu_bits); 89 91 90 92 clu_offset = dentry >> dentries_per_clu_bits; 91 93 exfat_chain_dup(&clu, &dir); ··· 111 109 } 112 110 } 113 111 114 - while (clu.dir != EXFAT_EOF_CLUSTER) { 112 + while (clu.dir != EXFAT_EOF_CLUSTER && dentry < max_dentries) { 115 113 i = dentry & (dentries_per_clu - 1); 116 114 117 115 for ( ; i < dentries_per_clu; i++, dentry++) { ··· 247 245 if (err) 248 246 goto unlock; 249 247 get_new: 250 - if (cpos >= i_size_read(inode)) 248 + if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode)) 251 249 goto end_of_dir; 252 250 253 251 err = exfat_readdir(inode, &cpos, &de);
+1 -1
fs/exfat/super.c
··· 690 690 if (!sb->s_root) { 691 691 exfat_err(sb, "failed to get the root dentry"); 692 692 err = -ENOMEM; 693 - goto put_inode; 693 + goto free_table; 694 694 } 695 695 696 696 return 0;