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

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

Pull exfat updates from Namjae Jeon:

- Clean-up unnecessary codes as ->valid_size is supported

- buffered-IO fallback is no longer needed when using direct-IO

- Move ->valid_size extension from mmap to ->page_mkwrite. This
improves the overhead caused by unnecessary zero-out during mmap.

- Fix memleaks from exfat_load_bitmap() and exfat_create_upcase_table()

- Add sops->shutdown and ioctl

- Add Yuezhang Mo as a reviwer

* tag 'exfat-for-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat:
MAINTAINERS: exfat: add myself as reviewer
exfat: resolve memory leak from exfat_create_upcase_table()
exfat: move extend valid_size into ->page_mkwrite()
exfat: fix memory leak in exfat_load_bitmap()
exfat: Implement sops->shutdown and ioctl
exfat: do not fallback to buffered write
exfat: drop ->i_size_ondisk

+200 -127
+1
MAINTAINERS
··· 8466 8466 EXFAT FILE SYSTEM 8467 8467 M: Namjae Jeon <linkinjeon@kernel.org> 8468 8468 M: Sungjong Seo <sj1557.seo@samsung.com> 8469 + R: Yuezhang Mo <yuezhang.mo@sony.com> 8469 8470 L: linux-fsdevel@vger.kernel.org 8470 8471 S: Maintained 8471 8472 T: git git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git
+5 -5
fs/exfat/balloc.c
··· 91 91 return -EIO; 92 92 93 93 type = exfat_get_entry_type(ep); 94 - if (type == TYPE_UNUSED) 95 - break; 96 - if (type != TYPE_BITMAP) 97 - continue; 98 - if (ep->dentry.bitmap.flags == 0x0) { 94 + if (type == TYPE_BITMAP && 95 + ep->dentry.bitmap.flags == 0x0) { 99 96 int err; 100 97 101 98 err = exfat_allocate_bitmap(sb, ep); ··· 100 103 return err; 101 104 } 102 105 brelse(bh); 106 + 107 + if (type == TYPE_UNUSED) 108 + return -EINVAL; 103 109 } 104 110 105 111 if (exfat_get_next_cluster(sb, &clu.dir))
+17 -7
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 <uapi/linux/exfat.h> 13 14 14 15 #define EXFAT_ROOT_INO 1 15 16 ··· 149 148 #define DIR_CACHE_SIZE \ 150 149 (DIV_ROUND_UP(EXFAT_DEN_TO_B(ES_MAX_ENTRY_NUM), SECTOR_SIZE) + 1) 151 150 151 + /* Superblock flags */ 152 + #define EXFAT_FLAGS_SHUTDOWN 1 153 + 152 154 struct exfat_dentry_namebuf { 153 155 char *lfn; 154 156 int lfnbuf_len; /* usually MAX_UNINAME_BUF_SIZE */ ··· 271 267 unsigned int clu_srch_ptr; /* cluster search pointer */ 272 268 unsigned int used_clusters; /* number of used clusters */ 273 269 270 + unsigned long s_exfat_flags; /* Exfat superblock flags */ 271 + 274 272 struct mutex s_lock; /* superblock lock */ 275 273 struct mutex bitmap_lock; /* bitmap lock */ 276 274 struct exfat_mount_options options; ··· 315 309 /* for avoiding the race between alloc and free */ 316 310 unsigned int cache_valid_id; 317 311 318 - /* 319 - * NOTE: i_size_ondisk is 64bits, so must hold ->inode_lock to access. 320 - * physically allocated size. 321 - */ 322 - loff_t i_size_ondisk; 323 - /* block-aligned i_size (used in cont_write_begin) */ 324 - loff_t i_size_aligned; 325 312 /* on-disk position of directory entry or 0 */ 326 313 loff_t i_pos; 327 314 loff_t valid_size; ··· 335 336 static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) 336 337 { 337 338 return container_of(inode, struct exfat_inode_info, vfs_inode); 339 + } 340 + 341 + static inline int exfat_forced_shutdown(struct super_block *sb) 342 + { 343 + return test_bit(EXFAT_FLAGS_SHUTDOWN, &EXFAT_SB(sb)->s_exfat_flags); 338 344 } 339 345 340 346 /* ··· 421 417 return clus >= EXFAT_FIRST_CLUSTER && clus < sbi->num_clusters; 422 418 } 423 419 420 + static inline loff_t exfat_ondisk_size(const struct inode *inode) 421 + { 422 + return ((loff_t)inode->i_blocks) << 9; 423 + } 424 + 424 425 /* super.c */ 425 426 int exfat_set_volume_dirty(struct super_block *sb); 426 427 int exfat_clear_volume_dirty(struct super_block *sb); ··· 470 461 long exfat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); 471 462 long exfat_compat_ioctl(struct file *filp, unsigned int cmd, 472 463 unsigned long arg); 464 + int exfat_force_shutdown(struct super_block *sb, u32 flags); 473 465 474 466 /* namei.c */ 475 467 extern const struct dentry_operations exfat_dentry_ops;
+68 -42
fs/exfat/file.c
··· 29 29 if (ret) 30 30 return ret; 31 31 32 - num_clusters = EXFAT_B_TO_CLU_ROUND_UP(ei->i_size_ondisk, sbi); 32 + num_clusters = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi); 33 33 new_num_clusters = EXFAT_B_TO_CLU_ROUND_UP(size, sbi); 34 34 35 35 if (new_num_clusters == num_clusters) ··· 74 74 /* Expanded range not zeroed, do not update valid_size */ 75 75 i_size_write(inode, size); 76 76 77 - ei->i_size_aligned = round_up(size, sb->s_blocksize); 78 - ei->i_size_ondisk = ei->i_size_aligned; 79 77 inode->i_blocks = round_up(size, sbi->cluster_size) >> 9; 80 78 mark_inode_dirty(inode); 81 79 ··· 157 159 exfat_set_volume_dirty(sb); 158 160 159 161 num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP(i_size_read(inode), sbi); 160 - num_clusters_phys = EXFAT_B_TO_CLU_ROUND_UP(ei->i_size_ondisk, sbi); 162 + num_clusters_phys = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi); 161 163 162 164 exfat_chain_set(&clu, ei->start_clu, num_clusters_phys, ei->flags); 163 165 ··· 243 245 struct super_block *sb = inode->i_sb; 244 246 struct exfat_sb_info *sbi = EXFAT_SB(sb); 245 247 struct exfat_inode_info *ei = EXFAT_I(inode); 246 - unsigned int blocksize = i_blocksize(inode); 247 - loff_t aligned_size; 248 248 int err; 249 249 250 250 mutex_lock(&sbi->s_lock); ··· 260 264 261 265 inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; 262 266 write_size: 263 - aligned_size = i_size_read(inode); 264 - if (aligned_size & (blocksize - 1)) { 265 - aligned_size |= (blocksize - 1); 266 - aligned_size++; 267 - } 268 - 269 - if (ei->i_size_ondisk > i_size_read(inode)) 270 - ei->i_size_ondisk = aligned_size; 271 - 272 - if (ei->i_size_aligned > i_size_read(inode)) 273 - ei->i_size_aligned = aligned_size; 274 267 mutex_unlock(&sbi->s_lock); 275 268 } 276 269 ··· 286 301 struct inode *inode = dentry->d_inode; 287 302 unsigned int ia_valid; 288 303 int error; 304 + 305 + if (unlikely(exfat_forced_shutdown(inode->i_sb))) 306 + return -EIO; 289 307 290 308 if ((attr->ia_valid & ATTR_SIZE) && 291 309 attr->ia_size > i_size_read(inode)) { ··· 473 485 return 0; 474 486 } 475 487 488 + static int exfat_ioctl_shutdown(struct super_block *sb, unsigned long arg) 489 + { 490 + u32 flags; 491 + 492 + if (!capable(CAP_SYS_ADMIN)) 493 + return -EPERM; 494 + 495 + if (get_user(flags, (__u32 __user *)arg)) 496 + return -EFAULT; 497 + 498 + return exfat_force_shutdown(sb, flags); 499 + } 500 + 476 501 long exfat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 477 502 { 478 503 struct inode *inode = file_inode(filp); ··· 496 495 return exfat_ioctl_get_attributes(inode, user_attr); 497 496 case FAT_IOCTL_SET_ATTRIBUTES: 498 497 return exfat_ioctl_set_attributes(filp, user_attr); 498 + case EXFAT_IOC_SHUTDOWN: 499 + return exfat_ioctl_shutdown(inode->i_sb, arg); 499 500 case FITRIM: 500 501 return exfat_ioctl_fitrim(inode, arg); 501 502 default: ··· 518 515 struct inode *inode = filp->f_mapping->host; 519 516 int err; 520 517 518 + if (unlikely(exfat_forced_shutdown(inode->i_sb))) 519 + return -EIO; 520 + 521 521 err = __generic_file_fsync(filp, start, end, datasync); 522 522 if (err) 523 523 return err; ··· 532 526 return blkdev_issue_flush(inode->i_sb->s_bdev); 533 527 } 534 528 535 - static int exfat_file_zeroed_range(struct file *file, loff_t start, loff_t end) 529 + static int exfat_extend_valid_size(struct file *file, loff_t new_valid_size) 536 530 { 537 531 int err; 532 + loff_t pos; 538 533 struct inode *inode = file_inode(file); 534 + struct exfat_inode_info *ei = EXFAT_I(inode); 539 535 struct address_space *mapping = inode->i_mapping; 540 536 const struct address_space_operations *ops = mapping->a_ops; 541 537 542 - while (start < end) { 543 - u32 zerofrom, len; 538 + pos = ei->valid_size; 539 + while (pos < new_valid_size) { 540 + u32 len; 544 541 struct folio *folio; 545 542 546 - zerofrom = start & (PAGE_SIZE - 1); 547 - len = PAGE_SIZE - zerofrom; 548 - if (start + len > end) 549 - len = end - start; 543 + len = PAGE_SIZE - (pos & (PAGE_SIZE - 1)); 544 + if (pos + len > new_valid_size) 545 + len = new_valid_size - pos; 550 546 551 - err = ops->write_begin(file, mapping, start, len, &folio, NULL); 547 + err = ops->write_begin(file, mapping, pos, len, &folio, NULL); 552 548 if (err) 553 549 goto out; 554 550 555 - folio_zero_range(folio, offset_in_folio(folio, start), len); 556 - 557 - err = ops->write_end(file, mapping, start, len, len, folio, NULL); 551 + err = ops->write_end(file, mapping, pos, len, len, folio, NULL); 558 552 if (err < 0) 559 553 goto out; 560 - start += len; 554 + pos += len; 561 555 562 556 balance_dirty_pages_ratelimited(mapping); 563 557 cond_resched(); ··· 585 579 goto unlock; 586 580 587 581 if (pos > valid_size) { 588 - ret = exfat_file_zeroed_range(file, valid_size, pos); 582 + ret = exfat_extend_valid_size(file, pos); 589 583 if (ret < 0 && ret != -ENOSPC) { 590 584 exfat_err(inode->i_sb, 591 585 "write: fail to zero from %llu to %llu(%zd)", ··· 619 613 return ret; 620 614 } 621 615 622 - static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma) 616 + static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf) 623 617 { 624 - int ret; 618 + int err; 619 + struct vm_area_struct *vma = vmf->vma; 620 + struct file *file = vma->vm_file; 625 621 struct inode *inode = file_inode(file); 626 622 struct exfat_inode_info *ei = EXFAT_I(inode); 627 - loff_t start = ((loff_t)vma->vm_pgoff << PAGE_SHIFT); 628 - loff_t end = min_t(loff_t, i_size_read(inode), 623 + loff_t start, end; 624 + 625 + if (!inode_trylock(inode)) 626 + return VM_FAULT_RETRY; 627 + 628 + start = ((loff_t)vma->vm_pgoff << PAGE_SHIFT); 629 + end = min_t(loff_t, i_size_read(inode), 629 630 start + vma->vm_end - vma->vm_start); 630 631 631 - if ((vma->vm_flags & VM_WRITE) && ei->valid_size < end) { 632 - ret = exfat_file_zeroed_range(file, ei->valid_size, end); 633 - if (ret < 0) { 634 - exfat_err(inode->i_sb, 635 - "mmap: fail to zero from %llu to %llu(%d)", 636 - start, end, ret); 637 - return ret; 632 + if (ei->valid_size < end) { 633 + err = exfat_extend_valid_size(file, end); 634 + if (err < 0) { 635 + inode_unlock(inode); 636 + return vmf_fs_error(err); 638 637 } 639 638 } 640 639 641 - return generic_file_mmap(file, vma); 640 + inode_unlock(inode); 641 + 642 + return filemap_page_mkwrite(vmf); 643 + } 644 + 645 + static const struct vm_operations_struct exfat_file_vm_ops = { 646 + .fault = filemap_fault, 647 + .map_pages = filemap_map_pages, 648 + .page_mkwrite = exfat_page_mkwrite, 649 + }; 650 + 651 + static int exfat_file_mmap(struct file *file, struct vm_area_struct *vma) 652 + { 653 + file_accessed(file); 654 + vma->vm_ops = &exfat_file_vm_ops; 655 + return 0; 642 656 } 643 657 644 658 const struct file_operations exfat_file_operations = {
+26 -68
fs/exfat/inode.c
··· 102 102 { 103 103 int ret; 104 104 105 + if (unlikely(exfat_forced_shutdown(inode->i_sb))) 106 + return -EIO; 107 + 105 108 mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock); 106 109 ret = __exfat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 107 110 mutex_unlock(&EXFAT_SB(inode->i_sb)->s_lock); ··· 133 130 struct exfat_sb_info *sbi = EXFAT_SB(sb); 134 131 struct exfat_inode_info *ei = EXFAT_I(inode); 135 132 unsigned int local_clu_offset = clu_offset; 136 - unsigned int num_to_be_allocated = 0, num_clusters = 0; 133 + unsigned int num_to_be_allocated = 0, num_clusters; 137 134 138 - if (ei->i_size_ondisk > 0) 139 - num_clusters = 140 - EXFAT_B_TO_CLU_ROUND_UP(ei->i_size_ondisk, sbi); 135 + num_clusters = EXFAT_B_TO_CLU(exfat_ondisk_size(inode), sbi); 141 136 142 137 if (clu_offset >= num_clusters) 143 138 num_to_be_allocated = clu_offset - num_clusters + 1; ··· 261 260 return 0; 262 261 } 263 262 264 - static int exfat_map_new_buffer(struct exfat_inode_info *ei, 265 - struct buffer_head *bh, loff_t pos) 266 - { 267 - if (buffer_delay(bh) && pos > ei->i_size_aligned) 268 - return -EIO; 269 - set_buffer_new(bh); 270 - 271 - /* 272 - * Adjust i_size_aligned if i_size_ondisk is bigger than it. 273 - */ 274 - if (ei->i_size_ondisk > ei->i_size_aligned) 275 - ei->i_size_aligned = ei->i_size_ondisk; 276 - return 0; 277 - } 278 - 279 263 static int exfat_get_block(struct inode *inode, sector_t iblock, 280 264 struct buffer_head *bh_result, int create) 281 265 { ··· 274 288 sector_t last_block; 275 289 sector_t phys = 0; 276 290 sector_t valid_blks; 277 - loff_t pos; 278 291 279 292 mutex_lock(&sbi->s_lock); 280 293 last_block = EXFAT_B_TO_BLK_ROUND_UP(i_size_read(inode), sb); ··· 301 316 mapped_blocks = sbi->sect_per_clus - sec_offset; 302 317 max_blocks = min(mapped_blocks, max_blocks); 303 318 304 - pos = EXFAT_BLK_TO_B((iblock + 1), sb); 305 - if ((create && iblock >= last_block) || buffer_delay(bh_result)) { 306 - if (ei->i_size_ondisk < pos) 307 - ei->i_size_ondisk = pos; 308 - } 309 - 310 319 map_bh(bh_result, sb, phys); 311 320 if (buffer_delay(bh_result)) 312 321 clear_buffer_delay(bh_result); ··· 321 342 } 322 343 323 344 /* The area has not been written, map and mark as new. */ 324 - err = exfat_map_new_buffer(ei, bh_result, pos); 325 - if (err) { 326 - exfat_fs_error(sb, 327 - "requested for bmap out of range(pos : (%llu) > i_size_aligned(%llu)\n", 328 - pos, ei->i_size_aligned); 329 - goto unlock_ret; 330 - } 345 + set_buffer_new(bh_result); 331 346 332 347 ei->valid_size = EXFAT_BLK_TO_B(iblock + max_blocks, sb); 333 348 mark_inode_dirty(inode); ··· 344 371 * The block has been partially written, 345 372 * zero the unwritten part and map the block. 346 373 */ 347 - loff_t size, off; 374 + loff_t size, off, pos; 348 375 349 376 max_blocks = 1; 350 377 ··· 355 382 if (!bh_result->b_folio) 356 383 goto done; 357 384 358 - pos -= sb->s_blocksize; 385 + pos = EXFAT_BLK_TO_B(iblock, sb); 359 386 size = ei->valid_size - pos; 360 387 off = pos & (PAGE_SIZE - 1); 361 388 ··· 405 432 static int exfat_writepages(struct address_space *mapping, 406 433 struct writeback_control *wbc) 407 434 { 435 + if (unlikely(exfat_forced_shutdown(mapping->host->i_sb))) 436 + return -EIO; 437 + 408 438 return mpage_writepages(mapping, wbc, exfat_get_block); 409 439 } 410 440 ··· 428 452 { 429 453 int ret; 430 454 455 + if (unlikely(exfat_forced_shutdown(mapping->host->i_sb))) 456 + return -EIO; 457 + 431 458 ret = block_write_begin(mapping, pos, len, foliop, exfat_get_block); 432 459 433 460 if (ret < 0) ··· 448 469 int err; 449 470 450 471 err = generic_write_end(file, mapping, pos, len, copied, folio, fsdata); 451 - 452 - if (ei->i_size_aligned < i_size_read(inode)) { 453 - exfat_fs_error(inode->i_sb, 454 - "invalid size(size(%llu) > aligned(%llu)\n", 455 - i_size_read(inode), ei->i_size_aligned); 456 - return -EIO; 457 - } 458 - 459 472 if (err < len) 460 473 exfat_write_failed(mapping, pos+len); 461 474 ··· 475 504 int rw = iov_iter_rw(iter); 476 505 ssize_t ret; 477 506 478 - if (rw == WRITE) { 479 - /* 480 - * FIXME: blockdev_direct_IO() doesn't use ->write_begin(), 481 - * so we need to update the ->i_size_aligned to block boundary. 482 - * 483 - * But we must fill the remaining area or hole by nul for 484 - * updating ->i_size_aligned 485 - * 486 - * Return 0, and fallback to normal buffered write. 487 - */ 488 - if (EXFAT_I(inode)->i_size_aligned < size) 489 - return 0; 490 - } 491 - 492 507 /* 493 508 * Need to use the DIO_LOCKING for avoiding the race 494 509 * condition of exfat_get_block() and ->truncate(). ··· 488 531 } else 489 532 size = pos + ret; 490 533 491 - /* zero the unwritten part in the partially written block */ 492 - if (rw == READ && pos < ei->valid_size && ei->valid_size < size) { 534 + if (rw == WRITE) { 535 + /* 536 + * If the block had been partially written before this write, 537 + * ->valid_size will not be updated in exfat_get_block(), 538 + * update it here. 539 + */ 540 + if (ei->valid_size < size) { 541 + ei->valid_size = size; 542 + mark_inode_dirty(inode); 543 + } 544 + } else if (pos < ei->valid_size && ei->valid_size < size) { 545 + /* zero the unwritten part in the partially written block */ 493 546 iov_iter_revert(iter, size - ei->valid_size); 494 547 iov_iter_zero(size - ei->valid_size, iter); 495 548 } ··· 633 666 } 634 667 635 668 i_size_write(inode, size); 636 - 637 - /* ondisk and aligned size should be aligned with block size */ 638 - if (size & (inode->i_sb->s_blocksize - 1)) { 639 - size |= (inode->i_sb->s_blocksize - 1); 640 - size++; 641 - } 642 - 643 - ei->i_size_aligned = size; 644 - ei->i_size_ondisk = size; 645 669 646 670 exfat_save_attr(inode, info->attr); 647 671
+15 -2
fs/exfat/namei.c
··· 372 372 373 373 /* directory inode should be updated in here */ 374 374 i_size_write(inode, size); 375 - ei->i_size_ondisk += sbi->cluster_size; 376 - ei->i_size_aligned += sbi->cluster_size; 377 375 ei->valid_size += sbi->cluster_size; 378 376 ei->flags = p_dir->flags; 379 377 inode->i_blocks += sbi->cluster_size >> 9; ··· 546 548 loff_t i_pos; 547 549 int err; 548 550 loff_t size = i_size_read(dir); 551 + 552 + if (unlikely(exfat_forced_shutdown(sb))) 553 + return -EIO; 549 554 550 555 mutex_lock(&EXFAT_SB(sb)->s_lock); 551 556 exfat_set_volume_dirty(sb); ··· 773 772 struct exfat_entry_set_cache es; 774 773 int entry, err = 0; 775 774 775 + if (unlikely(exfat_forced_shutdown(sb))) 776 + return -EIO; 777 + 776 778 mutex_lock(&EXFAT_SB(sb)->s_lock); 777 779 exfat_chain_dup(&cdir, &ei->dir); 778 780 entry = ei->entry; ··· 828 824 loff_t i_pos; 829 825 int err; 830 826 loff_t size = i_size_read(dir); 827 + 828 + if (unlikely(exfat_forced_shutdown(sb))) 829 + return -EIO; 831 830 832 831 mutex_lock(&EXFAT_SB(sb)->s_lock); 833 832 exfat_set_volume_dirty(sb); ··· 922 915 struct exfat_entry_set_cache es; 923 916 int entry, err; 924 917 918 + if (unlikely(exfat_forced_shutdown(sb))) 919 + return -EIO; 920 + 925 921 mutex_lock(&EXFAT_SB(inode->i_sb)->s_lock); 926 922 927 923 exfat_chain_dup(&cdir, &ei->dir); ··· 991 981 struct super_block *sb = inode->i_sb; 992 982 struct exfat_entry_set_cache old_es, new_es; 993 983 int sync = IS_DIRSYNC(inode); 984 + 985 + if (unlikely(exfat_forced_shutdown(sb))) 986 + return -EIO; 994 987 995 988 num_new_entries = exfat_calc_num_entries(p_uniname); 996 989 if (num_new_entries < 0)
+4 -1
fs/exfat/nls.c
··· 779 779 le32_to_cpu(ep->dentry.upcase.checksum)); 780 780 781 781 brelse(bh); 782 - if (ret && ret != -EIO) 782 + if (ret && ret != -EIO) { 783 + /* free memory from exfat_load_upcase_table call */ 784 + exfat_free_upcase_table(sbi); 783 785 goto load_default; 786 + } 784 787 785 788 /* load successfully */ 786 789 return ret;
+39 -2
fs/exfat/super.c
··· 46 46 struct exfat_sb_info *sbi = EXFAT_SB(sb); 47 47 int err = 0; 48 48 49 + if (unlikely(exfat_forced_shutdown(sb))) 50 + return 0; 51 + 49 52 if (!wait) 50 53 return 0; 51 54 ··· 170 167 return 0; 171 168 } 172 169 170 + int exfat_force_shutdown(struct super_block *sb, u32 flags) 171 + { 172 + int ret; 173 + struct exfat_sb_info *sbi = sb->s_fs_info; 174 + struct exfat_mount_options *opts = &sbi->options; 175 + 176 + if (exfat_forced_shutdown(sb)) 177 + return 0; 178 + 179 + switch (flags) { 180 + case EXFAT_GOING_DOWN_DEFAULT: 181 + case EXFAT_GOING_DOWN_FULLSYNC: 182 + ret = bdev_freeze(sb->s_bdev); 183 + if (ret) 184 + return ret; 185 + bdev_thaw(sb->s_bdev); 186 + set_bit(EXFAT_FLAGS_SHUTDOWN, &sbi->s_exfat_flags); 187 + break; 188 + case EXFAT_GOING_DOWN_NOSYNC: 189 + set_bit(EXFAT_FLAGS_SHUTDOWN, &sbi->s_exfat_flags); 190 + break; 191 + default: 192 + return -EINVAL; 193 + } 194 + 195 + if (opts->discard) 196 + opts->discard = 0; 197 + return 0; 198 + } 199 + 200 + static void exfat_shutdown(struct super_block *sb) 201 + { 202 + exfat_force_shutdown(sb, EXFAT_GOING_DOWN_NOSYNC); 203 + } 204 + 173 205 static struct inode *exfat_alloc_inode(struct super_block *sb) 174 206 { 175 207 struct exfat_inode_info *ei; ··· 231 193 .sync_fs = exfat_sync_fs, 232 194 .statfs = exfat_statfs, 233 195 .show_options = exfat_show_options, 196 + .shutdown = exfat_shutdown, 234 197 }; 235 198 236 199 enum { ··· 409 370 410 371 inode->i_blocks = round_up(i_size_read(inode), sbi->cluster_size) >> 9; 411 372 ei->i_pos = ((loff_t)sbi->root_dir << 32) | 0xffffffff; 412 - ei->i_size_aligned = i_size_read(inode); 413 - ei->i_size_ondisk = i_size_read(inode); 414 373 415 374 exfat_save_attr(inode, EXFAT_ATTR_SUBDIR); 416 375 ei->i_crtime = simple_inode_init_ts(inode);
+25
include/uapi/linux/exfat.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* 3 + * Copyright (C) 2024 Unisoc Technologies Co., Ltd. 4 + */ 5 + 6 + #ifndef _UAPI_LINUX_EXFAT_H 7 + #define _UAPI_LINUX_EXFAT_H 8 + #include <linux/types.h> 9 + #include <linux/ioctl.h> 10 + 11 + /* 12 + * exfat-specific ioctl commands 13 + */ 14 + 15 + #define EXFAT_IOC_SHUTDOWN _IOR('X', 125, __u32) 16 + 17 + /* 18 + * Flags used by EXFAT_IOC_SHUTDOWN 19 + */ 20 + 21 + #define EXFAT_GOING_DOWN_DEFAULT 0x0 /* default with full sync */ 22 + #define EXFAT_GOING_DOWN_FULLSYNC 0x1 /* going down with full sync*/ 23 + #define EXFAT_GOING_DOWN_NOSYNC 0x2 /* going down */ 24 + 25 + #endif /* _UAPI_LINUX_EXFAT_H */