aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/vfs.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2014-03-18 17:01:51 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-05-30 17:32:09 -0400
commitdc97618ddda9a23e5211e800f0614e9612178200 (patch)
treee4167f2ff3e8edf0bb5f331d58bc308476180744 /fs/nfsd/vfs.c
parent02fe4707740e7c8a3d0ec34ffbf4630d7d41ca68 (diff)
nfsd4: separate splice and readv cases
The splice and readv cases are actually quite different--for example the former case ignores the array of vectors we build up for the latter. It is probably clearer to separate the two cases entirely. There's some code duplication between the split out encoders, but this is only temporary and will be fixed by a later patch. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/vfs.c')
-rw-r--r--fs/nfsd/vfs.c121
1 files changed, 75 insertions, 46 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f3a0f6cc4298..b7d35a4afefb 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -820,41 +820,54 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
820 return __splice_from_pipe(pipe, sd, nfsd_splice_actor); 820 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
821} 821}
822 822
823static __be32 823__be32 nfsd_finish_read(struct file *file, unsigned long *count, int host_err)
824nfsd_vfs_read(struct svc_rqst *rqstp, struct file *file,
825 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
826{ 824{
827 mm_segment_t oldfs;
828 __be32 err;
829 int host_err;
830
831 err = nfserr_perm;
832
833 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
834 struct splice_desc sd = {
835 .len = 0,
836 .total_len = *count,
837 .pos = offset,
838 .u.data = rqstp,
839 };
840
841 rqstp->rq_next_page = rqstp->rq_respages + 1;
842 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
843 } else {
844 oldfs = get_fs();
845 set_fs(KERNEL_DS);
846 host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
847 set_fs(oldfs);
848 }
849
850 if (host_err >= 0) { 825 if (host_err >= 0) {
851 nfsdstats.io_read += host_err; 826 nfsdstats.io_read += host_err;
852 *count = host_err; 827 *count = host_err;
853 err = 0;
854 fsnotify_access(file); 828 fsnotify_access(file);
829 return 0;
855 } else 830 } else
856 err = nfserrno(host_err); 831 return nfserrno(host_err);
857 return err; 832}
833
834int nfsd_splice_read(struct svc_rqst *rqstp,
835 struct file *file, loff_t offset, unsigned long *count)
836{
837 struct splice_desc sd = {
838 .len = 0,
839 .total_len = *count,
840 .pos = offset,
841 .u.data = rqstp,
842 };
843 int host_err;
844
845 rqstp->rq_next_page = rqstp->rq_respages + 1;
846 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
847 return nfsd_finish_read(file, count, host_err);
848}
849
850int nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen,
851 unsigned long *count)
852{
853 mm_segment_t oldfs;
854 int host_err;
855
856 oldfs = get_fs();
857 set_fs(KERNEL_DS);
858 host_err = vfs_readv(file, (struct iovec __user *)vec, vlen, &offset);
859 set_fs(oldfs);
860 return nfsd_finish_read(file, count, host_err);
861}
862
863static __be32
864nfsd_vfs_read(struct svc_rqst *rqstp, struct file *file,
865 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
866{
867 if (file->f_op->splice_read && rqstp->rq_splice_ok)
868 return nfsd_splice_read(rqstp, file, offset, count);
869 else
870 return nfsd_readv(file, offset, vec, vlen, count);
858} 871}
859 872
860/* 873/*
@@ -956,33 +969,28 @@ out_nfserr:
956 return err; 969 return err;
957} 970}
958 971
959/* 972__be32 nfsd_get_tmp_read_open(struct svc_rqst *rqstp, struct svc_fh *fhp,
960 * Read data from a file. count must contain the requested read count 973 struct file **file, struct raparms **ra)
961 * on entry. On return, *count contains the number of bytes actually read.
962 * N.B. After this call fhp needs an fh_put
963 */
964__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
965 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
966{ 974{
967 struct file *file;
968 struct inode *inode; 975 struct inode *inode;
969 struct raparms *ra;
970 __be32 err; 976 __be32 err;
971 977
972 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); 978 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, file);
973 if (err) 979 if (err)
974 return err; 980 return err;
975 981
976 inode = file_inode(file); 982 inode = file_inode(*file);
977 983
978 /* Get readahead parameters */ 984 /* Get readahead parameters */
979 ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino); 985 *ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
980
981 if (ra && ra->p_set)
982 file->f_ra = ra->p_ra;
983 986
984 err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count); 987 if (*ra && (*ra)->p_set)
988 (*file)->f_ra = (*ra)->p_ra;
989 return nfs_ok;
990}
985 991
992void nfsd_put_tmp_read_open(struct file *file, struct raparms *ra)
993{
986 /* Write back readahead params */ 994 /* Write back readahead params */
987 if (ra) { 995 if (ra) {
988 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex]; 996 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
@@ -992,8 +1000,29 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
992 ra->p_count--; 1000 ra->p_count--;
993 spin_unlock(&rab->pb_lock); 1001 spin_unlock(&rab->pb_lock);
994 } 1002 }
995
996 nfsd_close(file); 1003 nfsd_close(file);
1004}
1005
1006/*
1007 * Read data from a file. count must contain the requested read count
1008 * on entry. On return, *count contains the number of bytes actually read.
1009 * N.B. After this call fhp needs an fh_put
1010 */
1011__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
1012 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
1013{
1014 struct file *file;
1015 struct raparms *ra;
1016 __be32 err;
1017
1018 err = nfsd_get_tmp_read_open(rqstp, fhp, &file, &ra);
1019 if (err)
1020 return err;
1021
1022 err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
1023
1024 nfsd_put_tmp_read_open(file, ra);
1025
997 return err; 1026 return err;
998} 1027}
999 1028