__filemap_fdatawait_range() waits for writeback using folio_wait_writeback(), which sleeps in TASK_UNINTERRUPTIBLE. On network filesystems (NFS, CIFS, 9P) the server can stall for minutes or hours, leaving processes in unkillable D-state. The only recovery is a node reboot. Replace folio_wait_writeback() with folio_wait_writeback_killable() so that SIGKILL can interrupt the wait. On fatal signal, release the folio batch and return early. The writeback itself continues on the server -- only the client-side wait is interrupted. The dying process never inspects the return value, and other processes get correct error reporting through errseq_t (mapping->wb_err) which is set by the writeback completion path independently of this wait. Additionally, skip the writeback wait entirely when the calling process has PF_EXITING set. This handles a re-entry trap discovered in testing: when SIGKILL wakes a process from the killable wait, do_exit() sets PF_EXITING and then exit_files() closes file descriptors, which on NFS triggers nfs4_file_flush() -> nfs_wb_all() -> filemap_write_and_wait() -> __filemap_fdatawait_range(). At that point wants_signal() (kernel/signal.c) rejects all signals for PF_EXITING tasks -- including SIGKILL -- because the PF_EXITING check precedes the SIGKILL exception. The second killable wait would therefore block forever. Checking PF_EXITING at entry avoids this: the process is dying and has no use for writeback confirmation. Signed-off-by: Rushil Patel --- mm/filemap.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mm/filemap.c b/mm/filemap.c index 406cef06b684..d348f1dd75f9 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -515,6 +515,15 @@ static void __filemap_fdatawait_range(struct address_space *mapping, struct folio_batch fbatch; unsigned nr_folios; + /* + * If the process is exiting (PF_EXITING), skip the writeback wait. + * During do_exit(), nfs4_file_flush() re-enters this function, but + * wants_signal() rejects signals for PF_EXITING tasks so a second + * SIGKILL cannot wake us from the TASK_KILLABLE wait below. + */ + if (current->flags & PF_EXITING) + return; + folio_batch_init(&fbatch); while (index <= end) { @@ -529,7 +538,10 @@ static void __filemap_fdatawait_range(struct address_space *mapping, for (i = 0; i < nr_folios; i++) { struct folio *folio = fbatch.folios[i]; - folio_wait_writeback(folio); + if (folio_wait_writeback_killable(folio)) { + folio_batch_release(&fbatch); + return; + } } folio_batch_release(&fbatch); cond_resched(); -- 2.47.3 For details of how GSA uses your personal information, please see our Privacy Notice here: https://www.gsacapital.com/privacy-notice This email and any files transmitted with it contain confidential and proprietary information and is solely for the use of the intended recipient. If you are not the intended recipient please return the email to the sender and delete it from your computer and you must not use, disclose, distribute, copy, print or rely on this email or its contents. This communication is for informational purposes only. It is not intended as an offer or solicitation for the purchase or sale of any financial instrument or as an official confirmation of any transaction. Any comments or statements made herein do not necessarily reflect those of GSA Capital. GSA Capital Partners LLP is authorised and regulated by the Financial Conduct Authority and is registered in England and Wales at Stratton House, 5 Stratton Street, London W1J 8LA, number OC309261. GSA Capital Services Limited is registered in England and Wales at the same address, number 5320529.