aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c')
-rw-r--r--sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c36
1 files changed, 30 insertions, 6 deletions
diff --git a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
index dcdf7b3d6fc9..ee1cdf59b9e5 100644
--- a/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
+++ b/sys/contrib/openzfs/lib/libspl/os/linux/getmntany.c
@@ -85,13 +85,21 @@ _sol_getmntent(FILE *fp, struct mnttab *mgetp)
}
static int
-getextmntent_impl(FILE *fp, struct extmnttab *mp)
+getextmntent_impl(FILE *fp, struct extmnttab *mp, uint64_t *mnt_id)
{
int ret;
struct stat64 st;
+ *mnt_id = 0;
ret = _sol_getmntent(fp, (struct mnttab *)mp);
if (ret == 0) {
+#ifdef HAVE_STATX_MNT_ID
+ struct statx stx;
+ if (statx(AT_FDCWD, mp->mnt_mountp,
+ AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW,
+ STATX_MNT_ID, &stx) == 0 && (stx.stx_mask & STATX_MNT_ID))
+ *mnt_id = stx.stx_mnt_id;
+#endif
if (stat64(mp->mnt_mountp, &st) != 0) {
mp->mnt_major = 0;
mp->mnt_minor = 0;
@@ -110,6 +118,12 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
struct stat64 st;
FILE *fp;
int match;
+ boolean_t have_mnt_id = B_FALSE;
+ uint64_t target_mnt_id = 0;
+ uint64_t entry_mnt_id;
+#ifdef HAVE_STATX_MNT_ID
+ struct statx stx;
+#endif
if (strlen(path) >= MAXPATHLEN) {
(void) fprintf(stderr, "invalid object; pathname too long\n");
@@ -128,6 +142,13 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
return (-1);
}
+#ifdef HAVE_STATX_MNT_ID
+ if (statx(AT_FDCWD, path, AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW,
+ STATX_MNT_ID, &stx) == 0 && (stx.stx_mask & STATX_MNT_ID)) {
+ have_mnt_id = B_TRUE;
+ target_mnt_id = stx.stx_mnt_id;
+ }
+#endif
if ((fp = fopen(MNTTAB, "re")) == NULL) {
(void) fprintf(stderr, "cannot open %s\n", MNTTAB);
@@ -139,12 +160,15 @@ getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
*/
match = 0;
- while (getextmntent_impl(fp, entry) == 0) {
- if (makedev(entry->mnt_major, entry->mnt_minor) ==
- statbuf->st_dev) {
- match = 1;
- break;
+ while (getextmntent_impl(fp, entry, &entry_mnt_id) == 0) {
+ if (have_mnt_id) {
+ match = (entry_mnt_id == target_mnt_id);
+ } else {
+ match = makedev(entry->mnt_major, entry->mnt_minor) ==
+ statbuf->st_dev;
}
+ if (match)
+ break;
}
(void) fclose(fp);