X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fstropts.c;h=a0b9e7fdf80a0f8967bda37c05b1ee34444769a0;hp=ceefdb0fc24cecb5a5215db809fbe01fece76251;hb=2498a68b1bec01d0ee8a63962b314140e8289036;hpb=a8b90e8f64a7d53b20c0980f2a6d9a8d5945bcc4 diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index ceefdb0..a0b9e7f 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -93,6 +93,25 @@ struct nfsmount_info { child; /* forked bg child? */ }; +#ifdef MOUNT_CONFIG +static void nfs_default_version(struct nfsmount_info *mi); + +static void nfs_default_version(struct nfsmount_info *mi) +{ + extern unsigned long config_default_vers; + /* + * Use the default value set in the config file when + * the version has not been explicitly set. + */ + if (mi->version == 0 && config_default_vers) { + if (config_default_vers < 4) + mi->version = config_default_vers; + } +} +#else +inline void nfs_default_version(struct nfsmount_info *mi) {} +#endif /* MOUNT_CONFIG */ + /* * Obtain a retry timeout value based on the value of the "retry=" option. * @@ -259,6 +278,40 @@ static int nfs_append_sloppy_option(struct mount_options *options) return 1; } +static int nfs_set_version(struct nfsmount_info *mi) +{ + if (!nfs_nfs_version(mi->options, &mi->version)) + return 0; + + if (strncmp(mi->type, "nfs4", 4) == 0) + mi->version = 4; + else { + char *option = po_get(mi->options, "proto"); + if (option && strcmp(option, "rdma") == 0) + mi->version = 3; + } + + /* + * If we still don't know, check for version-specific + * mount options. + */ + if (mi->version == 0) { + if (po_contains(mi->options, "mounthost") || + po_contains(mi->options, "mountaddr") || + po_contains(mi->options, "mountvers") || + po_contains(mi->options, "mountproto")) + mi->version = 3; + } + + /* + * If enabled, see if the default version was + * set in the config file + */ + nfs_default_version(mi); + + return 1; +} + /* * Set up mandatory non-version specific NFS mount options. * @@ -275,23 +328,8 @@ static int nfs_validate_options(struct nfsmount_info *mi) if (!nfs_name_to_address(mi->hostname, sap, &mi->salen)) return 0; - if (!nfs_nfs_version(mi->options, &mi->version)) + if (!nfs_set_version(mi)) return 0; - if (strncmp(mi->type, "nfs4", 4) == 0) - mi->version = 4; - else { - char *option = po_get(mi->options, "proto"); - if (option && strcmp(option, "rdma") == 0) - mi->version = 3; - } - /* - * Use the default value set in the config file when - * the version has not been explicitly set. - */ - if (mi->version == 0 && config_default_vers) { - if (config_default_vers < 4) - mi->version = config_default_vers; - } if (!nfs_append_sloppy_option(mi->options)) return 0; @@ -573,6 +611,18 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) } if (mi->version == 0) { + if (po_contains(options, "mounthost") || + po_contains(options, "mountaddr") || + po_contains(options, "mountvers") || + po_contains(options, "mountproto")) { + /* + * Since these mountd options are set assume version 3 + * is wanted so error out with EPROTONOSUPPORT so the + * protocol negation starts with v3. + */ + errno = EPROTONOSUPPORT; + goto out_fail; + } if (po_append(options, "vers=4") == PO_FAILED) { errno = EINVAL; goto out_fail; @@ -583,12 +633,13 @@ static int nfs_try_mount_v4(struct nfsmount_info *mi) errno = EINVAL; goto out_fail; } + /* * Update option string to be recorded in /etc/mtab. */ if (po_join(options, mi->extra_opts) == PO_FAILED) { errno = ENOMEM; - return 0; + goto out_fail; } result = nfs_sys_mount(mi, options); @@ -613,8 +664,15 @@ static int nfs_try_mount(struct nfsmount_info *mi) if (linux_version_code() > MAKE_VERSION(2, 6, 31)) { errno = 0; result = nfs_try_mount_v4(mi); - if (errno != EPROTONOSUPPORT) - break; + if (errno != EPROTONOSUPPORT) { + /* + * To deal with legacy Linux servers that don't + * automatically export a pseudo root, retry + * ENOENT errors using version 3 + */ + if (errno != ENOENT) + break; + } } case 2: case 3: