@@ -522,10 +522,11 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
522522{
523523 struct file * src = nf_src -> nf_file ;
524524 struct file * dst = nf_dst -> nf_file ;
525+ errseq_t since ;
525526 loff_t cloned ;
526527 __be32 ret = 0 ;
527528
528- down_write ( & nf_dst -> nf_rwsem );
529+ since = READ_ONCE ( dst -> f_wb_err );
529530 cloned = vfs_clone_file_range (src , src_pos , dst , dst_pos , count , 0 );
530531 if (cloned < 0 ) {
531532 ret = nfserrno (cloned );
@@ -539,6 +540,8 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
539540 loff_t dst_end = count ? dst_pos + count - 1 : LLONG_MAX ;
540541 int status = vfs_fsync_range (dst , dst_pos , dst_end , 0 );
541542
543+ if (!status )
544+ status = filemap_check_wb_err (dst -> f_mapping , since );
542545 if (!status )
543546 status = commit_inode_metadata (file_inode (src ));
544547 if (status < 0 ) {
@@ -548,7 +551,6 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
548551 }
549552 }
550553out_err :
551- up_write (& nf_dst -> nf_rwsem );
552554 return ret ;
553555}
554556
@@ -956,6 +958,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
956958 struct super_block * sb = file_inode (file )-> i_sb ;
957959 struct svc_export * exp ;
958960 struct iov_iter iter ;
961+ errseq_t since ;
959962 __be32 nfserr ;
960963 int host_err ;
961964 int use_wgather ;
@@ -993,8 +996,8 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
993996 flags |= RWF_SYNC ;
994997
995998 iov_iter_kvec (& iter , WRITE , vec , vlen , * cnt );
999+ since = READ_ONCE (file -> f_wb_err );
9961000 if (flags & RWF_SYNC ) {
997- down_write (& nf -> nf_rwsem );
9981001 if (verf )
9991002 nfsd_copy_boot_verifier (verf ,
10001003 net_generic (SVC_NET (rqstp ),
@@ -1003,15 +1006,12 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
10031006 if (host_err < 0 )
10041007 nfsd_reset_boot_verifier (net_generic (SVC_NET (rqstp ),
10051008 nfsd_net_id ));
1006- up_write (& nf -> nf_rwsem );
10071009 } else {
1008- down_read (& nf -> nf_rwsem );
10091010 if (verf )
10101011 nfsd_copy_boot_verifier (verf ,
10111012 net_generic (SVC_NET (rqstp ),
10121013 nfsd_net_id ));
10131014 host_err = vfs_iter_write (file , & iter , & pos , flags );
1014- up_read (& nf -> nf_rwsem );
10151015 }
10161016 if (host_err < 0 ) {
10171017 nfsd_reset_boot_verifier (net_generic (SVC_NET (rqstp ),
@@ -1021,6 +1021,9 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
10211021 * cnt = host_err ;
10221022 nfsd_stats_io_write_add (exp , * cnt );
10231023 fsnotify_modify (file );
1024+ host_err = filemap_check_wb_err (file -> f_mapping , since );
1025+ if (host_err < 0 )
1026+ goto out_nfserr ;
10241027
10251028 if (stable && use_wgather ) {
10261029 host_err = wait_for_concurrent_writes (file );
@@ -1101,19 +1104,6 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
11011104}
11021105
11031106#ifdef CONFIG_NFSD_V3
1104- static int
1105- nfsd_filemap_write_and_wait_range (struct nfsd_file * nf , loff_t offset ,
1106- loff_t end )
1107- {
1108- struct address_space * mapping = nf -> nf_file -> f_mapping ;
1109- int ret = filemap_fdatawrite_range (mapping , offset , end );
1110-
1111- if (ret )
1112- return ret ;
1113- filemap_fdatawait_range_keep_errors (mapping , offset , end );
1114- return 0 ;
1115- }
1116-
11171107/*
11181108 * Commit all pending writes to stable storage.
11191109 *
@@ -1144,25 +1134,25 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
11441134 if (err )
11451135 goto out ;
11461136 if (EX_ISSYNC (fhp -> fh_export )) {
1147- int err2 = nfsd_filemap_write_and_wait_range (nf , offset , end );
1137+ errseq_t since = READ_ONCE (nf -> nf_file -> f_wb_err );
1138+ int err2 ;
11481139
1149- down_write (& nf -> nf_rwsem );
1150- if (!err2 )
1151- err2 = vfs_fsync_range (nf -> nf_file , offset , end , 0 );
1140+ err2 = vfs_fsync_range (nf -> nf_file , offset , end , 0 );
11521141 switch (err2 ) {
11531142 case 0 :
11541143 nfsd_copy_boot_verifier (verf , net_generic (nf -> nf_net ,
11551144 nfsd_net_id ));
1145+ err2 = filemap_check_wb_err (nf -> nf_file -> f_mapping ,
1146+ since );
11561147 break ;
11571148 case - EINVAL :
11581149 err = nfserr_notsupp ;
11591150 break ;
11601151 default :
1161- err = nfserrno (err2 );
11621152 nfsd_reset_boot_verifier (net_generic (nf -> nf_net ,
11631153 nfsd_net_id ));
11641154 }
1165- up_write ( & nf -> nf_rwsem );
1155+ err = nfserrno ( err2 );
11661156 } else
11671157 nfsd_copy_boot_verifier (verf , net_generic (nf -> nf_net ,
11681158 nfsd_net_id ));
0 commit comments