From patchwork Tue Apr 18 09:33:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Weinberger X-Patchwork-Id: 13215317 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C3878C77B71 for ; Tue, 18 Apr 2023 09:34:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230253AbjDRJe0 (ORCPT ); Tue, 18 Apr 2023 05:34:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38450 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231360AbjDRJeV (ORCPT ); Tue, 18 Apr 2023 05:34:21 -0400 Received: from lithops.sigma-star.at (lithops.sigma-star.at [195.201.40.130]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAC083AA4 for ; Tue, 18 Apr 2023 02:34:15 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by lithops.sigma-star.at (Postfix) with ESMTP id 12B3164548AA; Tue, 18 Apr 2023 11:34:14 +0200 (CEST) Received: from lithops.sigma-star.at ([127.0.0.1]) by localhost (lithops.sigma-star.at [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id jGXi2-WbQWM7; Tue, 18 Apr 2023 11:34:13 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by lithops.sigma-star.at (Postfix) with ESMTP id 612C663CC168; Tue, 18 Apr 2023 11:34:13 +0200 (CEST) Received: from lithops.sigma-star.at ([127.0.0.1]) by localhost (lithops.sigma-star.at [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 07kss81YGmSn; Tue, 18 Apr 2023 11:34:13 +0200 (CEST) Received: from blindfold.corp.sigma-star.at (unknown [82.150.214.1]) by lithops.sigma-star.at (Postfix) with ESMTPSA id EACA06431C43; Tue, 18 Apr 2023 11:34:12 +0200 (CEST) From: Richard Weinberger To: linux-nfs@vger.kernel.org Cc: david@sigma-star.at, david.oberhollenzer@sigma-star.at, luis.turcitu@appsbroker.com, david.young@appsbroker.com, trond.myklebust@hammerspace.com, anna.schumaker@netapp.com, steved@redhat.com, chris.chilvers@appsbroker.com, Richard Weinberger Subject: [PATCH 3/8] export: Wireup reexport mechanism Date: Tue, 18 Apr 2023 11:33:45 +0200 Message-Id: <20230418093350.4550-4-richard@nod.at> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20230418093350.4550-1-richard@nod.at> References: <20230418093350.4550-1-richard@nod.at> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org Detect the case when a NFS share is re-exported and assign an fsidnum to it. The fsidnum is read (or created) from the reexport database. Signed-off-by: Richard Weinberger --- support/export/cache.c | 68 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/support/export/cache.c b/support/export/cache.c index 0a37703b..42a694d0 100644 --- a/support/export/cache.c +++ b/support/export/cache.c @@ -33,6 +33,7 @@ #include "export.h" #include "pseudoflavors.h" #include "xcommon.h" +#include "reexport.h" #ifdef HAVE_JUNCTION_SUPPORT #include "fsloc.h" @@ -235,6 +236,16 @@ static void auth_unix_gid(int f) xlog(L_ERROR, "auth_unix_gid: error writing reply"); } +static int match_crossmnt_fsidnum(uint32_t parsed_fsidnum, char *path) +{ + uint32_t fsidnum; + + if (reexpdb_fsidnum_by_path(path, &fsidnum, 0) == 0) + return 0; + + return fsidnum == parsed_fsidnum; +} + #ifdef USE_BLKID static const char *get_uuid_blkdev(char *path) { @@ -688,8 +699,13 @@ static int match_fsid(struct parsed_fsid *parsed, nfs_export *exp, char *path) goto match; case FSID_NUM: if (((exp->m_export.e_flags & NFSEXP_FSID) == 0 || - exp->m_export.e_fsid != parsed->fsidnum)) + exp->m_export.e_fsid != parsed->fsidnum)) { + if ((exp->m_export.e_flags & NFSEXP_CROSSMOUNT) && exp->m_export.e_reexport != REEXP_NONE && + match_crossmnt_fsidnum(parsed->fsidnum, path)) + goto match; + goto nomatch; + } goto match; case FSID_UUID4_INUM: case FSID_UUID16_INUM: @@ -937,7 +953,7 @@ static void write_fsloc(char **bp, int *blen, struct exportent *ep) } #endif -static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask) +static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_mask, int extra_flag) { struct sec_entry *p; @@ -952,7 +968,7 @@ static void write_secinfo(char **bp, int *blen, struct exportent *ep, int flag_m qword_addint(bp, blen, p - ep->e_secinfo); for (p = ep->e_secinfo; p->flav; p++) { qword_addint(bp, blen, p->flav->fnum); - qword_addint(bp, blen, p->flags & flag_mask); + qword_addint(bp, blen, (p->flags | extra_flag) & flag_mask); } } @@ -970,6 +986,15 @@ static void write_xprtsec(char **bp, int *blen, struct exportent *ep) qword_addint(bp, blen, p->info->number); } +static int can_reexport_via_fsidnum(struct exportent *exp, struct statfs *st) +{ + if (st->f_type != 0x6969 /* NFS_SUPER_MAGIC */) + return 0; + + return exp->e_reexport == REEXP_PREDEFINED_FSIDNUM || + exp->e_reexport == REEXP_AUTO_FSIDNUM; +} + static int dump_to_cache(int f, char *buf, int blen, char *domain, char *path, struct exportent *exp, int ttl) { @@ -986,17 +1011,48 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain, if (exp) { int different_fs = strcmp(path, exp->e_path) != 0; int flag_mask = different_fs ? ~NFSEXP_FSID : ~0; + int rc, do_fsidnum = 0; + uint32_t fsidnum = exp->e_fsid; + + if (different_fs) { + struct statfs st; + + rc = nfsd_path_statfs(path, &st); + if (rc) { + xlog(L_WARNING, "unable to statfs %s", path); + errno = EINVAL; + return -1; + } + + if (can_reexport_via_fsidnum(exp, &st)) { + do_fsidnum = 1; + flag_mask = ~0; + } + } qword_adduint(&bp, &blen, now + exp->e_ttl); - qword_addint(&bp, &blen, exp->e_flags & flag_mask); + + if (do_fsidnum) { + uint32_t search_fsidnum = 0; + if (exp->e_reexport != REEXP_NONE && reexpdb_fsidnum_by_path(path, &search_fsidnum, + exp->e_reexport == REEXP_AUTO_FSIDNUM) == 0) { + errno = EINVAL; + return -1; + } + fsidnum = search_fsidnum; + qword_addint(&bp, &blen, exp->e_flags | NFSEXP_FSID); + } else { + qword_addint(&bp, &blen, exp->e_flags & flag_mask); + } + qword_addint(&bp, &blen, exp->e_anonuid); qword_addint(&bp, &blen, exp->e_anongid); - qword_addint(&bp, &blen, exp->e_fsid); + qword_addint(&bp, &blen, fsidnum); #ifdef HAVE_JUNCTION_SUPPORT write_fsloc(&bp, &blen, exp); #endif - write_secinfo(&bp, &blen, exp, flag_mask); + write_secinfo(&bp, &blen, exp, flag_mask, do_fsidnum ? NFSEXP_FSID : 0); if (exp->e_uuid == NULL || different_fs) { char u[16]; if ((exp->e_flags & flag_mask & NFSEXP_FSID) == 0 &&