@@ -29,7 +29,7 @@ static int exfat_cont_expand(struct inode *inode, loff_t size)
2929 if (ret )
3030 return ret ;
3131
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 );
3333 new_num_clusters = EXFAT_B_TO_CLU_ROUND_UP (size , sbi );
3434
3535 if (new_num_clusters == num_clusters )
@@ -74,8 +74,6 @@ static int exfat_cont_expand(struct inode *inode, loff_t size)
7474 /* Expanded range not zeroed, do not update valid_size */
7575 i_size_write (inode , size );
7676
77- ei -> i_size_aligned = round_up (size , sb -> s_blocksize );
78- ei -> i_size_ondisk = ei -> i_size_aligned ;
7977 inode -> i_blocks = round_up (size , sbi -> cluster_size ) >> 9 ;
8078 mark_inode_dirty (inode );
8179
@@ -159,7 +157,7 @@ int __exfat_truncate(struct inode *inode)
159157 exfat_set_volume_dirty (sb );
160158
161159 num_clusters_new = EXFAT_B_TO_CLU_ROUND_UP (i_size_read (inode ), sbi );
162- num_clusters_phys = EXFAT_B_TO_CLU_ROUND_UP ( ei -> i_size_ondisk , sbi );
160+ num_clusters_phys = EXFAT_B_TO_CLU ( exfat_ondisk_size ( inode ) , sbi );
163161
164162 exfat_chain_set (& clu , ei -> start_clu , num_clusters_phys , ei -> flags );
165163
@@ -245,8 +243,6 @@ void exfat_truncate(struct inode *inode)
245243 struct super_block * sb = inode -> i_sb ;
246244 struct exfat_sb_info * sbi = EXFAT_SB (sb );
247245 struct exfat_inode_info * ei = EXFAT_I (inode );
248- unsigned int blocksize = i_blocksize (inode );
249- loff_t aligned_size ;
250246 int err ;
251247
252248 mutex_lock (& sbi -> s_lock );
@@ -264,17 +260,6 @@ void exfat_truncate(struct inode *inode)
264260
265261 inode -> i_blocks = round_up (i_size_read (inode ), sbi -> cluster_size ) >> 9 ;
266262write_size :
267- aligned_size = i_size_read (inode );
268- if (aligned_size & (blocksize - 1 )) {
269- aligned_size |= (blocksize - 1 );
270- aligned_size ++ ;
271- }
272-
273- if (ei -> i_size_ondisk > i_size_read (inode ))
274- ei -> i_size_ondisk = aligned_size ;
275-
276- if (ei -> i_size_aligned > i_size_read (inode ))
277- ei -> i_size_aligned = aligned_size ;
278263 mutex_unlock (& sbi -> s_lock );
279264}
280265
@@ -302,6 +287,9 @@ int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
302287 unsigned int ia_valid ;
303288 int error ;
304289
290+ if (unlikely (exfat_forced_shutdown (inode -> i_sb )))
291+ return - EIO ;
292+
305293 if ((attr -> ia_valid & ATTR_SIZE ) &&
306294 attr -> ia_size > i_size_read (inode )) {
307295 error = exfat_cont_expand (inode , attr -> ia_size );
@@ -485,6 +473,19 @@ static int exfat_ioctl_fitrim(struct inode *inode, unsigned long arg)
485473 return 0 ;
486474}
487475
476+ static int exfat_ioctl_shutdown (struct super_block * sb , unsigned long arg )
477+ {
478+ u32 flags ;
479+
480+ if (!capable (CAP_SYS_ADMIN ))
481+ return - EPERM ;
482+
483+ if (get_user (flags , (__u32 __user * )arg ))
484+ return - EFAULT ;
485+
486+ return exfat_force_shutdown (sb , flags );
487+ }
488+
488489long exfat_ioctl (struct file * filp , unsigned int cmd , unsigned long arg )
489490{
490491 struct inode * inode = file_inode (filp );
@@ -495,6 +496,8 @@ long exfat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
495496 return exfat_ioctl_get_attributes (inode , user_attr );
496497 case FAT_IOCTL_SET_ATTRIBUTES :
497498 return exfat_ioctl_set_attributes (filp , user_attr );
499+ case EXFAT_IOC_SHUTDOWN :
500+ return exfat_ioctl_shutdown (inode -> i_sb , arg );
498501 case FITRIM :
499502 return exfat_ioctl_fitrim (inode , arg );
500503 default :
@@ -515,6 +518,9 @@ int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
515518 struct inode * inode = filp -> f_mapping -> host ;
516519 int err ;
517520
521+ if (unlikely (exfat_forced_shutdown (inode -> i_sb )))
522+ return - EIO ;
523+
518524 err = __generic_file_fsync (filp , start , end , datasync );
519525 if (err )
520526 return err ;
@@ -526,32 +532,32 @@ int exfat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
526532 return blkdev_issue_flush (inode -> i_sb -> s_bdev );
527533}
528534
529- static int exfat_file_zeroed_range (struct file * file , loff_t start , loff_t end )
535+ static int exfat_extend_valid_size (struct file * file , loff_t new_valid_size )
530536{
531537 int err ;
538+ loff_t pos ;
532539 struct inode * inode = file_inode (file );
540+ struct exfat_inode_info * ei = EXFAT_I (inode );
533541 struct address_space * mapping = inode -> i_mapping ;
534542 const struct address_space_operations * ops = mapping -> a_ops ;
535543
536- while (start < end ) {
537- u32 zerofrom , len ;
544+ pos = ei -> valid_size ;
545+ while (pos < new_valid_size ) {
546+ u32 len ;
538547 struct folio * folio ;
539548
540- zerofrom = start & (PAGE_SIZE - 1 );
541- len = PAGE_SIZE - zerofrom ;
542- if (start + len > end )
543- len = end - start ;
549+ len = PAGE_SIZE - (pos & (PAGE_SIZE - 1 ));
550+ if (pos + len > new_valid_size )
551+ len = new_valid_size - pos ;
544552
545- err = ops -> write_begin (file , mapping , start , len , & folio , NULL );
553+ err = ops -> write_begin (file , mapping , pos , len , & folio , NULL );
546554 if (err )
547555 goto out ;
548556
549- folio_zero_range (folio , offset_in_folio (folio , start ), len );
550-
551- err = ops -> write_end (file , mapping , start , len , len , folio , NULL );
557+ err = ops -> write_end (file , mapping , pos , len , len , folio , NULL );
552558 if (err < 0 )
553559 goto out ;
554- start += len ;
560+ pos += len ;
555561
556562 balance_dirty_pages_ratelimited (mapping );
557563 cond_resched ();
@@ -579,7 +585,7 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
579585 goto unlock ;
580586
581587 if (pos > valid_size ) {
582- ret = exfat_file_zeroed_range (file , valid_size , pos );
588+ ret = exfat_extend_valid_size (file , pos );
583589 if (ret < 0 && ret != - ENOSPC ) {
584590 exfat_err (inode -> i_sb ,
585591 "write: fail to zero from %llu to %llu(%zd)" ,
@@ -613,26 +619,46 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
613619 return ret ;
614620}
615621
616- static int exfat_file_mmap (struct file * file , struct vm_area_struct * vma )
622+ static vm_fault_t exfat_page_mkwrite (struct vm_fault * vmf )
617623{
618- int ret ;
624+ int err ;
625+ struct vm_area_struct * vma = vmf -> vma ;
626+ struct file * file = vma -> vm_file ;
619627 struct inode * inode = file_inode (file );
620628 struct exfat_inode_info * ei = EXFAT_I (inode );
621- loff_t start = ((loff_t )vma -> vm_pgoff << PAGE_SHIFT );
622- loff_t end = min_t (loff_t , i_size_read (inode ),
629+ loff_t start , end ;
630+
631+ if (!inode_trylock (inode ))
632+ return VM_FAULT_RETRY ;
633+
634+ start = ((loff_t )vma -> vm_pgoff << PAGE_SHIFT );
635+ end = min_t (loff_t , i_size_read (inode ),
623636 start + vma -> vm_end - vma -> vm_start );
624637
625- if ((vma -> vm_flags & VM_WRITE ) && ei -> valid_size < end ) {
626- ret = exfat_file_zeroed_range (file , ei -> valid_size , end );
627- if (ret < 0 ) {
628- exfat_err (inode -> i_sb ,
629- "mmap: fail to zero from %llu to %llu(%d)" ,
630- start , end , ret );
631- return ret ;
638+ if (ei -> valid_size < end ) {
639+ err = exfat_extend_valid_size (file , end );
640+ if (err < 0 ) {
641+ inode_unlock (inode );
642+ return vmf_fs_error (err );
632643 }
633644 }
634645
635- return generic_file_mmap (file , vma );
646+ inode_unlock (inode );
647+
648+ return filemap_page_mkwrite (vmf );
649+ }
650+
651+ static const struct vm_operations_struct exfat_file_vm_ops = {
652+ .fault = filemap_fault ,
653+ .map_pages = filemap_map_pages ,
654+ .page_mkwrite = exfat_page_mkwrite ,
655+ };
656+
657+ static int exfat_file_mmap (struct file * file , struct vm_area_struct * vma )
658+ {
659+ file_accessed (file );
660+ vma -> vm_ops = & exfat_file_vm_ops ;
661+ return 0 ;
636662}
637663
638664const struct file_operations exfat_file_operations = {
0 commit comments