static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent, struct dentry *dentry, struct path *path, struct nfs_fh *fh, struct nfs_fattr *fattr, rpc_authflavor_t *flavor) { struct rpc_clnt *clone; struct rpc_auth *auth; int err; err = nfs_negotiate_security(parent, path->dentry, flavor); if (err < 0) goto out; clone = rpc_clone_client(server->client); auth = rpcauth_create(*flavor, clone); if (!auth) { err = -EIO; goto out_shutdown; } err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode, &path->dentry->d_name, fh, fattr); out_shutdown: rpc_shutdown_client(clone); out: return err; }
/* * Create an RPC client * FIXME: This should also take a flags argument (as in task->tk_flags). * It's called (among others) from pmap_create_client, which may in * turn be called by an async task. In this case, rpciod should not be * made to sleep too long. */ struct rpc_clnt * rpc_create_client(struct rpc_xprt *xprt, char *servname, struct rpc_program *program, u32 vers, int flavor) { struct rpc_version *version; struct rpc_clnt *clnt = NULL; dprintk("RPC: creating %s client for %s (xprt %p)\n", program->name, servname, xprt); if (!xprt) goto out; if (vers >= program->nrvers || !(version = program->version[vers])) goto out; clnt = (struct rpc_clnt *) rpc_allocate(0, sizeof(*clnt)); if (!clnt) goto out_no_clnt; memset(clnt, 0, sizeof(*clnt)); atomic_set(&clnt->cl_users, 0); clnt->cl_xprt = xprt; clnt->cl_procinfo = version->procs; clnt->cl_maxproc = version->nrprocs; clnt->cl_server = servname; clnt->cl_protname = program->name; clnt->cl_port = xprt->addr.sin_port; clnt->cl_prog = program->number; clnt->cl_vers = version->number; clnt->cl_prot = xprt->prot; clnt->cl_stats = program->stats; INIT_RPC_WAITQ(&clnt->cl_bindwait, "bindwait"); if (!clnt->cl_port) clnt->cl_autobind = 1; rpc_init_rtt(&clnt->cl_rtt, xprt->timeout.to_initval); if (!rpcauth_create(flavor, clnt)) goto out_no_auth; /* save the nodename */ clnt->cl_nodelen = strlen(system_utsname.nodename); if (clnt->cl_nodelen > UNX_MAXNODENAME) clnt->cl_nodelen = UNX_MAXNODENAME; memcpy(clnt->cl_nodename, system_utsname.nodename, clnt->cl_nodelen); out: return clnt; out_no_clnt: printk(KERN_INFO "RPC: out of memory in rpc_create_client\n"); goto out; out_no_auth: printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %d)\n", flavor); rpc_free(clnt); clnt = NULL; goto out; }
/* * Please call rpc_shutdown_client() when you are done with this client. */ struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode, struct qstr *name) { struct rpc_clnt *clone; struct rpc_auth *auth; rpc_authflavor_t flavor; flavor = nfs4_negotiate_security(inode, name); if (flavor < 0) return ERR_PTR(flavor); clone = rpc_clone_client(clnt); if (IS_ERR(clone)) return clone; auth = rpcauth_create(flavor, clone); if (!auth) { rpc_shutdown_client(clone); clone = ERR_PTR(-EIO); } return clone; }