|
@@ -1445,6 +1445,23 @@ out:
|
|
return xprt;
|
|
return xprt;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void xprt_destroy_cb(struct work_struct *work)
|
|
|
|
+{
|
|
|
|
+ struct rpc_xprt *xprt =
|
|
|
|
+ container_of(work, struct rpc_xprt, task_cleanup);
|
|
|
|
+
|
|
|
|
+ rpc_xprt_debugfs_unregister(xprt);
|
|
|
|
+ rpc_destroy_wait_queue(&xprt->binding);
|
|
|
|
+ rpc_destroy_wait_queue(&xprt->pending);
|
|
|
|
+ rpc_destroy_wait_queue(&xprt->sending);
|
|
|
|
+ rpc_destroy_wait_queue(&xprt->backlog);
|
|
|
|
+ kfree(xprt->servername);
|
|
|
|
+ /*
|
|
|
|
+ * Tear down transport state and free the rpc_xprt
|
|
|
|
+ */
|
|
|
|
+ xprt->ops->destroy(xprt);
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* xprt_destroy - destroy an RPC transport, killing off all requests.
|
|
* xprt_destroy - destroy an RPC transport, killing off all requests.
|
|
* @xprt: transport to destroy
|
|
* @xprt: transport to destroy
|
|
@@ -1454,22 +1471,19 @@ static void xprt_destroy(struct rpc_xprt *xprt)
|
|
{
|
|
{
|
|
dprintk("RPC: destroying transport %p\n", xprt);
|
|
dprintk("RPC: destroying transport %p\n", xprt);
|
|
|
|
|
|
- /* Exclude transport connect/disconnect handlers */
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Exclude transport connect/disconnect handlers and autoclose
|
|
|
|
+ */
|
|
wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_UNINTERRUPTIBLE);
|
|
wait_on_bit_lock(&xprt->state, XPRT_LOCKED, TASK_UNINTERRUPTIBLE);
|
|
|
|
|
|
del_timer_sync(&xprt->timer);
|
|
del_timer_sync(&xprt->timer);
|
|
|
|
|
|
- rpc_xprt_debugfs_unregister(xprt);
|
|
|
|
- rpc_destroy_wait_queue(&xprt->binding);
|
|
|
|
- rpc_destroy_wait_queue(&xprt->pending);
|
|
|
|
- rpc_destroy_wait_queue(&xprt->sending);
|
|
|
|
- rpc_destroy_wait_queue(&xprt->backlog);
|
|
|
|
- cancel_work_sync(&xprt->task_cleanup);
|
|
|
|
- kfree(xprt->servername);
|
|
|
|
/*
|
|
/*
|
|
- * Tear down transport state and free the rpc_xprt
|
|
|
|
|
|
+ * Destroy sockets etc from the system workqueue so they can
|
|
|
|
+ * safely flush receive work running on rpciod.
|
|
*/
|
|
*/
|
|
- xprt->ops->destroy(xprt);
|
|
|
|
|
|
+ INIT_WORK(&xprt->task_cleanup, xprt_destroy_cb);
|
|
|
|
+ schedule_work(&xprt->task_cleanup);
|
|
}
|
|
}
|
|
|
|
|
|
static void xprt_destroy_kref(struct kref *kref)
|
|
static void xprt_destroy_kref(struct kref *kref)
|