diff options
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r-- | fs/nfs/direct.c | 36 |
1 files changed, 12 insertions, 24 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index c3929fb2ab26..682f65fe09b5 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -240,7 +240,6 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, | |||
240 | 240 | ||
241 | /** | 241 | /** |
242 | * nfs_direct_IO - NFS address space operation for direct I/O | 242 | * nfs_direct_IO - NFS address space operation for direct I/O |
243 | * @rw: direction (read or write) | ||
244 | * @iocb: target I/O control block | 243 | * @iocb: target I/O control block |
245 | * @iov: array of vectors that define I/O buffer | 244 | * @iov: array of vectors that define I/O buffer |
246 | * @pos: offset in file to begin the operation | 245 | * @pos: offset in file to begin the operation |
@@ -251,7 +250,7 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, | |||
251 | * shunt off direct read and write requests before the VFS gets them, | 250 | * shunt off direct read and write requests before the VFS gets them, |
252 | * so this method is only ever called for swap. | 251 | * so this method is only ever called for swap. |
253 | */ | 252 | */ |
254 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) | 253 | ssize_t nfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) |
255 | { | 254 | { |
256 | struct inode *inode = iocb->ki_filp->f_mapping->host; | 255 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
257 | 256 | ||
@@ -267,9 +266,9 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t | |||
267 | #else | 266 | #else |
268 | VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE); | 267 | VM_BUG_ON(iov_iter_count(iter) != PAGE_SIZE); |
269 | 268 | ||
270 | if (rw == READ) | 269 | if (iov_iter_rw(iter) == READ) |
271 | return nfs_file_direct_read(iocb, iter, pos); | 270 | return nfs_file_direct_read(iocb, iter, pos); |
272 | return nfs_file_direct_write(iocb, iter, pos); | 271 | return nfs_file_direct_write(iocb, iter); |
273 | #endif /* CONFIG_NFS_SWAP */ | 272 | #endif /* CONFIG_NFS_SWAP */ |
274 | } | 273 | } |
275 | 274 | ||
@@ -960,8 +959,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, | |||
960 | * Note that O_APPEND is not supported for NFS direct writes, as there | 959 | * Note that O_APPEND is not supported for NFS direct writes, as there |
961 | * is no atomic O_APPEND write facility in the NFS protocol. | 960 | * is no atomic O_APPEND write facility in the NFS protocol. |
962 | */ | 961 | */ |
963 | ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, | 962 | ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) |
964 | loff_t pos) | ||
965 | { | 963 | { |
966 | ssize_t result = -EINVAL; | 964 | ssize_t result = -EINVAL; |
967 | struct file *file = iocb->ki_filp; | 965 | struct file *file = iocb->ki_filp; |
@@ -969,25 +967,16 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, | |||
969 | struct inode *inode = mapping->host; | 967 | struct inode *inode = mapping->host; |
970 | struct nfs_direct_req *dreq; | 968 | struct nfs_direct_req *dreq; |
971 | struct nfs_lock_context *l_ctx; | 969 | struct nfs_lock_context *l_ctx; |
972 | loff_t end; | 970 | loff_t pos, end; |
973 | size_t count = iov_iter_count(iter); | ||
974 | end = (pos + count - 1) >> PAGE_CACHE_SHIFT; | ||
975 | |||
976 | nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, count); | ||
977 | 971 | ||
978 | dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", | 972 | dfprintk(FILE, "NFS: direct write(%pD2, %zd@%Ld)\n", |
979 | file, count, (long long) pos); | 973 | file, iov_iter_count(iter), (long long) iocb->ki_pos); |
980 | 974 | ||
981 | result = generic_write_checks(file, &pos, &count, 0); | 975 | nfs_add_stats(mapping->host, NFSIOS_DIRECTWRITTENBYTES, |
982 | if (result) | 976 | iov_iter_count(iter)); |
983 | goto out; | ||
984 | 977 | ||
985 | result = -EINVAL; | 978 | pos = iocb->ki_pos; |
986 | if ((ssize_t) count < 0) | 979 | end = (pos + iov_iter_count(iter) - 1) >> PAGE_CACHE_SHIFT; |
987 | goto out; | ||
988 | result = 0; | ||
989 | if (!count) | ||
990 | goto out; | ||
991 | 980 | ||
992 | mutex_lock(&inode->i_mutex); | 981 | mutex_lock(&inode->i_mutex); |
993 | 982 | ||
@@ -1002,7 +991,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, | |||
1002 | goto out_unlock; | 991 | goto out_unlock; |
1003 | } | 992 | } |
1004 | 993 | ||
1005 | task_io_account_write(count); | 994 | task_io_account_write(iov_iter_count(iter)); |
1006 | 995 | ||
1007 | result = -ENOMEM; | 996 | result = -ENOMEM; |
1008 | dreq = nfs_direct_req_alloc(); | 997 | dreq = nfs_direct_req_alloc(); |
@@ -1010,7 +999,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter, | |||
1010 | goto out_unlock; | 999 | goto out_unlock; |
1011 | 1000 | ||
1012 | dreq->inode = inode; | 1001 | dreq->inode = inode; |
1013 | dreq->bytes_left = count; | 1002 | dreq->bytes_left = iov_iter_count(iter); |
1014 | dreq->io_start = pos; | 1003 | dreq->io_start = pos; |
1015 | dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); | 1004 | dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp)); |
1016 | l_ctx = nfs_get_lock_context(dreq->ctx); | 1005 | l_ctx = nfs_get_lock_context(dreq->ctx); |
@@ -1050,7 +1039,6 @@ out_release: | |||
1050 | nfs_direct_req_release(dreq); | 1039 | nfs_direct_req_release(dreq); |
1051 | out_unlock: | 1040 | out_unlock: |
1052 | mutex_unlock(&inode->i_mutex); | 1041 | mutex_unlock(&inode->i_mutex); |
1053 | out: | ||
1054 | return result; | 1042 | return result; |
1055 | } | 1043 | } |
1056 | 1044 | ||