fs/nfs/mount_clnt.c

Source file repositories/reference/linux-study-clean/fs/nfs/mount_clnt.c

File Facts

System
Linux kernel
Corpus path
fs/nfs/mount_clnt.c
Extension
.c
Size
11323 bytes
Lines
472
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mountres {
	int errno;
	struct nfs_fh *fh;
	unsigned int *auth_count;
	rpc_authflavor_t *auth_flavors;
};

/**
 * nfs_mount - Obtain an NFS file handle for the given host and path
 * @info: pointer to mount request arguments
 * @timeo: deciseconds the mount waits for a response before it retries
 * @retrans: number of times the mount retries a request
 *
 * Uses timeout parameters specified by caller. On successful return, the
 * auth_flavs list and auth_flav_len will be populated with the list from the
 * server or a faked-up list if the server didn't provide one.
 */
int nfs_mount(struct nfs_mount_request *info, int timeo, int retrans)
{
	struct rpc_timeout mnt_timeout;
	struct mountres	result = {
		.fh		= info->fh,
		.auth_count	= info->auth_flav_len,
		.auth_flavors	= info->auth_flavs,
	};
	struct rpc_message msg	= {
		.rpc_argp	= info->dirpath,
		.rpc_resp	= &result,
	};
	struct rpc_create_args args = {
		.net		= info->net,
		.protocol	= info->protocol,
		.address	= (struct sockaddr *)info->sap,
		.addrsize	= info->salen,
		.timeout	= &mnt_timeout,
		.servername	= info->hostname,
		.program	= &mnt_program,
		.version	= info->version,
		.authflavor	= RPC_AUTH_UNIX,
		.cred		= current_cred(),
	};
	struct rpc_clnt		*mnt_clnt;
	int			status;

	dprintk("NFS: sending MNT request for %s:%s\n",
		(info->hostname ? info->hostname : "server"),
			info->dirpath);

	if (strlen(info->dirpath) > MNTPATHLEN)
		return -ENAMETOOLONG;

	if (info->noresvport)
		args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;

	nfs_init_timeout_values(&mnt_timeout, info->protocol, timeo, retrans);
	mnt_clnt = rpc_create(&args);
	if (IS_ERR(mnt_clnt))
		goto out_clnt_err;

	if (info->version == NFS_MNT3_VERSION)
		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
	else
		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];

	status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
	rpc_shutdown_client(mnt_clnt);

	if (status < 0)
		goto out_call_err;
	if (result.errno != 0)
		goto out_mnt_err;

	dprintk("NFS: MNT request succeeded\n");
	status = 0;

	/*
	 * If the server didn't provide a flavor list, allow the
	 * client to try any flavor.
	 */
	if (info->version != NFS_MNT3_VERSION || *info->auth_flav_len == 0) {
		dprintk("NFS: Faking up auth_flavs list\n");
		info->auth_flavs[0] = RPC_AUTH_NULL;
		*info->auth_flav_len = 1;
	}
out:
	return status;

out_clnt_err:
	status = PTR_ERR(mnt_clnt);
	dprintk("NFS: failed to create MNT RPC client, status=%d\n", status);

Annotation

Implementation Notes