static int nfs_do_mount_v4(struct nfsmount_info *mi, struct sockaddr *sap, socklen_t salen) { struct mount_options *options = po_dup(mi->options); int result = 0; if (!options) { errno = ENOMEM; return result; } 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; } } if (!nfs_append_addr_option(sap, salen, options)) { errno = EINVAL; goto out_fail; } if (!nfs_append_clientaddr_option(sap, salen, options)) { 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; goto out_fail; } if (verbose) printf(_("%s: trying text-based options '%s'\n"), progname, *mi->extra_opts); result = nfs_sys_mount(mi, options); out_fail: po_destroy(options); return result; }
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; /* * Before 2.6.32, the kernel NFS client didn't * support "-t nfs vers=4" mounts, so NFS version * 4 cannot be included when autonegotiating * while running on those kernels. */ if (mi->version == 0 && linux_version_code() <= MAKE_VERSION(2, 6, 31)) 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; }
/* * Called to discover our address and append an appropriate 'clientaddr=' * option to the options string. * * Returns 1 if 'clientaddr=' option created successfully or if * 'clientaddr=' option is already present; otherwise zero. */ static int nfs_append_clientaddr_option(const struct sockaddr *sap, socklen_t salen, struct mount_options *options) { union nfs_sockaddr address; struct sockaddr *my_addr = &address.sa; socklen_t my_len = sizeof(address); if (po_contains(options, "clientaddr") == PO_FOUND) return 1; nfs_callback_address(sap, salen, my_addr, &my_len); return nfs_append_generic_address_option(my_addr, my_len, "clientaddr", options); }