* [PATCH 0/1] Mount option - force READDIRPLUS
@ 2025-03-12 19:46 Benjamin Coddington
2025-03-12 19:46 ` [PATCH 1/1] NFS: New mount option force_rdirplus Benjamin Coddington
0 siblings, 1 reply; 6+ messages in thread
From: Benjamin Coddington @ 2025-03-12 19:46 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs
After these two changes:
1a34c8c9a49e NFS: Support larger readdir buffers
and
85aa8ddc3818 NFS: Trigger the "ls -l" readdir heuristic sooner
.. we've disadvantaged/regressed some users workloads where the user is
forced to use NFSv3 (such that we cannot prime the dcache with d_type on
READDIR as we do for NFSv4), and where the workload is a search through a
large directory tree. Previously, the smaller buffers and/or the larger
heuristic size worked to their advantage to optimize the client toward the
READDIRPLUS path.
We've been able to relieve some pain temporarily by putting a knob into
sysfs to allow them to set the operation to one of:
- force READDIRPLUS
- disable READDIRPLUS
- use the default heurstic
That's exactly the solution they're looking for and we have most of that in
mount options today with the "rdirplus" and "nordirplus". Missing only is
the option to force the client to always use READDIR plus. What follows is
a patch to do that with a new mount option. I'll follow this up with a man
page update to nfs-utils.
The global heuristic is always going to be wrong for some workloads and we
cannnot depend on something like a mount-wide option to always work well for
mixed workloads on the same mount. A realistic long-term solution involves
allowing the applications to signal their intended behavior.
So, I am going to look at plumbing in a posix_fadvise() flag for
READDIRPLUS. There's been some interest expressed already for other
filesystems[1]. I plan to send along patches for this and face the
discussions. However, that work will take some time to filter up into the
utilities and into distros. In the meantime, I hope we can add this simpler
mount option to help the folks that need the old behaviors in recent
kernels.
[1]: https://lore.kernel.org/linux-fsdevel/CAOQ4uxhBWV3DfqaE=reuPjh8w92wwujA6Abj=Gt0YvapR4m_1g@mail.gmail.com/
Benjamin Coddington (1):
NFS: New mount option force_rdirplus
fs/nfs/dir.c | 2 ++
fs/nfs/fs_context.c | 14 ++++++++++++--
include/linux/nfs_fs_sb.h | 1 +
3 files changed, 15 insertions(+), 2 deletions(-)
base-commit: 2408a807bfc3f738850ef5ad5e3fd59d66168996
--
2.47.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/1] NFS: New mount option force_rdirplus
2025-03-12 19:46 [PATCH 0/1] Mount option - force READDIRPLUS Benjamin Coddington
@ 2025-03-12 19:46 ` Benjamin Coddington
2025-03-12 22:48 ` Trond Myklebust
2025-03-13 14:20 ` kernel test robot
0 siblings, 2 replies; 6+ messages in thread
From: Benjamin Coddington @ 2025-03-12 19:46 UTC (permalink / raw)
To: Trond Myklebust, Anna Schumaker; +Cc: linux-nfs
There are certain users that wish to force the NFS client to choose
READDIRPLUS over READDIR for a particular mount. Add a new kernel mount
option "force_rdirplus" to carry that intent.
Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
fs/nfs/dir.c | 2 ++
fs/nfs/fs_context.c | 14 ++++++++++++--
include/linux/nfs_fs_sb.h | 1 +
3 files changed, 15 insertions(+), 2 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..3ba44b444031 100644
--- a/fs/nfs/fs_context.c
+++ b/fs/nfs/fs_context.c
@@ -72,6 +72,7 @@ enum nfs_param {
Opt_posix,
Opt_proto,
Opt_rdirplus,
+ Opt_force_rdirplus,
Opt_rdma,
Opt_resvport,
Opt_retrans,
@@ -175,6 +176,7 @@ static const struct fs_parameter_spec nfs_fs_parameters[] = {
fsparam_flag_no("posix", Opt_posix),
fsparam_string("proto", Opt_proto),
fsparam_flag_no("rdirplus", Opt_rdirplus),
+ fsparam_flag ("force_rdirplus", Opt_force_rdirplus),
fsparam_flag ("rdma", Opt_rdma),
fsparam_flag_no("resvport", Opt_resvport),
fsparam_u32 ("retrans", Opt_retrans),
@@ -636,10 +638,18 @@ 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) {
+ if (ctx->flags && NFS_MOUNT_FORCE_RDIRPLUS)
+ return nfs_invalf(fc, "NFS: Cannot both force and disable READDIR PLUS");
ctx->flags |= NFS_MOUNT_NORDIRPLUS;
- else
+ } else {
ctx->flags &= ~NFS_MOUNT_NORDIRPLUS;
+ }
+ break;
+ case Opt_force_rdirplus:
+ if (ctx->flags && NFS_MOUNT_NORDIRPLUS)
+ return nfs_invalf(fc, "NFS: Cannot both force and disable READDIR PLUS");
+ ctx->flags |= NFS_MOUNT_FORCE_RDIRPLUS;
break;
case Opt_sharecache:
if (result.negated)
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index f00bfcee7120..3774b2235a1e 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -167,6 +167,7 @@ struct nfs_server {
#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000
#define NFS_MOUNT_SHUTDOWN 0x08000000
#define NFS_MOUNT_NO_ALIGNWRITE 0x10000000
+#define NFS_MOUNT_FORCE_RDIRPLUS 0x20000000
unsigned int fattr_valid; /* Valid attributes */
unsigned int caps; /* server capabilities */
--
2.47.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] NFS: New mount option force_rdirplus
2025-03-12 19:46 ` [PATCH 1/1] NFS: New mount option force_rdirplus Benjamin Coddington
@ 2025-03-12 22:48 ` Trond Myklebust
2025-03-12 22:57 ` Benjamin Coddington
2025-03-13 14:20 ` kernel test robot
1 sibling, 1 reply; 6+ messages in thread
From: Trond Myklebust @ 2025-03-12 22:48 UTC (permalink / raw)
To: anna@kernel.org, bcodding@redhat.com; +Cc: linux-nfs@vger.kernel.org
On Wed, 2025-03-12 at 15:46 -0400, Benjamin Coddington wrote:
> There are certain users that wish to force the NFS client to choose
> READDIRPLUS over READDIR for a particular mount. Add a new kernel
> mount
> option "force_rdirplus" to carry that intent.
Could we perhaps convert rdirplus to be a string with an optional
payload? Does the "fs_param_can_be_empty" flag allow you to convert
rdirplus into something that can behave as currently if you just
specify '-ordirplus', but that would allow you to specify '-
ordirplus=force' if you wanted to always use readdirplus?
--
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] NFS: New mount option force_rdirplus
2025-03-12 22:48 ` Trond Myklebust
@ 2025-03-12 22:57 ` Benjamin Coddington
2025-03-12 23:03 ` Trond Myklebust
0 siblings, 1 reply; 6+ messages in thread
From: Benjamin Coddington @ 2025-03-12 22:57 UTC (permalink / raw)
To: Trond Myklebust; +Cc: anna, linux-nfs
On 12 Mar 2025, at 18:48, Trond Myklebust wrote:
> On Wed, 2025-03-12 at 15:46 -0400, Benjamin Coddington wrote:
>> There are certain users that wish to force the NFS client to choose
>> READDIRPLUS over READDIR for a particular mount. Add a new kernel
>> mount
>> option "force_rdirplus" to carry that intent.
>
> Could we perhaps convert rdirplus to be a string with an optional
> payload? Does the "fs_param_can_be_empty" flag allow you to convert
> rdirplus into something that can behave as currently if you just
> specify '-ordirplus', but that would allow you to specify '-
> ordirplus=force' if you wanted to always use readdirplus?
Yes, I think that's possible. I originally started down that route, but
abandoned it after it appeared to be a bigger code diff because you have to
re-define the nordirplus option which we get for free with fsparam_flag_no.
I can send a v2 that way if it's preferred.
Ben
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] NFS: New mount option force_rdirplus
2025-03-12 22:57 ` Benjamin Coddington
@ 2025-03-12 23:03 ` Trond Myklebust
0 siblings, 0 replies; 6+ messages in thread
From: Trond Myklebust @ 2025-03-12 23:03 UTC (permalink / raw)
To: bcodding@redhat.com; +Cc: anna@kernel.org, linux-nfs@vger.kernel.org
On Wed, 2025-03-12 at 18:57 -0400, Benjamin Coddington wrote:
> On 12 Mar 2025, at 18:48, Trond Myklebust wrote:
>
> > On Wed, 2025-03-12 at 15:46 -0400, Benjamin Coddington wrote:
> > > There are certain users that wish to force the NFS client to
> > > choose
> > > READDIRPLUS over READDIR for a particular mount. Add a new
> > > kernel
> > > mount
> > > option "force_rdirplus" to carry that intent.
> >
> > Could we perhaps convert rdirplus to be a string with an optional
> > payload? Does the "fs_param_can_be_empty" flag allow you to convert
> > rdirplus into something that can behave as currently if you just
> > specify '-ordirplus', but that would allow you to specify '-
> > ordirplus=force' if you wanted to always use readdirplus?
>
> Yes, I think that's possible. I originally started down that route,
> but
> abandoned it after it appeared to be a bigger code diff because you
> have to
> re-define the nordirplus option which we get for free with
> fsparam_flag_no.
>
> I can send a v2 that way if it's preferred.
To me that seems tidier, and easier to remember. It also allows you to
alias nordirplus as a 'rdirplus=none' option, should that be desirable.
--
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/1] NFS: New mount option force_rdirplus
2025-03-12 19:46 ` [PATCH 1/1] NFS: New mount option force_rdirplus Benjamin Coddington
2025-03-12 22:48 ` Trond Myklebust
@ 2025-03-13 14:20 ` kernel test robot
1 sibling, 0 replies; 6+ messages in thread
From: kernel test robot @ 2025-03-13 14:20 UTC (permalink / raw)
To: Benjamin Coddington, Trond Myklebust, Anna Schumaker
Cc: llvm, oe-kbuild-all, linux-nfs
Hi Benjamin,
kernel test robot noticed the following build warnings:
[auto build test WARNING on 2408a807bfc3f738850ef5ad5e3fd59d66168996]
url: https://github.com/intel-lab-lkp/linux/commits/Benjamin-Coddington/NFS-New-mount-option-force_rdirplus/20250313-034816
base: 2408a807bfc3f738850ef5ad5e3fd59d66168996
patch link: https://lore.kernel.org/r/4a471ab1bdea1052f45d894c967d0a6b6e38d4a6.1741806879.git.bcodding%40redhat.com
patch subject: [PATCH 1/1] NFS: New mount option force_rdirplus
config: i386-randconfig-003-20250313 (https://download.01.org/0day-ci/archive/20250313/202503132212.aPAVQklX-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250313/202503132212.aPAVQklX-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202503132212.aPAVQklX-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> fs/nfs/fs_context.c:642:19: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
642 | if (ctx->flags && NFS_MOUNT_FORCE_RDIRPLUS)
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~
fs/nfs/fs_context.c:642:19: note: use '&' for a bitwise operation
642 | if (ctx->flags && NFS_MOUNT_FORCE_RDIRPLUS)
| ^~
| &
fs/nfs/fs_context.c:642:19: note: remove constant to silence this warning
642 | if (ctx->flags && NFS_MOUNT_FORCE_RDIRPLUS)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
fs/nfs/fs_context.c:650:18: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
650 | if (ctx->flags && NFS_MOUNT_NORDIRPLUS)
| ^ ~~~~~~~~~~~~~~~~~~~~
fs/nfs/fs_context.c:650:18: note: use '&' for a bitwise operation
650 | if (ctx->flags && NFS_MOUNT_NORDIRPLUS)
| ^~
| &
fs/nfs/fs_context.c:650:18: note: remove constant to silence this warning
650 | if (ctx->flags && NFS_MOUNT_NORDIRPLUS)
| ^~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
--
>> fs/nfs/dir.c:669:29: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
669 | if (NFS_SERVER(dir)->flags && NFS_MOUNT_FORCE_RDIRPLUS)
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~
fs/nfs/dir.c:669:29: note: use '&' for a bitwise operation
669 | if (NFS_SERVER(dir)->flags && NFS_MOUNT_FORCE_RDIRPLUS)
| ^~
| &
fs/nfs/dir.c:669:29: note: remove constant to silence this warning
669 | if (NFS_SERVER(dir)->flags && NFS_MOUNT_FORCE_RDIRPLUS)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
vim +642 fs/nfs/fs_context.c
529
530 /*
531 * Parse a single mount parameter.
532 */
533 static int nfs_fs_context_parse_param(struct fs_context *fc,
534 struct fs_parameter *param)
535 {
536 struct fs_parse_result result;
537 struct nfs_fs_context *ctx = nfs_fc2context(fc);
538 unsigned short protofamily, mountfamily;
539 unsigned int len;
540 int ret, opt;
541
542 trace_nfs_mount_option(param);
543
544 opt = fs_parse(fc, nfs_fs_parameters, param, &result);
545 if (opt < 0)
546 return (opt == -ENOPARAM && ctx->sloppy) ? 1 : opt;
547
548 if (fc->security)
549 ctx->has_sec_mnt_opts = 1;
550
551 switch (opt) {
552 case Opt_source:
553 if (fc->source)
554 return nfs_invalf(fc, "NFS: Multiple sources not supported");
555 fc->source = param->string;
556 param->string = NULL;
557 break;
558
559 /*
560 * boolean options: foo/nofoo
561 */
562 case Opt_soft:
563 ctx->flags |= NFS_MOUNT_SOFT;
564 ctx->flags &= ~NFS_MOUNT_SOFTERR;
565 break;
566 case Opt_softerr:
567 ctx->flags |= NFS_MOUNT_SOFTERR | NFS_MOUNT_SOFTREVAL;
568 ctx->flags &= ~NFS_MOUNT_SOFT;
569 break;
570 case Opt_hard:
571 ctx->flags &= ~(NFS_MOUNT_SOFT |
572 NFS_MOUNT_SOFTERR |
573 NFS_MOUNT_SOFTREVAL);
574 break;
575 case Opt_softreval:
576 if (result.negated)
577 ctx->flags &= ~NFS_MOUNT_SOFTREVAL;
578 else
579 ctx->flags |= NFS_MOUNT_SOFTREVAL;
580 break;
581 case Opt_posix:
582 if (result.negated)
583 ctx->flags &= ~NFS_MOUNT_POSIX;
584 else
585 ctx->flags |= NFS_MOUNT_POSIX;
586 break;
587 case Opt_cto:
588 if (result.negated)
589 ctx->flags |= NFS_MOUNT_NOCTO;
590 else
591 ctx->flags &= ~NFS_MOUNT_NOCTO;
592 break;
593 case Opt_trunkdiscovery:
594 if (result.negated)
595 ctx->flags &= ~NFS_MOUNT_TRUNK_DISCOVERY;
596 else
597 ctx->flags |= NFS_MOUNT_TRUNK_DISCOVERY;
598 break;
599 case Opt_alignwrite:
600 if (result.negated)
601 ctx->flags |= NFS_MOUNT_NO_ALIGNWRITE;
602 else
603 ctx->flags &= ~NFS_MOUNT_NO_ALIGNWRITE;
604 break;
605 case Opt_ac:
606 if (result.negated)
607 ctx->flags |= NFS_MOUNT_NOAC;
608 else
609 ctx->flags &= ~NFS_MOUNT_NOAC;
610 break;
611 case Opt_lock:
612 if (result.negated) {
613 ctx->lock_status = NFS_LOCK_NOLOCK;
614 ctx->flags |= NFS_MOUNT_NONLM;
615 ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
616 } else {
617 ctx->lock_status = NFS_LOCK_LOCK;
618 ctx->flags &= ~NFS_MOUNT_NONLM;
619 ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
620 }
621 break;
622 case Opt_udp:
623 ctx->flags &= ~NFS_MOUNT_TCP;
624 ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
625 break;
626 case Opt_tcp:
627 case Opt_rdma:
628 ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */
629 ret = xprt_find_transport_ident(param->key);
630 if (ret < 0)
631 goto out_bad_transport;
632 ctx->nfs_server.protocol = ret;
633 break;
634 case Opt_acl:
635 if (result.negated)
636 ctx->flags |= NFS_MOUNT_NOACL;
637 else
638 ctx->flags &= ~NFS_MOUNT_NOACL;
639 break;
640 case Opt_rdirplus:
641 if (result.negated) {
> 642 if (ctx->flags && NFS_MOUNT_FORCE_RDIRPLUS)
643 return nfs_invalf(fc, "NFS: Cannot both force and disable READDIR PLUS");
644 ctx->flags |= NFS_MOUNT_NORDIRPLUS;
645 } else {
646 ctx->flags &= ~NFS_MOUNT_NORDIRPLUS;
647 }
648 break;
649 case Opt_force_rdirplus:
650 if (ctx->flags && NFS_MOUNT_NORDIRPLUS)
651 return nfs_invalf(fc, "NFS: Cannot both force and disable READDIR PLUS");
652 ctx->flags |= NFS_MOUNT_FORCE_RDIRPLUS;
653 break;
654 case Opt_sharecache:
655 if (result.negated)
656 ctx->flags |= NFS_MOUNT_UNSHARED;
657 else
658 ctx->flags &= ~NFS_MOUNT_UNSHARED;
659 break;
660 case Opt_resvport:
661 if (result.negated)
662 ctx->flags |= NFS_MOUNT_NORESVPORT;
663 else
664 ctx->flags &= ~NFS_MOUNT_NORESVPORT;
665 break;
666 case Opt_fscache_flag:
667 if (result.negated)
668 ctx->options &= ~NFS_OPTION_FSCACHE;
669 else
670 ctx->options |= NFS_OPTION_FSCACHE;
671 kfree(ctx->fscache_uniq);
672 ctx->fscache_uniq = NULL;
673 break;
674 case Opt_fscache:
675 trace_nfs_mount_assign(param->key, param->string);
676 ctx->options |= NFS_OPTION_FSCACHE;
677 kfree(ctx->fscache_uniq);
678 ctx->fscache_uniq = param->string;
679 param->string = NULL;
680 break;
681 case Opt_migration:
682 if (result.negated)
683 ctx->options &= ~NFS_OPTION_MIGRATION;
684 else
685 ctx->options |= NFS_OPTION_MIGRATION;
686 break;
687
688 /*
689 * options that take numeric values
690 */
691 case Opt_port:
692 if (result.uint_32 > USHRT_MAX)
693 goto out_of_bounds;
694 ctx->nfs_server.port = result.uint_32;
695 break;
696 case Opt_rsize:
697 ctx->rsize = result.uint_32;
698 break;
699 case Opt_wsize:
700 ctx->wsize = result.uint_32;
701 break;
702 case Opt_bsize:
703 ctx->bsize = result.uint_32;
704 break;
705 case Opt_timeo:
706 if (result.uint_32 < 1 || result.uint_32 > INT_MAX)
707 goto out_of_bounds;
708 ctx->timeo = result.uint_32;
709 break;
710 case Opt_retrans:
711 if (result.uint_32 > INT_MAX)
712 goto out_of_bounds;
713 ctx->retrans = result.uint_32;
714 break;
715 case Opt_acregmin:
716 ctx->acregmin = result.uint_32;
717 break;
718 case Opt_acregmax:
719 ctx->acregmax = result.uint_32;
720 break;
721 case Opt_acdirmin:
722 ctx->acdirmin = result.uint_32;
723 break;
724 case Opt_acdirmax:
725 ctx->acdirmax = result.uint_32;
726 break;
727 case Opt_actimeo:
728 ctx->acregmin = result.uint_32;
729 ctx->acregmax = result.uint_32;
730 ctx->acdirmin = result.uint_32;
731 ctx->acdirmax = result.uint_32;
732 break;
733 case Opt_namelen:
734 ctx->namlen = result.uint_32;
735 break;
736 case Opt_mountport:
737 if (result.uint_32 > USHRT_MAX)
738 goto out_of_bounds;
739 ctx->mount_server.port = result.uint_32;
740 break;
741 case Opt_mountvers:
742 if (result.uint_32 < NFS_MNT_VERSION ||
743 result.uint_32 > NFS_MNT3_VERSION)
744 goto out_of_bounds;
745 ctx->mount_server.version = result.uint_32;
746 break;
747 case Opt_minorversion:
748 if (result.uint_32 > NFS4_MAX_MINOR_VERSION)
749 goto out_of_bounds;
750 ctx->minorversion = result.uint_32;
751 break;
752
753 /*
754 * options that take text values
755 */
756 case Opt_v:
757 ret = nfs_parse_version_string(fc, param->key + 1);
758 if (ret < 0)
759 return ret;
760 break;
761 case Opt_vers:
762 if (!param->string)
763 goto out_invalid_value;
764 trace_nfs_mount_assign(param->key, param->string);
765 ret = nfs_parse_version_string(fc, param->string);
766 if (ret < 0)
767 return ret;
768 break;
769 case Opt_sec:
770 ret = nfs_parse_security_flavors(fc, param);
771 if (ret < 0)
772 return ret;
773 break;
774 case Opt_xprtsec:
775 ret = nfs_parse_xprtsec_policy(fc, param);
776 if (ret < 0)
777 return ret;
778 break;
779
780 case Opt_proto:
781 if (!param->string)
782 goto out_invalid_value;
783 trace_nfs_mount_assign(param->key, param->string);
784 protofamily = AF_INET;
785 switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
786 case Opt_xprt_udp6:
787 protofamily = AF_INET6;
788 fallthrough;
789 case Opt_xprt_udp:
790 ctx->flags &= ~NFS_MOUNT_TCP;
791 ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
792 break;
793 case Opt_xprt_tcp6:
794 protofamily = AF_INET6;
795 fallthrough;
796 case Opt_xprt_tcp:
797 ctx->flags |= NFS_MOUNT_TCP;
798 ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
799 break;
800 case Opt_xprt_rdma6:
801 protofamily = AF_INET6;
802 fallthrough;
803 case Opt_xprt_rdma:
804 /* vector side protocols to TCP */
805 ctx->flags |= NFS_MOUNT_TCP;
806 ret = xprt_find_transport_ident(param->string);
807 if (ret < 0)
808 goto out_bad_transport;
809 ctx->nfs_server.protocol = ret;
810 break;
811 default:
812 goto out_bad_transport;
813 }
814
815 ctx->protofamily = protofamily;
816 break;
817
818 case Opt_mountproto:
819 if (!param->string)
820 goto out_invalid_value;
821 trace_nfs_mount_assign(param->key, param->string);
822 mountfamily = AF_INET;
823 switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
824 case Opt_xprt_udp6:
825 mountfamily = AF_INET6;
826 fallthrough;
827 case Opt_xprt_udp:
828 ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
829 break;
830 case Opt_xprt_tcp6:
831 mountfamily = AF_INET6;
832 fallthrough;
833 case Opt_xprt_tcp:
834 ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
835 break;
836 case Opt_xprt_rdma: /* not used for side protocols */
837 default:
838 goto out_bad_transport;
839 }
840 ctx->mountfamily = mountfamily;
841 break;
842
843 case Opt_addr:
844 trace_nfs_mount_assign(param->key, param->string);
845 len = rpc_pton(fc->net_ns, param->string, param->size,
846 &ctx->nfs_server.address,
847 sizeof(ctx->nfs_server._address));
848 if (len == 0)
849 goto out_invalid_address;
850 ctx->nfs_server.addrlen = len;
851 break;
852 case Opt_clientaddr:
853 trace_nfs_mount_assign(param->key, param->string);
854 kfree(ctx->client_address);
855 ctx->client_address = param->string;
856 param->string = NULL;
857 break;
858 case Opt_mounthost:
859 trace_nfs_mount_assign(param->key, param->string);
860 kfree(ctx->mount_server.hostname);
861 ctx->mount_server.hostname = param->string;
862 param->string = NULL;
863 break;
864 case Opt_mountaddr:
865 trace_nfs_mount_assign(param->key, param->string);
866 len = rpc_pton(fc->net_ns, param->string, param->size,
867 &ctx->mount_server.address,
868 sizeof(ctx->mount_server._address));
869 if (len == 0)
870 goto out_invalid_address;
871 ctx->mount_server.addrlen = len;
872 break;
873 case Opt_nconnect:
874 trace_nfs_mount_assign(param->key, param->string);
875 if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_CONNECTIONS)
876 goto out_of_bounds;
877 ctx->nfs_server.nconnect = result.uint_32;
878 break;
879 case Opt_max_connect:
880 trace_nfs_mount_assign(param->key, param->string);
881 if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_TRANSPORTS)
882 goto out_of_bounds;
883 ctx->nfs_server.max_connect = result.uint_32;
884 break;
885 case Opt_lookupcache:
886 trace_nfs_mount_assign(param->key, param->string);
887 switch (result.uint_32) {
888 case Opt_lookupcache_all:
889 ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
890 break;
891 case Opt_lookupcache_positive:
892 ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE;
893 ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG;
894 break;
895 case Opt_lookupcache_none:
896 ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
897 break;
898 default:
899 goto out_invalid_value;
900 }
901 break;
902 case Opt_local_lock:
903 trace_nfs_mount_assign(param->key, param->string);
904 switch (result.uint_32) {
905 case Opt_local_lock_all:
906 ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK |
907 NFS_MOUNT_LOCAL_FCNTL);
908 break;
909 case Opt_local_lock_flock:
910 ctx->flags |= NFS_MOUNT_LOCAL_FLOCK;
911 break;
912 case Opt_local_lock_posix:
913 ctx->flags |= NFS_MOUNT_LOCAL_FCNTL;
914 break;
915 case Opt_local_lock_none:
916 ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
917 NFS_MOUNT_LOCAL_FCNTL);
918 break;
919 default:
920 goto out_invalid_value;
921 }
922 break;
923 case Opt_write:
924 trace_nfs_mount_assign(param->key, param->string);
925 switch (result.uint_32) {
926 case Opt_write_lazy:
927 ctx->flags &=
928 ~(NFS_MOUNT_WRITE_EAGER | NFS_MOUNT_WRITE_WAIT);
929 break;
930 case Opt_write_eager:
931 ctx->flags |= NFS_MOUNT_WRITE_EAGER;
932 ctx->flags &= ~NFS_MOUNT_WRITE_WAIT;
933 break;
934 case Opt_write_wait:
935 ctx->flags |=
936 NFS_MOUNT_WRITE_EAGER | NFS_MOUNT_WRITE_WAIT;
937 break;
938 default:
939 goto out_invalid_value;
940 }
941 break;
942
943 /*
944 * Special options
945 */
946 case Opt_sloppy:
947 ctx->sloppy = true;
948 break;
949 }
950
951 return 0;
952
953 out_invalid_value:
954 return nfs_invalf(fc, "NFS: Bad mount option value specified");
955 out_invalid_address:
956 return nfs_invalf(fc, "NFS: Bad IP address specified");
957 out_of_bounds:
958 return nfs_invalf(fc, "NFS: Value for '%s' out of range", param->key);
959 out_bad_transport:
960 return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
961 }
962
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-03-13 14:21 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-12 19:46 [PATCH 0/1] Mount option - force READDIRPLUS Benjamin Coddington
2025-03-12 19:46 ` [PATCH 1/1] NFS: New mount option force_rdirplus Benjamin Coddington
2025-03-12 22:48 ` Trond Myklebust
2025-03-12 22:57 ` Benjamin Coddington
2025-03-12 23:03 ` Trond Myklebust
2025-03-13 14:20 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox