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

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

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

+101 -60
+60 -30
fs/exfat/dir.c
··· 29 29 30 30 } 31 31 32 - static void exfat_get_uniname_from_ext_entry(struct super_block *sb, 32 + static int exfat_get_uniname_from_ext_entry(struct super_block *sb, 33 33 struct exfat_chain *p_dir, int entry, unsigned short *uniname) 34 34 { 35 - int i; 35 + int i, err; 36 36 struct exfat_entry_set_cache es; 37 37 38 - if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES)) 39 - return; 38 + err = exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES); 39 + if (err) 40 + return err; 40 41 41 42 /* 42 43 * First entry : file entry ··· 57 56 } 58 57 59 58 exfat_put_dentry_set(&es, false); 59 + return 0; 60 60 } 61 61 62 62 /* read a directory entry from the opened directory */ 63 63 static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry) 64 64 { 65 - int i, dentries_per_clu, num_ext; 65 + int i, dentries_per_clu, num_ext, err; 66 66 unsigned int type, clu_offset, max_dentries; 67 67 struct exfat_chain dir, clu; 68 68 struct exfat_uni_name uni_name; ··· 102 100 clu.dir = ei->hint_bmap.clu; 103 101 } 104 102 105 - while (clu_offset > 0) { 103 + while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) { 106 104 if (exfat_get_next_cluster(sb, &(clu.dir))) 107 105 return -EIO; 108 106 ··· 148 146 0); 149 147 150 148 *uni_name.name = 0x0; 151 - exfat_get_uniname_from_ext_entry(sb, &clu, i, 149 + err = exfat_get_uniname_from_ext_entry(sb, &clu, i, 152 150 uni_name.name); 151 + if (err) { 152 + brelse(bh); 153 + continue; 154 + } 153 155 exfat_utf16_to_nls(sb, &uni_name, 154 156 dir_entry->namebuf.lfn, 155 157 dir_entry->namebuf.lfnbuf_len); ··· 240 234 fake_offset = 1; 241 235 } 242 236 243 - if (cpos & (DENTRY_SIZE - 1)) { 244 - err = -ENOENT; 245 - goto unlock; 246 - } 237 + cpos = round_up(cpos, DENTRY_SIZE); 247 238 248 239 /* name buffer should be allocated before use */ 249 240 err = exfat_alloc_namebuf(nb); ··· 381 378 return TYPE_ACL; 382 379 return TYPE_CRITICAL_SEC; 383 380 } 381 + 382 + if (ep->type == EXFAT_VENDOR_EXT) 383 + return TYPE_VENDOR_EXT; 384 + if (ep->type == EXFAT_VENDOR_ALLOC) 385 + return TYPE_VENDOR_ALLOC; 386 + 384 387 return TYPE_BENIGN_SEC; 385 388 } 386 389 ··· 530 521 return ret; 531 522 } 532 523 524 + static void exfat_free_benign_secondary_clusters(struct inode *inode, 525 + struct exfat_dentry *ep) 526 + { 527 + struct super_block *sb = inode->i_sb; 528 + struct exfat_chain dir; 529 + unsigned int start_clu = 530 + le32_to_cpu(ep->dentry.generic_secondary.start_clu); 531 + u64 size = le64_to_cpu(ep->dentry.generic_secondary.size); 532 + unsigned char flags = ep->dentry.generic_secondary.flags; 533 + 534 + if (!(flags & ALLOC_POSSIBLE) || !start_clu || !size) 535 + return; 536 + 537 + exfat_chain_set(&dir, start_clu, 538 + EXFAT_B_TO_CLU_ROUND_UP(size, EXFAT_SB(sb)), 539 + flags); 540 + exfat_free_cluster(inode, &dir); 541 + } 542 + 533 543 int exfat_init_ext_entry(struct inode *inode, struct exfat_chain *p_dir, 534 544 int entry, int num_entries, struct exfat_uni_name *p_uniname) 535 545 { ··· 581 553 if (!ep) 582 554 return -EIO; 583 555 556 + if (exfat_get_entry_type(ep) & TYPE_BENIGN_SEC) 557 + exfat_free_benign_secondary_clusters(inode, ep); 558 + 584 559 exfat_init_name_entry(ep, uniname); 585 560 exfat_update_bh(bh, sync); 586 561 brelse(bh); ··· 606 575 ep = exfat_get_dentry(sb, p_dir, entry + i, &bh); 607 576 if (!ep) 608 577 return -EIO; 578 + 579 + if (exfat_get_entry_type(ep) & TYPE_BENIGN_SEC) 580 + exfat_free_benign_secondary_clusters(inode, ep); 609 581 610 582 exfat_set_entry_type(ep, TYPE_DELETED); 611 583 exfat_update_bh(bh, IS_DIRSYNC(inode)); ··· 778 744 ES_MODE_GET_STRM_ENTRY, 779 745 ES_MODE_GET_NAME_ENTRY, 780 746 ES_MODE_GET_CRITICAL_SEC_ENTRY, 747 + ES_MODE_GET_BENIGN_SEC_ENTRY, 781 748 }; 782 749 783 750 static bool exfat_validate_entry(unsigned int type, ··· 792 757 if (type != TYPE_FILE && type != TYPE_DIR) 793 758 return false; 794 759 *mode = ES_MODE_GET_FILE_ENTRY; 795 - return true; 760 + break; 796 761 case ES_MODE_GET_FILE_ENTRY: 797 762 if (type != TYPE_STREAM) 798 763 return false; 799 764 *mode = ES_MODE_GET_STRM_ENTRY; 800 - return true; 765 + break; 801 766 case ES_MODE_GET_STRM_ENTRY: 802 767 if (type != TYPE_EXTEND) 803 768 return false; 804 769 *mode = ES_MODE_GET_NAME_ENTRY; 805 - return true; 770 + break; 806 771 case ES_MODE_GET_NAME_ENTRY: 807 - if (type == TYPE_STREAM) 772 + if (type & TYPE_BENIGN_SEC) 773 + *mode = ES_MODE_GET_BENIGN_SEC_ENTRY; 774 + else if (type != TYPE_EXTEND) 808 775 return false; 809 - if (type != TYPE_EXTEND) { 810 - if (!(type & TYPE_CRITICAL_SEC)) 811 - return false; 812 - *mode = ES_MODE_GET_CRITICAL_SEC_ENTRY; 813 - } 814 - return true; 815 - case ES_MODE_GET_CRITICAL_SEC_ENTRY: 816 - if (type == TYPE_EXTEND || type == TYPE_STREAM) 776 + break; 777 + case ES_MODE_GET_BENIGN_SEC_ENTRY: 778 + /* Assume unreconized benign secondary entry */ 779 + if (!(type & TYPE_BENIGN_SEC)) 817 780 return false; 818 - if ((type & TYPE_CRITICAL_SEC) != TYPE_CRITICAL_SEC) 819 - return false; 820 - return true; 781 + break; 821 782 default: 822 - WARN_ON_ONCE(1); 823 783 return false; 824 784 } 785 + 786 + return true; 825 787 } 826 788 827 789 struct exfat_dentry *exfat_get_dentry_cached( ··· 1199 1167 1200 1168 type = exfat_get_entry_type(ext_ep); 1201 1169 brelse(bh); 1202 - if (type == TYPE_EXTEND || type == TYPE_STREAM) 1170 + if (type & TYPE_CRITICAL_SEC || type & TYPE_BENIGN_SEC) 1203 1171 count++; 1204 - else 1205 - break; 1206 1172 } 1207 1173 return count; 1208 1174 }
+3 -1
fs/exfat/exfat_fs.h
··· 50 50 #define ES_IDX_LAST_FILENAME(name_len) \ 51 51 (ES_IDX_FIRST_FILENAME + EXFAT_FILENAME_ENTRY_NUM(name_len) - 1) 52 52 53 - #define DIR_DELETED 0xFFFF0321 53 + #define DIR_DELETED 0xFFFFFFF7 54 54 55 55 /* type values */ 56 56 #define TYPE_UNUSED 0x0000 ··· 71 71 #define TYPE_PADDING 0x0402 72 72 #define TYPE_ACLTAB 0x0403 73 73 #define TYPE_BENIGN_SEC 0x0800 74 + #define TYPE_VENDOR_EXT 0x0801 75 + #define TYPE_VENDOR_ALLOC 0x0802 74 76 75 77 #define MAX_CHARSET_SIZE 6 /* max size of multi-byte character */ 76 78 #define MAX_NAME_LENGTH 255 /* max len of file name excluding NULL */
+21
fs/exfat/exfat_raw.h
··· 27 27 ((sbi)->num_clusters - EXFAT_RESERVED_CLUSTERS) 28 28 29 29 /* AllocationPossible and NoFatChain field in GeneralSecondaryFlags Field */ 30 + #define ALLOC_POSSIBLE 0x01 30 31 #define ALLOC_FAT_CHAIN 0x01 31 32 #define ALLOC_NO_FAT_CHAIN 0x03 32 33 ··· 51 50 #define EXFAT_STREAM 0xC0 /* stream entry */ 52 51 #define EXFAT_NAME 0xC1 /* file name entry */ 53 52 #define EXFAT_ACL 0xC2 /* stream entry */ 53 + #define EXFAT_VENDOR_EXT 0xE0 /* vendor extension entry */ 54 + #define EXFAT_VENDOR_ALLOC 0xE1 /* vendor allocation entry */ 54 55 55 56 #define IS_EXFAT_CRITICAL_PRI(x) (x < 0xA0) 56 57 #define IS_EXFAT_BENIGN_PRI(x) (x < 0xC0) ··· 158 155 __le32 start_clu; 159 156 __le64 size; 160 157 } __packed upcase; /* up-case table directory entry */ 158 + struct { 159 + __u8 flags; 160 + __u8 vendor_guid[16]; 161 + __u8 vendor_defined[14]; 162 + } __packed vendor_ext; /* vendor extension directory entry */ 163 + struct { 164 + __u8 flags; 165 + __u8 vendor_guid[16]; 166 + __u8 vendor_defined[2]; 167 + __le32 start_clu; 168 + __le64 size; 169 + } __packed vendor_alloc; /* vendor allocation directory entry */ 170 + struct { 171 + __u8 flags; 172 + __u8 custom_defined[18]; 173 + __le32 start_clu; 174 + __le64 size; 175 + } __packed generic_secondary; /* generic secondary directory entry */ 161 176 } __packed dentry; 162 177 } __packed; 163 178
+12 -20
fs/exfat/fatent.c
··· 307 307 struct exfat_chain *p_chain, bool sync_bmap) 308 308 { 309 309 int ret = -ENOSPC; 310 - unsigned int num_clusters = 0, total_cnt; 310 + unsigned int total_cnt; 311 311 unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER; 312 312 struct super_block *sb = inode->i_sb; 313 313 struct exfat_sb_info *sbi = EXFAT_SB(sb); ··· 344 344 345 345 /* check cluster validation */ 346 346 if (!is_valid_cluster(sbi, hint_clu)) { 347 - exfat_err(sb, "hint_cluster is invalid (%u)", 348 - hint_clu); 347 + if (hint_clu != sbi->num_clusters) 348 + exfat_err(sb, "hint_cluster is invalid (%u), rewind to the first cluster", 349 + hint_clu); 349 350 hint_clu = EXFAT_FIRST_CLUSTER; 350 - if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { 351 - if (exfat_chain_cont_cluster(sb, p_chain->dir, 352 - num_clusters)) { 353 - ret = -EIO; 354 - goto unlock; 355 - } 356 - p_chain->flags = ALLOC_FAT_CHAIN; 357 - } 351 + p_chain->flags = ALLOC_FAT_CHAIN; 358 352 } 359 353 360 354 p_chain->dir = EXFAT_EOF_CLUSTER; ··· 358 364 if (new_clu != hint_clu && 359 365 p_chain->flags == ALLOC_NO_FAT_CHAIN) { 360 366 if (exfat_chain_cont_cluster(sb, p_chain->dir, 361 - num_clusters)) { 367 + p_chain->size)) { 362 368 ret = -EIO; 363 369 goto free_cluster; 364 370 } ··· 370 376 ret = -EIO; 371 377 goto free_cluster; 372 378 } 373 - 374 - num_clusters++; 375 379 376 380 /* update FAT table */ 377 381 if (p_chain->flags == ALLOC_FAT_CHAIN) { ··· 387 395 goto free_cluster; 388 396 } 389 397 } 398 + p_chain->size++; 399 + 390 400 last_clu = new_clu; 391 401 392 - if (--num_alloc == 0) { 402 + if (p_chain->size == num_alloc) { 393 403 sbi->clu_srch_ptr = hint_clu; 394 - sbi->used_clusters += num_clusters; 404 + sbi->used_clusters += num_alloc; 395 405 396 - p_chain->size += num_clusters; 397 406 mutex_unlock(&sbi->bitmap_lock); 398 407 return 0; 399 408 } ··· 405 412 406 413 if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { 407 414 if (exfat_chain_cont_cluster(sb, p_chain->dir, 408 - num_clusters)) { 415 + p_chain->size)) { 409 416 ret = -EIO; 410 417 goto free_cluster; 411 418 } ··· 414 421 } 415 422 } 416 423 free_cluster: 417 - if (num_clusters) 418 - __exfat_free_cluster(inode, p_chain); 424 + __exfat_free_cluster(inode, p_chain); 419 425 unlock: 420 426 mutex_unlock(&sbi->bitmap_lock); 421 427 return ret;
+1 -2
fs/exfat/file.c
··· 209 209 if (err) 210 210 goto write_size; 211 211 212 - inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 213 - inode->i_blkbits; 212 + inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; 214 213 write_size: 215 214 aligned_size = i_size_read(inode); 216 215 if (aligned_size & (blocksize - 1)) {
+2 -4
fs/exfat/inode.c
··· 220 220 num_clusters += num_to_be_allocated; 221 221 *clu = new_clu.dir; 222 222 223 - inode->i_blocks += 224 - num_to_be_allocated << sbi->sect_per_clus_bits; 223 + inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9; 225 224 226 225 /* 227 226 * Move *clu pointer along FAT chains (hole care) because the ··· 575 576 576 577 exfat_save_attr(inode, info->attr); 577 578 578 - inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 579 - inode->i_blkbits; 579 + inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; 580 580 inode->i_mtime = info->mtime; 581 581 inode->i_ctime = info->mtime; 582 582 ei->i_crtime = info->crtime;
+1 -1
fs/exfat/namei.c
··· 396 396 ei->i_size_ondisk += sbi->cluster_size; 397 397 ei->i_size_aligned += sbi->cluster_size; 398 398 ei->flags = p_dir->flags; 399 - inode->i_blocks += 1 << sbi->sect_per_clus_bits; 399 + inode->i_blocks += sbi->cluster_size >> 9; 400 400 } 401 401 402 402 return dentry;
+1 -2
fs/exfat/super.c
··· 373 373 inode->i_op = &exfat_dir_inode_operations; 374 374 inode->i_fop = &exfat_dir_operations; 375 375 376 - inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 377 - inode->i_blkbits; 376 + inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; 378 377 ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff; 379 378 ei->i_size_aligned = i_size_read(inode); 380 379 ei->i_size_ondisk = i_size_read(inode);