diff options
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r-- | fs/nfs/direct.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 2e7142bcb4c8..7ab7ec9f4eed 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -117,12 +117,6 @@ static inline int put_dreq(struct nfs_direct_req *dreq) | |||
117 | return atomic_dec_and_test(&dreq->io_count); | 117 | return atomic_dec_and_test(&dreq->io_count); |
118 | } | 118 | } |
119 | 119 | ||
120 | void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq) | ||
121 | { | ||
122 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(nfs_direct_set_resched_writes); | ||
125 | |||
126 | static void | 120 | static void |
127 | nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) | 121 | nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) |
128 | { | 122 | { |
@@ -735,14 +729,20 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) | |||
735 | nfs_direct_write_complete(dreq, data->inode); | 729 | nfs_direct_write_complete(dreq, data->inode); |
736 | } | 730 | } |
737 | 731 | ||
738 | static void nfs_direct_error_cleanup(struct nfs_inode *nfsi) | 732 | static void nfs_direct_resched_write(struct nfs_commit_info *cinfo, |
733 | struct nfs_page *req) | ||
739 | { | 734 | { |
740 | /* There is no lock to clear */ | 735 | struct nfs_direct_req *dreq = cinfo->dreq; |
736 | |||
737 | spin_lock(&dreq->lock); | ||
738 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; | ||
739 | spin_unlock(&dreq->lock); | ||
740 | nfs_mark_request_commit(req, NULL, cinfo, 0); | ||
741 | } | 741 | } |
742 | 742 | ||
743 | static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops = { | 743 | static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops = { |
744 | .completion = nfs_direct_commit_complete, | 744 | .completion = nfs_direct_commit_complete, |
745 | .error_cleanup = nfs_direct_error_cleanup, | 745 | .resched_write = nfs_direct_resched_write, |
746 | }; | 746 | }; |
747 | 747 | ||
748 | static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | 748 | static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) |
@@ -847,10 +847,25 @@ static void nfs_write_sync_pgio_error(struct list_head *head) | |||
847 | } | 847 | } |
848 | } | 848 | } |
849 | 849 | ||
850 | static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) | ||
851 | { | ||
852 | struct nfs_direct_req *dreq = hdr->dreq; | ||
853 | |||
854 | spin_lock(&dreq->lock); | ||
855 | if (dreq->error == 0) { | ||
856 | dreq->flags = NFS_ODIRECT_RESCHED_WRITES; | ||
857 | /* fake unstable write to let common nfs resend pages */ | ||
858 | hdr->verf.committed = NFS_UNSTABLE; | ||
859 | hdr->good_bytes = hdr->args.count; | ||
860 | } | ||
861 | spin_unlock(&dreq->lock); | ||
862 | } | ||
863 | |||
850 | static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { | 864 | static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { |
851 | .error_cleanup = nfs_write_sync_pgio_error, | 865 | .error_cleanup = nfs_write_sync_pgio_error, |
852 | .init_hdr = nfs_direct_pgio_init, | 866 | .init_hdr = nfs_direct_pgio_init, |
853 | .completion = nfs_direct_write_completion, | 867 | .completion = nfs_direct_write_completion, |
868 | .reschedule_io = nfs_direct_write_reschedule_io, | ||
854 | }; | 869 | }; |
855 | 870 | ||
856 | 871 | ||