SUNRPC: Make the transport-specific setup routine allocate rpc_xprt

Change the location where the rpc_xprt structure is allocated so each
transport implementation can allocate a private area from the same
chunk of memory.

Note also that xprt->ops->destroy, rather than xprt_destroy, is now
responsible for freeing rpc_xprt when the transport is destroyed.

Test plan:
Connectathon.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Chuck Lever
2006-10-17 14:44:27 -04:00
committed by Trond Myklebust
parent e744cf2e3a
commit c8541ecdd5
3 changed files with 61 additions and 47 deletions

View File

@@ -891,39 +891,25 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
*/
struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
{
int result;
struct rpc_xprt *xprt;
struct rpc_rqst *req;
if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) {
dprintk("RPC: xprt_create_transport: no memory\n");
return ERR_PTR(-ENOMEM);
}
if (size <= sizeof(xprt->addr)) {
memcpy(&xprt->addr, ap, size);
xprt->addrlen = size;
} else {
kfree(xprt);
dprintk("RPC: xprt_create_transport: address too large\n");
return ERR_PTR(-EBADF);
}
switch (proto) {
case IPPROTO_UDP:
result = xs_setup_udp(xprt, to);
xprt = xs_setup_udp(ap, size, to);
break;
case IPPROTO_TCP:
result = xs_setup_tcp(xprt, to);
xprt = xs_setup_tcp(ap, size, to);
break;
default:
printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
proto);
return ERR_PTR(-EIO);
}
if (result) {
kfree(xprt);
dprintk("RPC: xprt_create_transport: failed, %d\n", result);
return ERR_PTR(result);
if (IS_ERR(xprt)) {
dprintk("RPC: xprt_create_transport: failed, %ld\n",
-PTR_ERR(xprt));
return xprt;
}
kref_init(&xprt->kref);
@@ -969,8 +955,11 @@ static void xprt_destroy(struct kref *kref)
dprintk("RPC: destroying transport %p\n", xprt);
xprt->shutdown = 1;
del_timer_sync(&xprt->timer);
/*
* Tear down transport state and free the rpc_xprt
*/
xprt->ops->destroy(xprt);
kfree(xprt);
}
/**