]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/sunrpc/xprt.c
SUNRPC: prevent task_cleanup running on freed xprt
[net-next-2.6.git] / net / sunrpc / xprt.c
index 3fc325399ee4da4eaf77d19ace55717e34639798..970fb00f388ce532d7f0a4e3c7285f98e57af2f5 100644 (file)
@@ -166,7 +166,6 @@ EXPORT_SYMBOL_GPL(xprt_unregister_transport);
 int xprt_load_transport(const char *transport_name)
 {
        struct xprt_class *t;
-       char module_name[sizeof t->name + 5];
        int result;
 
        result = 0;
@@ -178,9 +177,7 @@ int xprt_load_transport(const char *transport_name)
                }
        }
        spin_unlock(&xprt_list_lock);
-       strcpy(module_name, "xprt");
-       strncat(module_name, transport_name, sizeof t->name);
-       result = request_module(module_name);
+       result = request_module("xprt%s", transport_name);
 out:
        return result;
 }
@@ -1035,6 +1032,8 @@ void xprt_release(struct rpc_task *task)
        spin_unlock_bh(&xprt->transport_lock);
        if (req->rq_buffer)
                xprt->ops->buf_free(req->rq_buffer);
+       if (req->rq_cred != NULL)
+               put_rpccred(req->rq_cred);
        task->tk_rqstp = NULL;
        if (req->rq_release_snd_buf)
                req->rq_release_snd_buf(req);
@@ -1132,6 +1131,7 @@ static void xprt_destroy(struct kref *kref)
        rpc_destroy_wait_queue(&xprt->sending);
        rpc_destroy_wait_queue(&xprt->resend);
        rpc_destroy_wait_queue(&xprt->backlog);
+       cancel_work_sync(&xprt->task_cleanup);
        /*
         * Tear down transport state and free the rpc_xprt
         */