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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull exfat updates from Namjae Jeon:

- Use generic_write_sync instead of vfs_fsync_range in exfat_file_write_iter.
It will fix an issue where fdatasync would be set incorrectly.

- Fix potential infinite loop by the self-linked chain.

* tag 'exfat-for-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
exfat: add cluster chain loop check for dir
exfat: fdatasync flag should be same like generic_write_sync()

+50 -14
+12
fs/exfat/dir.c
··· 996 996 struct exfat_hint_femp candi_empty; 997 997 struct exfat_sb_info *sbi = EXFAT_SB(sb); 998 998 int num_entries = exfat_calc_num_entries(p_uniname); 999 + unsigned int clu_count = 0; 999 1000 1000 1001 if (num_entries < 0) 1001 1002 return num_entries; ··· 1134 1133 } else { 1135 1134 if (exfat_get_next_cluster(sb, &clu.dir)) 1136 1135 return -EIO; 1136 + 1137 + /* break if the cluster chain includes a loop */ 1138 + if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi))) 1139 + goto not_found; 1137 1140 } 1138 1141 } 1139 1142 ··· 1200 1195 int i, count = 0; 1201 1196 int dentries_per_clu; 1202 1197 unsigned int entry_type; 1198 + unsigned int clu_count = 0; 1203 1199 struct exfat_chain clu; 1204 1200 struct exfat_dentry *ep; 1205 1201 struct exfat_sb_info *sbi = EXFAT_SB(sb); ··· 1233 1227 } else { 1234 1228 if (exfat_get_next_cluster(sb, &(clu.dir))) 1235 1229 return -EIO; 1230 + 1231 + if (unlikely(++clu_count > sbi->used_clusters)) { 1232 + exfat_fs_error(sb, "FAT or bitmap is corrupted"); 1233 + return -EIO; 1234 + } 1235 + 1236 1236 } 1237 1237 } 1238 1238
+10
fs/exfat/fatent.c
··· 490 490 } 491 491 492 492 *ret_count = count; 493 + 494 + /* 495 + * since exfat_count_used_clusters() is not called, sbi->used_clusters 496 + * cannot be used here. 497 + */ 498 + if (unlikely(i == sbi->num_clusters && clu != EXFAT_EOF_CLUSTER)) { 499 + exfat_fs_error(sb, "The cluster chain has a loop"); 500 + return -EIO; 501 + } 502 + 493 503 return 0; 494 504 }
+2 -3
fs/exfat/file.c
··· 622 622 if (pos > valid_size) 623 623 pos = valid_size; 624 624 625 - if (iocb_is_dsync(iocb) && iocb->ki_pos > pos) { 626 - ssize_t err = vfs_fsync_range(file, pos, iocb->ki_pos - 1, 627 - iocb->ki_flags & IOCB_SYNC); 625 + if (iocb->ki_pos > pos) { 626 + ssize_t err = generic_write_sync(iocb, iocb->ki_pos - pos); 628 627 if (err < 0) 629 628 return err; 630 629 }
+5
fs/exfat/namei.c
··· 890 890 { 891 891 int i, dentries_per_clu; 892 892 unsigned int type; 893 + unsigned int clu_count = 0; 893 894 struct exfat_chain clu; 894 895 struct exfat_dentry *ep; 895 896 struct exfat_sb_info *sbi = EXFAT_SB(sb); ··· 927 926 } else { 928 927 if (exfat_get_next_cluster(sb, &(clu.dir))) 929 928 return -EIO; 929 + 930 + /* break if the cluster chain includes a loop */ 931 + if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi))) 932 + break; 930 933 } 931 934 } 932 935
+21 -11
fs/exfat/super.c
··· 341 341 INIT_HLIST_HEAD(&sbi->inode_hashtable[i]); 342 342 } 343 343 344 - static int exfat_read_root(struct inode *inode) 344 + static int exfat_read_root(struct inode *inode, struct exfat_chain *root_clu) 345 345 { 346 346 struct super_block *sb = inode->i_sb; 347 347 struct exfat_sb_info *sbi = EXFAT_SB(sb); 348 348 struct exfat_inode_info *ei = EXFAT_I(inode); 349 - struct exfat_chain cdir; 350 - int num_subdirs, num_clu = 0; 349 + int num_subdirs; 351 350 352 351 exfat_chain_set(&ei->dir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); 353 352 ei->entry = -1; ··· 359 360 ei->hint_stat.clu = sbi->root_dir; 360 361 ei->hint_femp.eidx = EXFAT_HINT_NONE; 361 362 362 - exfat_chain_set(&cdir, sbi->root_dir, 0, ALLOC_FAT_CHAIN); 363 - if (exfat_count_num_clusters(sb, &cdir, &num_clu)) 364 - return -EIO; 365 - i_size_write(inode, num_clu << sbi->cluster_size_bits); 363 + i_size_write(inode, EXFAT_CLU_TO_B(root_clu->size, sbi)); 366 364 367 - num_subdirs = exfat_count_dir_entries(sb, &cdir); 365 + num_subdirs = exfat_count_dir_entries(sb, root_clu); 368 366 if (num_subdirs < 0) 369 367 return -EIO; 370 368 set_nlink(inode, num_subdirs + EXFAT_MIN_SUBDIR); ··· 574 578 } 575 579 576 580 /* mount the file system volume */ 577 - static int __exfat_fill_super(struct super_block *sb) 581 + static int __exfat_fill_super(struct super_block *sb, 582 + struct exfat_chain *root_clu) 578 583 { 579 584 int ret; 580 585 struct exfat_sb_info *sbi = EXFAT_SB(sb); ··· 589 592 ret = exfat_verify_boot_region(sb); 590 593 if (ret) { 591 594 exfat_err(sb, "invalid boot region"); 595 + goto free_bh; 596 + } 597 + 598 + /* 599 + * Call exfat_count_num_cluster() before searching for up-case and 600 + * bitmap directory entries to avoid infinite loop if they are missing 601 + * and the cluster chain includes a loop. 602 + */ 603 + exfat_chain_set(root_clu, sbi->root_dir, 0, ALLOC_FAT_CHAIN); 604 + ret = exfat_count_num_clusters(sb, root_clu, &root_clu->size); 605 + if (ret) { 606 + exfat_err(sb, "failed to count the number of clusters in root"); 592 607 goto free_bh; 593 608 } 594 609 ··· 636 627 struct exfat_sb_info *sbi = sb->s_fs_info; 637 628 struct exfat_mount_options *opts = &sbi->options; 638 629 struct inode *root_inode; 630 + struct exfat_chain root_clu; 639 631 int err; 640 632 641 633 if (opts->allow_utime == (unsigned short)-1) ··· 655 645 sb->s_time_min = EXFAT_MIN_TIMESTAMP_SECS; 656 646 sb->s_time_max = EXFAT_MAX_TIMESTAMP_SECS; 657 647 658 - err = __exfat_fill_super(sb); 648 + err = __exfat_fill_super(sb, &root_clu); 659 649 if (err) { 660 650 exfat_err(sb, "failed to recognize exfat type"); 661 651 goto check_nls_io; ··· 690 680 691 681 root_inode->i_ino = EXFAT_ROOT_INO; 692 682 inode_set_iversion(root_inode, 1); 693 - err = exfat_read_root(root_inode); 683 + err = exfat_read_root(root_inode, &root_clu); 694 684 if (err) { 695 685 exfat_err(sb, "failed to initialize root inode"); 696 686 goto put_inode;