Merge tag 'exfat-for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkin...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Mar 2023 16:42:27 +0000 (08:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Mar 2023 16:42:27 +0000 (08:42 -0800)
Pull exfat updates from Namjae Jeon:

 - Handle vendor extension and allocation entries as unrecognized benign
   secondary entries

 - Fix wrong ->i_blocks on devices with non-512 byte sector

 - Add the check to avoid returning -EIO from exfat_readdir() at current
   position exceeding the directory size

 - Fix a bug that reach the end of the directory stream at a position
   not aligned with the dentry size

 - Redefine DIR_DELETED as 0xFFFFFFF7, the bad cluster number

 - Two cleanup fixes and fix cluster leakage in error handling

* tag 'exfat-for-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
  exfat: fix the newly allocated clusters are not freed in error handling
  exfat: don't print error log in normal case
  exfat: remove unneeded code from exfat_alloc_cluster()
  exfat: handle unreconized benign secondary entries
  exfat: fix inode->i_blocks for non-512 byte sector size device
  exfat: redefine DIR_DELETED as the bad cluster number
  exfat: fix reporting fs error when reading dir beyond EOF
  exfat: fix unexpected EOF while reading dir

1  2 
fs/exfat/exfat_fs.h
fs/exfat/file.c
fs/exfat/namei.c

diff --combined fs/exfat/exfat_fs.h
@@@ -50,7 -50,7 +50,7 @@@ enum 
  #define ES_IDX_LAST_FILENAME(name_len)        \
        (ES_IDX_FIRST_FILENAME + EXFAT_FILENAME_ENTRY_NUM(name_len) - 1)
  
- #define DIR_DELETED           0xFFFF0321
+ #define DIR_DELETED           0xFFFFFFF7
  
  /* type values */
  #define TYPE_UNUSED           0x0000
@@@ -71,6 -71,8 +71,8 @@@
  #define TYPE_PADDING          0x0402
  #define TYPE_ACLTAB           0x0403
  #define TYPE_BENIGN_SEC               0x0800
+ #define TYPE_VENDOR_EXT               0x0801
+ #define TYPE_VENDOR_ALLOC     0x0802
  
  #define MAX_CHARSET_SIZE      6 /* max size of multi-byte character */
  #define MAX_NAME_LENGTH               255 /* max len of file name excluding NULL */
@@@ -450,9 -452,9 +452,9 @@@ int exfat_trim_fs(struct inode *inode, 
  extern const struct file_operations exfat_file_operations;
  int __exfat_truncate(struct inode *inode);
  void exfat_truncate(struct inode *inode);
 -int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 +int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
                  struct iattr *attr);
 -int exfat_getattr(struct user_namespace *mnt_userns, const struct path *path,
 +int exfat_getattr(struct mnt_idmap *idmap, const struct path *path,
                  struct kstat *stat, unsigned int request_mask,
                  unsigned int query_flags);
  int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
diff --combined fs/exfat/file.c
@@@ -209,8 -209,7 +209,7 @@@ void exfat_truncate(struct inode *inode
        if (err)
                goto write_size;
  
-       inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >>
-                               inode->i_blkbits;
+       inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9;
  write_size:
        aligned_size = i_size_read(inode);
        if (aligned_size & (blocksize - 1)) {
        mutex_unlock(&sbi->s_lock);
  }
  
 -int exfat_getattr(struct user_namespace *mnt_uerns, const struct path *path,
 +int exfat_getattr(struct mnt_idmap *idmap, const struct path *path,
                  struct kstat *stat, unsigned int request_mask,
                  unsigned int query_flags)
  {
        struct inode *inode = d_backing_inode(path->dentry);
        struct exfat_inode_info *ei = EXFAT_I(inode);
  
 -      generic_fillattr(&init_user_ns, inode, stat);
 +      generic_fillattr(&nop_mnt_idmap, inode, stat);
        exfat_truncate_atime(&stat->atime);
        stat->result_mask |= STATX_BTIME;
        stat->btime.tv_sec = ei->i_crtime.tv_sec;
        return 0;
  }
  
 -int exfat_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
 +int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
                  struct iattr *attr)
  {
        struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb);
                                ATTR_TIMES_SET);
        }
  
 -      error = setattr_prepare(&init_user_ns, dentry, attr);
 +      error = setattr_prepare(&nop_mnt_idmap, dentry, attr);
        attr->ia_valid = ia_valid;
        if (error)
                goto out;
        if (attr->ia_valid & ATTR_SIZE)
                inode->i_mtime = inode->i_ctime = current_time(inode);
  
 -      setattr_copy(&init_user_ns, inode, attr);
 +      setattr_copy(&nop_mnt_idmap, inode, attr);
        exfat_truncate_atime(&inode->i_atime);
  
        if (attr->ia_valid & ATTR_SIZE) {
diff --combined fs/exfat/namei.c
@@@ -396,7 -396,7 +396,7 @@@ static int exfat_find_empty_entry(struc
                ei->i_size_ondisk += sbi->cluster_size;
                ei->i_size_aligned += sbi->cluster_size;
                ei->flags = p_dir->flags;
-               inode->i_blocks += 1 << sbi->sect_per_clus_bits;
+               inode->i_blocks += sbi->cluster_size >> 9;
        }
  
        return dentry;
@@@ -551,7 -551,7 +551,7 @@@ out
        return ret;
  }
  
 -static int exfat_create(struct user_namespace *mnt_userns, struct inode *dir,
 +static int exfat_create(struct mnt_idmap *idmap, struct inode *dir,
                        struct dentry *dentry, umode_t mode, bool excl)
  {
        struct super_block *sb = dir->i_sb;
@@@ -834,7 -834,7 +834,7 @@@ unlock
        return err;
  }
  
 -static int exfat_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
 +static int exfat_mkdir(struct mnt_idmap *idmap, struct inode *dir,
                       struct dentry *dentry, umode_t mode)
  {
        struct super_block *sb = dir->i_sb;
@@@ -1285,7 -1285,7 +1285,7 @@@ out
        return ret;
  }
  
 -static int exfat_rename(struct user_namespace *mnt_userns,
 +static int exfat_rename(struct mnt_idmap *idmap,
                        struct inode *old_dir, struct dentry *old_dentry,
                        struct inode *new_dir, struct dentry *new_dentry,
                        unsigned int flags)