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>
This commit is contained in:
parent
97b1f9aae9
commit
e749a4621e
3 changed files with 43 additions and 55 deletions
|
@ -33,6 +33,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/file.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
#include <linux/statfs.h>
|
#include <linux/statfs.h>
|
||||||
|
@ -3419,7 +3420,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||||
struct file *file = read->rd_filp;
|
struct file *file = read->rd_filp;
|
||||||
struct svc_fh *fhp = read->rd_fhp;
|
struct svc_fh *fhp = read->rd_fhp;
|
||||||
int starting_len = xdr->buf->len;
|
int starting_len = xdr->buf->len;
|
||||||
struct raparms *ra;
|
struct raparms *ra = NULL;
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
__be32 err;
|
__be32 err;
|
||||||
|
|
||||||
|
@ -3441,23 +3442,30 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
||||||
maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
|
maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len));
|
||||||
maxcount = min_t(unsigned long, maxcount, read->rd_length);
|
maxcount = min_t(unsigned long, maxcount, read->rd_length);
|
||||||
|
|
||||||
if (read->rd_filp)
|
if (read->rd_filp) {
|
||||||
err = nfsd_permission(resp->rqstp, fhp->fh_export,
|
err = nfsd_permission(resp->rqstp, fhp->fh_export,
|
||||||
fhp->fh_dentry,
|
fhp->fh_dentry,
|
||||||
NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
|
NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
|
||||||
else
|
|
||||||
err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
|
|
||||||
&file, &ra);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto err_truncate;
|
goto err_truncate;
|
||||||
|
} else {
|
||||||
|
err = nfsd_open(resp->rqstp, fhp, S_IFREG, NFSD_MAY_READ,
|
||||||
|
&file);
|
||||||
|
if (err)
|
||||||
|
goto err_truncate;
|
||||||
|
|
||||||
|
ra = nfsd_init_raparms(file);
|
||||||
|
}
|
||||||
|
|
||||||
if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
|
if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
|
||||||
err = nfsd4_encode_splice_read(resp, read, file, maxcount);
|
err = nfsd4_encode_splice_read(resp, read, file, maxcount);
|
||||||
else
|
else
|
||||||
err = nfsd4_encode_readv(resp, read, file, maxcount);
|
err = nfsd4_encode_readv(resp, read, file, maxcount);
|
||||||
|
|
||||||
|
if (ra)
|
||||||
|
nfsd_put_raparams(file, ra);
|
||||||
if (!read->rd_filp)
|
if (!read->rd_filp)
|
||||||
nfsd_put_tmp_read_open(file, ra);
|
fput(file);
|
||||||
|
|
||||||
err_truncate:
|
err_truncate:
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -725,14 +725,12 @@ out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct raparms *
|
||||||
* Obtain the readahead parameters for the file
|
nfsd_init_raparms(struct file *file)
|
||||||
* specified by (dev, ino).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline struct raparms *
|
|
||||||
nfsd_get_raparms(dev_t dev, ino_t ino)
|
|
||||||
{
|
{
|
||||||
|
struct inode *inode = file_inode(file);
|
||||||
|
dev_t dev = inode->i_sb->s_dev;
|
||||||
|
ino_t ino = inode->i_ino;
|
||||||
struct raparms *ra, **rap, **frap = NULL;
|
struct raparms *ra, **rap, **frap = NULL;
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
|
@ -769,9 +767,23 @@ found:
|
||||||
ra->p_count++;
|
ra->p_count++;
|
||||||
nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
|
nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
|
||||||
spin_unlock(&rab->pb_lock);
|
spin_unlock(&rab->pb_lock);
|
||||||
|
|
||||||
|
if (ra->p_set)
|
||||||
|
file->f_ra = ra->p_ra;
|
||||||
return ra;
|
return ra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nfsd_put_raparams(struct file *file, struct raparms *ra)
|
||||||
|
{
|
||||||
|
struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
|
||||||
|
|
||||||
|
spin_lock(&rab->pb_lock);
|
||||||
|
ra->p_ra = file->f_ra;
|
||||||
|
ra->p_set = 1;
|
||||||
|
ra->p_count--;
|
||||||
|
spin_unlock(&rab->pb_lock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab and keep cached pages associated with a file in the svc_rqst
|
* Grab and keep cached pages associated with a file in the svc_rqst
|
||||||
* so that they can be passed to the network sendmsg/sendpage routines
|
* so that they can be passed to the network sendmsg/sendpage routines
|
||||||
|
@ -964,40 +976,6 @@ out_nfserr:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
__be32 nfsd_get_tmp_read_open(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
|
||||||
struct file **file, struct raparms **ra)
|
|
||||||
{
|
|
||||||
struct inode *inode;
|
|
||||||
__be32 err;
|
|
||||||
|
|
||||||
err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, file);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
inode = file_inode(*file);
|
|
||||||
|
|
||||||
/* Get readahead parameters */
|
|
||||||
*ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino);
|
|
||||||
|
|
||||||
if (*ra && (*ra)->p_set)
|
|
||||||
(*file)->f_ra = (*ra)->p_ra;
|
|
||||||
return nfs_ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nfsd_put_tmp_read_open(struct file *file, struct raparms *ra)
|
|
||||||
{
|
|
||||||
/* Write back readahead params */
|
|
||||||
if (ra) {
|
|
||||||
struct raparm_hbucket *rab = &raparm_hash[ra->p_hindex];
|
|
||||||
spin_lock(&rab->pb_lock);
|
|
||||||
ra->p_ra = file->f_ra;
|
|
||||||
ra->p_set = 1;
|
|
||||||
ra->p_count--;
|
|
||||||
spin_unlock(&rab->pb_lock);
|
|
||||||
}
|
|
||||||
fput(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read data from a file. count must contain the requested read count
|
* Read data from a file. count must contain the requested read count
|
||||||
* on entry. On return, *count contains the number of bytes actually read.
|
* 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,
|
||||||
struct raparms *ra;
|
struct raparms *ra;
|
||||||
__be32 err;
|
__be32 err;
|
||||||
|
|
||||||
err = nfsd_get_tmp_read_open(rqstp, fhp, &file, &ra);
|
err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
ra = nfsd_init_raparms(file);
|
||||||
err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
|
err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);
|
||||||
|
if (ra)
|
||||||
nfsd_put_tmp_read_open(file, ra);
|
nfsd_put_raparams(file, ra);
|
||||||
|
fput(file);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,9 +72,6 @@ __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
|
||||||
__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
|
__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
|
||||||
int, struct file **);
|
int, struct file **);
|
||||||
struct raparms;
|
struct raparms;
|
||||||
__be32 nfsd_get_tmp_read_open(struct svc_rqst *, struct svc_fh *,
|
|
||||||
struct file **, struct raparms **);
|
|
||||||
void nfsd_put_tmp_read_open(struct file *, struct raparms *);
|
|
||||||
__be32 nfsd_splice_read(struct svc_rqst *,
|
__be32 nfsd_splice_read(struct svc_rqst *,
|
||||||
struct file *, loff_t, unsigned long *);
|
struct file *, loff_t, unsigned long *);
|
||||||
__be32 nfsd_readv(struct file *, loff_t, struct kvec *, int,
|
__be32 nfsd_readv(struct file *, loff_t, struct kvec *, int,
|
||||||
|
@ -103,6 +100,9 @@ __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
|
||||||
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
|
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
|
||||||
struct dentry *, int);
|
struct dentry *, int);
|
||||||
|
|
||||||
|
struct raparms *nfsd_init_raparms(struct file *file);
|
||||||
|
void nfsd_put_raparams(struct file *file, struct raparms *ra);
|
||||||
|
|
||||||
static inline int fh_want_write(struct svc_fh *fh)
|
static inline int fh_want_write(struct svc_fh *fh)
|
||||||
{
|
{
|
||||||
int ret = mnt_want_write(fh->fh_export->ex_path.mnt);
|
int ret = mnt_want_write(fh->fh_export->ex_path.mnt);
|
||||||
|
|
Loading…
Add table
Reference in a new issue