Commit 7a5e9a17 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 79160a60 1e5654de
...@@ -63,7 +63,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, ...@@ -63,7 +63,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry) static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry)
{ {
int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext; int i, dentries_per_clu, dentries_per_clu_bits = 0, num_ext;
unsigned int type, clu_offset; unsigned int type, clu_offset, max_dentries;
sector_t sector; sector_t sector;
struct exfat_chain dir, clu; struct exfat_chain dir, clu;
struct exfat_uni_name uni_name; struct exfat_uni_name uni_name;
...@@ -86,6 +86,8 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent ...@@ -86,6 +86,8 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
dentries_per_clu = sbi->dentries_per_clu; dentries_per_clu = sbi->dentries_per_clu;
dentries_per_clu_bits = ilog2(dentries_per_clu); dentries_per_clu_bits = ilog2(dentries_per_clu);
max_dentries = (unsigned int)min_t(u64, MAX_EXFAT_DENTRIES,
(u64)sbi->num_clusters << dentries_per_clu_bits);
clu_offset = dentry >> dentries_per_clu_bits; clu_offset = dentry >> dentries_per_clu_bits;
exfat_chain_dup(&clu, &dir); exfat_chain_dup(&clu, &dir);
...@@ -109,7 +111,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent ...@@ -109,7 +111,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
} }
} }
while (clu.dir != EXFAT_EOF_CLUSTER) { while (clu.dir != EXFAT_EOF_CLUSTER && dentry < max_dentries) {
i = dentry & (dentries_per_clu - 1); i = dentry & (dentries_per_clu - 1);
for ( ; i < dentries_per_clu; i++, dentry++) { for ( ; i < dentries_per_clu; i++, dentry++) {
...@@ -245,7 +247,7 @@ static int exfat_iterate(struct file *filp, struct dir_context *ctx) ...@@ -245,7 +247,7 @@ static int exfat_iterate(struct file *filp, struct dir_context *ctx)
if (err) if (err)
goto unlock; goto unlock;
get_new: get_new:
if (cpos >= i_size_read(inode)) if (ei->flags == ALLOC_NO_FAT_CHAIN && cpos >= i_size_read(inode))
goto end_of_dir; goto end_of_dir;
err = exfat_readdir(inode, &cpos, &de); err = exfat_readdir(inode, &cpos, &de);
......
...@@ -690,7 +690,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -690,7 +690,7 @@ static int exfat_fill_super(struct super_block *sb, struct fs_context *fc)
if (!sb->s_root) { if (!sb->s_root) {
exfat_err(sb, "failed to get the root dentry"); exfat_err(sb, "failed to get the root dentry");
err = -ENOMEM; err = -ENOMEM;
goto put_inode; goto free_table;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment