⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Create a general RPC client */static int nfs_init_server_rpcclient(struct nfs_server *server, rpc_authflavor_t pseudoflavour){	struct nfs_client *clp = server->nfs_client;	server->client = rpc_clone_client(clp->cl_rpcclient);	if (IS_ERR(server->client)) {		dprintk("%s: couldn't create rpc_client!\n", __FUNCTION__);		return PTR_ERR(server->client);	}	if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {		struct rpc_auth *auth;		auth = rpcauth_create(pseudoflavour, server->client);		if (IS_ERR(auth)) {			dprintk("%s: couldn't create credcache!\n", __FUNCTION__);			return PTR_ERR(auth);		}	}	server->client->cl_softrtry = 0;	if (server->flags & NFS_MOUNT_SOFT)		server->client->cl_softrtry = 1;	server->client->cl_intr = 0;	if (server->flags & NFS4_MOUNT_INTR)		server->client->cl_intr = 1;	return 0;}/* * Initialise an NFS2 or NFS3 client */static int nfs_init_client(struct nfs_client *clp,			   const struct nfs_parsed_mount_data *data){	int error;	if (clp->cl_cons_state == NFS_CS_READY) {		/* the client is already initialised */		dprintk("<-- nfs_init_client() = 0 [already %p]\n", clp);		return 0;	}	/* Check NFS protocol revision and initialize RPC op vector */	clp->rpc_ops = &nfs_v2_clientops;#ifdef CONFIG_NFS_V3	if (clp->cl_nfsversion == 3)		clp->rpc_ops = &nfs_v3_clientops;#endif	/*	 * Create a client RPC handle for doing FSSTAT with UNIX auth only	 * - RFC 2623, sec 2.3.2	 */	error = nfs_create_rpc_client(clp, data->nfs_server.protocol,				data->timeo, data->retrans, RPC_AUTH_UNIX, 0);	if (error < 0)		goto error;	nfs_mark_client_ready(clp, NFS_CS_READY);	return 0;error:	nfs_mark_client_ready(clp, error);	dprintk("<-- nfs_init_client() = xerror %d\n", error);	return error;}/* * Create a version 2 or 3 client */static int nfs_init_server(struct nfs_server *server,			   const struct nfs_parsed_mount_data *data){	struct nfs_client *clp;	int error, nfsvers = 2;	dprintk("--> nfs_init_server()\n");#ifdef CONFIG_NFS_V3	if (data->flags & NFS_MOUNT_VER3)		nfsvers = 3;#endif	/* Allocate or find a client reference we can use */	clp = nfs_get_client(data->nfs_server.hostname,				&data->nfs_server.address, nfsvers);	if (IS_ERR(clp)) {		dprintk("<-- nfs_init_server() = error %ld\n", PTR_ERR(clp));		return PTR_ERR(clp);	}	error = nfs_init_client(clp, data);	if (error < 0)		goto error;	server->nfs_client = clp;	/* Initialise the client representation from the mount data */	server->flags = data->flags & NFS_MOUNT_FLAGMASK;	if (data->rsize)		server->rsize = nfs_block_size(data->rsize, NULL);	if (data->wsize)		server->wsize = nfs_block_size(data->wsize, NULL);	server->acregmin = data->acregmin * HZ;	server->acregmax = data->acregmax * HZ;	server->acdirmin = data->acdirmin * HZ;	server->acdirmax = data->acdirmax * HZ;	/* Start lockd here, before we might error out */	error = nfs_start_lockd(server);	if (error < 0)		goto error;	error = nfs_init_server_rpcclient(server, data->auth_flavors[0]);	if (error < 0)		goto error;	server->namelen  = data->namlen;	/* Create a client RPC handle for the NFSv3 ACL management interface */	nfs_init_server_aclclient(server);	dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);	return 0;error:	server->nfs_client = NULL;	nfs_put_client(clp);	dprintk("<-- nfs_init_server() = xerror %d\n", error);	return error;}/* * Load up the server record from information gained in an fsinfo record */static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *fsinfo){	unsigned long max_rpc_payload;	/* Work out a lot of parameters */	if (server->rsize == 0)		server->rsize = nfs_block_size(fsinfo->rtpref, NULL);	if (server->wsize == 0)		server->wsize = nfs_block_size(fsinfo->wtpref, NULL);	if (fsinfo->rtmax >= 512 && server->rsize > fsinfo->rtmax)		server->rsize = nfs_block_size(fsinfo->rtmax, NULL);	if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)		server->wsize = nfs_block_size(fsinfo->wtmax, NULL);	max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);	if (server->rsize > max_rpc_payload)		server->rsize = max_rpc_payload;	if (server->rsize > NFS_MAX_FILE_IO_SIZE)		server->rsize = NFS_MAX_FILE_IO_SIZE;	server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;	server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;	if (server->wsize > max_rpc_payload)		server->wsize = max_rpc_payload;	if (server->wsize > NFS_MAX_FILE_IO_SIZE)		server->wsize = NFS_MAX_FILE_IO_SIZE;	server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;	server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);	server->dtsize = nfs_block_size(fsinfo->dtpref, NULL);	if (server->dtsize > PAGE_CACHE_SIZE)		server->dtsize = PAGE_CACHE_SIZE;	if (server->dtsize > server->rsize)		server->dtsize = server->rsize;	if (server->flags & NFS_MOUNT_NOAC) {		server->acregmin = server->acregmax = 0;		server->acdirmin = server->acdirmax = 0;	}	server->maxfilesize = fsinfo->maxfilesize;	/* We're airborne Set socket buffersize */	rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);}/* * Probe filesystem information, including the FSID on v2/v3 */static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, struct nfs_fattr *fattr){	struct nfs_fsinfo fsinfo;	struct nfs_client *clp = server->nfs_client;	int error;	dprintk("--> nfs_probe_fsinfo()\n");	if (clp->rpc_ops->set_capabilities != NULL) {		error = clp->rpc_ops->set_capabilities(server, mntfh);		if (error < 0)			goto out_error;	}	fsinfo.fattr = fattr;	nfs_fattr_init(fattr);	error = clp->rpc_ops->fsinfo(server, mntfh, &fsinfo);	if (error < 0)		goto out_error;	nfs_server_set_fsinfo(server, &fsinfo);	error = bdi_init(&server->backing_dev_info);	if (error)		goto out_error;	/* Get some general file system info */	if (server->namelen == 0) {		struct nfs_pathconf pathinfo;		pathinfo.fattr = fattr;		nfs_fattr_init(fattr);		if (clp->rpc_ops->pathconf(server, mntfh, &pathinfo) >= 0)			server->namelen = pathinfo.max_namelen;	}	dprintk("<-- nfs_probe_fsinfo() = 0\n");	return 0;out_error:	dprintk("nfs_probe_fsinfo: error = %d\n", -error);	return error;}/* * Copy useful information when duplicating a server record */static void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *source){	target->flags = source->flags;	target->acregmin = source->acregmin;	target->acregmax = source->acregmax;	target->acdirmin = source->acdirmin;	target->acdirmax = source->acdirmax;	target->caps = source->caps;}/* * Allocate and initialise a server record */static struct nfs_server *nfs_alloc_server(void){	struct nfs_server *server;	server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);	if (!server)		return NULL;	server->client = server->client_acl = ERR_PTR(-EINVAL);	/* Zero out the NFS state stuff */	INIT_LIST_HEAD(&server->client_link);	INIT_LIST_HEAD(&server->master_link);	server->io_stats = nfs_alloc_iostats();	if (!server->io_stats) {		kfree(server);		return NULL;	}	return server;}/* * Free up a server record */void nfs_free_server(struct nfs_server *server){	dprintk("--> nfs_free_server()\n");	spin_lock(&nfs_client_lock);	list_del(&server->client_link);	list_del(&server->master_link);	spin_unlock(&nfs_client_lock);	if (server->destroy != NULL)		server->destroy(server);	if (!IS_ERR(server->client_acl))		rpc_shutdown_client(server->client_acl);	if (!IS_ERR(server->client))		rpc_shutdown_client(server->client);	nfs_put_client(server->nfs_client);	nfs_free_iostats(server->io_stats);	bdi_destroy(&server->backing_dev_info);	kfree(server);	nfs_release_automount_timer();	dprintk("<-- nfs_free_server()\n");}/* * Create a version 2 or 3 volume record * - keyed on server and FSID */struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,				     struct nfs_fh *mntfh){	struct nfs_server *server;	struct nfs_fattr fattr;	int error;	server = nfs_alloc_server();	if (!server)		return ERR_PTR(-ENOMEM);	/* Get a client representation */	error = nfs_init_server(server, data);	if (error < 0)		goto error;	BUG_ON(!server->nfs_client);	BUG_ON(!server->nfs_client->rpc_ops);	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);	/* Probe the root fh to retrieve its FSID */	error = nfs_probe_fsinfo(server, mntfh, &fattr);	if (error < 0)		goto error;	if (server->nfs_client->rpc_ops->version == 3) {		if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)			server->namelen = NFS3_MAXNAMLEN;		if (!(data->flags & NFS_MOUNT_NORDIRPLUS))			server->caps |= NFS_CAP_READDIRPLUS;	} else {		if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)			server->namelen = NFS2_MAXNAMLEN;	}	if (!(fattr.valid & NFS_ATTR_FATTR)) {		error = server->nfs_client->rpc_ops->getattr(server, mntfh, &fattr);		if (error < 0) {			dprintk("nfs_create_server: getattr error = %d\n", -error);			goto error;		}	}	memcpy(&server->fsid, &fattr.fsid, sizeof(server->fsid));	dprintk("Server FSID: %llx:%llx\n",		(unsigned long long) server->fsid.major,		(unsigned long long) server->fsid.minor);	BUG_ON(!server->nfs_client);	BUG_ON(!server->nfs_client->rpc_ops);	BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);	spin_lock(&nfs_client_lock);	list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks);	list_add_tail(&server->master_link, &nfs_volume_list);	spin_unlock(&nfs_client_lock);	server->mount_time = jiffies;	return server;error:	nfs_free_server(server);	return ERR_PTR(error);}#ifdef CONFIG_NFS_V4/* * Initialise an NFS4 client record */static int nfs4_init_client(struct nfs_client *clp,		int proto, int timeo, int retrans,		const char *ip_addr,		rpc_authflavor_t authflavour){	int error;	if (clp->cl_cons_state == NFS_CS_READY) {		/* the client is initialised already */		dprintk("<-- nfs4_init_client() = 0 [already %p]\n", clp);		return 0;	}	/* Check NFS protocol revision and initialize RPC op vector */	clp->rpc_ops = &nfs_v4_clientops;	error = nfs_create_rpc_client(clp, proto, timeo, retrans, authflavour,					RPC_CLNT_CREATE_DISCRTRY);	if (error < 0)		goto error;	memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));	error = nfs_idmap_new(clp);	if (error < 0) {		dprintk("%s: failed to create idmapper. Error = %d\n",			__FUNCTION__, error);		goto error;	}	__set_bit(NFS_CS_IDMAP, &clp->cl_res_state);	nfs_mark_client_ready(clp, NFS_CS_READY);	return 0;error:	nfs_mark_client_ready(clp, error);	dprintk("<-- nfs4_init_client() = xerror %d\n", error);	return error;}/* * Set up an NFS4 client */static int nfs4_set_client(struct nfs_server *server,		const char *hostname, const struct sockaddr_in *addr,		const char *ip_addr,		rpc_authflavor_t authflavour,		int proto, int timeo, int retrans){	struct nfs_client *clp;	int error;	dprintk("--> nfs4_set_client()\n");	/* Allocate or find a client reference we can use */	clp = nfs_get_client(hostname, addr, 4);	if (IS_ERR(clp)) {		error = PTR_ERR(clp);		goto error;	}	error = nfs4_init_client(clp, proto, timeo, retrans, ip_addr, authflavour);	if (error < 0)		goto error_put;	server->nfs_client = clp;	dprintk("<-- nfs4_set_client() = 0 [new %p]\n", clp);	return 0;error_put:	nfs_put_client(clp);error:	dprintk("<-- nfs4_set_client() = xerror %d\n", error);	return error;}/* * Create a version 4 volume record */static int nfs4_init_server(struct nfs_server *server,		const struct nfs_parsed_mount_data *data){	int error;	dprintk("--> nfs4_init_server()\n");	/* Initialise the client representation from the mount data */	server->flags = data->flags & NFS_MOUNT_FLAGMASK;	server->caps |= NFS_CAP_ATOMIC_OPEN;	if (data->rsize)		server->rsize = nfs_block_size(data->rsize, NULL);	if (data->wsize)		server->wsize = nfs_block_size(data->wsize, NULL);	server->acregmin = data->acregmin * HZ;	server->acregmax = data->acregmax * HZ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -