@@ -94,6 +94,7 @@ struct nfs_direct_req {
94
94
#define NFS_ODIRECT_RESCHED_WRITES (2) /* write verification failed */
95
95
/* for read */
96
96
#define NFS_ODIRECT_SHOULD_DIRTY (3) /* dirty user-space page after read */
97
+ #define NFS_ODIRECT_DONE INT_MAX /* write verification failed */
97
98
struct nfs_writeverf verf ; /* unstable write verifier */
98
99
};
99
100
@@ -678,8 +679,17 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
678
679
struct nfs_page * req ;
679
680
int status = data -> task .tk_status ;
680
681
682
+ if (status < 0 ) {
683
+ /* Errors in commit are fatal */
684
+ dreq -> error = status ;
685
+ dreq -> max_count = 0 ;
686
+ dreq -> count = 0 ;
687
+ dreq -> flags = NFS_ODIRECT_DONE ;
688
+ } else if (dreq -> flags == NFS_ODIRECT_DONE )
689
+ status = dreq -> error ;
690
+
681
691
nfs_init_cinfo_from_dreq (& cinfo , dreq );
682
- if (status < 0 || nfs_direct_cmp_commit_data_verf (dreq , data ))
692
+ if (nfs_direct_cmp_commit_data_verf (dreq , data ))
683
693
dreq -> flags = NFS_ODIRECT_RESCHED_WRITES ;
684
694
685
695
while (!list_empty (& data -> pages )) {
@@ -708,7 +718,8 @@ static void nfs_direct_resched_write(struct nfs_commit_info *cinfo,
708
718
struct nfs_direct_req * dreq = cinfo -> dreq ;
709
719
710
720
spin_lock (& dreq -> lock );
711
- dreq -> flags = NFS_ODIRECT_RESCHED_WRITES ;
721
+ if (dreq -> flags != NFS_ODIRECT_DONE )
722
+ dreq -> flags = NFS_ODIRECT_RESCHED_WRITES ;
712
723
spin_unlock (& dreq -> lock );
713
724
nfs_mark_request_commit (req , NULL , cinfo , 0 );
714
725
}
@@ -731,6 +742,22 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
731
742
nfs_direct_write_reschedule (dreq );
732
743
}
733
744
745
+ static void nfs_direct_write_clear_reqs (struct nfs_direct_req * dreq )
746
+ {
747
+ struct nfs_commit_info cinfo ;
748
+ struct nfs_page * req ;
749
+ LIST_HEAD (reqs );
750
+
751
+ nfs_init_cinfo_from_dreq (& cinfo , dreq );
752
+ nfs_direct_write_scan_commit_list (dreq -> inode , & reqs , & cinfo );
753
+
754
+ while (!list_empty (& reqs )) {
755
+ req = nfs_list_entry (reqs .next );
756
+ nfs_list_remove_request (req );
757
+ nfs_unlock_and_release_request (req );
758
+ }
759
+ }
760
+
734
761
static void nfs_direct_write_schedule_work (struct work_struct * work )
735
762
{
736
763
struct nfs_direct_req * dreq = container_of (work , struct nfs_direct_req , work );
@@ -745,6 +772,7 @@ static void nfs_direct_write_schedule_work(struct work_struct *work)
745
772
nfs_direct_write_reschedule (dreq );
746
773
break ;
747
774
default :
775
+ nfs_direct_write_clear_reqs (dreq );
748
776
nfs_zap_mapping (dreq -> inode , dreq -> inode -> i_mapping );
749
777
nfs_direct_complete (dreq );
750
778
}
0 commit comments