From nobody Fri Dec 19 08:58:01 2025 Received: from mout-p-102.mailbox.org (mout-p-102.mailbox.org [80.241.56.152]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 93E1940C03; Wed, 4 Sep 2024 19:48:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.241.56.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725479326; cv=none; b=tc22VSQcTj9vkGOEbyyKORhncwqpxVYK5akx6ij8feIShlzhLj6Z2X10CX/0An9KOa8Z8eg0x9+/eyF+zRfw4tPffhJpriKetPi/M0yrTj//9nH1VJWBc+iZJY3l7zKY3xx8vumJaZmgTdIb5KZQttqfBI6WwkiKdwcPWQw27QE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725479326; c=relaxed/simple; bh=+BEzFkMA6X18VDv8VAVAuyHtyNyqRK56bhKY4sqG7NU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ple1WRfOnY9laoNi2+Xcgzub5ELlQoVUqhSz4lhPNR6GV9ATqP7o0ePKurOENxYBakduXG4453mJBNHBBQyy36lCRigjOkI3SUNlo6X3BO3Te8fIH/heazdI/+WRTbi9WqeuEh/QKs1tM3rdyj4GiocqQwCLoDZNc/rEgkQQUB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com; spf=pass smtp.mailfrom=cyphar.com; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b=ZENjZ5lt; arc=none smtp.client-ip=80.241.56.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyphar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b="ZENjZ5lt" Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-102.mailbox.org (Postfix) with ESMTPS id 4WzY2c36W2z9stH; Wed, 4 Sep 2024 21:48:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cyphar.com; s=MBO0001; t=1725479320; h=from:from:reply-to:subject:subject: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=2aa3h7uu8Ajlu4C0h74xCDfvRf6u0K/78nks73Z7uTQ=; b=ZENjZ5ltRRW2mVE/uEP7sPhsxUMwIvZEWWx7mBubRfp3OSwfT1xNE61hjtagcumBACTR/q wDE2uQwLwvqroxpzhrpCuCaY9Js8VyaZ+eu9aj6DbIVCFnh+7BK+jnqhFMmZb94nPYn5Ms +WIDvOlFdCS2q1k6/ojBjCNRO7eDjd+eo45XnB+uECk7eewp21lm+7IfHlIz6KxnkYQV3S TxTvEKQSo6+qG++ZX4LvzhtVtIVZL/3pZ3nhvwQWyVCj70uKY9F1mal0y7atve1nc/9dn9 S0c4Zt0JLU+7kCGUWc52+s8Oy80EvUguri24cUZtA+dIuPLm8UmifyOorfT/Nw== From: Aleksa Sarai To: fstests@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Jeff Layton , Amir Goldstein , Alexander Aring , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" Cc: Aleksa Sarai , Christoph Hellwig , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-perf-users@vger.kernel.org Subject: [PATCH xfstests v4 1/2] open_by_handle: verify u32 and u64 mount IDs Date: Thu, 5 Sep 2024 05:48:22 +1000 Message-ID: <20240904194823.2456471-1-cyphar@cyphar.com> In-Reply-To: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> References: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Now that open_by_handle_at(2) can return u64 mount IDs, do some tests to make sure they match properly as part of the regular open_by_handle tests. Also, add automatic tests for the old u32 mount IDs as well. By default, we do mount ID checks but silently skip the tests if the syscalls are not supported by the running kernel (to ensure the tests continue to work for old kernels). We will add some tests explicitly checking the new features (with no silent skipping) in a future patch. The u32 mount ID tests require STATX_MNT_ID (Linux 5.8), while the u64 mount ID tests require STATX_MNT_ID_UNIQUE (Linux 6.9) and AT_HANDLE_MNT_ID_UNIQUE (linux-next). Link: https://lore.kernel.org/all/20240828-exportfs-u64-mount-id-v3-0-10c2c= 4c16708@cyphar.com/ Reviewed-by: Amir Goldstein Signed-off-by: Aleksa Sarai --- Changed in v4: - Fix minor flub in patch split. [Amir Goldstein] - v3: Changed in v3: - Make skipping completely silent in regular open_by_handle mode. [Amir Gol= dstein] - Re-add -M to turn skipping into errors and add a new test that uses -M, but is skipped on older kernels. [Amir Goldstein] - v2: Changed in v2: - Remove -M argument and always do the mount ID tests. [Amir Goldstein] - Do not error out if the kernel doesn't support STATX_MNT_ID_UNIQUE or AT_HANDLE_MNT_ID_UNIQUE. [Amir Goldstein] - v1: --- src/open_by_handle.c | 131 +++++++++++++++++++++++++++++++++---------- 1 file changed, 102 insertions(+), 29 deletions(-) diff --git a/src/open_by_handle.c b/src/open_by_handle.c index 0f74ed08b1f0..dcbcd35561fb 100644 --- a/src/open_by_handle.c +++ b/src/open_by_handle.c @@ -87,6 +87,15 @@ Examples: #include #include #include +#include +#include + +#include +#include "statx.h" + +#ifndef AT_HANDLE_MNT_ID_UNIQUE +# define AT_HANDLE_MNT_ID_UNIQUE 0x001 +#endif =20 #define MAXFILES 1024 =20 @@ -118,6 +127,94 @@ void usage(void) exit(EXIT_FAILURE); } =20 +static int do_name_to_handle_at(const char *fname, struct file_handle *fh, + int bufsz) +{ + int ret; + int mntid_short; + + static bool skip_mntid, skip_mntid_unique; + + uint64_t statx_mntid_short =3D 0, statx_mntid_unique =3D 0; + struct statx statxbuf; + + /* Get both the short and unique mount id. */ + if (!skip_mntid) { + if (xfstests_statx(AT_FDCWD, fname, 0, STATX_MNT_ID, &statxbuf) < 0) { + fprintf(stderr, "%s: statx(STATX_MNT_ID): %m\n", fname); + return EXIT_FAILURE; + } + if (!(statxbuf.stx_mask & STATX_MNT_ID)) + skip_mntid =3D true; + else + statx_mntid_short =3D statxbuf.stx_mnt_id; + } + + if (!skip_mntid_unique) { + if (xfstests_statx(AT_FDCWD, fname, 0, STATX_MNT_ID_UNIQUE, &statxbuf) <= 0) { + fprintf(stderr, "%s: statx(STATX_MNT_ID_UNIQUE): %m\n", fname); + return EXIT_FAILURE; + } + /* + * STATX_MNT_ID_UNIQUE was added fairly recently in Linux 6.8, so if the + * kernel doesn't give us a unique mount ID just skip it. + */ + if (!(statxbuf.stx_mask & STATX_MNT_ID_UNIQUE)) + skip_mntid_unique =3D true; + else + statx_mntid_unique =3D statxbuf.stx_mnt_id; + } + + fh->handle_bytes =3D bufsz; + ret =3D name_to_handle_at(AT_FDCWD, fname, fh, &mntid_short, 0); + if (bufsz < fh->handle_bytes) { + /* Query the filesystem required bufsz and the file handle */ + if (ret !=3D -1 || errno !=3D EOVERFLOW) { + fprintf(stderr, "%s: unexpected result from name_to_handle_at: %d (%m)\= n", fname, ret); + return EXIT_FAILURE; + } + ret =3D name_to_handle_at(AT_FDCWD, fname, fh, &mntid_short, 0); + } + if (ret < 0) { + fprintf(stderr, "%s: name_to_handle: %m\n", fname); + return EXIT_FAILURE; + } + + if (!skip_mntid) { + if (mntid_short !=3D (int) statx_mntid_short) { + fprintf(stderr, "%s: name_to_handle_at returned a different mount ID to= STATX_MNT_ID: %u !=3D %lu\n", fname, mntid_short, statx_mntid_short); + return EXIT_FAILURE; + } + } + + if (!skip_mntid_unique) { + struct handle dummy_fh; + uint64_t mntid_unique =3D 0; + + /* + * Get the unique mount ID. We don't need to get another copy of the + * handle so store it in a dummy struct. + */ + dummy_fh.fh.handle_bytes =3D fh->handle_bytes; + ret =3D name_to_handle_at(AT_FDCWD, fname, &dummy_fh.fh, (int *) &mntid_= unique, AT_HANDLE_MNT_ID_UNIQUE); + if (ret < 0) { + if (errno !=3D EINVAL) { + fprintf(stderr, "%s: name_to_handle_at(AT_HANDLE_MNT_ID_UNIQUE): %m\n"= , fname); + return EXIT_FAILURE; + } + /* EINVAL means AT_HANDLE_MNT_ID_UNIQUE is not supported */ + skip_mntid_unique =3D true; + } else { + if (mntid_unique !=3D statx_mntid_unique) { + fprintf(stderr, "%s: name_to_handle_at(AT_HANDLE_MNT_ID_UNIQUE) return= ed a different mount ID to STATX_MNT_ID_UNIQUE: %lu !=3D %lu\n", fname, mnt= id_unique, statx_mntid_unique); + return EXIT_FAILURE; + } + } + } + + return 0; +} + int main(int argc, char **argv) { int i, c; @@ -130,7 +227,7 @@ int main(int argc, char **argv) char fname2[PATH_MAX]; char *test_dir; char *mount_dir; - int mount_fd, mount_id; + int mount_fd; char *infile =3D NULL, *outfile =3D NULL; int in_fd =3D 0, out_fd =3D 0; int numfiles =3D 1; @@ -305,21 +402,9 @@ int main(int argc, char **argv) return EXIT_FAILURE; } } else { - handle[i].fh.handle_bytes =3D bufsz; - ret =3D name_to_handle_at(AT_FDCWD, fname, &handle[i].fh, &mount_id, 0); - if (bufsz < handle[i].fh.handle_bytes) { - /* Query the filesystem required bufsz and the file handle */ - if (ret !=3D -1 || errno !=3D EOVERFLOW) { - fprintf(stderr, "Unexpected result from name_to_handle_at(%s)\n", fna= me); - return EXIT_FAILURE; - } - ret =3D name_to_handle_at(AT_FDCWD, fname, &handle[i].fh, &mount_id, 0= ); - } - if (ret < 0) { - strcat(fname, ": name_to_handle"); - perror(fname); + ret =3D do_name_to_handle_at(fname, &handle[i].fh, bufsz); + if (ret) return EXIT_FAILURE; - } } if (keepopen) { /* Open without close to keep unlinked files around */ @@ -347,21 +432,9 @@ int main(int argc, char **argv) return EXIT_FAILURE; } } else { - dir_handle.fh.handle_bytes =3D bufsz; - ret =3D name_to_handle_at(AT_FDCWD, test_dir, &dir_handle.fh, &mount_id= , 0); - if (bufsz < dir_handle.fh.handle_bytes) { - /* Query the filesystem required bufsz and the file handle */ - if (ret !=3D -1 || errno !=3D EOVERFLOW) { - fprintf(stderr, "Unexpected result from name_to_handle_at(%s)\n", dna= me); - return EXIT_FAILURE; - } - ret =3D name_to_handle_at(AT_FDCWD, test_dir, &dir_handle.fh, &mount_i= d, 0); - } - if (ret < 0) { - strcat(dname, ": name_to_handle"); - perror(dname); + ret =3D do_name_to_handle_at(test_dir, &dir_handle.fh, bufsz); + if (ret) return EXIT_FAILURE; - } } if (out_fd) { ret =3D write(out_fd, (char *)&dir_handle, sizeof(*handle)); --=20 2.46.0 From nobody Fri Dec 19 08:58:01 2025 Received: from mout-p-102.mailbox.org (mout-p-102.mailbox.org [80.241.56.152]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5059C1D88BF; Wed, 4 Sep 2024 17:57:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.241.56.152 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725472648; cv=none; b=J4EkL5S9VvQGQZbrLYEMlpaAmSWwehl27+XwThtCZRJogyFQEo9t5+z1kaX1R/elUE/5DYUk+sSiMaXJUayvOp7ZQMAw9gKuP6qwJjATrJwCCaRKe/GbNGTU2BpXJgEggGSxPTEPDuO3tNiJTRcEZCrA2GoQaIXcuBgliJ99qhc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725472648; c=relaxed/simple; bh=f0rWgWl3Jbp67vtePZy9hnee39Eahoe856cAV6S3LSo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Wz69aRGKKCLlBUpbhR0/OFKlWWI0lGrgGNQ+wBlKcJjyPAbCmi9wsEyc/TgNO2I4W7+WDwckvXWNmei1pdp9ci5Tog3k6FnwZv6i5G+hdUtJEI71XA7lQwqOBdZMAqHk323Aq3ay+VyVrFpu+NewjKQhtABIBOBMcTcZEQ/qFhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com; spf=pass smtp.mailfrom=cyphar.com; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b=mnlocwHO; arc=none smtp.client-ip=80.241.56.152 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyphar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b="mnlocwHO" Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-102.mailbox.org (Postfix) with ESMTPS id 4WzVZ81MZzz9sdW; Wed, 4 Sep 2024 19:57:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cyphar.com; s=MBO0001; t=1725472640; h=from:from:reply-to:subject:subject: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=1ybZuNM9wO8duPmiRVKL3f0gGJvGPSGKvN0cowgJxlI=; b=mnlocwHO8KlVsvYz9JsdPbgkYAQao0Vlb9GCFJB4oIhTP8UA8Du2vhgelNPk84xZh6SdQl iMz9b6Ia9CTdAvqU3tGBMt1zbeCTBAWm5e7210bwjabWQYWhBxCiQz2jSKNc7fYrm6r7kT M4jpDiZFZgPcR97DS9z2RDFTEM4Jbw+syLmTKif55L4KEm+Zvb7PnIvhDC6d101cQqD2nX 17KFMLxAm56djjw9IfsNK5lh+CuPTnnAlT/pyRBe5KxMsWhN9nYqiDCG2a7oboXxgpfojp baKL2vlmXo0vF2pocgNtjugiw7D+J9bMM2MFR6UNXF2ySV5USRODeVaaK/OMUA== From: Aleksa Sarai To: fstests@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Jeff Layton , Amir Goldstein , Alexander Aring , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" Cc: Aleksa Sarai , Christoph Hellwig , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-perf-users@vger.kernel.org Subject: [PATCH xfstests v3 1/2] open_by_handle: verify u32 and u64 mount IDs Date: Thu, 5 Sep 2024 03:56:37 +1000 Message-ID: <20240904175639.2269694-1-cyphar@cyphar.com> In-Reply-To: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> References: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 4WzVZ81MZzz9sdW Content-Type: text/plain; charset="utf-8" Now that open_by_handle_at(2) can return u64 mount IDs, do some tests to make sure they match properly as part of the regular open_by_handle tests. Also, add automatic tests for the old u32 mount IDs as well. By default, we do mount ID checks but silently skip the tests if the syscalls are not supported by the running kernel (to ensure the tests continue to work for old kernels). We will add some tests explicitly checking the new features (with no silent skipping) in a future patch. The u32 mount ID tests require STATX_MNT_ID (Linux 5.8), while the u64 mount ID tests require STATX_MNT_ID_UNIQUE (Linux 6.9) and AT_HANDLE_MNT_ID_UNIQUE (linux-next). Link: https://lore.kernel.org/all/20240828-exportfs-u64-mount-id-v3-0-10c2c= 4c16708@cyphar.com/ Signed-off-by: Aleksa Sarai Reviewed-by: Amir Goldstein --- Changed in v3: - Make skipping completely silent in regular open_by_handle mode. [Amir Gol= dstein] - Re-add -M to turn skipping into errors and add a new test that uses -M, but is skipped on older kernels. [Amir Goldstein] - v2: Changed in v2: - Remove -M argument and always do the mount ID tests. [Amir Goldstein] - Do not error out if the kernel doesn't support STATX_MNT_ID_UNIQUE or AT_HANDLE_MNT_ID_UNIQUE. [Amir Goldstein] - v1: --- src/open_by_handle.c | 132 +++++++++++++++++++++++++++++++++---------- 1 file changed, 103 insertions(+), 29 deletions(-) diff --git a/src/open_by_handle.c b/src/open_by_handle.c index 0f74ed08b1f0..920ec7d9170b 100644 --- a/src/open_by_handle.c +++ b/src/open_by_handle.c @@ -87,6 +87,15 @@ Examples: #include #include #include +#include +#include + +#include +#include "statx.h" + +#ifndef AT_HANDLE_MNT_ID_UNIQUE +# define AT_HANDLE_MNT_ID_UNIQUE 0x001 +#endif =20 #define MAXFILES 1024 =20 @@ -108,6 +117,7 @@ void usage(void) fprintf(stderr, "open_by_handle -a [N] - write data to test fi= les after open by handle\n"); fprintf(stderr, "open_by_handle -l [N] - create hardlinks to t= est files, drop caches and try to open by handle\n"); fprintf(stderr, "open_by_handle -u [N] - unlink (hardlinked) t= est files, drop caches and try to open by handle\n"); + fprintf(stderr, "open_by_handle -U [N] - verify the mount ID r= eturned with AT_HANDLE_MNT_ID_UNIQUE is correct\n"); fprintf(stderr, "open_by_handle -d [N] - unlink test files and= hardlinks, drop caches and try to open by handle\n"); fprintf(stderr, "open_by_handle -m [N] - rename test files, dr= op caches and try to open by handle\n"); fprintf(stderr, "open_by_handle -p - create/delete and try= to open by handle also test_dir itself\n"); @@ -118,6 +128,94 @@ void usage(void) exit(EXIT_FAILURE); } =20 +static int do_name_to_handle_at(const char *fname, struct file_handle *fh, + int bufsz) +{ + int ret; + int mntid_short; + + static bool skip_mntid, skip_mntid_unique; + + uint64_t statx_mntid_short =3D 0, statx_mntid_unique =3D 0; + struct statx statxbuf; + + /* Get both the short and unique mount id. */ + if (!skip_mntid) { + if (xfstests_statx(AT_FDCWD, fname, 0, STATX_MNT_ID, &statxbuf) < 0) { + fprintf(stderr, "%s: statx(STATX_MNT_ID): %m\n", fname); + return EXIT_FAILURE; + } + if (!(statxbuf.stx_mask & STATX_MNT_ID)) + skip_mntid =3D true; + else + statx_mntid_short =3D statxbuf.stx_mnt_id; + } + + if (!skip_mntid_unique) { + if (xfstests_statx(AT_FDCWD, fname, 0, STATX_MNT_ID_UNIQUE, &statxbuf) <= 0) { + fprintf(stderr, "%s: statx(STATX_MNT_ID_UNIQUE): %m\n", fname); + return EXIT_FAILURE; + } + /* + * STATX_MNT_ID_UNIQUE was added fairly recently in Linux 6.8, so if the + * kernel doesn't give us a unique mount ID just skip it. + */ + if (!(statxbuf.stx_mask & STATX_MNT_ID_UNIQUE)) + skip_mntid_unique =3D true; + else + statx_mntid_unique =3D statxbuf.stx_mnt_id; + } + + fh->handle_bytes =3D bufsz; + ret =3D name_to_handle_at(AT_FDCWD, fname, fh, &mntid_short, 0); + if (bufsz < fh->handle_bytes) { + /* Query the filesystem required bufsz and the file handle */ + if (ret !=3D -1 || errno !=3D EOVERFLOW) { + fprintf(stderr, "%s: unexpected result from name_to_handle_at: %d (%m)\= n", fname, ret); + return EXIT_FAILURE; + } + ret =3D name_to_handle_at(AT_FDCWD, fname, fh, &mntid_short, 0); + } + if (ret < 0) { + fprintf(stderr, "%s: name_to_handle: %m\n", fname); + return EXIT_FAILURE; + } + + if (!skip_mntid) { + if (mntid_short !=3D (int) statx_mntid_short) { + fprintf(stderr, "%s: name_to_handle_at returned a different mount ID to= STATX_MNT_ID: %u !=3D %lu\n", fname, mntid_short, statx_mntid_short); + return EXIT_FAILURE; + } + } + + if (!skip_mntid_unique) { + struct handle dummy_fh; + uint64_t mntid_unique =3D 0; + + /* + * Get the unique mount ID. We don't need to get another copy of the + * handle so store it in a dummy struct. + */ + dummy_fh.fh.handle_bytes =3D fh->handle_bytes; + ret =3D name_to_handle_at(AT_FDCWD, fname, &dummy_fh.fh, (int *) &mntid_= unique, AT_HANDLE_MNT_ID_UNIQUE); + if (ret < 0) { + if (errno !=3D EINVAL) { + fprintf(stderr, "%s: name_to_handle_at(AT_HANDLE_MNT_ID_UNIQUE): %m\n"= , fname); + return EXIT_FAILURE; + } + /* EINVAL means AT_HANDLE_MNT_ID_UNIQUE is not supported */ + skip_mntid_unique =3D true; + } else { + if (mntid_unique !=3D statx_mntid_unique) { + fprintf(stderr, "%s: name_to_handle_at(AT_HANDLE_MNT_ID_UNIQUE) return= ed a different mount ID to STATX_MNT_ID_UNIQUE: %lu !=3D %lu\n", fname, mnt= id_unique, statx_mntid_unique); + return EXIT_FAILURE; + } + } + } + + return 0; +} + int main(int argc, char **argv) { int i, c; @@ -130,7 +228,7 @@ int main(int argc, char **argv) char fname2[PATH_MAX]; char *test_dir; char *mount_dir; - int mount_fd, mount_id; + int mount_fd; char *infile =3D NULL, *outfile =3D NULL; int in_fd =3D 0, out_fd =3D 0; int numfiles =3D 1; @@ -305,21 +403,9 @@ int main(int argc, char **argv) return EXIT_FAILURE; } } else { - handle[i].fh.handle_bytes =3D bufsz; - ret =3D name_to_handle_at(AT_FDCWD, fname, &handle[i].fh, &mount_id, 0); - if (bufsz < handle[i].fh.handle_bytes) { - /* Query the filesystem required bufsz and the file handle */ - if (ret !=3D -1 || errno !=3D EOVERFLOW) { - fprintf(stderr, "Unexpected result from name_to_handle_at(%s)\n", fna= me); - return EXIT_FAILURE; - } - ret =3D name_to_handle_at(AT_FDCWD, fname, &handle[i].fh, &mount_id, 0= ); - } - if (ret < 0) { - strcat(fname, ": name_to_handle"); - perror(fname); + ret =3D do_name_to_handle_at(fname, &handle[i].fh, bufsz); + if (ret) return EXIT_FAILURE; - } } if (keepopen) { /* Open without close to keep unlinked files around */ @@ -347,21 +433,9 @@ int main(int argc, char **argv) return EXIT_FAILURE; } } else { - dir_handle.fh.handle_bytes =3D bufsz; - ret =3D name_to_handle_at(AT_FDCWD, test_dir, &dir_handle.fh, &mount_id= , 0); - if (bufsz < dir_handle.fh.handle_bytes) { - /* Query the filesystem required bufsz and the file handle */ - if (ret !=3D -1 || errno !=3D EOVERFLOW) { - fprintf(stderr, "Unexpected result from name_to_handle_at(%s)\n", dna= me); - return EXIT_FAILURE; - } - ret =3D name_to_handle_at(AT_FDCWD, test_dir, &dir_handle.fh, &mount_i= d, 0); - } - if (ret < 0) { - strcat(dname, ": name_to_handle"); - perror(dname); + ret =3D do_name_to_handle_at(test_dir, &dir_handle.fh, bufsz); + if (ret) return EXIT_FAILURE; - } } if (out_fd) { ret =3D write(out_fd, (char *)&dir_handle, sizeof(*handle)); --=20 2.46.0 From nobody Fri Dec 19 08:58:01 2025 Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [80.241.56.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04E1D1AB6D0; Mon, 2 Sep 2024 16:46:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.241.56.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725295601; cv=none; b=ArYdKjRtG8Gc+BPizAjm7yZ6NpG4Q8xRLsk9owLXRmCZPnZewPC+/fgDqUtRkgXtjDWfizDtQEzm5daAbGCibcx4raSbal6ROrMPXSgGon0Cd7TVeDV1zCF6kFTxaU5w7EZ6Xr7e4hFLe94ZD2JWLbPDAeHyEZr/GXvsGbtZ6EM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725295601; c=relaxed/simple; bh=2JEtkyYBzbNUNWYD6K3reCmf/PfliNsGWxt62ICcuOU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VcdnAuD9ZWoiPALu6yGmuctzK3/nU0UWigeP5xHSdK4nk+1g7+cVpcKe/VWdnbltmHVRethqlbu0axhtUZk1/YNl05xcfY7xnVP5S0SmNcEw2eiufxvJ2GtBgunx51dd7ySxdw+wnwlx3pOZ0MNpXX+9ptRfN0OafYHhBjP9ToI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com; spf=pass smtp.mailfrom=cyphar.com; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b=oPQnB+hq; arc=none smtp.client-ip=80.241.56.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyphar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b="oPQnB+hq" Received: from smtp2.mailbox.org (smtp2.mailbox.org [10.196.197.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4WyF5L1kQqz9tqL; Mon, 2 Sep 2024 18:46:30 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cyphar.com; s=MBO0001; t=1725295590; h=from:from:reply-to:subject:subject: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=DYW8e2RAgi5MkOkqfurv6e1luZxwkEFySGMNtg8Nzlo=; b=oPQnB+hqa7XH5g9+gr6LNTU20LJqEkqpeyTK30MGGwRdEzKbVOpOAmNhhxrqJbO/UyXT2P GDQSz1ZtpmPJAQSbpR6gsfBGdGnenHUxjxCTIMn+dkByq8f8I2iITdoR6L8oJn9ReDYrij jg5HW040NxkE3/t5/p68SIPlJ8arf5Iut5uoBZnho3NCut3SZvYZ/xs6ZqqDQ30KuCPqAV cZsRtiHdPXMFu5dkGfuqT4Hp4mzYM+sAOadY2yHJLjB0kwllmri5HCSwioall5AH+LIlzq pcGEsJFvlFRgcSNiInvFTo1VZhXZ9C1A+dTjE7xTLKVW8xEgxtsj53YyVPf10w== From: Aleksa Sarai To: fstests@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Jeff Layton , Amir Goldstein , Alexander Aring , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" Cc: Aleksa Sarai , Christoph Hellwig , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-perf-users@vger.kernel.org Subject: [PATCH xfstests v2 1/2] statx: update headers to include newer statx fields Date: Tue, 3 Sep 2024 02:45:53 +1000 Message-ID: <20240902164554.928371-1-cyphar@cyphar.com> In-Reply-To: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> References: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" These come from Linux v6.11-rc5. Signed-off-by: Aleksa Sarai --- src/open_by_handle.c | 4 +++- src/statx.h | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/open_by_handle.c b/src/open_by_handle.c index 0f74ed08b1f0..d9c802ca9bd1 100644 --- a/src/open_by_handle.c +++ b/src/open_by_handle.c @@ -82,12 +82,14 @@ Examples: #include #include #include -#include #include #include #include #include =20 +#include +#include "statx.h" + #define MAXFILES 1024 =20 struct handle { diff --git a/src/statx.h b/src/statx.h index 3f239d791dfe..935cb2ed415e 100644 --- a/src/statx.h +++ b/src/statx.h @@ -102,7 +102,7 @@ struct statx { __u64 stx_ino; /* Inode number */ __u64 stx_size; /* File size */ __u64 stx_blocks; /* Number of 512-byte blocks allocated */ - __u64 __spare1[1]; + __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attrib= utes */ /* 0x40 */ struct statx_timestamp stx_atime; /* Last access time */ struct statx_timestamp stx_btime; /* File creation time */ @@ -114,7 +114,18 @@ struct statx { __u32 stx_dev_major; /* ID of device containing file [uncond] */ __u32 stx_dev_minor; /* 0x90 */ - __u64 __spare2[14]; /* Spare space for future expansion */ + __u64 stx_mnt_id; + __u32 stx_dio_mem_align; /* Memory buffer alignment for direct I/O */ + __u32 stx_dio_offset_align; /* File offset alignment for direct I/O */ + /* 0xa0 */ + __u64 stx_subvol; /* Subvolume identifier */ + __u32 stx_atomic_write_unit_min; /* Min atomic write unit in bytes */ + __u32 stx_atomic_write_unit_max; /* Max atomic write unit in bytes */ + /* 0xb0 */ + __u32 stx_atomic_write_segments_max; /* Max atomic write segment count = */ + __u32 __spare1[1]; + /* 0xb8 */ + __u64 __spare3[9]; /* Spare space for future expansion */ /* 0x100 */ }; =20 @@ -139,6 +150,13 @@ struct statx { #define STATX_BLOCKS 0x00000400U /* Want/got stx_blocks */ #define STATX_BASIC_STATS 0x000007ffU /* The stuff in the normal stat stru= ct */ #define STATX_BTIME 0x00000800U /* Want/got stx_btime */ +#define STATX_MNT_ID 0x00001000U /* Got stx_mnt_id */ +#define STATX_DIOALIGN 0x00002000U /* Want/got direct I/O alignment info = */ +#define STATX_MNT_ID_UNIQUE 0x00004000U /* Want/got extended stx_mount_id = */ +#define STATX_SUBVOL 0x00008000U /* Want/got stx_subvol */ +#define STATX_WRITE_ATOMIC 0x00010000U /* Want/got atomic_write_* fields */ + +#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx e= xpansion */ #define STATX_ALL 0x00000fffU /* All currently supported flags */ =20 /* --=20 2.46.0 From nobody Fri Dec 19 08:58:01 2025 Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [80.241.56.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C552B16B74A; Wed, 28 Aug 2024 10:20:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.241.56.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724840421; cv=none; b=gClIrGTjZ1pYWKe4/9M/4KJXWxrLnNj2cPDj55r8SQUDPhhx57hZfA4iG/2156qPpU4j2XFLWRZyQg+QlqGfaujxXqGBit2SS5GdmX8fX08F+E0OD6mSbvD88dOd9y+yPcE154jP5ToqrSLOdvMibcD0jcrVl7ml3kryF2Y5/J0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724840421; c=relaxed/simple; bh=ZDBBE7Olysb+GOy+rui6xqJeogFiBpA1eQ1ZuRCSe7Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=P7navi9KpMOPdygC+i0Vy8TSY9jhWGGjUul0q1EWiiRqDHRE/fMOcqZAiQTq7d8TFmIZex4N5pbgJvV0D65bGrgEEOeNQovAGbYxYXuZeQK4SzEFxKKFh+UfLblDtXtIKn2bFBADEHc19DP3+VTkIIe/MjqW242eBE+4IUFVJMc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com; spf=pass smtp.mailfrom=cyphar.com; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b=NYNlZuvc; arc=none smtp.client-ip=80.241.56.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyphar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b="NYNlZuvc" Received: from smtp202.mailbox.org (smtp202.mailbox.org [IPv6:2001:67c:2050:b231:465::202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4Wv0ly73tsz9tSW; Wed, 28 Aug 2024 12:20:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cyphar.com; s=MBO0001; t=1724840415; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YQbaqtCcYzWvH6YOM7jCI493EAQ425eOarur6ctccck=; b=NYNlZuvc/e++tY6yiizNH4WtOKxUI8NZ4Dsrm9r1QhAmdhHVplZ8Q5aNPj8uIlOIXVqobG xFJeJ5a6DSFfVrs9ttredBFGRaaMJ54+QSdLTQ7Hlz/RReyHUwAF7YZnTcq5K0SSuYSeSo zkGmJW3QoJN/w4orbU9R5eNbmnk6q+rUO4Sb3oRKJR16LmCWnxWrAGfMs4l1EmkqRtNl3E sUmgao1VBj/VZMcELuRcBLp/f7cNaCbsCKAQaMckkXiyzkKUu5D3XkImrWLsoGUGCK8CnV BxqHc0Z61RR4eGkOSlCpY1BUq2dceLmS1v+t3CmP9tnb78UjrzyTx2j9kFXJ/A== From: Aleksa Sarai Date: Wed, 28 Aug 2024 20:19:42 +1000 Subject: [PATCH RESEND v3 1/2] uapi: explain how per-syscall AT_* flags should be allocated Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240828-exportfs-u64-mount-id-v3-1-10c2c4c16708@cyphar.com> References: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> In-Reply-To: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Jeff Layton , Amir Goldstein , Alexander Aring , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter Cc: Christoph Hellwig , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-perf-users@vger.kernel.org, Aleksa Sarai X-Developer-Signature: v=1; a=openpgp-sha256; l=13861; i=cyphar@cyphar.com; h=from:subject:message-id; bh=ZDBBE7Olysb+GOy+rui6xqJeogFiBpA1eQ1ZuRCSe7Q=; b=owGbwMvMwCWmMf3Xpe0vXfIZT6slMaSd+3l8Q/SEve1vpLwX1GZziS7V0POVvmXzs/bU7piGa 2fOJ6780FHKwiDGxSArpsiyzc8zdNP8xVeSP61kg5nDygQyhIGLUwAmwpfHyLB/9eX/2zYYHr18 bWbeqy8fzdwnb5y971HL8UVtQREOzkvtGf6ZS71qfpr4bC7fb1HdafqWfXU3JnxddeLGJyXL2kl VOoz8AA== X-Developer-Key: i=cyphar@cyphar.com; a=openpgp; fpr=C9C370B246B09F6DBCFC744C34401015D1D2D386 X-Rspamd-Queue-Id: 4Wv0ly73tsz9tSW Unfortunately, the way we have gone about adding new AT_* flags has been a little messy. In the beginning, all of the AT_* flags had generic meanings and so it made sense to share the flag bits indiscriminately. However, we inevitably ran into syscalls that needed their own syscall-specific flags. Due to the lack of a planned out policy, we ended up with the following situations: * Existing syscalls adding new features tended to use new AT_* bits, with some effort taken to try to re-use bits for flags that were so obviously syscall specific that they only make sense for a single syscall (such as the AT_EACCESS/AT_REMOVEDIR/AT_HANDLE_FID triplet). Given the constraints of bitflags, this works well in practice, but ideally (to avoid future confusion) we would plan ahead and define a set of "per-syscall bits" ahead of time so that when allocating new bits we don't end up with a complete mish-mash of which bits are supposed to be per-syscall and which aren't. * New syscalls dealt with this in several ways: - Some syscalls (like renameat2(2), move_mount(2), fsopen(2), and fspick(2)) created their separate own flag spaces that have no overlap with the AT_* flags. Most of these ended up allocating their bits sequentually. In the case of move_mount(2) and fspick(2), several flags have identical meanings to AT_* flags but were allocated in their own flag space. This makes sense for syscalls that will never share AT_* flags, but for some syscalls this leads to duplication with AT_* flags in a way that could cause confusion (if renameat2(2) grew a RENAME_EMPTY_PATH it seems likely that users could mistake it for AT_EMPTY_PATH since it is an *at(2) syscall). - Some syscalls unfortunately ended up both creating their own flag space while also using bits from other flag spaces. The most obvious example is open_tree(2), where the standard usage ends up using flags from *THREE* separate flag spaces: open_tree(AT_FDCWD, "/foo", OPEN_TREE_CLONE|O_CLOEXEC|AT_RECURSIVE); (Note that O_CLOEXEC is also platform-specific, so several future OPEN_TREE_* bits are also made unusable in one fell swoop.) It's not entirely clear to me what the "right" choice is for new syscalls. Just saying that all future VFS syscalls should use AT_* flags doesn't seem practical. openat2(2) has RESOLVE_* flags (many of which don't make much sense to burn generic AT_* flags for) and move_mount(2) has separate AT_*-like flags for both the source and target so separate flags are needed anyway (though it seems possible that renameat2(2) could grow *_EMPTY_PATH flags at some point, and it's a bit of a shame they can't be reused). But at least for syscalls that _do_ choose to use AT_* flags, we should explicitly state the policy that 0x2ff is currently intended for per-syscall flags and that new flags should err on the side of overlapping with existing flag bits (so we can extend the scope of generic flags in the future if necessary). And add AT_* aliases for the RENAME_* flags to further cement that renameat2(2) is an *at(2) flag, just with its own per-syscall flags. Suggested-by: Amir Goldstein Reviewed-by: Jeff Layton Reviewed-by: Josef Bacik Signed-off-by: Aleksa Sarai Reviewed-by: Jan Kara --- include/uapi/linux/fcntl.h | 80 ++++++++++++++----= --- tools/perf/trace/beauty/include/uapi/linux/fcntl.h | 83 +++++++++++++++---= ---- 2 files changed, 115 insertions(+), 48 deletions(-) diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index e55a3314bcb0..38a6d66d9e88 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -90,37 +90,69 @@ #define DN_ATTRIB 0x00000020 /* File changed attibutes */ #define DN_MULTISHOT 0x80000000 /* Don't remove notifier */ =20 +#define AT_FDCWD -100 /* Special value for dirfd used to + indicate openat should use the + current working directory. */ + + +/* Generic flags for the *at(2) family of syscalls. */ + +/* Reserved for per-syscall flags 0xff. */ +#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic + links. */ +/* Reserved for per-syscall flags 0x200 */ +#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ +#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount + traversal. */ +#define AT_EMPTY_PATH 0x1000 /* Allow empty relative + pathname to operate on dirfd + directly. */ /* - * The constants AT_REMOVEDIR and AT_EACCESS have the same value. AT_EACC= ESS is - * meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to - * unlinkat. The two functions do completely different things and therefo= re, - * the flags can be allowed to overlap. For example, passing AT_REMOVEDIR= to - * faccessat would be undefined behavior and thus treating it equivalent to - * AT_EACCESS is valid undefined behavior. + * These flags are currently statx(2)-specific, but they could be made gen= eric + * in the future and so they should not be used for other per-syscall flag= s. */ -#define AT_FDCWD -100 /* Special value used to indicate - openat should use the current - working directory. */ -#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */ +#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required fro= m statx() */ +#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ +#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd= with the server */ +#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the ser= ver */ + +#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ + +/* + * Per-syscall flags for the *at(2) family of syscalls. + * + * These are flags that are so syscall-specific that a user passing these = flags + * to the wrong syscall is so "clearly wrong" that we can safely call such + * usage "undefined behaviour". + * + * For example, the constants AT_REMOVEDIR and AT_EACCESS have the same va= lue. + * AT_EACCESS is meaningful only to faccessat, while AT_REMOVEDIR is meani= ngful + * only to unlinkat. The two functions do completely different things and + * therefore, the flags can be allowed to overlap. For example, passing + * AT_REMOVEDIR to faccessat would be undefined behavior and thus treating= it + * equivalent to AT_EACCESS is valid undefined behavior. + * + * Note for implementers: When picking a new per-syscall AT_* flag, try to + * reuse already existing flags first. This leaves us with as many unused = bits + * as possible, so we can use them for generic bits in the future if neces= sary. + */ + +/* Flags for renameat2(2) (must match legacy RENAME_* flags). */ +#define AT_RENAME_NOREPLACE 0x0001 +#define AT_RENAME_EXCHANGE 0x0002 +#define AT_RENAME_WHITEOUT 0x0004 + +/* Flag for faccessat(2). */ #define AT_EACCESS 0x200 /* Test access permitted for effective IDs, not real IDs. */ +/* Flag for unlinkat(2). */ #define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */ -#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ -#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */ -#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */ - -#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from= statx() */ -#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ -#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd = with the server */ -#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the serv= er */ - -#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ +/* Flags for name_to_handle_at(2). */ +#define AT_HANDLE_FID 0x200 /* File handle is needed to compare + object identity and may not be + usable with open_by_handle_at(2). */ =20 -/* Flags for name_to_handle_at(2). We reuse AT_ flag space to save bits...= */ -#define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to - compare object identity and may not - be usable to open_by_handle_at(2) */ #if defined(__KERNEL__) #define AT_GETATTR_NOSEC 0x80000000 #endif diff --git a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h b/tools/per= f/trace/beauty/include/uapi/linux/fcntl.h index c0bcc185fa48..38a6d66d9e88 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fcntl.h @@ -16,6 +16,9 @@ =20 #define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3) =20 +/* Was the file just created? */ +#define F_CREATED_QUERY (F_LINUX_SPECIFIC_BASE + 4) + /* * Cancel a blocking posix lock; internal use only until we expose an * asynchronous lock api to userspace: @@ -87,37 +90,69 @@ #define DN_ATTRIB 0x00000020 /* File changed attibutes */ #define DN_MULTISHOT 0x80000000 /* Don't remove notifier */ =20 +#define AT_FDCWD -100 /* Special value for dirfd used to + indicate openat should use the + current working directory. */ + + +/* Generic flags for the *at(2) family of syscalls. */ + +/* Reserved for per-syscall flags 0xff. */ +#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic + links. */ +/* Reserved for per-syscall flags 0x200 */ +#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ +#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount + traversal. */ +#define AT_EMPTY_PATH 0x1000 /* Allow empty relative + pathname to operate on dirfd + directly. */ +/* + * These flags are currently statx(2)-specific, but they could be made gen= eric + * in the future and so they should not be used for other per-syscall flag= s. + */ +#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required fro= m statx() */ +#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ +#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd= with the server */ +#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the ser= ver */ + +#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ + /* - * The constants AT_REMOVEDIR and AT_EACCESS have the same value. AT_EACC= ESS is - * meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to - * unlinkat. The two functions do completely different things and therefo= re, - * the flags can be allowed to overlap. For example, passing AT_REMOVEDIR= to - * faccessat would be undefined behavior and thus treating it equivalent to - * AT_EACCESS is valid undefined behavior. + * Per-syscall flags for the *at(2) family of syscalls. + * + * These are flags that are so syscall-specific that a user passing these = flags + * to the wrong syscall is so "clearly wrong" that we can safely call such + * usage "undefined behaviour". + * + * For example, the constants AT_REMOVEDIR and AT_EACCESS have the same va= lue. + * AT_EACCESS is meaningful only to faccessat, while AT_REMOVEDIR is meani= ngful + * only to unlinkat. The two functions do completely different things and + * therefore, the flags can be allowed to overlap. For example, passing + * AT_REMOVEDIR to faccessat would be undefined behavior and thus treating= it + * equivalent to AT_EACCESS is valid undefined behavior. + * + * Note for implementers: When picking a new per-syscall AT_* flag, try to + * reuse already existing flags first. This leaves us with as many unused = bits + * as possible, so we can use them for generic bits in the future if neces= sary. */ -#define AT_FDCWD -100 /* Special value used to indicate - openat should use the current - working directory. */ -#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */ + +/* Flags for renameat2(2) (must match legacy RENAME_* flags). */ +#define AT_RENAME_NOREPLACE 0x0001 +#define AT_RENAME_EXCHANGE 0x0002 +#define AT_RENAME_WHITEOUT 0x0004 + +/* Flag for faccessat(2). */ #define AT_EACCESS 0x200 /* Test access permitted for effective IDs, not real IDs. */ +/* Flag for unlinkat(2). */ #define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */ -#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ -#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */ -#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */ - -#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from= statx() */ -#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ -#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd = with the server */ -#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the serv= er */ - -#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ +/* Flags for name_to_handle_at(2). */ +#define AT_HANDLE_FID 0x200 /* File handle is needed to compare + object identity and may not be + usable with open_by_handle_at(2). */ =20 -/* Flags for name_to_handle_at(2). We reuse AT_ flag space to save bits...= */ -#define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to - compare object identity and may not - be usable to open_by_handle_at(2) */ #if defined(__KERNEL__) #define AT_GETATTR_NOSEC 0x80000000 #endif --=20 2.46.0 From nobody Fri Dec 19 08:58:01 2025 Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [80.241.56.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B424158DC2; Wed, 28 Aug 2024 10:37:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.241.56.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724841463; cv=none; b=C3KP9ntMzfjug84ZgZYbFr8J/WflUYZNI8KQQ/GVqGLRTeyVulRozhK3KV5fUMeSuuZtXobcS8qM+I6DqX07ZxCDZHT38YbMzeyv8DEfFNpFh78IcnqKzn8c37serVyzHBxuoiv4/J3CLtSvXLjhi7SsrfJv3JY5T4u6pGLuFKc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724841463; c=relaxed/simple; bh=2JEtkyYBzbNUNWYD6K3reCmf/PfliNsGWxt62ICcuOU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MVkk/3iWA1hfCUW101CiiQP+imjLG83B/XOn5VAABouImo2Vrr3NB+9C+BdK3l0nM5+da4hMtyg1/0tzHXBma3xZXm0FhQgtXIkHPp8aFcJuJ1CpZs4yHg2BbbZsRpUMsppi8eYmq++DWoYLwDCFlLVSdoLSrIYMqHWQMbzYcbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com; spf=pass smtp.mailfrom=cyphar.com; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b=u8xRLBYo; arc=none smtp.client-ip=80.241.56.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyphar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b="u8xRLBYo" Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:b231:465::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4Wv18138Bxz9tG3; Wed, 28 Aug 2024 12:37:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cyphar.com; s=MBO0001; t=1724841457; h=from:from:reply-to:subject:subject: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=DYW8e2RAgi5MkOkqfurv6e1luZxwkEFySGMNtg8Nzlo=; b=u8xRLBYo8f3HvWo+EN4nNZ/jxSloc0Ej/w6jhQXsNFzY03E55oe7bCKEI2WM2rgUwMS0X7 EKZbB+0IHPy9pJamyj10EgVQqcDxHk+AeYXdWPmlB1Ibw+nzXfSSw6vmy7C2koNNuxe5rt Tirf0RKIJYTrk1eKLKqlsVeunacYT3KHktJhhmoCvGGRaB1kK56kWdH061ts+i6mXyd96h 50k7sRb8GRun9MayBzaZqCL0qBK/lwESCdDTtOqxLqSBHVMi28lRgyyMWG/51li8Nd0gwJ o7L/9gC82L/dOmA7OZ5mvDjhookETmIZFXmdzKYghJ0xGAUdRMVOqIdd9AlhaA== From: Aleksa Sarai To: fstests@vger.kernel.org, Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Jeff Layton , Amir Goldstein , Alexander Aring , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , "Liang, Kan" Cc: Aleksa Sarai , Christoph Hellwig , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-perf-users@vger.kernel.org Subject: [PATCH xfstests v1 1/2] statx: update headers to include newer statx fields Date: Wed, 28 Aug 2024 20:37:05 +1000 Message-ID: <20240828103706.2393267-1-cyphar@cyphar.com> In-Reply-To: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> References: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: 4Wv18138Bxz9tG3 Content-Type: text/plain; charset="utf-8" These come from Linux v6.11-rc5. Signed-off-by: Aleksa Sarai --- src/open_by_handle.c | 4 +++- src/statx.h | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/open_by_handle.c b/src/open_by_handle.c index 0f74ed08b1f0..d9c802ca9bd1 100644 --- a/src/open_by_handle.c +++ b/src/open_by_handle.c @@ -82,12 +82,14 @@ Examples: #include #include #include -#include #include #include #include #include =20 +#include +#include "statx.h" + #define MAXFILES 1024 =20 struct handle { diff --git a/src/statx.h b/src/statx.h index 3f239d791dfe..935cb2ed415e 100644 --- a/src/statx.h +++ b/src/statx.h @@ -102,7 +102,7 @@ struct statx { __u64 stx_ino; /* Inode number */ __u64 stx_size; /* File size */ __u64 stx_blocks; /* Number of 512-byte blocks allocated */ - __u64 __spare1[1]; + __u64 stx_attributes_mask; /* Mask to show what's supported in stx_attrib= utes */ /* 0x40 */ struct statx_timestamp stx_atime; /* Last access time */ struct statx_timestamp stx_btime; /* File creation time */ @@ -114,7 +114,18 @@ struct statx { __u32 stx_dev_major; /* ID of device containing file [uncond] */ __u32 stx_dev_minor; /* 0x90 */ - __u64 __spare2[14]; /* Spare space for future expansion */ + __u64 stx_mnt_id; + __u32 stx_dio_mem_align; /* Memory buffer alignment for direct I/O */ + __u32 stx_dio_offset_align; /* File offset alignment for direct I/O */ + /* 0xa0 */ + __u64 stx_subvol; /* Subvolume identifier */ + __u32 stx_atomic_write_unit_min; /* Min atomic write unit in bytes */ + __u32 stx_atomic_write_unit_max; /* Max atomic write unit in bytes */ + /* 0xb0 */ + __u32 stx_atomic_write_segments_max; /* Max atomic write segment count = */ + __u32 __spare1[1]; + /* 0xb8 */ + __u64 __spare3[9]; /* Spare space for future expansion */ /* 0x100 */ }; =20 @@ -139,6 +150,13 @@ struct statx { #define STATX_BLOCKS 0x00000400U /* Want/got stx_blocks */ #define STATX_BASIC_STATS 0x000007ffU /* The stuff in the normal stat stru= ct */ #define STATX_BTIME 0x00000800U /* Want/got stx_btime */ +#define STATX_MNT_ID 0x00001000U /* Got stx_mnt_id */ +#define STATX_DIOALIGN 0x00002000U /* Want/got direct I/O alignment info = */ +#define STATX_MNT_ID_UNIQUE 0x00004000U /* Want/got extended stx_mount_id = */ +#define STATX_SUBVOL 0x00008000U /* Want/got stx_subvol */ +#define STATX_WRITE_ATOMIC 0x00010000U /* Want/got atomic_write_* fields */ + +#define STATX__RESERVED 0x80000000U /* Reserved for future struct statx e= xpansion */ #define STATX_ALL 0x00000fffU /* All currently supported flags */ =20 /* --=20 2.46.0 From nobody Fri Dec 19 08:58:01 2025 Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [80.241.56.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB0B616B3B6; Wed, 28 Aug 2024 10:20:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=80.241.56.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724840436; cv=none; b=pn134X3FiRoNeA9rHy2A7koDQLO/M3hWUx16QNU+suZ3THqFpklj2+/Tk0sf7dT14diw/tAIlnd6Xv5q5s6xufw8MCc7kp/TSNC1Djjb/TkUAe247wSJoYydi/9/IwfYdk9c44ODtDJGlVa4E/M+66GHnv9io/7FgOpcEVi/ibc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724840436; c=relaxed/simple; bh=V7tyZo42KRzhJMOB9sBnRwanzsU4h7z0p4i43WPkloc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tCJDcWDYJUT+9YF2fdF3x3S/EWEtq9rY6jVVAOJYnJD9hpiy1qp2XWMdF7VUnsT2LI7U1MDp9E/v5F+BP+YhZZ1zMaX8rkuaHXjRS02zwpkqyoaK/nb9ynPPf07qon+wQD9IBMnfMZTOsTJxKtiXVswbhAYlJybiYzCCvV4pLH4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com; spf=pass smtp.mailfrom=cyphar.com; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b=srfh1/j2; arc=none smtp.client-ip=80.241.56.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=cyphar.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=cyphar.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=cyphar.com header.i=@cyphar.com header.b="srfh1/j2" Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4Wv0m82GSxz9sxG; Wed, 28 Aug 2024 12:20:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cyphar.com; s=MBO0001; t=1724840424; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l/etGWng+vYhHUDTPmtySIMqzp4DMXHgo5r9nN5CsXw=; b=srfh1/j2rt2BdkqLXBO2XOA6AqLofSnEL0E2ArCAsQFJE8k4c24J368PKSfoQAKkUef7L3 leH/BJF+8nOankXab0tHP3BX0m2mDoxkgRY/ABfCYP15bCpvHXWWosZyMD2RihqytvKL0+ mNX2fbq88sSOwH076p3xtiUakCQbBMfp5nbCncJLkfCH2y59xQyytGzrRRlh7ZNfWnHjRA gc4vmMTr2lfi2fR/4HVS8zYHa+nTCXbpTrcCVEVknTgB7jYzh9tBDOJvU7mw+bGYxDZtXc sxtOb5L2iW2qamiAwOf4rOYAyRT48IGxfpqnjZ2gQ47Xx8ZcF4h+nbcJ6Wm7Aw== From: Aleksa Sarai Date: Wed, 28 Aug 2024 20:19:43 +1000 Subject: [PATCH RESEND v3 2/2] fhandle: expose u64 mount id to name_to_handle_at(2) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20240828-exportfs-u64-mount-id-v3-2-10c2c4c16708@cyphar.com> References: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> In-Reply-To: <20240828-exportfs-u64-mount-id-v3-0-10c2c4c16708@cyphar.com> To: Alexander Viro , Christian Brauner , Jan Kara , Chuck Lever , Jeff Layton , Amir Goldstein , Alexander Aring , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter Cc: Christoph Hellwig , Josef Bacik , linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-perf-users@vger.kernel.org, Aleksa Sarai X-Developer-Signature: v=1; a=openpgp-sha256; l=5961; i=cyphar@cyphar.com; h=from:subject:message-id; bh=V7tyZo42KRzhJMOB9sBnRwanzsU4h7z0p4i43WPkloc=; b=owGbwMvMwCWmMf3Xpe0vXfIZT6slMaSd+3lc8UbM4Smfko719Z+be32esdrpqgsxomJ56zX4u a0vNJ6z6ChlYRDjYpAVU2TZ5ucZumn+4ivJn1aywcxhZQIZwsDFKQATie5g+MMta2kWnMcYxJxY 5xlTWG4gPH2iwGIr0fSHosYTa1xY1RkZjnjv23b9Tt1jjfLqQhmeE7dlF1mtD/T3M5tc+La4huE nOwA= X-Developer-Key: i=cyphar@cyphar.com; a=openpgp; fpr=C9C370B246B09F6DBCFC744C34401015D1D2D386 Now that we provide a unique 64-bit mount ID interface in statx(2), we can now provide a race-free way for name_to_handle_at(2) to provide a file handle and corresponding mount without needing to worry about racing with /proc/mountinfo parsing or having to open a file just to do statx(2). While this is not necessary if you are using AT_EMPTY_PATH and don't care about an extra statx(2) call, users that pass full paths into name_to_handle_at(2) need to know which mount the file handle comes from (to make sure they don't try to open_by_handle_at a file handle from a different filesystem) and switching to AT_EMPTY_PATH would require allocating a file for every name_to_handle_at(2) call, turning err =3D name_to_handle_at(-EBADF, "/foo/bar/baz", &handle, &mntid, AT_HANDLE_MNT_ID_UNIQUE); into int fd =3D openat(-EBADF, "/foo/bar/baz", O_PATH | O_CLOEXEC); err1 =3D name_to_handle_at(fd, "", &handle, &unused_mntid, AT_EMPTY_PATH); err2 =3D statx(fd, "", AT_EMPTY_PATH, STATX_MNT_ID_UNIQUE, &statxbuf); mntid =3D statxbuf.stx_mnt_id; close(fd); Reviewed-by: Jeff Layton Signed-off-by: Aleksa Sarai Reviewed-by: Jan Kara --- fs/fhandle.c | 29 ++++++++++++++++--= ---- include/linux/syscalls.h | 2 +- include/uapi/linux/fcntl.h | 1 + tools/perf/trace/beauty/include/uapi/linux/fcntl.h | 1 + 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/fs/fhandle.c b/fs/fhandle.c index 6e8cea16790e..8cb665629f4a 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -16,7 +16,8 @@ =20 static long do_sys_name_to_handle(const struct path *path, struct file_handle __user *ufh, - int __user *mnt_id, int fh_flags) + void __user *mnt_id, bool unique_mntid, + int fh_flags) { long retval; struct file_handle f_handle; @@ -69,9 +70,19 @@ static long do_sys_name_to_handle(const struct path *pat= h, } else retval =3D 0; /* copy the mount id */ - if (put_user(real_mount(path->mnt)->mnt_id, mnt_id) || - copy_to_user(ufh, handle, - struct_size(handle, f_handle, handle_bytes))) + if (unique_mntid) { + if (put_user(real_mount(path->mnt)->mnt_id_unique, + (u64 __user *) mnt_id)) + retval =3D -EFAULT; + } else { + if (put_user(real_mount(path->mnt)->mnt_id, + (int __user *) mnt_id)) + retval =3D -EFAULT; + } + /* copy the handle */ + if (retval !=3D -EFAULT && + copy_to_user(ufh, handle, + struct_size(handle, f_handle, handle_bytes))) retval =3D -EFAULT; kfree(handle); return retval; @@ -83,6 +94,7 @@ static long do_sys_name_to_handle(const struct path *path, * @name: name that should be converted to handle. * @handle: resulting file handle * @mnt_id: mount id of the file system containing the file + * (u64 if AT_HANDLE_MNT_ID_UNIQUE, otherwise int) * @flag: flag value to indicate whether to follow symlink or not * and whether a decodable file handle is required. * @@ -92,7 +104,7 @@ static long do_sys_name_to_handle(const struct path *pat= h, * value required. */ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name, - struct file_handle __user *, handle, int __user *, mnt_id, + struct file_handle __user *, handle, void __user *, mnt_id, int, flag) { struct path path; @@ -100,7 +112,8 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char= __user *, name, int fh_flags; int err; =20 - if (flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH | AT_HANDLE_FID)) + if (flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH | AT_HANDLE_FID | + AT_HANDLE_MNT_ID_UNIQUE)) return -EINVAL; =20 lookup_flags =3D (flag & AT_SYMLINK_FOLLOW) ? LOOKUP_FOLLOW : 0; @@ -109,7 +122,9 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char= __user *, name, lookup_flags |=3D LOOKUP_EMPTY; err =3D user_path_at(dfd, name, lookup_flags, &path); if (!err) { - err =3D do_sys_name_to_handle(&path, handle, mnt_id, fh_flags); + err =3D do_sys_name_to_handle(&path, handle, mnt_id, + flag & AT_HANDLE_MNT_ID_UNIQUE, + fh_flags); path_put(&path); } return err; diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 4bcf6754738d..5758104921e6 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -870,7 +870,7 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsi= gned int flags, #endif asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name, struct file_handle __user *handle, - int __user *mnt_id, int flag); + void __user *mnt_id, int flag); asmlinkage long sys_open_by_handle_at(int mountdirfd, struct file_handle __user *handle, int flags); diff --git a/include/uapi/linux/fcntl.h b/include/uapi/linux/fcntl.h index 38a6d66d9e88..87e2dec79fea 100644 --- a/include/uapi/linux/fcntl.h +++ b/include/uapi/linux/fcntl.h @@ -152,6 +152,7 @@ #define AT_HANDLE_FID 0x200 /* File handle is needed to compare object identity and may not be usable with open_by_handle_at(2). */ +#define AT_HANDLE_MNT_ID_UNIQUE 0x001 /* Return the u64 unique mount ID. */ =20 #if defined(__KERNEL__) #define AT_GETATTR_NOSEC 0x80000000 diff --git a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h b/tools/per= f/trace/beauty/include/uapi/linux/fcntl.h index 38a6d66d9e88..87e2dec79fea 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fcntl.h @@ -152,6 +152,7 @@ #define AT_HANDLE_FID 0x200 /* File handle is needed to compare object identity and may not be usable with open_by_handle_at(2). */ +#define AT_HANDLE_MNT_ID_UNIQUE 0x001 /* Return the u64 unique mount ID. */ =20 #if defined(__KERNEL__) #define AT_GETATTR_NOSEC 0x80000000 --=20 2.46.0