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-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat

Pull exfat updates from Namjae Jeon:

- Implement FALLOC_FL_ALLOCATE_RANGE to add support for preallocating
clusters without zeroing, helping to reduce file fragmentation

- Add a unified block readahead helper for FAT chain conversion, bitmap
allocation, and directory entry lookups

- Optimize exfat_chain_cont_cluster() by caching buffer heads to
minimize mark_buffer_dirty() and mirroring overhead during
NO_FAT_CHAIN to FAT_CHAIN conversion

- Switch to truncate_inode_pages_final() in evict_inode() to prevent
BUG_ON caused by shadow entries during reclaim

- Fix a 32-bit truncation bug in directory entry calculations by
ensuring proper bitwise coercion

- Fix sb->s_maxbytes calculation to correctly reflect the maximum
possible volume size for a given cluster size, resolving xfstests
generic/213

- Introduced exfat_cluster_walk() helper to traverse FAT chains by a
specified step, handling both ALLOC_NO_FAT_CHAIN and ALLOC_FAT_CHAIN
modes

- Introduced exfat_chain_advance() helper to advance an exfat_chain
structure, updating both the current cluster and remaining size

- Remove dead assignments and fix Smatch warnings

* tag 'exfat-for-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
exfat: use exfat_chain_advance helper
exfat: introduce exfat_chain_advance helper
exfat: remove NULL cache pointer case in exfat_ent_get
exfat: use exfat_cluster_walk helper
exfat: introduce exfat_cluster_walk helper
exfat: fix incorrect directory checksum after rename to shorter name
exfat: fix s_maxbytes
exfat: fix passing zero to ERR_PTR() in exfat_mkdir()
exfat: fix error handling for FAT table operations
exfat: optimize exfat_chain_cont_cluster with cached buffer heads
exfat: drop redundant sec parameter from exfat_mirror_bh
exfat: use readahead helper in exfat_get_dentry
exfat: use readahead helper in exfat_allocate_bitmap
exfat: add block readahead in exfat_chain_cont_cluster
exfat: add fallocate FALLOC_FL_ALLOCATE_RANGE support
exfat: Fix bitwise operation having different size
exfat: Drop dead assignment of num_clusters
exfat: use truncate_inode_pages_final() at evict_inode()

+274 -227
+6 -12
fs/exfat/balloc.c
··· 74 74 struct exfat_dentry *ep) 75 75 { 76 76 struct exfat_sb_info *sbi = EXFAT_SB(sb); 77 - struct blk_plug plug; 78 77 long long map_size; 79 78 unsigned int i, j, need_map_size; 80 - sector_t sector; 81 - unsigned int max_ra_count; 79 + sector_t sector, end, ra; 80 + blkcnt_t ra_cnt = 0; 82 81 83 82 sbi->map_clu = le32_to_cpu(ep->dentry.bitmap.start_clu); 84 83 map_size = le64_to_cpu(ep->dentry.bitmap.size); ··· 99 100 if (!sbi->vol_amap) 100 101 return -ENOMEM; 101 102 102 - sector = exfat_cluster_to_sector(sbi, sbi->map_clu); 103 - max_ra_count = min(sb->s_bdi->ra_pages, sb->s_bdi->io_pages) << 104 - (PAGE_SHIFT - sb->s_blocksize_bits); 103 + sector = ra = exfat_cluster_to_sector(sbi, sbi->map_clu); 104 + end = sector + sbi->map_sectors - 1; 105 + 105 106 for (i = 0; i < sbi->map_sectors; i++) { 106 107 /* Trigger the next readahead in advance. */ 107 - if (max_ra_count && 0 == (i % max_ra_count)) { 108 - blk_start_plug(&plug); 109 - for (j = i; j < min(max_ra_count, sbi->map_sectors - i) + i; j++) 110 - sb_breadahead(sb, sector + j); 111 - blk_finish_plug(&plug); 112 - } 108 + exfat_blk_readahead(sb, sector + i, &ra, &ra_cnt, end); 113 109 114 110 sbi->vol_amap[i] = sb_bread(sb, sector + i); 115 111 if (!sbi->vol_amap[i])
+45 -128
fs/exfat/dir.c
··· 93 93 clu_offset = EXFAT_DEN_TO_CLU(dentry, sbi); 94 94 exfat_chain_dup(&clu, &dir); 95 95 96 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 97 - clu.dir += clu_offset; 98 - clu.size -= clu_offset; 99 - } else { 96 + if (clu.flags == ALLOC_FAT_CHAIN) { 100 97 /* hint_information */ 101 98 if (clu_offset > 0 && ei->hint_bmap.off != EXFAT_EOF_CLUSTER && 102 99 ei->hint_bmap.off > 0 && clu_offset >= ei->hint_bmap.off) { 103 100 clu_offset -= ei->hint_bmap.off; 104 101 clu.dir = ei->hint_bmap.clu; 105 - } 106 - 107 - while (clu_offset > 0 && clu.dir != EXFAT_EOF_CLUSTER) { 108 - if (exfat_get_next_cluster(sb, &(clu.dir))) 109 - return -EIO; 110 - 111 - clu_offset--; 102 + clu.size -= ei->hint_bmap.off; 112 103 } 113 104 } 105 + 106 + if (exfat_chain_advance(sb, &clu, clu_offset)) 107 + return -EIO; 114 108 115 109 while (clu.dir != EXFAT_EOF_CLUSTER && dentry < max_dentries) { 116 110 i = dentry & (dentries_per_clu - 1); ··· 154 160 return 0; 155 161 } 156 162 157 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 158 - if (--clu.size > 0) 159 - clu.dir++; 160 - else 161 - clu.dir = EXFAT_EOF_CLUSTER; 162 - } else { 163 - if (exfat_get_next_cluster(sb, &(clu.dir))) 164 - return -EIO; 165 - } 163 + if (exfat_chain_advance(sb, &clu, 1)) 164 + return -EIO; 166 165 } 167 166 168 167 out: ··· 236 249 */ 237 250 if (err == -EIO) { 238 251 cpos += 1 << (sb->s_blocksize_bits); 239 - cpos &= ~(sb->s_blocksize - 1); 252 + cpos &= ~(loff_t)(sb->s_blocksize - 1); 240 253 } 241 254 242 255 err = -EIO; ··· 477 490 unsigned short *uniname = p_uniname->name; 478 491 struct exfat_dentry *ep; 479 492 493 + es->num_entries = num_entries; 480 494 ep = exfat_get_dentry_cached(es, ES_IDX_FILE); 481 495 ep->dentry.file.num_ext = (unsigned char)(num_entries - 1); 482 496 ··· 549 561 return err; 550 562 } 551 563 552 - static int exfat_walk_fat_chain(struct super_block *sb, 553 - struct exfat_chain *p_dir, unsigned int byte_offset, 554 - unsigned int *clu) 555 - { 556 - struct exfat_sb_info *sbi = EXFAT_SB(sb); 557 - unsigned int clu_offset; 558 - unsigned int cur_clu; 559 - 560 - clu_offset = EXFAT_B_TO_CLU(byte_offset, sbi); 561 - cur_clu = p_dir->dir; 562 - 563 - if (p_dir->flags == ALLOC_NO_FAT_CHAIN) { 564 - cur_clu += clu_offset; 565 - } else { 566 - while (clu_offset > 0) { 567 - if (exfat_get_next_cluster(sb, &cur_clu)) 568 - return -EIO; 569 - if (cur_clu == EXFAT_EOF_CLUSTER) { 570 - exfat_fs_error(sb, 571 - "invalid dentry access beyond EOF (clu : %u, eidx : %d)", 572 - p_dir->dir, 573 - EXFAT_B_TO_DEN(byte_offset)); 574 - return -EIO; 575 - } 576 - clu_offset--; 577 - } 578 - } 579 - 580 - *clu = cur_clu; 581 - return 0; 582 - } 583 - 584 564 static int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir, 585 565 int entry, sector_t *sector, int *offset) 586 566 { ··· 558 602 559 603 off = EXFAT_DEN_TO_B(entry); 560 604 561 - ret = exfat_walk_fat_chain(sb, p_dir, off, &clu); 605 + clu = p_dir->dir; 606 + ret = exfat_cluster_walk(sb, &clu, EXFAT_B_TO_CLU(off, sbi), p_dir->flags); 562 607 if (ret) 563 608 return ret; 609 + 610 + if (clu == EXFAT_EOF_CLUSTER) { 611 + exfat_fs_error(sb, 612 + "unexpected early break in cluster chain (clu : %u, len : %d)", 613 + p_dir->dir, 614 + EXFAT_B_TO_CLU(off, sbi)); 615 + return -EIO; 616 + } 564 617 565 618 if (!exfat_test_bitmap(sb, clu)) { 566 619 exfat_err(sb, "failed to test cluster bit(%u)", clu); ··· 588 623 return 0; 589 624 } 590 625 591 - #define EXFAT_MAX_RA_SIZE (128*1024) 592 - static int exfat_dir_readahead(struct super_block *sb, sector_t sec) 593 - { 594 - struct exfat_sb_info *sbi = EXFAT_SB(sb); 595 - struct buffer_head *bh; 596 - unsigned int max_ra_count = EXFAT_MAX_RA_SIZE >> sb->s_blocksize_bits; 597 - unsigned int page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits; 598 - unsigned int adj_ra_count = max(sbi->sect_per_clus, page_ra_count); 599 - unsigned int ra_count = min(adj_ra_count, max_ra_count); 600 - 601 - /* Read-ahead is not required */ 602 - if (sbi->sect_per_clus == 1) 603 - return 0; 604 - 605 - if (sec < sbi->data_start_sector) { 606 - exfat_err(sb, "requested sector is invalid(sect:%llu, root:%llu)", 607 - (unsigned long long)sec, sbi->data_start_sector); 608 - return -EIO; 609 - } 610 - 611 - /* Not sector aligned with ra_count, resize ra_count to page size */ 612 - if ((sec - sbi->data_start_sector) & (ra_count - 1)) 613 - ra_count = page_ra_count; 614 - 615 - bh = sb_find_get_block(sb, sec); 616 - if (!bh || !buffer_uptodate(bh)) { 617 - unsigned int i; 618 - 619 - for (i = 0; i < ra_count; i++) 620 - sb_breadahead(sb, (sector_t)(sec + i)); 621 - } 622 - brelse(bh); 623 - return 0; 624 - } 625 - 626 626 struct exfat_dentry *exfat_get_dentry(struct super_block *sb, 627 627 struct exfat_chain *p_dir, int entry, struct buffer_head **bh) 628 628 { 629 + struct exfat_sb_info *sbi = EXFAT_SB(sb); 630 + unsigned int sect_per_clus = sbi->sect_per_clus; 629 631 unsigned int dentries_per_page = EXFAT_B_TO_DEN(PAGE_SIZE); 630 632 int off; 631 633 sector_t sec; ··· 605 673 if (exfat_find_location(sb, p_dir, entry, &sec, &off)) 606 674 return NULL; 607 675 608 - if (p_dir->dir != EXFAT_FREE_CLUSTER && 609 - !(entry & (dentries_per_page - 1))) 610 - exfat_dir_readahead(sb, sec); 676 + if (sect_per_clus > 1 && 677 + (entry & (dentries_per_page - 1)) == 0) { 678 + sector_t ra = sec; 679 + blkcnt_t cnt = 0; 680 + unsigned int ra_count = sect_per_clus; 681 + 682 + /* Not sector aligned with ra_count, resize ra_count to page size */ 683 + if ((sec - sbi->data_start_sector) & (ra_count - 1)) 684 + ra_count = PAGE_SIZE >> sb->s_blocksize_bits; 685 + 686 + exfat_blk_readahead(sb, sec, &ra, &cnt, sec + ra_count - 1); 687 + } 611 688 612 689 *bh = sb_bread(sb, sec); 613 690 if (!*bh) ··· 756 815 if (exfat_is_last_sector_in_cluster(sbi, sec)) { 757 816 unsigned int clu = exfat_sector_to_cluster(sbi, sec); 758 817 759 - if (p_dir->flags == ALLOC_NO_FAT_CHAIN) 760 - clu++; 761 - else if (exfat_get_next_cluster(sb, &clu)) 818 + if (exfat_cluster_walk(sb, &clu, 1, p_dir->flags)) 762 819 goto put_es; 763 820 sec = exfat_cluster_to_sector(sbi, clu); 764 821 } else { ··· 1072 1133 step = DIRENT_STEP_FILE; 1073 1134 } 1074 1135 1075 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 1076 - if (--clu.size > 0) 1077 - clu.dir++; 1078 - else 1079 - clu.dir = EXFAT_EOF_CLUSTER; 1080 - } else { 1081 - if (exfat_get_next_cluster(sb, &clu.dir)) 1082 - return -EIO; 1136 + if (exfat_chain_advance(sb, &clu, 1)) 1137 + return -EIO; 1083 1138 1084 - /* break if the cluster chain includes a loop */ 1085 - if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi))) 1086 - goto not_found; 1087 - } 1139 + /* break if the cluster chain includes a loop */ 1140 + if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi))) 1141 + goto not_found; 1088 1142 } 1089 1143 1090 1144 not_found: ··· 1112 1180 if (!((dentry + 1) & (dentries_per_clu - 1))) { 1113 1181 int ret = 0; 1114 1182 1115 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 1116 - if (--clu.size > 0) 1117 - clu.dir++; 1118 - else 1119 - clu.dir = EXFAT_EOF_CLUSTER; 1120 - } else { 1121 - ret = exfat_get_next_cluster(sb, &clu.dir); 1122 - } 1183 + ret = exfat_chain_advance(sb, &clu, 1); 1123 1184 1124 1185 if (ret || clu.dir == EXFAT_EOF_CLUSTER) { 1125 1186 /* just initialized hint_stat */ ··· 1157 1232 count++; 1158 1233 } 1159 1234 1160 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 1161 - if (--clu.size > 0) 1162 - clu.dir++; 1163 - else 1164 - clu.dir = EXFAT_EOF_CLUSTER; 1165 - } else { 1166 - if (exfat_get_next_cluster(sb, &(clu.dir))) 1167 - return -EIO; 1235 + if (exfat_chain_advance(sb, &clu, 1)) 1236 + return -EIO; 1168 1237 1169 - if (unlikely(++clu_count > sbi->used_clusters)) { 1170 - exfat_fs_error(sb, "FAT or bitmap is corrupted"); 1171 - return -EIO; 1172 - } 1173 - 1238 + if (unlikely(++clu_count > sbi->used_clusters)) { 1239 + exfat_fs_error(sb, "FAT or bitmap is corrupted"); 1240 + return -EIO; 1174 1241 } 1175 1242 } 1176 1243
+53 -4
fs/exfat/exfat_fs.h
··· 10 10 #include <linux/ratelimit.h> 11 11 #include <linux/nls.h> 12 12 #include <linux/blkdev.h> 13 + #include <linux/backing-dev.h> 13 14 #include <uapi/linux/exfat.h> 14 15 15 16 #define EXFAT_ROOT_INO 1 ··· 80 79 #define EXFAT_HINT_NONE -1 81 80 #define EXFAT_MIN_SUBDIR 2 82 81 82 + #define EXFAT_BLK_RA_SIZE(sb) \ 83 + (min_t(blkcnt_t, (sb)->s_bdi->ra_pages, (sb)->s_bdi->io_pages) \ 84 + << (PAGE_SHIFT - (sb)->s_blocksize_bits)) 85 + 83 86 /* 84 87 * helpers for cluster size to byte conversion. 85 88 */ ··· 122 117 #define FAT_ENT_SIZE (4) 123 118 #define FAT_ENT_SIZE_BITS (2) 124 119 #define FAT_ENT_OFFSET_SECTOR(sb, loc) (EXFAT_SB(sb)->FAT1_start_sector + \ 125 - (((u64)loc << FAT_ENT_SIZE_BITS) >> sb->s_blocksize_bits)) 120 + (((u64)(loc) << FAT_ENT_SIZE_BITS) >> sb->s_blocksize_bits)) 126 121 #define FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc) \ 127 - ((loc << FAT_ENT_SIZE_BITS) & (sb->s_blocksize - 1)) 122 + (((loc) << FAT_ENT_SIZE_BITS) & (sb->s_blocksize - 1)) 128 123 129 124 /* 130 125 * helpers for bitmap. ··· 437 432 int exfat_clear_volume_dirty(struct super_block *sb); 438 433 439 434 /* fatent.c */ 440 - #define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu, NULL) 435 + #define exfat_get_next_cluster(sb, pclu) \ 436 + exfat_cluster_walk(sb, (pclu), 1, ALLOC_FAT_CHAIN) 441 437 442 438 int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc, 443 439 struct exfat_chain *p_chain, bool sync_bmap); ··· 454 448 unsigned int *ret_clu); 455 449 int exfat_count_num_clusters(struct super_block *sb, 456 450 struct exfat_chain *p_chain, unsigned int *ret_count); 451 + int exfat_blk_readahead(struct super_block *sb, sector_t sec, 452 + sector_t *ra, blkcnt_t *ra_cnt, sector_t end); 453 + 454 + static inline int 455 + exfat_cluster_walk(struct super_block *sb, unsigned int *clu, 456 + unsigned int step, int flags) 457 + { 458 + struct buffer_head *bh = NULL; 459 + 460 + if (flags == ALLOC_NO_FAT_CHAIN) { 461 + (*clu) += step; 462 + return 0; 463 + } 464 + 465 + while (step--) { 466 + if (exfat_ent_get(sb, *clu, clu, &bh)) 467 + return -EIO; 468 + } 469 + brelse(bh); 470 + 471 + return 0; 472 + } 457 473 458 474 /* balloc.c */ 459 475 int exfat_load_bitmap(struct super_block *sb); ··· 552 524 int exfat_write_volume_label(struct super_block *sb, 553 525 struct exfat_uni_name *label); 554 526 527 + static inline int exfat_chain_advance(struct super_block *sb, 528 + struct exfat_chain *chain, unsigned int step) 529 + { 530 + unsigned int clu = chain->dir; 531 + 532 + if (unlikely(chain->size < step)) 533 + return -EIO; 534 + 535 + if (exfat_cluster_walk(sb, &clu, step, chain->flags)) 536 + return -EIO; 537 + 538 + chain->size -= step; 539 + 540 + if (chain->size == 0 && chain->flags == ALLOC_NO_FAT_CHAIN) 541 + chain->dir = EXFAT_EOF_CLUSTER; 542 + else 543 + chain->dir = clu; 544 + 545 + return 0; 546 + } 547 + 555 548 /* inode.c */ 556 549 extern const struct inode_operations exfat_file_inode_operations; 557 550 void exfat_sync_inode(struct inode *inode); ··· 626 577 u8 *tz, __le16 *time, __le16 *date, u8 *time_cs); 627 578 u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type); 628 579 u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type); 629 - void exfat_update_bh(struct buffer_head *bh, int sync); 580 + int exfat_update_bh(struct buffer_head *bh, int sync); 630 581 int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync); 631 582 void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, 632 583 unsigned int size, unsigned char flags);
+1
fs/exfat/exfat_raw.h
··· 25 25 #define EXFAT_FIRST_CLUSTER 2 26 26 #define EXFAT_DATA_CLUSTER_COUNT(sbi) \ 27 27 ((sbi)->num_clusters - EXFAT_RESERVED_CLUSTERS) 28 + #define EXFAT_MAX_NUM_CLUSTER (0xFFFFFFF5) 28 29 29 30 /* AllocationPossible and NoFatChain field in GeneralSecondaryFlags Field */ 30 31 #define ALLOC_POSSIBLE 0x01
+94 -40
fs/exfat/fatent.c
··· 11 11 #include "exfat_raw.h" 12 12 #include "exfat_fs.h" 13 13 14 - static int exfat_mirror_bh(struct super_block *sb, sector_t sec, 15 - struct buffer_head *bh) 14 + static int exfat_mirror_bh(struct super_block *sb, struct buffer_head *bh) 16 15 { 17 16 struct buffer_head *c_bh; 18 17 struct exfat_sb_info *sbi = EXFAT_SB(sb); 18 + sector_t sec = bh->b_blocknr; 19 19 sector_t sec2; 20 20 int err = 0; 21 21 ··· 25 25 if (!c_bh) 26 26 return -ENOMEM; 27 27 memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize); 28 - set_buffer_uptodate(c_bh); 29 - mark_buffer_dirty(c_bh); 30 - if (sb->s_flags & SB_SYNCHRONOUS) 31 - err = sync_dirty_buffer(c_bh); 28 + err = exfat_update_bh(c_bh, sb->s_flags & SB_SYNCHRONOUS); 32 29 brelse(c_bh); 33 30 } 34 31 35 32 return err; 36 33 } 37 34 35 + static int exfat_end_bh(struct super_block *sb, struct buffer_head *bh) 36 + { 37 + int err; 38 + 39 + err = exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS); 40 + if (!err) 41 + err = exfat_mirror_bh(sb, bh); 42 + brelse(bh); 43 + return err; 44 + } 45 + 38 46 static int __exfat_ent_get(struct super_block *sb, unsigned int loc, 39 - unsigned int *content, struct buffer_head **last) 47 + unsigned int *content, struct buffer_head **cache) 40 48 { 41 49 unsigned int off; 42 50 sector_t sec; 43 - struct buffer_head *bh = last ? *last : NULL; 51 + struct buffer_head *bh = *cache; 44 52 45 53 sec = FAT_ENT_OFFSET_SECTOR(sb, loc); 46 54 off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); ··· 56 48 if (!bh || bh->b_blocknr != sec || !buffer_uptodate(bh)) { 57 49 brelse(bh); 58 50 bh = sb_bread(sb, sec); 59 - if (last) 60 - *last = bh; 51 + *cache = bh; 61 52 if (unlikely(!bh)) 62 53 return -EIO; 63 54 } ··· 67 60 if (*content > EXFAT_BAD_CLUSTER) 68 61 *content = EXFAT_EOF_CLUSTER; 69 62 70 - if (!last) 71 - brelse(bh); 63 + return 0; 64 + } 65 + 66 + static int __exfat_ent_set(struct super_block *sb, unsigned int loc, 67 + unsigned int content, struct buffer_head **cache) 68 + { 69 + sector_t sec; 70 + __le32 *fat_entry; 71 + struct buffer_head *bh = cache ? *cache : NULL; 72 + unsigned int off; 73 + 74 + sec = FAT_ENT_OFFSET_SECTOR(sb, loc); 75 + off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); 76 + 77 + if (!bh || bh->b_blocknr != sec || !buffer_uptodate(bh)) { 78 + if (bh) 79 + exfat_end_bh(sb, bh); 80 + bh = sb_bread(sb, sec); 81 + if (cache) 82 + *cache = bh; 83 + if (unlikely(!bh)) 84 + return -EIO; 85 + } 86 + 87 + fat_entry = (__le32 *)&(bh->b_data[off]); 88 + *fat_entry = cpu_to_le32(content); 89 + if (!cache) 90 + exfat_end_bh(sb, bh); 72 91 return 0; 73 92 } 74 93 75 94 int exfat_ent_set(struct super_block *sb, unsigned int loc, 76 95 unsigned int content) 77 96 { 78 - unsigned int off; 79 - sector_t sec; 80 - __le32 *fat_entry; 81 - struct buffer_head *bh; 82 - 83 - sec = FAT_ENT_OFFSET_SECTOR(sb, loc); 84 - off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); 85 - 86 - bh = sb_bread(sb, sec); 87 - if (!bh) 88 - return -EIO; 89 - 90 - fat_entry = (__le32 *)&(bh->b_data[off]); 91 - *fat_entry = cpu_to_le32(content); 92 - exfat_update_bh(bh, sb->s_flags & SB_SYNCHRONOUS); 93 - exfat_mirror_bh(sb, sec, bh); 94 - brelse(bh); 95 - return 0; 97 + return __exfat_ent_set(sb, loc, content, NULL); 96 98 } 97 99 98 100 /* 99 101 * Caller must release the buffer_head if no error return. 100 102 */ 101 103 int exfat_ent_get(struct super_block *sb, unsigned int loc, 102 - unsigned int *content, struct buffer_head **last) 104 + unsigned int *content, struct buffer_head **cache) 103 105 { 104 106 struct exfat_sb_info *sbi = EXFAT_SB(sb); 105 107 ··· 119 103 goto err; 120 104 } 121 105 122 - if (unlikely(__exfat_ent_get(sb, loc, content, last))) { 106 + if (unlikely(__exfat_ent_get(sb, loc, content, cache))) { 123 107 exfat_fs_error_ratelimit(sb, 124 108 "failed to access to FAT (entry 0x%08x)", 125 109 loc); ··· 148 132 } 149 133 150 134 return 0; 151 - err: 152 - if (last) { 153 - brelse(*last); 154 135 155 - /* Avoid double release */ 156 - *last = NULL; 157 - } 136 + err: 137 + /* Avoid double release */ 138 + brelse(*cache); 139 + *cache = NULL; 158 140 return -EIO; 141 + } 142 + 143 + int exfat_blk_readahead(struct super_block *sb, sector_t sec, 144 + sector_t *ra, blkcnt_t *ra_cnt, sector_t end) 145 + { 146 + struct blk_plug plug; 147 + 148 + if (sec < *ra) 149 + return 0; 150 + 151 + *ra += *ra_cnt; 152 + 153 + /* No blocks left (or only the last block), skip readahead. */ 154 + if (*ra >= end) 155 + return 0; 156 + 157 + *ra_cnt = min(end - *ra + 1, EXFAT_BLK_RA_SIZE(sb)); 158 + if (*ra_cnt == 0) { 159 + /* Move 'ra' to the end to disable readahead. */ 160 + *ra = end; 161 + return 0; 162 + } 163 + 164 + blk_start_plug(&plug); 165 + for (unsigned int i = 0; i < *ra_cnt; i++) 166 + sb_breadahead(sb, *ra + i); 167 + blk_finish_plug(&plug); 168 + return 0; 159 169 } 160 170 161 171 int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain, 162 172 unsigned int len) 163 173 { 174 + struct buffer_head *bh = NULL; 175 + sector_t sec, end, ra; 176 + blkcnt_t ra_cnt = 0; 177 + 164 178 if (!len) 165 179 return 0; 166 180 181 + ra = FAT_ENT_OFFSET_SECTOR(sb, chain); 182 + end = FAT_ENT_OFFSET_SECTOR(sb, chain + len - 1); 183 + 167 184 while (len > 1) { 168 - if (exfat_ent_set(sb, chain, chain + 1)) 185 + sec = FAT_ENT_OFFSET_SECTOR(sb, chain); 186 + exfat_blk_readahead(sb, sec, &ra, &ra_cnt, end); 187 + 188 + if (__exfat_ent_set(sb, chain, chain + 1, &bh)) 169 189 return -EIO; 170 190 chain++; 171 191 len--; 172 192 } 173 193 174 - if (exfat_ent_set(sb, chain, EXFAT_EOF_CLUSTER)) 194 + if (__exfat_ent_set(sb, chain, EXFAT_EOF_CLUSTER, &bh)) 175 195 return -EIO; 196 + 197 + exfat_end_bh(sb, bh); 176 198 return 0; 177 199 } 178 200
+42
fs/exfat/file.c
··· 13 13 #include <linux/msdos_fs.h> 14 14 #include <linux/writeback.h> 15 15 #include <linux/filelock.h> 16 + #include <linux/falloc.h> 16 17 17 18 #include "exfat_raw.h" 18 19 #include "exfat_fs.h" ··· 34 33 return ret; 35 34 36 35 num_clusters = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi); 36 + /* integer overflow is already checked in inode_newsize_ok(). */ 37 37 new_num_clusters = EXFAT_B_TO_CLU_ROUND_UP(size, sbi); 38 38 39 39 if (new_num_clusters == num_clusters) ··· 90 88 free_clu: 91 89 exfat_free_cluster(inode, &clu); 92 90 return -EIO; 91 + } 92 + 93 + /* 94 + * Preallocate space for a file. This implements exfat's fallocate file 95 + * operation, which gets called from sys_fallocate system call. User space 96 + * requests len bytes at offset. In contrary to fat, we only support 97 + * FALLOC_FL_ALLOCATE_RANGE because by leaving the valid data length(VDL) 98 + * field, it is unnecessary to zero out the newly allocated clusters. 99 + */ 100 + static long exfat_fallocate(struct file *file, int mode, 101 + loff_t offset, loff_t len) 102 + { 103 + struct inode *inode = file->f_mapping->host; 104 + loff_t newsize = offset + len; 105 + int err = 0; 106 + 107 + /* No support for other modes */ 108 + if (mode != FALLOC_FL_ALLOCATE_RANGE) 109 + return -EOPNOTSUPP; 110 + 111 + /* No support for dir */ 112 + if (!S_ISREG(inode->i_mode)) 113 + return -EOPNOTSUPP; 114 + 115 + if (unlikely(exfat_forced_shutdown(inode->i_sb))) 116 + return -EIO; 117 + 118 + inode_lock(inode); 119 + 120 + if (newsize <= i_size_read(inode)) 121 + goto error; 122 + 123 + /* This is just an expanding truncate */ 124 + err = exfat_cont_expand(inode, newsize); 125 + 126 + error: 127 + inode_unlock(inode); 128 + 129 + return err; 93 130 } 94 131 95 132 static bool exfat_allow_set_time(struct mnt_idmap *idmap, ··· 812 771 .fsync = exfat_file_fsync, 813 772 .splice_read = exfat_splice_read, 814 773 .splice_write = iter_file_splice_write, 774 + .fallocate = exfat_fallocate, 815 775 .setlease = generic_setlease, 816 776 }; 817 777
+6 -13
fs/exfat/inode.c
··· 204 204 * so fat-chain should be synced with 205 205 * alloc-bitmap 206 206 */ 207 - exfat_chain_cont_cluster(sb, ei->start_clu, 208 - num_clusters); 207 + if (exfat_chain_cont_cluster(sb, ei->start_clu, 208 + num_clusters)) 209 + return -EIO; 209 210 ei->flags = ALLOC_FAT_CHAIN; 210 211 } 211 212 if (new_clu.flags == ALLOC_FAT_CHAIN) ··· 214 213 return -EIO; 215 214 } 216 215 217 - num_clusters += num_to_be_allocated; 218 216 *clu = new_clu.dir; 219 217 220 218 inode->i_blocks += EXFAT_CLU_TO_B(num_to_be_allocated, sbi) >> 9; ··· 225 225 * *clu = (the first cluster of the allocated chain) => 226 226 * (the last cluster of ...) 227 227 */ 228 - if (ei->flags == ALLOC_NO_FAT_CHAIN) { 229 - *clu += num_to_be_allocated - 1; 230 - } else { 231 - while (num_to_be_allocated > 1) { 232 - if (exfat_get_next_cluster(sb, clu)) 233 - return -EIO; 234 - num_to_be_allocated--; 235 - } 236 - } 228 + if (exfat_cluster_walk(sb, clu, num_to_be_allocated - 1, ei->flags)) 229 + return -EIO; 237 230 *count = 1; 238 231 } 239 232 ··· 679 686 680 687 void exfat_evict_inode(struct inode *inode) 681 688 { 682 - truncate_inode_pages(&inode->i_data, 0); 689 + truncate_inode_pages_final(&inode->i_data); 683 690 684 691 if (!inode->i_nlink) { 685 692 i_size_write(inode, 0);
+6 -2
fs/exfat/misc.c
··· 161 161 return chksum; 162 162 } 163 163 164 - void exfat_update_bh(struct buffer_head *bh, int sync) 164 + int exfat_update_bh(struct buffer_head *bh, int sync) 165 165 { 166 + int err = 0; 167 + 166 168 set_buffer_uptodate(bh); 167 169 mark_buffer_dirty(bh); 168 170 169 171 if (sync) 170 - sync_dirty_buffer(bh); 172 + err = sync_dirty_buffer(bh); 173 + 174 + return err; 171 175 } 172 176 173 177 int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync)
+13 -25
fs/exfat/namei.c
··· 246 246 i += ret; 247 247 248 248 while (i >= dentries_per_clu) { 249 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 250 - if (--clu.size > 0) 251 - clu.dir++; 252 - else 253 - clu.dir = EXFAT_EOF_CLUSTER; 254 - } else { 255 - if (exfat_get_next_cluster(sb, &clu.dir)) 256 - return -EIO; 257 - } 249 + if (exfat_chain_advance(sb, &clu, 1)) 250 + return -EIO; 258 251 259 252 i -= dentries_per_clu; 260 253 } ··· 358 365 /* no-fat-chain bit is disabled, 359 366 * so fat-chain should be synced with alloc-bitmap 360 367 */ 361 - exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size); 368 + if (exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size)) 369 + return -EIO; 362 370 p_dir->flags = ALLOC_FAT_CHAIN; 363 371 hint_femp.cur.flags = ALLOC_FAT_CHAIN; 364 372 } ··· 867 873 868 874 i_pos = exfat_make_i_pos(&info); 869 875 inode = exfat_build_inode(sb, &info, i_pos); 870 - err = PTR_ERR_OR_ZERO(inode); 871 - if (err) 876 + if (IS_ERR(inode)) { 877 + err = PTR_ERR(inode); 872 878 goto unlock; 879 + } 873 880 874 881 inode_inc_iversion(inode); 875 882 EXFAT_I(inode)->i_crtime = simple_inode_init_ts(inode); ··· 881 886 882 887 unlock: 883 888 mutex_unlock(&EXFAT_SB(sb)->s_lock); 884 - return ERR_PTR(err); 889 + return err ? ERR_PTR(err) : NULL; 885 890 } 886 891 887 892 static int exfat_check_dir_empty(struct super_block *sb, ··· 918 923 return -ENOTEMPTY; 919 924 } 920 925 921 - if (clu.flags == ALLOC_NO_FAT_CHAIN) { 922 - if (--clu.size > 0) 923 - clu.dir++; 924 - else 925 - clu.dir = EXFAT_EOF_CLUSTER; 926 - } else { 927 - if (exfat_get_next_cluster(sb, &(clu.dir))) 928 - return -EIO; 926 + if (exfat_chain_advance(sb, &clu, 1)) 927 + return -EIO; 929 928 930 - /* break if the cluster chain includes a loop */ 931 - if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi))) 932 - break; 933 - } 929 + /* break if the cluster chain includes a loop */ 930 + if (unlikely(++clu_count > EXFAT_DATA_CLUSTER_COUNT(sbi))) 931 + break; 934 932 } 935 933 936 934 return 0;
+8 -3
fs/exfat/super.c
··· 531 531 if (sbi->vol_flags & MEDIA_FAILURE) 532 532 exfat_warn(sb, "Medium has reported failures. Some data may be lost."); 533 533 534 - /* exFAT file size is limited by a disk volume size */ 535 - sb->s_maxbytes = (u64)(sbi->num_clusters - EXFAT_RESERVED_CLUSTERS) << 536 - sbi->cluster_size_bits; 534 + /* 535 + * Set to the max possible volume size for this volume's cluster size so 536 + * that any integer overflow from bytes to cluster size conversion is 537 + * checked in inode_newsize_ok(). Clamped to MAX_LFS_FILESIZE for 32-bit 538 + * machines. 539 + */ 540 + sb->s_maxbytes = min(MAX_LFS_FILESIZE, 541 + EXFAT_CLU_TO_B((loff_t)EXFAT_MAX_NUM_CLUSTER, sbi)); 537 542 538 543 /* check logical sector size */ 539 544 if (exfat_calibrate_blocksize(sb, 1 << p_boot->sect_size_bits))