Received: by 2002:a05:7412:251c:b0:e2:908c:2ebd with SMTP id w28csp964080rda; Sun, 22 Oct 2023 19:12:18 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEgL4RKunn0YLSRE456LMbkS7piXDRYSKoa7Ja6i6uDtmxuW19DGtN+mDBB41RwNX4Nc667 X-Received: by 2002:a17:90b:8c:b0:27d:1aa:32b8 with SMTP id bb12-20020a17090b008c00b0027d01aa32b8mr15444534pjb.9.1698027137799; Sun, 22 Oct 2023 19:12:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698027137; cv=none; d=google.com; s=arc-20160816; b=bB5xYsDkqaYYqPee7EPh4aB+aQJOokXcNL8t7OBk5tGJvv19esQbBdmZ7xwIjN/bB7 8O/da0GKY2W6pt8mr5GO/bpXA96RfImkRJXjnf8yR+kv+uoGfzpiyh3GsEfuvelpqfrj MhfA+bAyr15pYUpcPIbOyqjlyUkFl9Sm92sWtZoiitwlJmavhJVKoKceSs4aJ0TtUSqU QBmK+y0HTgQzFhZRncmjOI8LHQ6UczoaH/4Raewc7Q4qdd2vrlRkeAW4ucmS3FbgY6bW O3HPxIVAXUAkaI7E8au6kv9FfyzQXt6p+Uoqso1IWx8Xilmomtsd9LUSIDjvvrvs09A/ 8iGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=GDCSGpqzzQCPsWJnFwARKruyZ2iXRyLzv259sJdXiwE=; fh=7qEnEX/LkcfVW+x9QL9Kl5KXgIktTChUzdd7gz02GxQ=; b=Ogg59lIhkgxB9KO20PRscEhrFSLuRHtkxz56kECmGT9ctJbbD51KdYkdPSRulU5crS 7ULqAnHDMVqwomxHoG2tRPzKhMsJJ7RgxBZ30y4o+306us91EwAzCtjBCX5S7UjIeIMe c62AYgTCMR5wjM2WmUZ5cKF+EoL011z/xEnZCUMJ2uYQMUvno4fsVwYXqycbhNE+wEwz 6I8Wjy+X326dRehKRM+GMgPAD11ffQFB4yBQ9rTytG+pCj1MqJj/u0Tev8MdS5SmaejQ fDlrgNz83Lr6YOlC/VYqQ5Yi4+CvlXP/530286CUgAaVkwayegwmMQjZtFXA4oXXutcn vpOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=afeTQ7mX; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519 header.b="twdbu0D/"; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Return-Path: Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id y11-20020a17090a8b0b00b00276c22ca6a4si8107544pjn.147.2023.10.22.19.12.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 22 Oct 2023 19:12:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b=afeTQ7mX; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519 header.b="twdbu0D/"; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id 965E28061CF3; Sun, 22 Oct 2023 19:12:13 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233057AbjJWCMN (ORCPT + 99 others); Sun, 22 Oct 2023 22:12:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233094AbjJWCMM (ORCPT ); Sun, 22 Oct 2023 22:12:12 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB137E6 for ; Sun, 22 Oct 2023 19:12:07 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 4F69821A80; Mon, 23 Oct 2023 02:12:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1698027126; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GDCSGpqzzQCPsWJnFwARKruyZ2iXRyLzv259sJdXiwE=; b=afeTQ7mXkyYdbgtEKuSYzWrtRlNWK/cTAVgg3QXY+LYjaNo4xCXFPkYSK2V4Rwfst/3EWS F8k88gQQEi3oqvogw940iZR/Iaw5AuZ/gSxXe1Y0r9JXa2yDT6n+g34S4uXDhdT0kT1UE3 odzgtxr4/mMlD09hds9cRYZR+GQfh7k= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1698027126; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GDCSGpqzzQCPsWJnFwARKruyZ2iXRyLzv259sJdXiwE=; b=twdbu0D/g6tyU74HoZ17i88eIkkID54jA378UPB7mgSkhwcE2cK8QML9HJ4tCyL4SF0YSS Rv8GEnVuMpcfVxBg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 23A19132FD; Mon, 23 Oct 2023 02:12:04 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id VccwM3TWNWWTbwAAMHmgww (envelope-from ); Mon, 23 Oct 2023 02:12:04 +0000 From: NeilBrown To: Steve Dickson Cc: linux-nfs@vger.kernel.org, Trond Myklebust Subject: [PATCH 6/6] cache: periodically retry requests that couldn't be answered. Date: Mon, 23 Oct 2023 12:58:36 +1100 Message-ID: <20231023021052.5258-7-neilb@suse.de> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231023021052.5258-1-neilb@suse.de> References: <20231023021052.5258-1-neilb@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Authentication-Results: smtp-out1.suse.de; none X-Spam-Level: X-Spam-Score: -2.10 X-Spamd-Result: default: False [-2.10 / 50.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; FROM_HAS_DN(0.00)[]; RCPT_COUNT_THREE(0.00)[3]; TO_DN_SOME(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; MIME_GOOD(-0.10)[text/plain]; R_MISSING_CHARSET(2.50)[]; BROKEN_CONTENT_TYPE(1.50)[]; NEURAL_HAM_LONG(-3.00)[-1.000]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; NEURAL_HAM_SHORT(-1.00)[-1.000]; MID_CONTAINS_FROM(1.00)[]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; RCVD_COUNT_TWO(0.00)[2]; RCVD_TLS_ALL(0.00)[]; BAYES_HAM(-3.00)[100.00%] X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Sun, 22 Oct 2023 19:12:13 -0700 (PDT) Requests from the kernel to map the fsid from a filehandle to a path name sometimes cannot be answered because the filesystems isn't available now but might be available later. This happens if an export is marked "mountpoint" but the mountpoint isn't currently mounted. In this case it might get mounted in the future. It also happens in an NFS filesystem is being re-exported and the server is unresponsive. In that case (if it was mounted "softerr") we get ETIMEDOUT from a stat() attempt and so cannot give either a positive or negative response. These cases are currently handled poorly. No answer is returned to the kernel so it will continue waiting for an answer - and never get one even if the NFS server comes back or the mountpoint is mounted. We cannot report a soft error to the kernel so much retry ourselves. With this patch we record the request when the lookup fails with dev_missing or similar and retry every 2 minutes. Signed-off-by: NeilBrown --- support/export/cache.c | 121 +++++++++++++++++++++++++++++++++++------ 1 file changed, 103 insertions(+), 18 deletions(-) diff --git a/support/export/cache.c b/support/export/cache.c index a01eba4f6619..6c0a44a3a209 100644 --- a/support/export/cache.c +++ b/support/export/cache.c @@ -759,7 +759,15 @@ static struct addrinfo *lookup_client_addr(char *dom) return ret; } -static void nfsd_fh(int f) +#define RETRY_SEC 120 +struct delayed { + char *message; + time_t last_attempt; + int f; + struct delayed *next; +} *delayed; + +static int nfsd_handle_fh(int f, char *bp, int blen) { /* request are: * domain fsidtype fsid @@ -777,21 +785,13 @@ static void nfsd_fh(int f) nfs_export *exp; int i; int dev_missing = 0; - char buf[RPC_CHAN_BUF_SIZE], *bp; - int blen; + char buf[RPC_CHAN_BUF_SIZE]; int did_uncover = 0; - - blen = cache_read(f, buf, sizeof(buf)); - if (blen <= 0 || buf[blen-1] != '\n') return; - buf[blen-1] = 0; - - xlog(D_CALL, "nfsd_fh: inbuf '%s'", buf); - - bp = buf; + int ret = 0; dom = malloc(blen); if (dom == NULL) - return; + return ret; if (qword_get(&bp, dom, blen) <= 0) goto out; if (qword_get_int(&bp, &fsidtype) != 0) @@ -893,8 +893,10 @@ static void nfsd_fh(int f) /* The missing dev could be what we want, so just be * quiet rather than returning stale yet */ - if (dev_missing) + if (dev_missing) { + ret = 1; goto out; + } } else if (found->e_mountpoint && !is_mountpoint(found->e_mountpoint[0]? found->e_mountpoint: @@ -904,7 +906,7 @@ static void nfsd_fh(int f) xlog(L_WARNING, "%s not exported as %d not a mountpoint", found->e_path, found->e_mountpoint); */ - /* FIXME we need to make sure we re-visit this later */ + ret = 1; goto out; } @@ -933,7 +935,68 @@ out: free(found_path); nfs_freeaddrinfo(ai); free(dom); - xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL); + if (!ret) + xlog(D_CALL, "nfsd_fh: found %p path %s", + found, found ? found->e_path : NULL); + return ret; +} + +static void nfsd_fh(int f) +{ + struct delayed *d, **dp; + char inbuf[RPC_CHAN_BUF_SIZE]; + int blen; + + blen = cache_read(f, inbuf, sizeof(inbuf)); + if (blen <= 0 || inbuf[blen-1] != '\n') return; + inbuf[blen-1] = 0; + + xlog(D_CALL, "nfsd_fh: inbuf '%s'", inbuf); + + if (nfsd_handle_fh(f, inbuf, blen) == 0) + return; + /* We don't have a definitive answer to give the kernel. + * This is because an export marked "mountpoint" isn't a + * mountpoint, or because a stat of a mountpoint fails with + * a strange error like ETIMEDOUT as is possible with an + * NFS mount marked "softerr" which is being re-exported. + * + * We cannot tell the kernel to retry, so we have to + * retry ourselves. + */ + d = malloc(sizeof(*d)); + + if (!d) + return; + d->message = strndup(inbuf, blen); + if (!d->message) { + free(d); + return; + } + d->f = f; + d->last_attempt = time(NULL); + d->next = NULL; + dp = &delayed; + while (*dp) + dp = &(*dp)->next; + *dp = d; +} + +static void nfsd_retry_fh(struct delayed *d) +{ + struct delayed **dp; + + if (nfsd_handle_fh(d->f, d->message, strlen(d->message)+1) == 0) { + free(d->message); + free(d); + return; + } + d->last_attempt = time(NULL); + d->next = NULL; + dp = &delayed; + while (*dp) + dp = &(*dp)->next; + *dp = d; } #ifdef HAVE_JUNCTION_SUPPORT @@ -1512,7 +1575,7 @@ static void nfsd_export(int f) * This will cause it not to appear in the V4 Pseudo-root * and so a "mount" of this path will fail, just like with * V3. - * And filehandle for this mountpoint from an earlier + * Any filehandle for this mountpoint from an earlier * mount will block in nfsd.fh lookup. */ xlog(L_WARNING, @@ -1610,6 +1673,7 @@ int cache_process(fd_set *readfds) { fd_set fdset; int selret; + struct timeval tv = { 24*3600, 0 }; if (!readfds) { FD_ZERO(&fdset); @@ -1618,8 +1682,29 @@ int cache_process(fd_set *readfds) cache_set_fds(readfds); v4clients_set_fds(readfds); - selret = select(FD_SETSIZE, readfds, - (void *) 0, (void *) 0, (struct timeval *) 0); + if (delayed) { + time_t now = time(NULL); + time_t delay; + if (delayed->last_attempt > now) + /* Clock updated - retry immediately */ + delayed->last_attempt = now - RETRY_SEC; + delay = delayed->last_attempt + RETRY_SEC - now; + if (delay < 0) + delay = 0; + tv.tv_sec = delay; + } + selret = select(FD_SETSIZE, readfds, NULL, NULL, &tv); + + if (delayed) { + time_t now = time(NULL); + struct delayed *d = delayed; + + if (d->last_attempt + RETRY_SEC <= now) { + delayed = d->next; + d->next = NULL; + nfsd_retry_fh(d); + } + } switch (selret) { case -1: -- 2.42.0