aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2010-07-27 16:48:54 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-07-27 18:15:54 -0400
commitfa0a21269f807bb2e95b8b642c4a739714780172 (patch)
treece469ff0ce6bcc7373b17fc90d1451cb93883bf2 /fs
parentaf4718f3f996925f770e540004ec9224243d1682 (diff)
nfsd: bypass readahead cache when have struct file
The readahead cache compensates for the fact that the NFS server currently does an open and close on every IO operation in the NFSv2 and NFSv3 case. In the NFSv4 case we have long-lived struct files associated with client opens, so there's no need for this. In fact, concurrent IO's using trying to modify the same file->f_ra may cause problems. So, don't bother with the readahead cache in that case. Note eventually we'll likely do this in the v2/v3 case as well by keeping a cache of struct files instead of struct file_ra_state's. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-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}