aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r--fs/nfs/direct.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index e5da9d7fb69e..6a4083d550c6 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -288,8 +288,8 @@ ssize_t nfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
288 VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE); 288 VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE);
289 289
290 if (iov_iter_rw(iter) == READ) 290 if (iov_iter_rw(iter) == READ)
291 return nfs_file_direct_read(iocb, iter); 291 return nfs_file_direct_read(iocb, iter, true);
292 return nfs_file_direct_write(iocb, iter); 292 return nfs_file_direct_write(iocb, iter, true);
293} 293}
294 294
295static void nfs_direct_release_pages(struct page **pages, unsigned int npages) 295static void nfs_direct_release_pages(struct page **pages, unsigned int npages)
@@ -553,6 +553,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
553 * nfs_file_direct_read - file direct read operation for NFS files 553 * nfs_file_direct_read - file direct read operation for NFS files
554 * @iocb: target I/O control block 554 * @iocb: target I/O control block
555 * @iter: vector of user buffers into which to read data 555 * @iter: vector of user buffers into which to read data
556 * @swap: flag indicating this is swap IO, not O_DIRECT IO
556 * 557 *
557 * We use this function for direct reads instead of calling 558 * We use this function for direct reads instead of calling
558 * generic_file_aio_read() in order to avoid gfar's check to see if 559 * generic_file_aio_read() in order to avoid gfar's check to see if
@@ -568,7 +569,8 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
568 * client must read the updated atime from the server back into its 569 * client must read the updated atime from the server back into its
569 * cache. 570 * cache.
570 */ 571 */
571ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter) 572ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter,
573 bool swap)
572{ 574{
573 struct file *file = iocb->ki_filp; 575 struct file *file = iocb->ki_filp;
574 struct address_space *mapping = file->f_mapping; 576 struct address_space *mapping = file->f_mapping;
@@ -610,12 +612,14 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
610 if (iter_is_iovec(iter)) 612 if (iter_is_iovec(iter))
611 dreq->flags = NFS_ODIRECT_SHOULD_DIRTY; 613 dreq->flags = NFS_ODIRECT_SHOULD_DIRTY;
612 614
613 nfs_start_io_direct(inode); 615 if (!swap)
616 nfs_start_io_direct(inode);
614 617
615 NFS_I(inode)->read_io += count; 618 NFS_I(inode)->read_io += count;
616 requested = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos); 619 requested = nfs_direct_read_schedule_iovec(dreq, iter, iocb->ki_pos);
617 620
618 nfs_end_io_direct(inode); 621 if (!swap)
622 nfs_end_io_direct(inode);
619 623
620 if (requested > 0) { 624 if (requested > 0) {
621 result = nfs_direct_wait(dreq); 625 result = nfs_direct_wait(dreq);
@@ -884,7 +888,7 @@ static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = {
884 */ 888 */
885static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, 889static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
886 struct iov_iter *iter, 890 struct iov_iter *iter,
887 loff_t pos) 891 loff_t pos, int ioflags)
888{ 892{
889 struct nfs_pageio_descriptor desc; 893 struct nfs_pageio_descriptor desc;
890 struct inode *inode = dreq->inode; 894 struct inode *inode = dreq->inode;
@@ -892,7 +896,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
892 size_t requested_bytes = 0; 896 size_t requested_bytes = 0;
893 size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE); 897 size_t wsize = max_t(size_t, NFS_SERVER(inode)->wsize, PAGE_SIZE);
894 898
895 nfs_pageio_init_write(&desc, inode, FLUSH_COND_STABLE, false, 899 nfs_pageio_init_write(&desc, inode, ioflags, false,
896 &nfs_direct_write_completion_ops); 900 &nfs_direct_write_completion_ops);
897 desc.pg_dreq = dreq; 901 desc.pg_dreq = dreq;
898 get_dreq(dreq); 902 get_dreq(dreq);
@@ -971,6 +975,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
971 * nfs_file_direct_write - file direct write operation for NFS files 975 * nfs_file_direct_write - file direct write operation for NFS files
972 * @iocb: target I/O control block 976 * @iocb: target I/O control block
973 * @iter: vector of user buffers from which to write data 977 * @iter: vector of user buffers from which to write data
978 * @swap: flag indicating this is swap IO, not O_DIRECT IO
974 * 979 *
975 * We use this function for direct writes instead of calling 980 * We use this function for direct writes instead of calling
976 * generic_file_aio_write() in order to avoid taking the inode 981 * generic_file_aio_write() in order to avoid taking the inode
@@ -987,7 +992,8 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
987 * Note that O_APPEND is not supported for NFS direct writes, as there 992 * Note that O_APPEND is not supported for NFS direct writes, as there
988 * is no atomic O_APPEND write facility in the NFS protocol. 993 * is no atomic O_APPEND write facility in the NFS protocol.
989 */ 994 */
990ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) 995ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
996 bool swap)
991{ 997{
992 ssize_t result = -EINVAL, requested; 998 ssize_t result = -EINVAL, requested;
993 size_t count; 999 size_t count;
@@ -1001,7 +1007,11 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
1001 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", 1007 dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n",
1002 file, iov_iter_count(iter), (long long) iocb->ki_pos); 1008 file, iov_iter_count(iter), (long long) iocb->ki_pos);
1003 1009
1004 result = generic_write_checks(iocb, iter); 1010 if (swap)
1011 /* bypass generic checks */
1012 result = iov_iter_count(iter);
1013 else
1014 result = generic_write_checks(iocb, iter);
1005 if (result <= 0) 1015 if (result <= 0)
1006 return result; 1016 return result;
1007 count = result; 1017 count = result;
@@ -1031,16 +1041,22 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
1031 if (!is_sync_kiocb(iocb)) 1041 if (!is_sync_kiocb(iocb))
1032 dreq->iocb = iocb; 1042 dreq->iocb = iocb;
1033 1043
1034 nfs_start_io_direct(inode); 1044 if (swap) {
1045 requested = nfs_direct_write_schedule_iovec(dreq, iter, pos,
1046 FLUSH_STABLE);
1047 } else {
1048 nfs_start_io_direct(inode);
1035 1049
1036 requested = nfs_direct_write_schedule_iovec(dreq, iter, pos); 1050 requested = nfs_direct_write_schedule_iovec(dreq, iter, pos,
1051 FLUSH_COND_STABLE);
1037 1052
1038 if (mapping->nrpages) { 1053 if (mapping->nrpages) {
1039 invalidate_inode_pages2_range(mapping, 1054 invalidate_inode_pages2_range(mapping,
1040 pos >> PAGE_SHIFT, end); 1055 pos >> PAGE_SHIFT, end);
1041 } 1056 }
1042 1057
1043 nfs_end_io_direct(inode); 1058 nfs_end_io_direct(inode);
1059 }
1044 1060
1045 if (requested > 0) { 1061 if (requested > 0) {
1046 result = nfs_direct_wait(dreq); 1062 result = nfs_direct_wait(dreq);