On 13 Mar 2025, at 10:33, Benjamin Coddington wrote: > There are certain users that wish to force the NFS client to choose > READDIRPLUS over READDIR for a particular mount. Update the "rdirplus" mount > option to optionally accept values. For "rdirplus=force", the NFS client > will always attempt to use READDDIRPLUS. The setting of "rdirplus=none" is > aliased to the existing "nordirplus". > > Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx> > --- > fs/nfs/dir.c | 2 ++ > fs/nfs/fs_context.c | 32 ++++++++++++++++++++++++++++---- > fs/nfs/super.c | 1 + > include/linux/nfs_fs_sb.h | 1 + > 4 files changed, 32 insertions(+), 4 deletions(-) > > diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c > index 2b04038b0e40..c9de0e474cf5 100644 > --- a/fs/nfs/dir.c > +++ b/fs/nfs/dir.c > @@ -666,6 +666,8 @@ static bool nfs_use_readdirplus(struct inode *dir, struct dir_context *ctx, > { > if (!nfs_server_capable(dir, NFS_CAP_READDIRPLUS)) > return false; > + if (NFS_SERVER(dir)->flags && NFS_MOUNT_FORCE_RDIRPLUS) > + return true; > if (ctx->pos == 0 || > cache_hits + cache_misses > NFS_READDIR_CACHE_USAGE_THRESHOLD) > return true; > diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c > index b069385eea17..ad0135fcc563 100644 > --- a/fs/nfs/fs_context.c > +++ b/fs/nfs/fs_context.c > @@ -72,6 +72,8 @@ enum nfs_param { > Opt_posix, > Opt_proto, > Opt_rdirplus, > + Opt_rdirplus_none, > + Opt_rdirplus_force, > Opt_rdma, > Opt_resvport, > Opt_retrans, > @@ -174,7 +176,8 @@ 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_flag_no("rdirplus", Opt_rdirplus), > + fsparam_flag_no("rdirplus", Opt_rdirplus), // rdirplus|nordirplus > + fsparam_string("rdirplus", Opt_rdirplus), // rdirplus=... > fsparam_flag ("rdma", Opt_rdma), > fsparam_flag_no("resvport", Opt_resvport), > fsparam_u32 ("retrans", Opt_retrans), > @@ -288,6 +291,12 @@ static const struct constant_table nfs_xprtsec_policies[] = { > {} > }; > > +static const struct constant_table nfs_rdirplus_tokens[] = { > + { "none", Opt_rdirplus_none }, > + { "force", Opt_rdirplus_force }, > + {} > +}; > + > /* > * Sanity-check a server address provided by the mount command. > * > @@ -636,10 +645,25 @@ static int nfs_fs_context_parse_param(struct fs_context *fc, > ctx->flags &= ~NFS_MOUNT_NOACL; > break; > case Opt_rdirplus: > - if (result.negated) > + if (result.negated) { > + ctx->flags &= ~NFS_MOUNT_FORCE_RDIRPLUS; > ctx->flags |= NFS_MOUNT_NORDIRPLUS; > - else > - ctx->flags &= ~NFS_MOUNT_NORDIRPLUS; > + } else if (!param->string) { > + ctx->flags &= ~(NFS_MOUNT_NORDIRPLUS || NFS_MOUNT_FORCE_RDIRPLUS); ^^ this is broken.. v3 incoming. Ben