aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/direct.c21
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c13
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/write.c6
-rw-r--r--include/linux/nfs_xdr.h1
5 files changed, 23 insertions, 19 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 4b1d08f56aba..e73693f75dee 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{
@@ -839,10 +833,25 @@ static void nfs_write_sync_pgio_error(struct list_head *head)
839 } 833 }
840} 834}
841 835
836static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr)
837{
838 struct nfs_direct_req *dreq = hdr->dreq;
839
840 spin_lock(&dreq->lock);
841 if (dreq->error == 0) {
842 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
843 /* fake unstable write to let common nfs resend pages */
844 hdr->verf.committed = NFS_UNSTABLE;
845 hdr->good_bytes = hdr->args.count;
846 }
847 spin_unlock(&dreq->lock);
848}
849
842static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { 850static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = {
843 .error_cleanup = nfs_write_sync_pgio_error, 851 .error_cleanup = nfs_write_sync_pgio_error,
844 .init_hdr = nfs_direct_pgio_init, 852 .init_hdr = nfs_direct_pgio_init,
845 .completion = nfs_direct_write_completion, 853 .completion = nfs_direct_write_completion,
854 .reschedule_io = nfs_direct_write_reschedule_io,
846}; 855};
847 856
848 857
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 03516c80855a..df475d42df77 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -912,18 +912,7 @@ static void ff_layout_reset_write(struct nfs_pgio_header *hdr, bool retry_pnfs)
912 hdr->args.count, 912 hdr->args.count,
913 (unsigned long long)hdr->args.offset); 913 (unsigned long long)hdr->args.offset);
914 914
915 if (!hdr->dreq) { 915 hdr->completion_ops->reschedule_io(hdr);
916 struct nfs_open_context *ctx;
917
918 ctx = nfs_list_entry(hdr->pages.next)->wb_context;
919 set_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
920 hdr->completion_ops->error_cleanup(&hdr->pages);
921 } else {
922 nfs_direct_set_resched_writes(hdr->dreq);
923 /* fake unstable write to let common nfs resend pages */
924 hdr->verf.committed = NFS_UNSTABLE;
925 hdr->good_bytes = hdr->args.count;
926 }
927 return; 916 return;
928 } 917 }
929 918
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 313d55402238..99a2919047e9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -519,7 +519,6 @@ static inline void nfs_inode_dio_wait(struct inode *inode)
519 inode_dio_wait(inode); 519 inode_dio_wait(inode);
520} 520}
521extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); 521extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
522extern void nfs_direct_set_resched_writes(struct nfs_direct_req *dreq);
523 522
524/* nfs4proc.c */ 523/* nfs4proc.c */
525extern void __nfs4_read_done_cb(struct nfs_pgio_header *); 524extern void __nfs4_read_done_cb(struct nfs_pgio_header *);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 7b9316406930..0aa3e6b3db70 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1326,9 +1326,15 @@ static void nfs_async_write_error(struct list_head *head)
1326 } 1326 }
1327} 1327}
1328 1328
1329static void nfs_async_write_reschedule_io(struct nfs_pgio_header *hdr)
1330{
1331 nfs_async_write_error(&hdr->pages);
1332}
1333
1329static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = { 1334static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops = {
1330 .error_cleanup = nfs_async_write_error, 1335 .error_cleanup = nfs_async_write_error,
1331 .completion = nfs_write_completion, 1336 .completion = nfs_write_completion,
1337 .reschedule_io = nfs_async_write_reschedule_io,
1332}; 1338};
1333 1339
1334void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio, 1340void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 11bbae44f4cb..e89dbb14138c 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1460,6 +1460,7 @@ struct nfs_pgio_completion_ops {
1460 void (*error_cleanup)(struct list_head *head); 1460 void (*error_cleanup)(struct list_head *head);
1461 void (*init_hdr)(struct nfs_pgio_header *hdr); 1461 void (*init_hdr)(struct nfs_pgio_header *hdr);
1462 void (*completion)(struct nfs_pgio_header *hdr); 1462 void (*completion)(struct nfs_pgio_header *hdr);
1463 void (*reschedule_io)(struct nfs_pgio_header *hdr);
1463}; 1464};
1464 1465
1465struct nfs_unlinkdata { 1466struct nfs_unlinkdata {