mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
To: "ceph-devel@vger.kernel.org" <ceph-devel@vger.kernel.org>,
	"ionut.nechita@windriver.com" <ionut.nechita@windriver.com>
Cc: "idryomov@gmail.com" <idryomov@gmail.com>,
	Xiubo Li <xiubli@redhat.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"ionut_n2001@yahoo.com" <ionut_n2001@yahoo.com>
Subject: Re:  [PATCH v1 04/13] ceph: fix race condition in cleanup_session_requests()
Date: Thu, 12 Mar 2026 19:32:41 +0000	[thread overview]
Message-ID: <c04ac668137d1ff6cd76565c0450eb2e02e2d265.camel@ibm.com> (raw)
In-Reply-To: <20260312081619.40854-5-ionut.nechita@windriver.com>

On Thu, 2026-03-12 at 10:16 +0200, Ionut Nechita (Wind River) wrote:
> From: Ionut Nechita <ionut.nechita@windriver.com>
> 
> When an MDS session is closed or reset, cleanup_session_requests()
> only unregisters requests that are on the session's s_unsafe list.
> However, requests are only added to s_unsafe after receiving an
> "unsafe" reply from the MDS.
> This creates a race condition: if a write request has been sent
> but the MDS becomes unavailable before sending the unsafe reply,
> the request will:
>   - Have r_session set (points to the failed session)
>   - Be in the request_tree
>   - NOT be on s_unsafe list
>   - Never have r_safe_completion signaled
> Meanwhile, flush_mdlog_and_wait_mdsc_unsafe_requests() iterates
> the request_tree looking for write requests with r_session set,
> and waits on r_safe_completion for each one. Since the request
> is not on s_unsafe, cleanup_session_requests() won't unregister
> it, and the completion is never signaled - causing an indefinite
> hang.
> This was observed in production when running xfstests generic/013
> in a loop, with stack traces showing:
>   INFO: task fsstress:14466 blocked for more than 122 seconds.
>   Call Trace:
>     wait_for_completion+0x14a/0x340
>     ceph_mdsc_sync+0x4b4/0xe80
>     ceph_sync_fs+0xa0/0x4c0
>     sync_filesystem+0x182/0x240
> Fix this by extending cleanup_session_requests() to also unregister
> requests that:
>   - Belong to the closing session (r_session->s_mds matches)
>   - Have NOT received an unsafe reply (CEPH_MDS_R_GOT_UNSAFE not set)
>   - Have NOT received a safe reply (CEPH_MDS_R_GOT_SAFE not set)
> These are requests that were in-flight when the session failed and
> will never complete. Unregistering them signals r_safe_completion,
> unblocking any waiters.
> Requests that received an unsafe reply but not yet a safe reply
> are already on s_unsafe and handled by the existing code. For
> these, we preserve the original behavior of resetting r_attempts
> to allow re-sending when the session reconnects.
> Fixes: e3ec8d689cf4 ("ceph: clean up unsafe requests when reconnecting is denied")
> Signed-off-by: Ionut Nechita <ionut.nechita@windriver.com>
> ---
>  fs/ceph/mds_client.c | 24 +++++++++++++++++++++---
>  1 file changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
> index 37899464101f7..45abddd7f317e 100644
> --- a/fs/ceph/mds_client.c
> +++ b/fs/ceph/mds_client.c
> @@ -1792,6 +1792,8 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
>  
>  	doutc(cl, "mds%d\n", session->s_mds);
>  	mutex_lock(&mdsc->mutex);
> +
> +	/* First, handle requests on the unsafe list */
>  	while (!list_empty(&session->s_unsafe)) {
>  		req = list_first_entry(&session->s_unsafe,
>  				       struct ceph_mds_request, r_unsafe_item);
> @@ -1803,14 +1805,30 @@ static void cleanup_session_requests(struct ceph_mds_client *mdsc,
>  			mapping_set_error(req->r_unsafe_dir->i_mapping, -EIO);
>  		__unregister_request(mdsc, req);
>  	}
> -	/* zero r_attempts, so kick_requests() will re-send requests */
> +
> +	/*
> +	 * Iterate through all pending requests for this session.
> +	 * Requests that haven't received an unsafe reply yet will never
> +	 * complete on this session - unregister them to signal waiters.
> +	 * Requests that got unsafe but not safe are handled above via
> +	 * s_unsafe list; for any remaining, reset r_attempts to allow
> +	 * re-sending when session reconnects.
> +	 */
>  	p = rb_first(&mdsc->request_tree);
>  	while (p) {
>  		req = rb_entry(p, struct ceph_mds_request, r_node);
>  		p = rb_next(p);
>  		if (req->r_session &&
> -		    req->r_session->s_mds == session->s_mds)
> -			req->r_attempts = 0;
> +		    req->r_session->s_mds == session->s_mds) {
> +			if (!test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags) &&
> +			    !test_bit(CEPH_MDS_R_GOT_SAFE, &req->r_req_flags)) {
> +				doutc(cl, " dropping pending request %llu\n",
> +				      req->r_tid);
> +				__unregister_request(mdsc, req);
> +			} else {
> +				req->r_attempts = 0;
> +			}
> +		}
>  	}
>  	mutex_unlock(&mdsc->mutex);
>  }

Nice fix.

Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>

Thanks,
Slava.

  reply	other threads:[~2026-03-12 19:32 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-12  8:16 [PATCH v1 00/13] ceph/libceph: fix hung tasks and connection recovery during network disruptions Ionut Nechita (Wind River)
2026-03-12  8:16 ` [PATCH v1 01/13] libceph: handle EADDRNOTAVAIL more gracefully Ionut Nechita (Wind River)
2026-03-12 18:51   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 02/13] ceph: add timeout protection to ceph_mdsc_sync() path Ionut Nechita (Wind River)
2026-03-12 19:19   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 03/13] ceph: add timeout protection to ceph_osdc_sync() path Ionut Nechita (Wind River)
2026-03-12 19:26   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 04/13] ceph: fix race condition in cleanup_session_requests() Ionut Nechita (Wind River)
2026-03-12 19:32   ` Viacheslav Dubeyko [this message]
2026-03-12  8:16 ` [PATCH v1 05/13] ceph: add timeout protection to ceph_lock_wait_for_completion() Ionut Nechita (Wind River)
2026-03-12 19:38   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 06/13] ceph: set default timeout for MDS requests Ionut Nechita (Wind River)
2026-03-12 19:41   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 07/13] ceph: add timeout to caps wait in __ceph_get_caps() Ionut Nechita (Wind River)
2026-03-12 19:52   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 08/13] ceph: make ceph_start_io_write() killable Ionut Nechita (Wind River)
2026-03-12 20:02   ` Viacheslav Dubeyko
2026-03-12 20:45     ` Ionut Nechita (Wind River)
2026-03-13 18:28       ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 09/13] ceph: make remaining I/O lock functions killable Ionut Nechita (Wind River)
2026-03-12 20:05   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 10/13] ceph: force mdsmap refresh on persistent MDS connection failures Ionut Nechita (Wind River)
2026-03-12 21:23   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 11/13] libceph: reset source address on persistent EADDRNOTAVAIL Ionut Nechita (Wind River)
2026-03-12 21:39   ` Viacheslav Dubeyko
2026-03-12  8:16 ` [PATCH v1 12/13] libceph: force monitor reconnect " Ionut Nechita (Wind River)
2026-03-12  8:16 ` [PATCH v1 13/13] libceph: force host network namespace for kernel CephFS mounts Ionut Nechita (Wind River)
2026-03-16 15:28   ` Ilya Dryomov
2026-03-16 21:20     ` Ionut Nechita (Wind River)
2026-04-02 17:06       ` Ionut Nechita (Wind River)
2026-04-03 15:05         ` Ionut Nechita (Wind River)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c04ac668137d1ff6cd76565c0450eb2e02e2d265.camel@ibm.com \
    --to=slava.dubeyko@ibm.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=idryomov@gmail.com \
    --cc=ionut.nechita@windriver.com \
    --cc=ionut_n2001@yahoo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=xiubli@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®