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

Pull exfat updates from Namjae Jeon:

- Fix random stack corruption and incorrect error returns in
exfat_get_block()

- Optimize exfat_get_block() by improving checking corner cases

- Fix an endless loop by self-linked chain in exfat_find_last_cluster

- Remove dead EXFAT_CLUSTERS_UNTRACKED codes

- Add missing shutdown check

- Improve the delete performance with discard mount option

* tag 'exfat-for-6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
exfat: call bh_read in get_block only when necessary
exfat: fix potential wrong error return from get_block
exfat: fix missing shutdown check
exfat: fix the infinite loop in exfat_find_last_cluster()
exfat: fix random stack corruption after get_block
exfat: remove count used cluster from exfat_statfs()
exfat: support batch discard of clusters when freeing clusters

+146 -94
-14
fs/exfat/balloc.c
··· 147 147 unsigned int ent_idx; 148 148 struct super_block *sb = inode->i_sb; 149 149 struct exfat_sb_info *sbi = EXFAT_SB(sb); 150 - struct exfat_mount_options *opts = &sbi->options; 151 150 152 151 if (!is_valid_cluster(sbi, clu)) 153 152 return -EIO; ··· 161 162 clear_bit_le(b, sbi->vol_amap[i]->b_data); 162 163 163 164 exfat_update_bh(sbi->vol_amap[i], sync); 164 - 165 - if (opts->discard) { 166 - int ret_discard; 167 - 168 - ret_discard = sb_issue_discard(sb, 169 - exfat_cluster_to_sector(sbi, clu), 170 - (1 << sbi->sect_per_clus_bits), GFP_NOFS, 0); 171 - 172 - if (ret_discard == -EOPNOTSUPP) { 173 - exfat_err(sb, "discard not supported by device, disabling"); 174 - opts->discard = 0; 175 - } 176 - } 177 165 178 166 return 0; 179 167 }
-2
fs/exfat/exfat_fs.h
··· 14 14 15 15 #define EXFAT_ROOT_INO 1 16 16 17 - #define EXFAT_CLUSTERS_UNTRACKED (~0u) 18 - 19 17 /* 20 18 * exfat error flags 21 19 */
+30 -1
fs/exfat/fatent.c
··· 144 144 return 0; 145 145 } 146 146 147 + static inline void exfat_discard_cluster(struct super_block *sb, 148 + unsigned int clu, unsigned int num_clusters) 149 + { 150 + int ret; 151 + struct exfat_sb_info *sbi = EXFAT_SB(sb); 152 + 153 + ret = sb_issue_discard(sb, exfat_cluster_to_sector(sbi, clu), 154 + sbi->sect_per_clus * num_clusters, GFP_NOFS, 0); 155 + if (ret == -EOPNOTSUPP) { 156 + exfat_err(sb, "discard not supported by device, disabling"); 157 + sbi->options.discard = 0; 158 + } 159 + } 160 + 147 161 /* This function must be called with bitmap_lock held */ 148 162 static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) 149 163 { ··· 210 196 clu++; 211 197 num_clusters++; 212 198 } while (num_clusters < p_chain->size); 199 + 200 + if (sbi->options.discard) 201 + exfat_discard_cluster(sb, p_chain->dir, p_chain->size); 213 202 } else { 203 + unsigned int nr_clu = 1; 204 + 214 205 do { 215 206 bool sync = false; 216 207 unsigned int n_clu = clu; ··· 234 215 235 216 if (exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)))) 236 217 break; 218 + 219 + if (sbi->options.discard) { 220 + if (n_clu == clu + 1) 221 + nr_clu++; 222 + else { 223 + exfat_discard_cluster(sb, clu - nr_clu + 1, nr_clu); 224 + nr_clu = 1; 225 + } 226 + } 227 + 237 228 clu = n_clu; 238 229 num_clusters++; 239 230 ··· 294 265 clu = next; 295 266 if (exfat_ent_get(sb, clu, &next)) 296 267 return -EIO; 297 - } while (next != EXFAT_EOF_CLUSTER); 268 + } while (next != EXFAT_EOF_CLUSTER && count <= p_chain->size); 298 269 299 270 if (p_chain->size != count) { 300 271 exfat_fs_error(sb,
+27 -2
fs/exfat/file.c
··· 582 582 loff_t pos = iocb->ki_pos; 583 583 loff_t valid_size; 584 584 585 + if (unlikely(exfat_forced_shutdown(inode->i_sb))) 586 + return -EIO; 587 + 585 588 inode_lock(inode); 586 589 587 590 valid_size = ei->valid_size; ··· 638 635 return ret; 639 636 } 640 637 638 + static ssize_t exfat_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) 639 + { 640 + struct inode *inode = file_inode(iocb->ki_filp); 641 + 642 + if (unlikely(exfat_forced_shutdown(inode->i_sb))) 643 + return -EIO; 644 + 645 + return generic_file_read_iter(iocb, iter); 646 + } 647 + 641 648 static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf) 642 649 { 643 650 int err; ··· 685 672 686 673 static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma) 687 674 { 675 + if (unlikely(exfat_forced_shutdown(file_inode(file)->i_sb))) 676 + return -EIO; 677 + 688 678 file_accessed(file); 689 679 vma->vm_ops = &exfat_file_vm_ops; 690 680 return 0; 691 681 } 692 682 683 + static ssize_t exfat_splice_read(struct file *in, loff_t *ppos, 684 + struct pipe_inode_info *pipe, size_t len, unsigned int flags) 685 + { 686 + if (unlikely(exfat_forced_shutdown(file_inode(in)->i_sb))) 687 + return -EIO; 688 + 689 + return filemap_splice_read(in, ppos, pipe, len, flags); 690 + } 691 + 693 692 const struct file_operations exfat_file_operations = { 694 693 .llseek = generic_file_llseek, 695 - .read_iter = generic_file_read_iter, 694 + .read_iter = exfat_file_read_iter, 696 695 .write_iter = exfat_file_write_iter, 697 696 .unlocked_ioctl = exfat_ioctl, 698 697 #ifdef CONFIG_COMPAT ··· 712 687 #endif 713 688 .mmap = exfat_file_mmap, 714 689 .fsync = exfat_file_fsync, 715 - .splice_read = filemap_splice_read, 690 + .splice_read = exfat_splice_read, 716 691 .splice_write = iter_file_splice_write, 717 692 }; 718 693
+89 -65
fs/exfat/inode.c
··· 274 274 sector_t last_block; 275 275 sector_t phys = 0; 276 276 sector_t valid_blks; 277 + loff_t i_size; 277 278 278 279 mutex_lock(&sbi->s_lock); 279 - last_block = EXFAT_B_TO_BLK_ROUND_UP(i_size_read(inode), sb); 280 + i_size = i_size_read(inode); 281 + last_block = EXFAT_B_TO_BLK_ROUND_UP(i_size, sb); 280 282 if (iblock >= last_block && !create) 281 283 goto done; 282 284 ··· 307 305 if (buffer_delay(bh_result)) 308 306 clear_buffer_delay(bh_result); 309 307 310 - if (create) { 308 + /* 309 + * In most cases, we just need to set bh_result to mapped, unmapped 310 + * or new status as follows: 311 + * 1. i_size == valid_size 312 + * 2. write case (create == 1) 313 + * 3. direct_read (!bh_result->b_folio) 314 + * -> the unwritten part will be zeroed in exfat_direct_IO() 315 + * 316 + * Otherwise, in the case of buffered read, it is necessary to take 317 + * care the last nested block if valid_size is not equal to i_size. 318 + */ 319 + if (i_size == ei->valid_size || create || !bh_result->b_folio) 311 320 valid_blks = EXFAT_B_TO_BLK_ROUND_UP(ei->valid_size, sb); 312 - 313 - if (iblock + max_blocks < valid_blks) { 314 - /* The range has been written, map it */ 315 - goto done; 316 - } else if (iblock < valid_blks) { 317 - /* 318 - * The range has been partially written, 319 - * map the written part. 320 - */ 321 - max_blocks = valid_blks - iblock; 322 - goto done; 323 - } 324 - 325 - /* The area has not been written, map and mark as new. */ 326 - set_buffer_new(bh_result); 327 - 328 - ei->valid_size = EXFAT_BLK_TO_B(iblock + max_blocks, sb); 329 - mark_inode_dirty(inode); 330 - } else { 321 + else 331 322 valid_blks = EXFAT_B_TO_BLK(ei->valid_size, sb); 332 323 333 - if (iblock + max_blocks < valid_blks) { 334 - /* The range has been written, map it */ 335 - goto done; 336 - } else if (iblock < valid_blks) { 337 - /* 338 - * The area has been partially written, 339 - * map the written part. 340 - */ 341 - max_blocks = valid_blks - iblock; 342 - goto done; 343 - } else if (iblock == valid_blks && 344 - (ei->valid_size & (sb->s_blocksize - 1))) { 345 - /* 346 - * The block has been partially written, 347 - * zero the unwritten part and map the block. 348 - */ 349 - loff_t size, off, pos; 324 + /* The range has been fully written, map it */ 325 + if (iblock + max_blocks < valid_blks) 326 + goto done; 350 327 351 - max_blocks = 1; 352 - 353 - /* 354 - * For direct read, the unwritten part will be zeroed in 355 - * exfat_direct_IO() 356 - */ 357 - if (!bh_result->b_folio) 358 - goto done; 359 - 360 - pos = EXFAT_BLK_TO_B(iblock, sb); 361 - size = ei->valid_size - pos; 362 - off = pos & (PAGE_SIZE - 1); 363 - 364 - folio_set_bh(bh_result, bh_result->b_folio, off); 365 - err = bh_read(bh_result, 0); 366 - if (err < 0) 367 - goto unlock_ret; 368 - 369 - folio_zero_segment(bh_result->b_folio, off + size, 370 - off + sb->s_blocksize); 371 - } else { 372 - /* 373 - * The range has not been written, clear the mapped flag 374 - * to only zero the cache and do not read from disk. 375 - */ 376 - clear_buffer_mapped(bh_result); 377 - } 328 + /* The range has been partially written, map the written part */ 329 + if (iblock < valid_blks) { 330 + max_blocks = valid_blks - iblock; 331 + goto done; 378 332 } 333 + 334 + /* The area has not been written, map and mark as new for create case */ 335 + if (create) { 336 + set_buffer_new(bh_result); 337 + ei->valid_size = EXFAT_BLK_TO_B(iblock + max_blocks, sb); 338 + mark_inode_dirty(inode); 339 + goto done; 340 + } 341 + 342 + /* 343 + * The area has just one block partially written. 344 + * In that case, we should read and fill the unwritten part of 345 + * a block with zero. 346 + */ 347 + if (bh_result->b_folio && iblock == valid_blks && 348 + (ei->valid_size & (sb->s_blocksize - 1))) { 349 + loff_t size, pos; 350 + void *addr; 351 + 352 + max_blocks = 1; 353 + 354 + /* 355 + * No buffer_head is allocated. 356 + * (1) bmap: It's enough to set blocknr without I/O. 357 + * (2) read: The unwritten part should be filled with zero. 358 + * If a folio does not have any buffers, 359 + * let's returns -EAGAIN to fallback to 360 + * block_read_full_folio() for per-bh IO. 361 + */ 362 + if (!folio_buffers(bh_result->b_folio)) { 363 + err = -EAGAIN; 364 + goto done; 365 + } 366 + 367 + pos = EXFAT_BLK_TO_B(iblock, sb); 368 + size = ei->valid_size - pos; 369 + addr = folio_address(bh_result->b_folio) + 370 + offset_in_folio(bh_result->b_folio, pos); 371 + 372 + /* Check if bh->b_data points to proper addr in folio */ 373 + if (bh_result->b_data != addr) { 374 + exfat_fs_error_ratelimit(sb, 375 + "b_data(%p) != folio_addr(%p)", 376 + bh_result->b_data, addr); 377 + err = -EINVAL; 378 + goto done; 379 + } 380 + 381 + /* Read a block */ 382 + err = bh_read(bh_result, 0); 383 + if (err < 0) 384 + goto done; 385 + 386 + /* Zero unwritten part of a block */ 387 + memset(bh_result->b_data + size, 0, bh_result->b_size - size); 388 + err = 0; 389 + goto done; 390 + } 391 + 392 + /* 393 + * The area has not been written, clear mapped for read/bmap cases. 394 + * If so, it will be filled with zero without reading from disk. 395 + */ 396 + clear_buffer_mapped(bh_result); 379 397 done: 380 398 bh_result->b_size = EXFAT_BLK_TO_B(max_blocks, sb); 399 + if (err < 0) 400 + clear_buffer_mapped(bh_result); 381 401 unlock_ret: 382 402 mutex_unlock(&sbi->s_lock); 383 403 return err;
-10
fs/exfat/super.c
··· 67 67 struct exfat_sb_info *sbi = EXFAT_SB(sb); 68 68 unsigned long long id = huge_encode_dev(sb->s_bdev->bd_dev); 69 69 70 - if (sbi->used_clusters == EXFAT_CLUSTERS_UNTRACKED) { 71 - mutex_lock(&sbi->s_lock); 72 - if (exfat_count_used_clusters(sb, &sbi->used_clusters)) { 73 - mutex_unlock(&sbi->s_lock); 74 - return -EIO; 75 - } 76 - mutex_unlock(&sbi->s_lock); 77 - } 78 - 79 70 buf->f_type = sb->s_magic; 80 71 buf->f_bsize = sbi->cluster_size; 81 72 buf->f_blocks = sbi->num_clusters - 2; /* clu 0 & 1 */ ··· 522 531 sbi->vol_flags = le16_to_cpu(p_boot->vol_flags); 523 532 sbi->vol_flags_persistent = sbi->vol_flags & (VOLUME_DIRTY | MEDIA_FAILURE); 524 533 sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER; 525 - sbi->used_clusters = EXFAT_CLUSTERS_UNTRACKED; 526 534 527 535 /* check consistencies */ 528 536 if ((u64)sbi->num_FAT_sectors << p_boot->sect_size_bits <