aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-06-18 10:44:58 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-06-19 15:39:51 -0400
commite749a4621e414c36a54ac8b3205955e267f00db3 (patch)
tree5567c049b21a6e9fdf9025b5a6fc0c8ec742f493
parent97b1f9aae963cc0b229ef8147db4782170564d4f (diff)
nfsd: clean up raparams handling
Refactor the raparam hash helpers to just deal with the raparms, and keep opening/closing files separate from that. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4xdr.c24
-rw-r--r--fs/nfsd/vfs.c68
-rw-r--r--fs/nfsd/vfs.h6
3 files changed, 43 insertions, 55 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5c7eab9c12ba..5286206169bc 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -33,6 +33,7 @@
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <linux/file.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <linux/namei.h> 38#include <linux/namei.h>
38#include <linux/statfs.h> 39#include <linux/statfs.h>
@@ -3419,7 +3420,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3419 struct file *file = read->rd_filp; 3420 struct file *file = read->rd_filp;
3420 struct svc_fh *fhp = read->rd_fhp; 3421 struct svc_fh *fhp = read->rd_fhp;
3421 int starting_len = xdr->buf->len; 3422 int starting_len = xdr->buf->len;
3422 struct raparms *ra; 3423 struct raparms *ra = NULL;
3423 __be32 *p; 3424 __be32 *p;
3424 __be32 err; 3425 __be32 err;
3425 3426
@@ -3441,23 +3442,30 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3441 maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len)); 3442 maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
3442 maxcount = min_t(unsigned long, maxcount, read->rd_length); 3443 maxcount = min_t(unsigned long, maxcount, read->rd_length);
3443 3444
3444 if (read->rd_filp) 3445 if (read->rd_filp) {
3445 err = nfsd_permission(resp->rqstp, fhp->fh_export, 3446 err = nfsd_permission(resp->rqstp, fhp->fh_export,
3446 fhp->fh_dentry, 3447 fhp->fh_dentry,
3447 NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE); 3448 NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
3448 else 3449 if (err)
3449 err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp, 3450 goto err_truncate;
3450 &file, &ra); 3451 } else {
3451 if (err) 3452 err = nfsd_open(resp->rqstp, fhp, S_IFREG, NFSD_MAY_READ,
3452 goto err_truncate; 3453 &file);
3454 if (err)
3455 goto err_truncate;
3456
3457 ra = nfsd_init_raparms(file);
3458 }
3453 3459
3454 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) 3460 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
3455 err = nfsd4_encode_splice_read(resp, read, file, maxcount); 3461 err = nfsd4_encode_splice_read(resp, read, file, maxcount);
3456 else 3462 else
3457 err = nfsd4_encode_readv(resp, read, file, maxcount); 3463 err = nfsd4_encode_readv(resp, read, file, maxcount);
3458 3464
3465 if (ra)
3466 nfsd_put_raparams(file, ra);
3459 if (!read->rd_filp) 3467 if (!read->rd_filp)
3460 nfsd_put_tmp_read_open(file, ra); 3468 fput(file);
3461 3469
3462err_truncate: 3470err_truncate:
3463 if (err) 3471 if (err)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index b540ca789906..52f2dd3898c4 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -725,14 +725,12 @@ out:
725 return err; 725 return err;
726} 726}
727 727
728/* 728struct raparms *
729 * Obtain the readahead parameters for the file 729nfsd_init_raparms(struct file *file)
730 * specified by (dev, ino).
731 */
732
733static inline struct raparms *
734nfsd_get_raparms(dev_t dev, ino_t ino)
735{ 730{
731 struct inode *inode = file_inode(file);
732 dev_t dev = inode->i_sb->s_dev;
733 ino_t ino = inode->i_ino;
736 struct raparms *ra, **rap, **frap = NULL; 734 struct raparms *ra, **rap, **frap = NULL;
737 int depth = 0; 735 int depth = 0;
738 unsigned int hash; 736 unsigned int hash;
@@ -769,9 +767,23 @@ found:
769 ra->p_count++; 767 ra->p_count++;
770 nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++; 768 nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
771 spin_unlock(&rab->pb_lock); 769 spin_unlock(&rab->pb_lock);
770
771 if (ra->p_set)
772 file->f_ra = ra->p_ra;
772 return ra; 773 return ra;
773} 774}
774 775
776void nfsd_put_raparams(struct file *file, struct raparms *ra)
777{
778 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
779
780 spin_lock(&rab->pb_lock);
781 ra->p_ra = file->f_ra;
782 ra->p_set = 1;
783 ra->p_count--;
784 spin_unlock(&rab->pb_lock);
785}
786
775/* 787/*
776 * Grab and keep cached pages associated with a file in the svc_rqst 788 * Grab and keep cached pages associated with a file in the svc_rqst
777 * so that they can be passed to the network sendmsg/sendpage routines 789 * so that they can be passed to the network sendmsg/sendpage routines
@@ -964,40 +976,6 @@ out_nfserr:
964 return err; 976 return err;
965} 977}
966 978
967__be32 nfsd_get_tmp_read_open(struct svc_rqst *rqstp, struct svc_fh *fhp,
968 struct file **file, struct raparms **ra)
969{
970 struct inode *inode;
971 __be32 err;
972
973 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, file);
974 if (err)
975 return err;
976
977 inode = file_inode(*file);
978
979 /* Get readahead parameters */
980 *ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
981
982 if (*ra && (*ra)->p_set)
983 (*file)->f_ra = (*ra)->p_ra;
984 return nfs_ok;
985}
986
987void nfsd_put_tmp_read_open(struct file *file, struct raparms *ra)
988{
989 /* Write back readahead params */
990 if (ra) {
991 struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
992 spin_lock(&rab->pb_lock);
993 ra->p_ra = file->f_ra;
994 ra->p_set = 1;
995 ra->p_count--;
996 spin_unlock(&rab->pb_lock);
997 }
998 fput(file);
999}
1000
1001/* 979/*
1002 * Read data from a file. count must contain the requested read count 980 * Read data from a file. count must contain the requested read count
1003 * on entry. On return, *count contains the number of bytes actually read. 981 * on entry. On return, *count contains the number of bytes actually read.
@@ -1010,13 +988,15 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
1010 struct raparms *ra; 988 struct raparms *ra;
1011 __be32 err; 989 __be32 err;
1012 990
1013 err = nfsd_get_tmp_read_open(rqstp, fhp, &file, &ra); 991 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
1014 if (err) 992 if (err)
1015 return err; 993 return err;
1016 994
995 ra = nfsd_init_raparms(file);
1017 err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count); 996 err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
1018 997 if (ra)
1019 nfsd_put_tmp_read_open(file, ra); 998 nfsd_put_raparams(file, ra);
999 fput(file);
1020 1000
1021 return err; 1001 return err;
1022} 1002}
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 17a5e0db6a77..053c4addbd9d 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -72,9 +72,6 @@ __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
72__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, 72__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
73 int, struct file **); 73 int, struct file **);
74struct raparms; 74struct raparms;
75__be32 nfsd_get_tmp_read_open(struct svc_rqst *, struct svc_fh *,
76 struct file **, struct raparms **);
77void nfsd_put_tmp_read_open(struct file *, struct raparms *);
78__be32 nfsd_splice_read(struct svc_rqst *, 75__be32 nfsd_splice_read(struct svc_rqst *,
79 struct file *, loff_t, unsigned long *); 76 struct file *, loff_t, unsigned long *);
80__be32 nfsd_readv(struct file *, loff_t, struct kvec *, int, 77__be32 nfsd_readv(struct file *, loff_t, struct kvec *, int,
@@ -103,6 +100,9 @@ __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
103__be32 nfsd_permission(struct svc_rqst *, struct svc_export *, 100__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
104 struct dentry *, int); 101 struct dentry *, int);
105 102
103struct raparms *nfsd_init_raparms(struct file *file);
104void nfsd_put_raparams(struct file *file, struct raparms *ra);
105
106static inline int fh_want_write(struct svc_fh *fh) 106static inline int fh_want_write(struct svc_fh *fh)
107{ 107{
108 int ret = mnt_want_write(fh->fh_export->ex_path.mnt); 108 int ret = mnt_want_write(fh->fh_export->ex_path.mnt);