diff --git a/patches.suse/NFSD-Reschedule-CB-operations-when-backchannel-rpc_c.patch b/patches.suse/NFSD-Reschedule-CB-operations-when-backchannel-rpc_c.patch new file mode 100644 index 0000000..aea4a3a --- /dev/null +++ b/patches.suse/NFSD-Reschedule-CB-operations-when-backchannel-rpc_c.patch @@ -0,0 +1,97 @@ +From: Chuck Lever +Date: Fri, 26 Jan 2024 12:45:29 -0500 +Subject: [PATCH] NFSD: Reschedule CB operations when backchannel rpc_clnt is + shut down +Git-commit: c1ccfcf1a9bf3630fc4739713df6e62bb524c42c +Patch-mainline: v6.9-rc1 +References: git-fixes + +As part of managing a client disconnect, NFSD closes down and +replaces the backchannel rpc_clnt. + +If a callback operation is pending when the backchannel rpc_clnt is +shut down, currently nfsd4_run_cb_work() just discards that +callback. But there are multiple cases to deal with here: + + o The client's lease is getting destroyed. Throw the CB away. + + o The client disconnected. It might be forcing a retransmit of + CB operations, or it could have disconnected for other reasons. + Reschedule the CB so it is retransmitted when the client + reconnects. + +Since callback operations can now be rescheduled, ensure that +cb_ops->prepare can be called only once by moving the +cb_ops->prepare paragraph down to just before the rpc_call_async() +call. + +Fixes: 2bbfed98a4d8 ("nfsd: Fix races between nfsd4_cb_release() and nfsd4_shutdown_callback()") +Reviewed-by: Jeff Layton +Reviewed-by: Benjamin Coddington +Signed-off-by: Chuck Lever +Acked-by: NeilBrown + +--- + fs/nfsd/nfs4callback.c | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -843,6 +843,13 @@ static bool nfsd4_queue_cb(struct nfsd4_ + return queue_delayed_work(callback_wq, &cb->cb_work, 0); + } + ++static void nfsd4_queue_cb_delayed(struct nfsd4_callback *cb, ++ unsigned long msecs) ++{ ++ queue_delayed_work(callback_wq, &cb->cb_work, ++ msecs_to_jiffies(msecs)); ++} ++ + static void nfsd41_cb_inflight_begin(struct nfs4_client *clp) + { + atomic_inc(&clp->cl_cb_inflight); +@@ -1328,20 +1335,21 @@ nfsd4_run_cb_work(struct work_struct *wo + struct rpc_clnt *clnt; + int flags; + +- if (cb->cb_need_restart) { +- cb->cb_need_restart = false; +- } else { +- if (cb->cb_ops && cb->cb_ops->prepare) +- cb->cb_ops->prepare(cb); +- } +- + if (clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK) + nfsd4_process_cb_update(cb); + + clnt = clp->cl_cb_client; + if (!clnt) { +- /* Callback channel broken, or client killed; give up: */ +- nfsd41_destroy_cb(cb); ++ if (test_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags)) ++ nfsd41_destroy_cb(cb); ++ else { ++ /* ++ * XXX: Ideally, we could wait for the client to ++ * reconnect, but I haven't figured out how ++ * to do that yet. ++ */ ++ nfsd4_queue_cb_delayed(cb, 25); ++ } + return; + } + +@@ -1354,6 +1362,12 @@ nfsd4_run_cb_work(struct work_struct *wo + return; + } + ++ if (cb->cb_need_restart) { ++ cb->cb_need_restart = false; ++ } else { ++ if (cb->cb_ops && cb->cb_ops->prepare) ++ cb->cb_ops->prepare(cb); ++ } + cb->cb_msg.rpc_cred = clp->cl_cb_cred; + flags = clp->cl_minorversion ? RPC_TASK_NOCONNECT : RPC_TASK_SOFTCONN; + rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | flags, diff --git a/series.conf b/series.conf index 3459c75..90a70e9 100644 --- a/series.conf +++ b/series.conf @@ -45594,6 +45594,7 @@ patches.suse/NFSD-fix-LISTXATTRS-returning-more-bytes-than-maxcou.patch patches.suse/NFSD-Reset-cb_seq_status-after-NFS4ERR_DELAY.patch patches.suse/NFSD-Convert-the-callback-workqueue-to-use-delayed_w.patch + patches.suse/NFSD-Reschedule-CB-operations-when-backchannel-rpc_c.patch patches.suse/doc-guide-kernel-doc-tell-about-object-like-macros.patch patches.suse/wifi-b43-Stop-wake-correct-queue-in-DMA-Tx-path-when.patch patches.suse/wifi-b43-Stop-wake-correct-queue-in-PIO-Tx-path-when.patch