@@ -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;
@@ -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;
@@ -97,6 +97,7 @@ struct nfs_fs_context {
unsigned short protofamily;
unsigned short mountfamily;
bool has_sec_mnt_opts;
+ unsigned int rasize;
struct {
union {
@@ -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;
@@ -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;
}
@@ -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 */
@@ -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 */
@@ -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 */
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@gmail.com> --- 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(-)