diff options
author | Christoph Hellwig <hch@infradead.org> | 2013-11-14 11:50:31 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-01-13 17:29:49 -0500 |
commit | 14a3ec79437252d922bae574ecbf0c0584c330f3 (patch) | |
tree | 120ba99abc7f8f3aa93dd3e66ca10b515d8ddf84 /fs/nfs | |
parent | 1f90ee27461e31a1c18e5d819f6ea6f5c7304b16 (diff) |
nfs: merge nfs_direct_read into nfs_file_direct_read
Simple code cleanup to prepare for later fixes.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/direct.c | 107 |
1 files changed, 49 insertions, 58 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 6c232107e835..f8b0a81c340e 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -458,14 +458,55 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, | |||
458 | return 0; | 458 | return 0; |
459 | } | 459 | } |
460 | 460 | ||
461 | static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, | 461 | /** |
462 | unsigned long nr_segs, loff_t pos, bool uio) | 462 | * nfs_file_direct_read - file direct read operation for NFS files |
463 | * @iocb: target I/O control block | ||
464 | * @iov: vector of user buffers into which to read data | ||
465 | * @nr_segs: size of iov vector | ||
466 | * @pos: byte offset in file where reading starts | ||
467 | * | ||
468 | * We use this function for direct reads instead of calling | ||
469 | * generic_file_aio_read() in order to avoid gfar's check to see if | ||
470 | * the request starts before the end of the file. For that check | ||
471 | * to work, we must generate a GETATTR before each direct read, and | ||
472 | * even then there is a window between the GETATTR and the subsequent | ||
473 | * READ where the file size could change. Our preference is simply | ||
474 | * to do all reads the application wants, and the server will take | ||
475 | * care of managing the end of file boundary. | ||
476 | * | ||
477 | * This function also eliminates unnecessarily updating the file's | ||
478 | * atime locally, as the NFS server sets the file's atime, and this | ||
479 | * client must read the updated atime from the server back into its | ||
480 | * cache. | ||
481 | */ | ||
482 | ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | ||
483 | unsigned long nr_segs, loff_t pos, bool uio) | ||
463 | { | 484 | { |
464 | ssize_t result = -ENOMEM; | 485 | struct file *file = iocb->ki_filp; |
465 | struct inode *inode = iocb->ki_filp->f_mapping->host; | 486 | struct address_space *mapping = file->f_mapping; |
487 | struct inode *inode = mapping->host; | ||
466 | struct nfs_direct_req *dreq; | 488 | struct nfs_direct_req *dreq; |
467 | struct nfs_lock_context *l_ctx; | 489 | struct nfs_lock_context *l_ctx; |
490 | ssize_t result = -EINVAL; | ||
491 | size_t count; | ||
492 | |||
493 | count = iov_length(iov, nr_segs); | ||
494 | nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); | ||
495 | |||
496 | dfprintk(FILE, "NFS: direct read(%pD2, %zd@%Ld)\n", | ||
497 | file, count, (long long) pos); | ||
498 | |||
499 | result = 0; | ||
500 | if (!count) | ||
501 | goto out; | ||
502 | |||
503 | result = nfs_sync_mapping(mapping); | ||
504 | if (result) | ||
505 | goto out; | ||
506 | |||
507 | task_io_account_read(count); | ||
468 | 508 | ||
509 | result = -ENOMEM; | ||
469 | dreq = nfs_direct_req_alloc(); | 510 | dreq = nfs_direct_req_alloc(); |
470 | if (dreq == NULL) | 511 | if (dreq == NULL) |
471 | goto out; | 512 | goto out; |
@@ -484,8 +525,11 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, | |||
484 | 525 | ||
485 | NFS_I(inode)->read_io += iov_length(iov, nr_segs); | 526 | NFS_I(inode)->read_io += iov_length(iov, nr_segs); |
486 | result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio); | 527 | result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio); |
487 | if (!result) | 528 | if (!result) { |
488 | result = nfs_direct_wait(dreq); | 529 | result = nfs_direct_wait(dreq); |
530 | if (result > 0) | ||
531 | iocb->ki_pos = pos + result; | ||
532 | } | ||
489 | out_release: | 533 | out_release: |
490 | nfs_direct_req_release(dreq); | 534 | nfs_direct_req_release(dreq); |
491 | out: | 535 | out: |
@@ -889,59 +933,6 @@ out: | |||
889 | } | 933 | } |
890 | 934 | ||
891 | /** | 935 | /** |
892 | * nfs_file_direct_read - file direct read operation for NFS files | ||
893 | * @iocb: target I/O control block | ||
894 | * @iov: vector of user buffers into which to read data | ||
895 | * @nr_segs: size of iov vector | ||
896 | * @pos: byte offset in file where reading starts | ||
897 | * | ||
898 | * We use this function for direct reads instead of calling | ||
899 | * generic_file_aio_read() in order to avoid gfar's check to see if | ||
900 | * the request starts before the end of the file. For that check | ||
901 | * to work, we must generate a GETATTR before each direct read, and | ||
902 | * even then there is a window between the GETATTR and the subsequent | ||
903 | * READ where the file size could change. Our preference is simply | ||
904 | * to do all reads the application wants, and the server will take | ||
905 | * care of managing the end of file boundary. | ||
906 | * | ||
907 | * This function also eliminates unnecessarily updating the file's | ||
908 | * atime locally, as the NFS server sets the file's atime, and this | ||
909 | * client must read the updated atime from the server back into its | ||
910 | * cache. | ||
911 | */ | ||
912 | ssize_t nfs_file_direct_read(struct kiocb *iocb, const struct iovec *iov, | ||
913 | unsigned long nr_segs, loff_t pos, bool uio) | ||
914 | { | ||
915 | ssize_t retval = -EINVAL; | ||
916 | struct file *file = iocb->ki_filp; | ||
917 | struct address_space *mapping = file->f_mapping; | ||
918 | size_t count; | ||
919 | |||
920 | count = iov_length(iov, nr_segs); | ||
921 | nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); | ||
922 | |||
923 | dfprintk(FILE, "NFS: direct read(%pD2, %zd@%Ld)\n", | ||
924 | file, count, (long long) pos); | ||
925 | |||
926 | retval = 0; | ||
927 | if (!count) | ||
928 | goto out; | ||
929 | |||
930 | retval = nfs_sync_mapping(mapping); | ||
931 | if (retval) | ||
932 | goto out; | ||
933 | |||
934 | task_io_account_read(count); | ||
935 | |||
936 | retval = nfs_direct_read(iocb, iov, nr_segs, pos, uio); | ||
937 | if (retval > 0) | ||
938 | iocb->ki_pos = pos + retval; | ||
939 | |||
940 | out: | ||
941 | return retval; | ||
942 | } | ||
943 | |||
944 | /** | ||
945 | * nfs_file_direct_write - file direct write operation for NFS files | 936 | * nfs_file_direct_write - file direct write operation for NFS files |
946 | * @iocb: target I/O control block | 937 | * @iocb: target I/O control block |
947 | * @iov: vector of user buffers from which to write data | 938 | * @iov: vector of user buffers from which to write data |