[RFC PATCH] nfs: add rasize mount option to control read ahead

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Limiting nfs to 128kB of read ahead is performing poorly in high volume
mounts. Add the rasize option to set the read ahead to a more suitable
value.

Signed-off-by: Thiago Rafael Becker <trbecker@xxxxxxxxx>
---
 fs/nfs/client.c                 |  3 +++
 fs/nfs/fs_context.c             | 11 ++++++++++-
 fs/nfs/internal.h               |  1 +
 fs/nfs/nfs4client.c             |  2 ++
 fs/nfs/super.c                  |  2 ++
 include/linux/nfs_fs_sb.h       |  1 +
 include/uapi/linux/nfs4_mount.h |  1 +
 include/uapi/linux/nfs_mount.h  |  1 +
 8 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 330f65727c45..042677cd82f5 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -713,6 +713,8 @@ static int nfs_init_server(struct nfs_server *server,
 		server->rsize = nfs_block_size(ctx->rsize, NULL);
 	if (ctx->wsize)
 		server->wsize = nfs_block_size(ctx->wsize, NULL);
+	if (ctx->rasize)
+		server->rasize = ctx->rasize;
 
 	server->acregmin = ctx->acregmin * HZ;
 	server->acregmax = ctx->acregmax * HZ;
@@ -869,6 +871,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
 {
 	target->flags = source->flags;
 	target->rsize = source->rsize;
+	target->rasize = source->rasize;
 	target->wsize = source->wsize;
 	target->acregmin = source->acregmin;
 	target->acregmax = source->acregmax;
diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
index d95c9a39bc70..8dcf14864d22 100644
--- a/fs/nfs/fs_context.c
+++ b/fs/nfs/fs_context.c
@@ -65,6 +65,7 @@ enum nfs_param {
 	Opt_proto,
 	Opt_rdirplus,
 	Opt_rdma,
+	Opt_rasize,
 	Opt_resvport,
 	Opt_retrans,
 	Opt_retry,
@@ -162,6 +163,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
 	fsparam_u32   ("port",		Opt_port),
 	fsparam_flag_no("posix",	Opt_posix),
 	fsparam_string("proto",		Opt_proto),
+	fsparam_u32   ("rasize",        Opt_rasize),
 	fsparam_flag_no("rdirplus",	Opt_rdirplus),
 	fsparam_flag  ("rdma",		Opt_rdma),
 	fsparam_flag_no("resvport",	Opt_resvport),
@@ -476,7 +478,6 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
 	int ret, opt;
 
 	dfprintk(MOUNT, "NFS:   parsing nfs mount option '%s'\n", param->key);
-
 	opt = fs_parse(fc, nfs_fs_parameters, param, &result);
 	if (opt < 0)
 		return ctx->sloppy ? 1 : opt;
@@ -824,6 +825,9 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
 			goto out_invalid_value;
 		}
 		break;
+	case Opt_rasize:
+		ctx->rasize = result.uint_32;
+		break;
 
 		/*
 		 * Special options
@@ -1012,6 +1016,7 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
 		ctx->flags	|= extra_flags;
 		ctx->rsize	= data->rsize;
 		ctx->wsize	= data->wsize;
+		ctx->rasize     = data->rasize;
 		ctx->timeo	= data->timeo;
 		ctx->retrans	= data->retrans;
 		ctx->acregmin	= data->acregmin;
@@ -1145,6 +1150,7 @@ struct compat_nfs4_mount_data_v1 {
 	compat_int_t proto;
 	compat_int_t auth_flavourlen;
 	compat_uptr_t auth_flavours;
+	compat_int_t rasize;
 };
 
 static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data)
@@ -1169,6 +1175,7 @@ static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data)
 	data->timeo = compat->timeo;
 	data->wsize = compat->wsize;
 	data->rsize = compat->rsize;
+	data->rasize = compat->rasize;
 	data->flags = compat->flags;
 	data->version = compat->version;
 }
@@ -1247,6 +1254,7 @@ static int nfs4_parse_monolithic(struct fs_context *fc,
 	ctx->flags	= data->flags & NFS4_MOUNT_FLAGMASK;
 	ctx->rsize	= data->rsize;
 	ctx->wsize	= data->wsize;
+	ctx->rasize     = data->rasize;
 	ctx->timeo	= data->timeo;
 	ctx->retrans	= data->retrans;
 	ctx->acregmin	= data->acregmin;
@@ -1508,6 +1516,7 @@ static int nfs_init_fs_context(struct fs_context *fc)
 		ctx->flags		= nfss->flags;
 		ctx->rsize		= nfss->rsize;
 		ctx->wsize		= nfss->wsize;
+		ctx->rasize             = nfss->rasize;
 		ctx->retrans		= nfss->client->cl_timeout->to_retries;
 		ctx->selected_flavor	= nfss->client->cl_auth->au_flavor;
 		ctx->acregmin		= nfss->acregmin / HZ;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index a36af04188c2..975f49a03de6 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -97,6 +97,7 @@ struct nfs_fs_context {
 	unsigned short		protofamily;
 	unsigned short		mountfamily;
 	bool			has_sec_mnt_opts;
+	unsigned int            rasize;
 
 	struct {
 		union {
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 28431acd1230..f3cb9e9ff656 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -1130,6 +1130,8 @@ static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)
 		server->rsize = nfs_block_size(ctx->rsize, NULL);
 	if (ctx->wsize)
 		server->wsize = nfs_block_size(ctx->wsize, NULL);
+	if (ctx->rasize)
+		server->rasize = ctx->rasize;
 
 	server->acregmin = ctx->acregmin * HZ;
 	server->acregmax = ctx->acregmax * HZ;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index fe58525cfed4..df5d27931ee6 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -456,6 +456,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
 	seq_printf(m, ",wsize=%u", nfss->wsize);
 	if (nfss->bsize != 0)
 		seq_printf(m, ",bsize=%u", nfss->bsize);
+	seq_printf(m, ",rasize=%lu", nfss->super->s_bdi->ra_pages * PAGE_SIZE);
 	seq_printf(m, ",namlen=%u", nfss->namelen);
 	if (nfss->acregmin != NFS_DEF_ACREGMIN*HZ || showdefaults)
 		seq_printf(m, ",acregmin=%u", nfss->acregmin/HZ);
@@ -1281,6 +1282,7 @@ int nfs_get_tree_common(struct fs_context *fc)
 		if (error)
 			goto error_splat_super;
 		s->s_bdi->io_pages = server->rpages;
+		s->s_bdi->ra_pages = server->rasize / PAGE_SIZE;
 		server->super = s;
 	}
 
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index d71a0e90faeb..fe7469ce81e1 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -162,6 +162,7 @@ struct nfs_server {
 	unsigned int		rpages;		/* read size (in pages) */
 	unsigned int		wsize;		/* write size */
 	unsigned int		wpages;		/* write size (in pages) */
+	unsigned int            rasize;         /* read ahead size */
 	unsigned int		wtmult;		/* server disk block size */
 	unsigned int		dtsize;		/* readdir size */
 	unsigned short		port;		/* "port=" setting */
diff --git a/include/uapi/linux/nfs4_mount.h b/include/uapi/linux/nfs4_mount.h
index d20bb869bb99..f9799fdccf06 100644
--- a/include/uapi/linux/nfs4_mount.h
+++ b/include/uapi/linux/nfs4_mount.h
@@ -54,6 +54,7 @@ struct nfs4_mount_data {
 	/* Pseudo-flavours to use for authentication. See RFC2623 */
 	int auth_flavourlen;			/* 1 */
 	int __user *auth_flavours;		/* 1 */
+	int rasize;                             /* 1 */
 };
 
 /* bits in the flags field */
diff --git a/include/uapi/linux/nfs_mount.h b/include/uapi/linux/nfs_mount.h
index e3bcfc6aa3b0..0a5f40e986cf 100644
--- a/include/uapi/linux/nfs_mount.h
+++ b/include/uapi/linux/nfs_mount.h
@@ -44,6 +44,7 @@ struct nfs_mount_data {
 	struct nfs3_fh	root;			/* 4 */
 	int		pseudoflavor;		/* 5 */
 	char		context[NFS_MAX_CONTEXT_LEN + 1];	/* 6 */
+	int		rasize;			/* 1 */
 };
 
 /* bits in the flags field visible to user space */
-- 
2.31.1




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux