Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e749a462 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by J. Bruce Fields
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 97b1f9aa
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/file.h>
#include <linux/slab.h>
#include <linux/namei.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 svc_fh *fhp = read->rd_fhp;
	int starting_len = xdr->buf->len;
	struct raparms *ra;
	struct raparms *ra = NULL;
	__be32 *p;
	__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, read->rd_length);

	if (read->rd_filp)
	if (read->rd_filp) {
		err = nfsd_permission(resp->rqstp, fhp->fh_export,
				fhp->fh_dentry,
				NFSD_MAY_READ|NFSD_MAY_OWNER_OVERRIDE);
	else
		err = nfsd_get_tmp_read_open(resp->rqstp, read->rd_fhp,
						&file, &ra);
		if (err)
			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))
		err = nfsd4_encode_splice_read(resp, read, file, maxcount);
	else
		err = nfsd4_encode_readv(resp, read, file, maxcount);

	if (ra)
		nfsd_put_raparams(file, ra);
	if (!read->rd_filp)
		nfsd_put_tmp_read_open(file, ra);
		fput(file);

err_truncate:
	if (err)
+24 −44
Original line number Diff line number Diff line
@@ -725,14 +725,12 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type,
	return err;
}

/*
 * Obtain the readahead parameters for the file
 * specified by (dev, ino).
 */

static inline struct raparms *
nfsd_get_raparms(dev_t dev, ino_t ino)
struct raparms *
nfsd_init_raparms(struct file *file)
{
	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;
	int depth = 0;
	unsigned int hash;
@@ -769,9 +767,23 @@ nfsd_get_raparms(dev_t dev, ino_t ino)
	ra->p_count++;
	nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
	spin_unlock(&rab->pb_lock);

	if (ra->p_set)
		file->f_ra = ra->p_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
 * so that they can be passed to the network sendmsg/sendpage routines
@@ -964,40 +976,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
	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
 * 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;
	__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)
		return err;

	ra = nfsd_init_raparms(file);
	err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count);

	nfsd_put_tmp_read_open(file, ra);
	if (ra)
		nfsd_put_raparams(file, ra);
	fput(file);

	return err;
}
+3 −3
Original line number Diff line number Diff line
@@ -72,9 +72,6 @@ __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
__be32		nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
				int, struct file **);
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 *,
				struct file *, loff_t, unsigned long *);
__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 *,
				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)
{
	int ret = mnt_want_write(fh->fh_export->ex_path.mnt);