aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfsd/vfs.c62
1 files changed, 38 insertions, 24 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 5ca984bbd7d3..31d32aeda2c2 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -904,7 +904,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
904 loff_t offset, struct kvec *vec, int vlen, unsigned long *count) 904 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
905{ 905{
906 struct inode *inode; 906 struct inode *inode;
907 struct raparms *ra;
908 mm_segment_t oldfs; 907 mm_segment_t oldfs;
909 __be32 err; 908 __be32 err;
910 int host_err; 909 int host_err;
@@ -915,12 +914,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
915 if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count)) 914 if (svc_msnfs(fhp) && !lock_may_read(inode, offset, *count))
916 goto out; 915 goto out;
917 916
918 /* Get readahead parameters */
919 ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
920
921 if (ra && ra->p_set)
922 file->f_ra = ra->p_ra;
923
924 if (file->f_op->splice_read && rqstp->rq_splice_ok) { 917 if (file->f_op->splice_read && rqstp->rq_splice_ok) {
925 struct splice_desc sd = { 918 struct splice_desc sd = {
926 .len = 0, 919 .len = 0,
@@ -938,16 +931,6 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
938 set_fs(oldfs); 931 set_fs(oldfs);
939 } 932 }
940 933
941 /* Write back readahead params */
942 if (ra) {
943 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
944 spin_lock(&rab->pb_lock);
945 ra->p_ra = file->f_ra;
946 ra->p_set = 1;
947 ra->p_count--;
948 spin_unlock(&rab->pb_lock);
949 }
950
951 if (host_err >= 0) { 934 if (host_err >= 0) {
952 nfsdstats.io_read += host_err; 935 nfsdstats.io_read += host_err;
953 *count = host_err; 936 *count = host_err;
@@ -1082,6 +1065,42 @@ out:
1082 return err; 1065 return err;
1083} 1066}
1084 1067
1068static __be32 nfsd_open_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
1069 loff_t offset, struct kvec *vec, int vlen, unsigned long *count)
1070{
1071 struct file *file;
1072 struct inode *inode;
1073 struct raparms *ra;
1074 __be32 err;
1075
1076 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
1077 if (err)
1078 return err;
1079
1080 inode = file->f_path.dentry->d_inode;
1081
1082 /* Get readahead parameters */
1083 ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
1084
1085 if (ra && ra->p_set)
1086 file->f_ra = ra->p_ra;
1087
1088 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1089
1090 /* Write back readahead params */
1091 if (ra) {
1092 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
1093 spin_lock(&rab->pb_lock);
1094 ra->p_ra = file->f_ra;
1095 ra->p_set = 1;
1096 ra->p_count--;
1097 spin_unlock(&rab->pb_lock);
1098 }
1099
1100 nfsd_close(file);
1101 return err;
1102}
1103
1085/* 1104/*
1086 * Read data from a file. count must contain the requested read count 1105 * Read data from a file. count must contain the requested read count
1087 * on entry. On return, *count contains the number of bytes actually read. 1106 * on entry. On return, *count contains the number of bytes actually read.
@@ -1100,13 +1119,8 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
1100 if (err) 1119 if (err)
1101 goto out; 1120 goto out;
1102 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count); 1121 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1103 } else { 1122 } else
1104 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); 1123 err = nfsd_open_read(rqstp, fhp, offset, vec, vlen, count);
1105 if (err)
1106 goto out;
1107 err = nfsd_vfs_read(rqstp, fhp, file, offset, vec, vlen, count);
1108 nfsd_close(file);
1109 }
1110out: 1124out:
1111 return err; 1125 return err;
1112} 1126}