aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/direct.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r--fs/nfs/direct.c33
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
120void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq)
121{
122 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
123}
124EXPORT_SYMBOL_GPL(nfs_direct_set_resched_writes);
125
126static void 120static void
127nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) 121nfs_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
738static void nfs_direct_error_cleanup(struct nfs_inode *nfsi) 732static 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
743static const struct nfs_commit_completion_ops nfs_direct_commit_completion_ops = { 743static 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
748static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) 748static 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
850static 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
850static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { 864static 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