static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
 {
-       struct nfs4_client *clp = calldata;
+       struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
 
        if (task->tk_status)
                warn_no_callback_path(clp, task->tk_status);
 }
 
 static const struct rpc_call_ops nfsd4_cb_probe_ops = {
+       /* XXX: release method to ensure we set the cb channel down if
+        * necessary on early failure? */
        .rpc_call_done = nfsd4_cb_probe_done,
 };
 
        return 0;
 }
 
+static struct workqueue_struct *callback_wq;
 
 void do_probe_callback(struct nfs4_client *clp)
 {
-       struct rpc_message msg = {
-               .rpc_proc       = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
-               .rpc_argp       = clp,
-               .rpc_cred       = callback_cred
-       };
-       int status;
+       struct nfsd4_callback *cb = &clp->cl_cb_null;
 
-       status = rpc_call_async(clp->cl_cb_client, &msg,
-                               RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
-                               &nfsd4_cb_probe_ops, (void *)clp);
-       if (status)
-               warn_no_callback_path(clp, status);
+       cb->cb_args.args_op = NULL;
+       cb->cb_args.args_clp = clp;
+
+       cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL];
+       cb->cb_msg.rpc_argp = NULL;
+       cb->cb_msg.rpc_resp = NULL;
+       cb->cb_msg.rpc_cred = callback_cred;
+
+       cb->cb_ops = &nfsd4_cb_probe_ops;
+
+       queue_work(callback_wq, &cb->cb_work);
 }
 
 /*
        .rpc_release = nfsd4_cb_recall_release,
 };
 
-static struct workqueue_struct *callback_wq;
-
 int nfsd4_create_callback_queue(void)
 {
        callback_wq = create_singlethread_workqueue("nfsd4_callbacks");
                nfsd4_release_cb(cb);
                return; /* Client is shutting down; give up. */
        }
-       rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT, cb->cb_ops, cb);
+       rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
+                       cb->cb_ops, cb);
 }
 
 void nfsd4_cb_recall(struct nfs4_delegation *dp)
 
        INIT_LIST_HEAD(&clp->cl_delegations);
        INIT_LIST_HEAD(&clp->cl_sessions);
        INIT_LIST_HEAD(&clp->cl_lru);
+       INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
        clp->cl_time = get_seconds();
        clear_bit(0, &clp->cl_cb_slot_busy);
        rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");