^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/nfs/fs_context.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1992 Rick Sladkey
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Conversion to new mount api Copyright (C) David Howells
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * NFS mount handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/fs_parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/nfs_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/nfs_mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/nfs4_mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "nfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define NFSDBG_FACILITY NFSDBG_MOUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #if IS_ENABLED(CONFIG_NFS_V3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define NFS_DEFAULT_VERSION 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define NFS_DEFAULT_VERSION 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define NFS_MAX_CONNECTIONS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) enum nfs_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) Opt_ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) Opt_acdirmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) Opt_acdirmin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) Opt_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) Opt_acregmax,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) Opt_acregmin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) Opt_actimeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) Opt_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) Opt_bg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) Opt_bsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) Opt_clientaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) Opt_cto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) Opt_fg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) Opt_fscache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) Opt_fscache_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) Opt_hard,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) Opt_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) Opt_local_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) Opt_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) Opt_lookupcache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) Opt_migration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) Opt_minorversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) Opt_mountaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) Opt_mounthost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) Opt_mountport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) Opt_mountproto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) Opt_mountvers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) Opt_namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) Opt_nconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) Opt_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) Opt_posix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) Opt_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) Opt_rdirplus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) Opt_rdma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) Opt_resvport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) Opt_retrans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) Opt_retry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) Opt_rsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) Opt_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) Opt_sharecache,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) Opt_sloppy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) Opt_soft,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) Opt_softerr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) Opt_softreval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) Opt_source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) Opt_tcp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) Opt_timeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) Opt_udp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) Opt_v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) Opt_vers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) Opt_wsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) Opt_local_lock_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) Opt_local_lock_flock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) Opt_local_lock_none,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) Opt_local_lock_posix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static const struct constant_table nfs_param_enums_local_lock[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { "all", Opt_local_lock_all },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) { "flock", Opt_local_lock_flock },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) { "posix", Opt_local_lock_posix },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) { "none", Opt_local_lock_none },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) Opt_lookupcache_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) Opt_lookupcache_none,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) Opt_lookupcache_positive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static const struct constant_table nfs_param_enums_lookupcache[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) { "all", Opt_lookupcache_all },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) { "none", Opt_lookupcache_none },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) { "pos", Opt_lookupcache_positive },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) { "positive", Opt_lookupcache_positive },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const struct fs_parameter_spec nfs_fs_parameters[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) fsparam_flag_no("ac", Opt_ac),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) fsparam_u32 ("acdirmax", Opt_acdirmax),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) fsparam_u32 ("acdirmin", Opt_acdirmin),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) fsparam_flag_no("acl", Opt_acl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) fsparam_u32 ("acregmax", Opt_acregmax),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) fsparam_u32 ("acregmin", Opt_acregmin),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) fsparam_u32 ("actimeo", Opt_actimeo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) fsparam_string("addr", Opt_addr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) fsparam_flag ("bg", Opt_bg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) fsparam_u32 ("bsize", Opt_bsize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) fsparam_string("clientaddr", Opt_clientaddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) fsparam_flag_no("cto", Opt_cto),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) fsparam_flag ("fg", Opt_fg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) fsparam_flag_no("fsc", Opt_fscache_flag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) fsparam_string("fsc", Opt_fscache),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) fsparam_flag ("hard", Opt_hard),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) __fsparam(NULL, "intr", Opt_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) fs_param_neg_with_no|fs_param_deprecated, NULL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) fsparam_enum ("local_lock", Opt_local_lock, nfs_param_enums_local_lock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) fsparam_flag_no("lock", Opt_lock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) fsparam_enum ("lookupcache", Opt_lookupcache, nfs_param_enums_lookupcache),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) fsparam_flag_no("migration", Opt_migration),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) fsparam_u32 ("minorversion", Opt_minorversion),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) fsparam_string("mountaddr", Opt_mountaddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) fsparam_string("mounthost", Opt_mounthost),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) fsparam_u32 ("mountport", Opt_mountport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) fsparam_string("mountproto", Opt_mountproto),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) fsparam_u32 ("mountvers", Opt_mountvers),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) fsparam_u32 ("namlen", Opt_namelen),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) fsparam_u32 ("nconnect", Opt_nconnect),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) fsparam_string("nfsvers", Opt_vers),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) fsparam_u32 ("port", Opt_port),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) fsparam_flag_no("posix", Opt_posix),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) fsparam_string("proto", Opt_proto),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) fsparam_flag_no("rdirplus", Opt_rdirplus),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) fsparam_flag ("rdma", Opt_rdma),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) fsparam_flag_no("resvport", Opt_resvport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) fsparam_u32 ("retrans", Opt_retrans),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) fsparam_string("retry", Opt_retry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) fsparam_u32 ("rsize", Opt_rsize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) fsparam_string("sec", Opt_sec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) fsparam_flag_no("sharecache", Opt_sharecache),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) fsparam_flag ("sloppy", Opt_sloppy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) fsparam_flag ("soft", Opt_soft),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) fsparam_flag ("softerr", Opt_softerr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) fsparam_flag ("softreval", Opt_softreval),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) fsparam_string("source", Opt_source),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) fsparam_flag ("tcp", Opt_tcp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) fsparam_u32 ("timeo", Opt_timeo),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) fsparam_flag ("udp", Opt_udp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) fsparam_flag ("v2", Opt_v),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) fsparam_flag ("v3", Opt_v),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) fsparam_flag ("v4", Opt_v),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) fsparam_flag ("v4.0", Opt_v),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) fsparam_flag ("v4.1", Opt_v),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) fsparam_flag ("v4.2", Opt_v),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) fsparam_string("vers", Opt_vers),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) fsparam_u32 ("wsize", Opt_wsize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) Opt_vers_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) Opt_vers_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) Opt_vers_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) Opt_vers_4_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) Opt_vers_4_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) Opt_vers_4_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static const struct constant_table nfs_vers_tokens[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { "2", Opt_vers_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) { "3", Opt_vers_3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) { "4", Opt_vers_4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) { "4.0", Opt_vers_4_0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { "4.1", Opt_vers_4_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) { "4.2", Opt_vers_4_2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) Opt_xprt_rdma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) Opt_xprt_rdma6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) Opt_xprt_tcp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) Opt_xprt_tcp6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) Opt_xprt_udp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) Opt_xprt_udp6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) nr__Opt_xprt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static const struct constant_table nfs_xprt_protocol_tokens[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { "rdma", Opt_xprt_rdma },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) { "rdma6", Opt_xprt_rdma6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) { "tcp", Opt_xprt_tcp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) { "tcp6", Opt_xprt_tcp6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) { "udp", Opt_xprt_udp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { "udp6", Opt_xprt_udp6 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) Opt_sec_krb5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) Opt_sec_krb5i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) Opt_sec_krb5p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) Opt_sec_lkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) Opt_sec_lkeyi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) Opt_sec_lkeyp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) Opt_sec_none,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) Opt_sec_spkm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) Opt_sec_spkmi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) Opt_sec_spkmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) Opt_sec_sys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) nr__Opt_sec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static const struct constant_table nfs_secflavor_tokens[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) { "krb5", Opt_sec_krb5 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { "krb5i", Opt_sec_krb5i },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) { "krb5p", Opt_sec_krb5p },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { "lkey", Opt_sec_lkey },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { "lkeyi", Opt_sec_lkeyi },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) { "lkeyp", Opt_sec_lkeyp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) { "none", Opt_sec_none },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) { "null", Opt_sec_none },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) { "spkm3", Opt_sec_spkm },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { "spkm3i", Opt_sec_spkmi },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) { "spkm3p", Opt_sec_spkmp },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { "sys", Opt_sec_sys },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Sanity-check a server address provided by the mount command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Address family must be initialized, and address must not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * the ANY address for that family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int nfs_verify_server_address(struct sockaddr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) switch (addr->sa_family) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) case AF_INET: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct sockaddr_in *sa = (struct sockaddr_in *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return sa->sin_addr.s_addr != htonl(INADDR_ANY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case AF_INET6: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return !ipv6_addr_any(sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dfprintk(MOUNT, "NFS: Invalid IP address specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * Sanity check the NFS transport protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void nfs_validate_transport_protocol(struct nfs_fs_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) switch (ctx->nfs_server.protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case XPRT_TRANSPORT_UDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) case XPRT_TRANSPORT_TCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) case XPRT_TRANSPORT_RDMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * For text based NFSv2/v3 mounts, the mount protocol transport default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * settings should depend upon the specified NFS transport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static void nfs_set_mount_transport_protocol(struct nfs_fs_context *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) nfs_validate_transport_protocol(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ctx->mount_server.protocol == XPRT_TRANSPORT_UDP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ctx->mount_server.protocol == XPRT_TRANSPORT_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) switch (ctx->nfs_server.protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) case XPRT_TRANSPORT_UDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) case XPRT_TRANSPORT_TCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) case XPRT_TRANSPORT_RDMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Add 'flavor' to 'auth_info' if not already present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * Returns true if 'flavor' ends up in the list, false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int nfs_auth_info_add(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct nfs_auth_info *auth_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) rpc_authflavor_t flavor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* make sure this flavor isn't already in the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) for (i = 0; i < auth_info->flavor_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (flavor == auth_info->flavors[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (auth_info->flavor_len + 1 >= max_flavor_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return nfs_invalf(fc, "NFS: too many sec= flavors");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) auth_info->flavors[auth_info->flavor_len++] = flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Parse the value of the 'sec=' option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int nfs_parse_security_flavors(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) rpc_authflavor_t pseudoflavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) char *string = param->string, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) dfprintk(MOUNT, "NFS: parsing %s=%s option\n", param->key, param->string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) while ((p = strsep(&string, ":")) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (!*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) switch (lookup_constant(nfs_secflavor_tokens, p, -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case Opt_sec_none:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pseudoflavor = RPC_AUTH_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) case Opt_sec_sys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pseudoflavor = RPC_AUTH_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case Opt_sec_krb5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pseudoflavor = RPC_AUTH_GSS_KRB5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case Opt_sec_krb5i:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) pseudoflavor = RPC_AUTH_GSS_KRB5I;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case Opt_sec_krb5p:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) pseudoflavor = RPC_AUTH_GSS_KRB5P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case Opt_sec_lkey:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) pseudoflavor = RPC_AUTH_GSS_LKEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case Opt_sec_lkeyi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pseudoflavor = RPC_AUTH_GSS_LKEYI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case Opt_sec_lkeyp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pseudoflavor = RPC_AUTH_GSS_LKEYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case Opt_sec_spkm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pseudoflavor = RPC_AUTH_GSS_SPKM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case Opt_sec_spkmi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pseudoflavor = RPC_AUTH_GSS_SPKMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case Opt_sec_spkmp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) pseudoflavor = RPC_AUTH_GSS_SPKMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return nfs_invalf(fc, "NFS: sec=%s option not recognized", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = nfs_auth_info_add(fc, &ctx->auth_info, pseudoflavor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int nfs_parse_version_string(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ctx->flags &= ~NFS_MOUNT_VER3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) switch (lookup_constant(nfs_vers_tokens, string, -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) case Opt_vers_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ctx->version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case Opt_vers_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ctx->flags |= NFS_MOUNT_VER3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ctx->version = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case Opt_vers_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* Backward compatibility option. In future,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * the mount program should always supply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * a NFSv4 minor version number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) ctx->version = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case Opt_vers_4_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ctx->version = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ctx->minorversion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case Opt_vers_4_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ctx->version = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ctx->minorversion = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case Opt_vers_4_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ctx->version = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ctx->minorversion = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return nfs_invalf(fc, "NFS: Unsupported NFS version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * Parse a single mount parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int nfs_fs_context_parse_param(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct fs_parse_result result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) unsigned short protofamily, mountfamily;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int ret, opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) opt = fs_parse(fc, nfs_fs_parameters, param, &result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (opt < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return ctx->sloppy ? 1 : opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) switch (opt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case Opt_source:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (fc->source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return nfs_invalf(fc, "NFS: Multiple sources not supported");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) fc->source = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * boolean options: foo/nofoo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case Opt_soft:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ctx->flags |= NFS_MOUNT_SOFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ctx->flags &= ~NFS_MOUNT_SOFTERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case Opt_softerr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ctx->flags |= NFS_MOUNT_SOFTERR | NFS_MOUNT_SOFTREVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ctx->flags &= ~NFS_MOUNT_SOFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) case Opt_hard:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ctx->flags &= ~(NFS_MOUNT_SOFT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) NFS_MOUNT_SOFTERR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) NFS_MOUNT_SOFTREVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case Opt_softreval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ctx->flags &= ~NFS_MOUNT_SOFTREVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ctx->flags &= NFS_MOUNT_SOFTREVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case Opt_posix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ctx->flags &= ~NFS_MOUNT_POSIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ctx->flags |= NFS_MOUNT_POSIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) case Opt_cto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ctx->flags |= NFS_MOUNT_NOCTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ctx->flags &= ~NFS_MOUNT_NOCTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) case Opt_ac:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ctx->flags |= NFS_MOUNT_NOAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ctx->flags &= ~NFS_MOUNT_NOAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case Opt_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (result.negated) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ctx->flags |= NFS_MOUNT_NONLM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ctx->flags &= ~NFS_MOUNT_NONLM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case Opt_udp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ctx->flags &= ~NFS_MOUNT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) case Opt_tcp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ctx->flags |= NFS_MOUNT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case Opt_rdma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) xprt_load_transport(param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case Opt_acl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) ctx->flags |= NFS_MOUNT_NOACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ctx->flags &= ~NFS_MOUNT_NOACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case Opt_rdirplus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ctx->flags |= NFS_MOUNT_NORDIRPLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ctx->flags &= ~NFS_MOUNT_NORDIRPLUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) case Opt_sharecache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ctx->flags |= NFS_MOUNT_UNSHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ctx->flags &= ~NFS_MOUNT_UNSHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) case Opt_resvport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ctx->flags |= NFS_MOUNT_NORESVPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ctx->flags &= ~NFS_MOUNT_NORESVPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case Opt_fscache_flag:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ctx->options &= ~NFS_OPTION_FSCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ctx->options |= NFS_OPTION_FSCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) kfree(ctx->fscache_uniq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ctx->fscache_uniq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) case Opt_fscache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ctx->options |= NFS_OPTION_FSCACHE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) kfree(ctx->fscache_uniq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ctx->fscache_uniq = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) case Opt_migration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (result.negated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ctx->options &= ~NFS_OPTION_MIGRATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ctx->options |= NFS_OPTION_MIGRATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * options that take numeric values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) case Opt_port:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (result.uint_32 > USHRT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ctx->nfs_server.port = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) case Opt_rsize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) ctx->rsize = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) case Opt_wsize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ctx->wsize = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case Opt_bsize:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ctx->bsize = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case Opt_timeo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (result.uint_32 < 1 || result.uint_32 > INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ctx->timeo = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) case Opt_retrans:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (result.uint_32 > INT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ctx->retrans = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case Opt_acregmin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ctx->acregmin = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case Opt_acregmax:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ctx->acregmax = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) case Opt_acdirmin:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ctx->acdirmin = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case Opt_acdirmax:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) ctx->acdirmax = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case Opt_actimeo:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ctx->acregmin = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ctx->acregmax = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ctx->acdirmin = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ctx->acdirmax = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) case Opt_namelen:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ctx->namlen = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case Opt_mountport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (result.uint_32 > USHRT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ctx->mount_server.port = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) case Opt_mountvers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (result.uint_32 < NFS_MNT_VERSION ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) result.uint_32 > NFS_MNT3_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ctx->mount_server.version = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case Opt_minorversion:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (result.uint_32 > NFS4_MAX_MINOR_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ctx->minorversion = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * options that take text values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case Opt_v:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = nfs_parse_version_string(fc, param->key + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) case Opt_vers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = nfs_parse_version_string(fc, param->string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case Opt_sec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) ret = nfs_parse_security_flavors(fc, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) case Opt_proto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) protofamily = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case Opt_xprt_udp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) protofamily = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) case Opt_xprt_udp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ctx->flags &= ~NFS_MOUNT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) case Opt_xprt_tcp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) protofamily = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case Opt_xprt_tcp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ctx->flags |= NFS_MOUNT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) case Opt_xprt_rdma6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) protofamily = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case Opt_xprt_rdma:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* vector side protocols to TCP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ctx->flags |= NFS_MOUNT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) xprt_load_transport(param->string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ctx->protofamily = protofamily;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) case Opt_mountproto:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) mountfamily = AF_INET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) case Opt_xprt_udp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) mountfamily = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case Opt_xprt_udp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case Opt_xprt_tcp6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) mountfamily = AF_INET6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) case Opt_xprt_tcp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case Opt_xprt_rdma: /* not used for side protocols */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ctx->mountfamily = mountfamily;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) case Opt_addr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) len = rpc_pton(fc->net_ns, param->string, param->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) &ctx->nfs_server.address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) sizeof(ctx->nfs_server._address));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) goto out_invalid_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) ctx->nfs_server.addrlen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) case Opt_clientaddr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) kfree(ctx->client_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ctx->client_address = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case Opt_mounthost:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) kfree(ctx->mount_server.hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ctx->mount_server.hostname = param->string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) param->string = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) case Opt_mountaddr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) len = rpc_pton(fc->net_ns, param->string, param->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) &ctx->mount_server.address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) sizeof(ctx->mount_server._address));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) goto out_invalid_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ctx->mount_server.addrlen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) case Opt_nconnect:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_CONNECTIONS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) goto out_of_bounds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ctx->nfs_server.nconnect = result.uint_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) case Opt_lookupcache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) switch (result.uint_32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) case Opt_lookupcache_all:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) case Opt_lookupcache_positive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case Opt_lookupcache_none:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) goto out_invalid_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case Opt_local_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) switch (result.uint_32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) case Opt_local_lock_all:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) case Opt_local_lock_flock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ctx->flags |= NFS_MOUNT_LOCAL_FLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case Opt_local_lock_posix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ctx->flags |= NFS_MOUNT_LOCAL_FCNTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case Opt_local_lock_none:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) goto out_invalid_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * Special options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case Opt_sloppy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ctx->sloppy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dfprintk(MOUNT, "NFS: relaxing parsing rules\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) out_invalid_value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) return nfs_invalf(fc, "NFS: Bad mount option value specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) out_invalid_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return nfs_invalf(fc, "NFS: Bad IP address specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) out_of_bounds:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return nfs_invalf(fc, "NFS: Value for '%s' out of range", param->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * Split fc->source into "hostname:export_path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * The leftmost colon demarks the split between the server's hostname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * and the export path. If the hostname starts with a left square
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * bracket, then it may contain colons.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * Note: caller frees hostname and export path, even on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static int nfs_parse_source(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) size_t maxnamlen, size_t maxpathlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) const char *dev_name = fc->source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) const char *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (unlikely(!dev_name || !*dev_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) dfprintk(MOUNT, "NFS: device name not specified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* Is the host name protected with square brakcets? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (*dev_name == '[') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) end = strchr(++dev_name, ']');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (end == NULL || end[1] != ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) goto out_bad_devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) len = end - dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) end++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) const char *comma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) end = strchr(dev_name, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (end == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) goto out_bad_devname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) len = end - dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) /* kill possible hostname list: not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) comma = memchr(dev_name, ',', len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (comma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) len = comma - dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (len > maxnamlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) goto out_hostname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) kfree(ctx->nfs_server.hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* N.B. caller will free nfs_server.hostname in all cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (!ctx->nfs_server.hostname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) len = strlen(++end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (len > maxpathlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) goto out_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) ctx->nfs_server.export_path = kmemdup_nul(end, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!ctx->nfs_server.export_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", ctx->nfs_server.export_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) out_bad_devname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return nfs_invalf(fc, "NFS: device name not in host:path format");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) out_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) nfs_errorf(fc, "NFS: not enough memory to parse device name");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) out_hostname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) nfs_errorf(fc, "NFS: server hostname too long");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) out_path:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) nfs_errorf(fc, "NFS: export pathname too long");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static inline bool is_remount_fc(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return fc->root != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * Parse monolithic NFS2/NFS3 mount data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * - fills in the mount root filehandle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * For option strings, user space handles the following behaviors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * + DNS: mapping server host name to IP address ("addr=" option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * + failure mode: how to behave if a mount request can't be handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * immediately ("fg/bg" option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * + retry: how often to retry a mount request ("retry=" option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * mountproto=tcp after mountproto=udp, and so on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static int nfs23_parse_monolithic(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct nfs_mount_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct nfs_fh *mntfh = ctx->mntfh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) goto out_no_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) ctx->version = NFS_DEFAULT_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) switch (data->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) data->namlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) data->bsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (data->flags & NFS_MOUNT_VER3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto out_no_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) data->root.size = NFS2_FHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /* Turn off security negotiation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) extra_flags |= NFS_MOUNT_SECFLAVOUR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (data->flags & NFS_MOUNT_SECFLAVOUR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) goto out_no_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) memset(data->context, 0, sizeof(data->context));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (data->flags & NFS_MOUNT_VER3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) goto out_invalid_fh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) mntfh->size = data->root.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ctx->version = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) mntfh->size = NFS2_FHSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ctx->version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) memcpy(mntfh->data, data->root.data, mntfh->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (mntfh->size < sizeof(mntfh->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) memset(mntfh->data + mntfh->size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) sizeof(mntfh->data) - mntfh->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * for proto == XPRT_TRANSPORT_UDP, which is what uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * to_exponential, implying shift: limit the shift value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * to BITS_PER_LONG (majortimeo is unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!(data->flags & NFS_MOUNT_TCP)) /* this will be UDP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (data->retrans >= 64) /* shift value is too large */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) goto out_invalid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * Translate to nfs_fs_context, which nfs_fill_super
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * can deal with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) ctx->flags = data->flags & NFS_MOUNT_FLAGMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) ctx->flags |= extra_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) ctx->rsize = data->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) ctx->wsize = data->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) ctx->timeo = data->timeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ctx->retrans = data->retrans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ctx->acregmin = data->acregmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) ctx->acregmax = data->acregmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) ctx->acdirmin = data->acdirmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) ctx->acdirmax = data->acdirmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ctx->need_mount = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) memcpy(sap, &data->addr, sizeof(data->addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) ctx->nfs_server.addrlen = sizeof(data->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) ctx->nfs_server.port = ntohs(data->addr.sin_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (sap->sa_family != AF_INET ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) !nfs_verify_server_address(sap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) goto out_no_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (!(data->flags & NFS_MOUNT_TCP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /* N.B. caller will free nfs_server.hostname in all cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!ctx->nfs_server.hostname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) goto out_nomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) ctx->namlen = data->namlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) ctx->bsize = data->bsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (data->flags & NFS_MOUNT_SECFLAVOUR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ctx->selected_flavor = data->pseudoflavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) ctx->selected_flavor = RPC_AUTH_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!(data->flags & NFS_MOUNT_NONLM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * The legacy version 6 binary mount data from userspace has a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * field used only to transport selinux information into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * kernel. To continue to support that functionality we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * have a touch of selinux knowledge here in the NFS code. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * userspace code converted context=blah to just blah so we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * converting back to the full string selinux understands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (data->context[0]){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) #ifdef CONFIG_SECURITY_SELINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) data->context[NFS_MAX_CONTEXT_LEN] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ret = vfs_parse_fs_string(fc, "context",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) data->context, strlen(data->context));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) goto generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ctx->skip_reconfig_option_check = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) generic:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return generic_parse_monolithic(fc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) out_no_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (is_remount_fc(fc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) ctx->skip_reconfig_option_check = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return nfs_invalf(fc, "NFS: mount program didn't pass any mount data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) out_no_v3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return nfs_invalf(fc, "NFS: nfs_mount_data version does not support v3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) out_no_sec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) return nfs_invalf(fc, "NFS: nfs_mount_data version supports only AUTH_SYS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) out_nomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) dfprintk(MOUNT, "NFS: not enough memory to handle mount options");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) out_no_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return nfs_invalf(fc, "NFS: mount program didn't pass remote address");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) out_invalid_fh:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return nfs_invalf(fc, "NFS: invalid root filehandle");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) out_invalid_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return nfs_invalf(fc, "NFS: invalid binary mount data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) #if IS_ENABLED(CONFIG_NFS_V4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) struct compat_nfs_string {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) compat_uint_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) compat_uptr_t data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static inline void compat_nfs_string(struct nfs_string *dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct compat_nfs_string *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) dst->data = compat_ptr(src->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dst->len = src->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct compat_nfs4_mount_data_v1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) compat_int_t version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) compat_int_t flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) compat_int_t rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) compat_int_t wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) compat_int_t timeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) compat_int_t retrans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) compat_int_t acregmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) compat_int_t acregmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) compat_int_t acdirmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) compat_int_t acdirmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct compat_nfs_string client_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct compat_nfs_string mnt_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct compat_nfs_string hostname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) compat_uint_t host_addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) compat_uptr_t host_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) compat_int_t proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) compat_int_t auth_flavourlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) compat_uptr_t auth_flavours;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void nfs4_compat_mount_data_conv(struct nfs4_mount_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct compat_nfs4_mount_data_v1 *compat =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) (struct compat_nfs4_mount_data_v1 *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* copy the fields backwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) data->auth_flavours = compat_ptr(compat->auth_flavours);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) data->auth_flavourlen = compat->auth_flavourlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) data->proto = compat->proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) data->host_addr = compat_ptr(compat->host_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) data->host_addrlen = compat->host_addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) compat_nfs_string(&data->hostname, &compat->hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) compat_nfs_string(&data->mnt_path, &compat->mnt_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) compat_nfs_string(&data->client_addr, &compat->client_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) data->acdirmax = compat->acdirmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) data->acdirmin = compat->acdirmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) data->acregmax = compat->acregmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) data->acregmin = compat->acregmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) data->retrans = compat->retrans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) data->timeo = compat->timeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) data->wsize = compat->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) data->rsize = compat->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) data->flags = compat->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) data->version = compat->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) * Validate NFSv4 mount options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) static int nfs4_parse_monolithic(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) struct nfs4_mount_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) char *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (is_remount_fc(fc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return nfs_invalf(fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) "NFS4: mount program didn't pass any mount data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ctx->version = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (data->version != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) return generic_parse_monolithic(fc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (in_compat_syscall())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) nfs4_compat_mount_data_conv(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (data->host_addrlen > sizeof(ctx->nfs_server.address))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto out_no_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (data->host_addrlen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) goto out_no_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) ctx->nfs_server.addrlen = data->host_addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (copy_from_user(sap, data->host_addr, data->host_addrlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (!nfs_verify_server_address(sap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) goto out_no_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (data->auth_flavourlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) rpc_authflavor_t pseudoflavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (data->auth_flavourlen > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) goto out_inval_auth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (copy_from_user(&pseudoflavor, data->auth_flavours,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) sizeof(pseudoflavor)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) ctx->selected_flavor = pseudoflavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ctx->selected_flavor = RPC_AUTH_UNIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (IS_ERR(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return PTR_ERR(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) ctx->nfs_server.hostname = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (IS_ERR(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) return PTR_ERR(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ctx->nfs_server.export_path = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) c = strndup_user(data->client_addr.data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (IS_ERR(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return PTR_ERR(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ctx->client_address = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) * Translate to nfs_fs_context, which nfs_fill_super
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * can deal with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) ctx->flags = data->flags & NFS4_MOUNT_FLAGMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ctx->rsize = data->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ctx->wsize = data->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ctx->timeo = data->timeo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ctx->retrans = data->retrans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) ctx->acregmin = data->acregmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) ctx->acregmax = data->acregmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ctx->acdirmin = data->acdirmin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) ctx->acdirmax = data->acdirmax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) ctx->nfs_server.protocol = data->proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) nfs_validate_transport_protocol(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) goto out_invalid_transport_udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) ctx->skip_reconfig_option_check = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) out_inval_auth:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return nfs_invalf(fc, "NFS4: Invalid number of RPC auth flavours %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) data->auth_flavourlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) out_no_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) return nfs_invalf(fc, "NFS4: mount program didn't pass remote address");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) out_invalid_transport_udp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) return nfs_invalf(fc, "NFS: Unsupported transport protocol udp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) * Parse a monolithic block of data from sys_mount().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static int nfs_fs_context_parse_monolithic(struct fs_context *fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (fc->fs_type == &nfs_fs_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) return nfs23_parse_monolithic(fc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) #if IS_ENABLED(CONFIG_NFS_V4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (fc->fs_type == &nfs4_fs_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) return nfs4_parse_monolithic(fc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return nfs_invalf(fc, "NFS: Unsupported monolithic data version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * Validate the preparsed information in the config.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static int nfs_fs_context_validate(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) struct nfs_subversion *nfs_mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) int max_namelen = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) int max_pathlen = NFS_MAXPATHLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) int port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (!fc->source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) goto out_no_device_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) /* Check for sanity first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (ctx->minorversion && ctx->version != 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) goto out_minorversion_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (ctx->options & NFS_OPTION_MIGRATION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) (ctx->version != 4 || ctx->minorversion != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) goto out_migration_misuse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) /* Verify that any proto=/mountproto= options match the address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) * families in the addr=/mountaddr= options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) if (ctx->protofamily != AF_UNSPEC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) ctx->protofamily != ctx->nfs_server.address.sa_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto out_proto_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (ctx->mountfamily != AF_UNSPEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (ctx->mount_server.addrlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) if (ctx->mountfamily != ctx->mount_server.address.sa_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) goto out_mountproto_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (ctx->mountfamily != ctx->nfs_server.address.sa_family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) goto out_mountproto_mismatch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (!nfs_verify_server_address(sap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) goto out_no_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (ctx->version == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (IS_ENABLED(CONFIG_NFS_V4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) port = NFS_RDMA_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) port = NFS_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) max_namelen = NFS4_MAXNAMLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) max_pathlen = NFS4_MAXPATHLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) nfs_validate_transport_protocol(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) goto out_invalid_transport_udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) ctx->flags &= ~(NFS_MOUNT_NONLM | NFS_MOUNT_NOACL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) NFS_MOUNT_VER3 | NFS_MOUNT_LOCAL_FLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) NFS_MOUNT_LOCAL_FCNTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) goto out_v4_not_compiled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) nfs_set_mount_transport_protocol(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) #ifdef CONFIG_NFS_DISABLE_UDP_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) goto out_invalid_transport_udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) port = NFS_RDMA_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) nfs_set_port(sap, &ctx->nfs_server.port, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) ret = nfs_parse_source(fc, max_namelen, max_pathlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /* Load the NFS protocol module if we haven't done so yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (!ctx->nfs_mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) nfs_mod = get_nfs_version(ctx->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (IS_ERR(nfs_mod)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) ret = PTR_ERR(nfs_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) goto out_version_unavailable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) ctx->nfs_mod = nfs_mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) /* Ensure the filesystem context has the correct fs_type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (fc->fs_type != ctx->nfs_mod->nfs_fs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) module_put(fc->fs_type->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) __module_get(ctx->nfs_mod->nfs_fs->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) fc->fs_type = ctx->nfs_mod->nfs_fs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) out_no_device_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return nfs_invalf(fc, "NFS: Device name not specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) out_v4_not_compiled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) nfs_errorf(fc, "NFS: NFSv4 is not compiled into kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) return -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) out_invalid_transport_udp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return nfs_invalf(fc, "NFS: Unsupported transport protocol udp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) out_no_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return nfs_invalf(fc, "NFS: mount program didn't pass remote address");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) out_mountproto_mismatch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return nfs_invalf(fc, "NFS: Mount server address does not match mountproto= option");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) out_proto_mismatch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return nfs_invalf(fc, "NFS: Server address does not match proto= option");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) out_minorversion_mismatch:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return nfs_invalf(fc, "NFS: Mount option vers=%u does not support minorversion=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ctx->version, ctx->minorversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) out_migration_misuse:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return nfs_invalf(fc, "NFS: 'Migration' not supported for this NFS version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) out_version_unavailable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) nfs_errorf(fc, "NFS: Version unavailable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * Create an NFS superblock by the appropriate method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static int nfs_get_tree(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) int err = nfs_fs_context_validate(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (!ctx->internal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return ctx->nfs_mod->rpc_ops->try_get_tree(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return nfs_get_tree_common(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * Handle duplication of a configuration. The caller copied *src into *sc, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * it can't deal with resource pointers in the filesystem context, so we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * to do that. We need to clear pointers, copy data or get extra refs as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) static int nfs_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct nfs_fs_context *src = nfs_fc2context(src_fc), *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ctx = kmemdup(src, sizeof(struct nfs_fs_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (!ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ctx->mntfh = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (!ctx->mntfh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) nfs_copy_fh(ctx->mntfh, src->mntfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) __module_get(ctx->nfs_mod->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) ctx->client_address = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ctx->mount_server.hostname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) ctx->nfs_server.export_path = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) ctx->nfs_server.hostname = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) ctx->fscache_uniq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) ctx->clone_data.fattr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) fc->fs_private = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static void nfs_fs_context_free(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct nfs_fs_context *ctx = nfs_fc2context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (ctx->server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) nfs_free_server(ctx->server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (ctx->nfs_mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) put_nfs_version(ctx->nfs_mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) kfree(ctx->client_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) kfree(ctx->mount_server.hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) kfree(ctx->nfs_server.export_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) kfree(ctx->nfs_server.hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) kfree(ctx->fscache_uniq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) nfs_free_fhandle(ctx->mntfh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) nfs_free_fattr(ctx->clone_data.fattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static const struct fs_context_operations nfs_fs_context_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) .free = nfs_fs_context_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) .dup = nfs_fs_context_dup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) .parse_param = nfs_fs_context_parse_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .parse_monolithic = nfs_fs_context_parse_monolithic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .get_tree = nfs_get_tree,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .reconfigure = nfs_reconfigure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * Prepare superblock configuration. We use the namespaces attached to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * context. This may be the current process's namespaces, or it may be a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) * container's namespaces.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static int nfs_init_fs_context(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) struct nfs_fs_context *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ctx = kzalloc(sizeof(struct nfs_fs_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (unlikely(!ctx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) ctx->mntfh = nfs_alloc_fhandle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (unlikely(!ctx->mntfh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) kfree(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) ctx->protofamily = AF_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) ctx->mountfamily = AF_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) ctx->mount_server.port = NFS_UNSPEC_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) if (fc->root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) /* reconfigure, start with the current config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct nfs_server *nfss = fc->root->d_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) struct net *net = nfss->nfs_client->cl_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) ctx->flags = nfss->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) ctx->rsize = nfss->rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) ctx->wsize = nfss->wsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ctx->retrans = nfss->client->cl_timeout->to_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) ctx->selected_flavor = nfss->client->cl_auth->au_flavor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) ctx->acregmin = nfss->acregmin / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) ctx->acregmax = nfss->acregmax / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) ctx->acdirmin = nfss->acdirmin / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) ctx->acdirmax = nfss->acdirmax / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) ctx->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) ctx->nfs_server.port = nfss->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) ctx->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) ctx->version = nfss->nfs_client->rpc_ops->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) ctx->minorversion = nfss->nfs_client->cl_minorversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) ctx->nfs_server.addrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (fc->net_ns != net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) put_net(fc->net_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) fc->net_ns = get_net(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) ctx->nfs_mod = nfss->nfs_client->cl_nfs_mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) __module_get(ctx->nfs_mod->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /* defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) ctx->timeo = NFS_UNSPEC_TIMEO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) ctx->retrans = NFS_UNSPEC_RETRANS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) ctx->acregmin = NFS_DEF_ACREGMIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) ctx->acregmax = NFS_DEF_ACREGMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) ctx->acdirmin = NFS_DEF_ACDIRMIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) ctx->acdirmax = NFS_DEF_ACDIRMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) ctx->nfs_server.port = NFS_UNSPEC_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) ctx->selected_flavor = RPC_AUTH_MAXFLAVOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ctx->minorversion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) ctx->need_mount = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) fc->fs_private = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) fc->ops = &nfs_fs_context_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct file_system_type nfs_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) .name = "nfs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) .init_fs_context = nfs_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) .parameters = nfs_fs_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) .kill_sb = nfs_kill_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) MODULE_ALIAS_FS("nfs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) EXPORT_SYMBOL_GPL(nfs_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) #if IS_ENABLED(CONFIG_NFS_V4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) struct file_system_type nfs4_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) .name = "nfs4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) .init_fs_context = nfs_init_fs_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .parameters = nfs_fs_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .kill_sb = nfs_kill_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) MODULE_ALIAS_FS("nfs4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) MODULE_ALIAS("nfs4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) EXPORT_SYMBOL_GPL(nfs4_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) #endif /* CONFIG_NFS_V4 */