示例#1
0
文件: network.c 项目: AllardJ/Tomato
/**
 * nfs_options2pmap - set up pmap structs based on mount options
 * @options: pointer to mount options
 * @nfs_pmap: OUT: pointer to pmap arguments for NFS server
 * @mnt_pmap: OUT: pointer to pmap arguments for mountd server
 *
 */
void nfs_options2pmap(struct mount_options *options,
		      struct pmap *nfs_pmap, struct pmap *mnt_pmap)
{
	nfs_pmap->pm_prog = nfs_nfs_program(options);
	nfs_pmap->pm_vers = nfs_nfs_version(options);
	nfs_pmap->pm_prot = nfs_nfs_protocol(options);
	nfs_pmap->pm_port = nfs_nfs_port(options);

	mnt_pmap->pm_prog = nfs_mount_program(options);
	mnt_pmap->pm_vers = nfs_mount_version(options);
	mnt_pmap->pm_prot = nfs_mount_protocol(options);
	mnt_pmap->pm_port = nfs_mount_port(options);
}
示例#2
0
/*
 * Reconstruct the mount option string based on a portmapper probe
 * of the server.  Returns one if the server's portmapper returned
 * something we can use, otherwise zero.
 *
 * To handle version and transport protocol fallback properly, we
 * need to parse some of the mount options in order to set up a
 * portmap probe.  Mount options that nfs_rewrite_pmap_mount_options()
 * doesn't recognize are left alone.
 *
 * Returns TRUE if rewriting was successful; otherwise
 * FALSE is returned if some failure occurred.
 */
static int
nfs_rewrite_pmap_mount_options(struct mount_options *options, int checkv4,
			       struct local_bind_info *local_ip)
{
	union nfs_sockaddr nfs_address;
	struct sockaddr *nfs_saddr = &nfs_address.sa;
	socklen_t nfs_salen = sizeof(nfs_address);
	struct pmap nfs_pmap;
	union nfs_sockaddr mnt_address;
	struct sockaddr *mnt_saddr = &mnt_address.sa;
	socklen_t mnt_salen = sizeof(mnt_address);
	unsigned long protocol;
	struct pmap mnt_pmap;

	/*
	 * Version and transport negotiation is not required
	 * and does not work for RDMA mounts.
	 */
	if (!nfs_nfs_protocol(options, &protocol)) {
		errno = EINVAL;
		return 0;
	}
	if (protocol == NFSPROTO_RDMA)
		goto out;

	/*
	 * Extract just the options needed to contact server.
	 * Bail now if any of these have bad values.
	 */
	if (!nfs_extract_server_addresses(options, nfs_saddr, &nfs_salen,
						mnt_saddr, &mnt_salen)) {
		errno = EINVAL;
		return 0;
	}
	if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap)) {
		errno = EINVAL;
		return 0;
	}

	/*
	 * The kernel NFS client doesn't support changing the RPC
	 * program number for these services, so force the value of
	 * these fields before probing the server's ports.
	 */
	nfs_pmap.pm_prog = NFS_PROGRAM;
	mnt_pmap.pm_prog = MOUNTPROG;

	/*
	 * If the server's rpcbind service isn't available, we can't
	 * negotiate.  Bail now if we can't contact it.
	 */
	if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap,
				 nfs_saddr, nfs_salen, &nfs_pmap, checkv4,
				 local_ip)) {
		errno = ESPIPE;
		if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
			errno = EOPNOTSUPP;
		else if (rpc_createerr.cf_stat == RPC_AUTHERROR)
			errno = EACCES;
		else if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
			errno = ETIMEDOUT;
		else if (rpc_createerr.cf_stat == RPC_PROGVERSMISMATCH)
			errno = EPROTONOSUPPORT;
		else if (rpc_createerr.cf_error.re_errno != 0)
			errno = rpc_createerr.cf_error.re_errno;
		return 0;
	}

	if (!nfs_construct_new_options(options, nfs_saddr, &nfs_pmap,
					mnt_saddr, &mnt_pmap)) {
		if (rpc_createerr.cf_stat == RPC_UNKNOWNPROTO)
			errno = EPROTONOSUPPORT;
		else
			errno = EINVAL;
		return 0;
	}

out:
	errno = 0;
	return 1;
}