On 12/28/25 15:01, Bernhard Voelker wrote:
On 12/5/25 16:24, Lukáš Zaoral wrote:
+  The -mount option is now POSIX compliant. [...]

This is not quite true [...]

* [PATCH 1/4] find: make -mount POSIX 2024 compliant

I've pushed your patch with the minor tweak ...

  -  The -mount option is now POSIX compliant. [...]
  +  The -mount option is now POSIX 2024 compliant. [...]

... and pushed the following on top to improve the NEWS and to add
regular and check-root tests:

* [PATCH 2/4] NEWS: enhance description about the -mount change
* [PATCH 3/4] find: add -mount tests
* [PATCH 4/4] find: add more -mount tests (check-root)

As the change is quite delicate, I'd like to add some follow-up commits to 
clarify
the new -mount behavior vs. -xdev in the documentation as well.

I'm still on this one ...

Have a nice day,
Berny
From cd8568758a108ef0e6e1905ce540cd2ade3da796 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Zaoral?= <[email protected]>
Date: Sun, 28 Dec 2025 14:53:41 +0100
Subject: [PATCH 1/4] find: make -mount POSIX 2024 compliant

* find/defs.h (struct options): Add mount member and rename
stay_on_filesystem to xdev.
* find/ftsfind.c (find): Set FTS_MOUNT flag when -mount is enabled.
* find/parser.c (parse_table): Use a separate parser for -mount.
(parse_mount): Declare and define function.
(parse_xdev): Use xdev option flag.
* find/util.c (set_option_defaults): Initialize new struct members.
* doc/find.texi (node Filesystems): Add new section describing the new
behaviour of -mount and specify the current behaviour of -xdev.
* find/find.1: Document the new -mount behaviour and specify current
behaviour of -xdev.
* NEWS (Changes in find): Mention the -mount behaviour change.
---
 NEWS           |  3 +++
 doc/find.texi  |  8 +++++---
 find/defs.h    |  7 +++++--
 find/find.1    | 10 ++++------
 find/ftsfind.c |  5 ++++-
 find/parser.c  | 12 ++++++++++--
 find/util.c    |  2 +-
 7 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/NEWS b/NEWS
index 549f6d4c..5ce613c1 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,9 @@ GNU findutils NEWS - User visible changes.      -*- outline -*- (allout)
   are passed with a leading dash, e.g. '-!'.  Future releases will not accept
   that any more.  Accepting that was rather a bug "since the beginning".
 
+  The -mount option is now POSIX 2024 compliant.  Find will ignore files on
+  different devices as opposed to being a mere alias for -xdev. [#54745]
+
 ** Documentation Changes
 
   The forthcoming Issue 8 of the POSIX standard will standardise "find
diff --git a/doc/find.texi b/doc/find.texi
index 4852a5a1..192f7dea 100644
--- a/doc/find.texi
+++ b/doc/find.texi
@@ -1624,10 +1624,12 @@ them.
 There are two ways to avoid searching certain filesystems.  One way is
 to tell @code{find} to only search one filesystem:
 
+@deffn Option -mount
+Ignore files on other devices.
+@end deffn
+
 @deffn Option -xdev
-@deffnx Option -mount
-Don't descend directories on other filesystems.  These options are
-synonyms.
+Don't descend into directories on other devices.
 @end deffn
 
 The other way is to check the type of filesystem each file is on, and
diff --git a/find/defs.h b/find/defs.h
index ea3e5cab..f1c8d706 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -549,8 +549,11 @@ struct options
      are non-directories. */
   bool no_leaf_check;
 
+  /* If true, skip files on other devices. */
+  bool mount;
+
   /* If true, don't cross filesystem boundaries. */
-  bool stay_on_filesystem;
+  bool xdev;
 
   /* If true, we ignore the problem where we find that a directory entry
    * no longer exists by the time we get around to processing it.
@@ -648,7 +651,7 @@ struct state
   int starting_path_length;
 
   /* If true, don't descend past current directory.
-     Can be set by -prune, -maxdepth, and -xdev/-mount. */
+     Can be set by -prune, -maxdepth, -mount and -xdev. */
   bool stop_at_current_level;
 
   /* Status value to return to system. */
diff --git a/find/find.1 b/find/find.1
index 88591d69..e5868272 100644
--- a/find/find.1
+++ b/find/find.1
@@ -630,10 +630,7 @@ non-negative integer).  Using
 means process all files except the starting-points.
 
 .IP \-mount
-Don't descend directories on other filesystems.  An alternate name for
-.BR \-xdev ,
-for compatibility with some other versions of
-.BR find .
+Ignore files on other devices.
 
 .IP \-noignore_readdir_race
 Turns off the effect of
@@ -659,7 +656,7 @@ to stat them; this gives a significant increase in search speed.
 Print the \fBfind\fR version number and exit.
 
 .IP \-xdev
-Don't descend directories on other filesystems.
+Don't descend into directories on other devices.
 
 .SS TESTS
 Some tests, for example
@@ -1989,7 +1986,7 @@ For closest compliance to the POSIX standard, you should set the
 .B POSIXLY_CORRECT
 environment variable.
 The following options are specified in the POSIX standard
-(IEEE Std 1003.1-2008, 2016 Edition):
+(IEEE Std 1003.1-2024 Edition):
 
 .IP \fB\-H\fR
 This option is supported.
@@ -2053,6 +2050,7 @@ The primaries
 .BR \-exec ,
 .BR \-group ,
 .BR \-links ,
+.BR \-mount ,
 .BR \-mtime ,
 .BR \-nogroup ,
 .BR \-nouser ,
diff --git a/find/ftsfind.c b/find/ftsfind.c
index 5709b1db..17cfb1d1 100644
--- a/find/ftsfind.c
+++ b/find/ftsfind.c
@@ -480,7 +480,10 @@ find (char *arg)
       break;
     }
 
-  if (options.stay_on_filesystem)
+  if (options.mount)
+    ftsoptions |= FTS_MOUNT;
+
+  if (options.xdev)
     ftsoptions |= FTS_XDEV;
 
   p = fts_open (arglist, ftsoptions, nullptr);
diff --git a/find/parser.c b/find/parser.c
index f740b06d..52df3577 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -122,6 +122,7 @@ static bool parse_ls            (const struct parser_table*, char *argv[], int *
 static bool parse_maxdepth      (const struct parser_table*, char *argv[], int *arg_ptr);
 static bool parse_mindepth      (const struct parser_table*, char *argv[], int *arg_ptr);
 static bool parse_mmin          (const struct parser_table*, char *argv[], int *arg_ptr);
+static bool parse_mount         (const struct parser_table*, char *argv[], int *arg_ptr);
 static bool parse_name          (const struct parser_table*, char *argv[], int *arg_ptr);
 static bool parse_negate        (const struct parser_table*, char *argv[], int *arg_ptr);
 static bool parse_newer         (const struct parser_table*, char *argv[], int *arg_ptr);
@@ -214,7 +215,7 @@ static struct parser_table const parse_table[] =
   { ARG_OPTION, "ignore_readdir_race",   parse_ignore_race,   nullptr }, /* GNU */
   { ARG_OPTION, "maxdepth",              parse_maxdepth,      nullptr }, /* GNU */
   { ARG_OPTION, "mindepth",              parse_mindepth,      nullptr }, /* GNU */
-  { ARG_OPTION, "mount",                 parse_xdev,          nullptr }, /* Unix */
+  { ARG_OPTION, "mount",                 parse_mount,         nullptr }, /* POSIX */
   { ARG_OPTION, "noleaf",                parse_noleaf,        nullptr }, /* GNU */
   { ARG_OPTION, "noignore_readdir_race", parse_noignore_race, nullptr }, /* GNU */
   { ARG_OPTION, "xdev",                  parse_xdev,          nullptr }, /* POSIX */
@@ -2476,10 +2477,17 @@ parse_context (const struct parser_table* entry, char **argv, int *arg_ptr)
   return true;
 }
 
+static bool
+parse_mount (const struct parser_table* entry, char **argv, int *arg_ptr)
+{
+  options.mount = true;
+  return parse_noop (entry, argv, arg_ptr);
+}
+
 static bool
 parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr)
 {
-  options.stay_on_filesystem = true;
+  options.xdev = true;
   return parse_noop (entry, argv, arg_ptr);
 }
 
diff --git a/find/util.c b/find/util.c
index 2e8fbc1e..509a6c2c 100644
--- a/find/util.c
+++ b/find/util.c
@@ -1010,7 +1010,7 @@ set_option_defaults (struct options *p)
   p->cur_day_start.tv_nsec = p->start_time.tv_nsec;
 
   p->full_days = false;
-  p->stay_on_filesystem = false;
+  p->mount = p->xdev = false;
   p->ignore_readdir_race = false;
 
   if (p->posixly_correct)
-- 
2.52.0

From 6da3a73f73eb01efe0511c2643e66bb2f980b642 Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <[email protected]>
Date: Thu, 1 Jan 2026 20:25:56 +0100
Subject: [PATCH 2/4] NEWS: enhance description about the -mount change

* NEWS (Changes in find): Clarify better what is the difference between
the -mount and -xdev options including an example.  Also move the
topic to the top of the section due to its importance.
---
 NEWS | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 5ce613c1..d4002688 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,17 @@ GNU findutils NEWS - User visible changes.      -*- outline -*- (allout)
 
 ** Changes in find
 
+  As announced since the release of 4.7.0 (2019) and mandated by POSIX 2024,
+  the behaviour of the -mount option changed: while it was a mere alias for
+  the -xdev option to prevent descending into directories of another device,
+  the -mount option now makes find(1) ignore files on another device, i.e.,
+  'find -mount' will skip the entry of active mount points already.
+  Example, assuming the PROC filesystem is mounted on '/proc':
+    $ find / -mount -path /proc -print
+    $ find / -xdev -path /proc -print
+    /proc
+  [#54745]
+
   The actions -execdir and -okdir now refuse the '{}' replacement in the zeroth
   argument of the command to be run.  While POSIX allows this for -exec, this is
   deemed insecure as an attacker could influence which files could be found.
@@ -28,9 +39,6 @@ GNU findutils NEWS - User visible changes.      -*- outline -*- (allout)
   are passed with a leading dash, e.g. '-!'.  Future releases will not accept
   that any more.  Accepting that was rather a bug "since the beginning".
 
-  The -mount option is now POSIX 2024 compliant.  Find will ignore files on
-  different devices as opposed to being a mere alias for -xdev. [#54745]
-
 ** Documentation Changes
 
   The forthcoming Issue 8 of the POSIX standard will standardise "find
-- 
2.52.0

From 0d8de8729964a93741888d3316c589790debdbc3 Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <[email protected]>
Date: Sun, 28 Dec 2025 16:07:03 +0100
Subject: [PATCH 3/4] find: add -mount tests

* tests/find/mount-vs-xdev.sh: Add test.
* tests/local.mk (sh_tests): Reference it.
---
 tests/find/mount-vs-xdev.sh | 59 +++++++++++++++++++++++++++++++++++++
 tests/local.mk              |  1 +
 2 files changed, 60 insertions(+)
 create mode 100755 tests/find/mount-vs-xdev.sh

diff --git a/tests/find/mount-vs-xdev.sh b/tests/find/mount-vs-xdev.sh
new file mode 100755
index 00000000..9007a81e
--- /dev/null
+++ b/tests/find/mount-vs-xdev.sh
@@ -0,0 +1,59 @@
+#!/bin/sh
+# Exercise find -mount vs. -xdev behaviour.
+
+# Copyright (C) 2026 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; fu_path_prepend_
+print_ver_ find
+
+getmntpoint () {
+  # Skip header line and print last field.
+  df "$1" | awk 'NR==2 {print $NF}'
+}
+
+mnt_root=$( getmntpoint '/' ) \
+  && test "$mnt_root" \
+  || framework_failure_
+
+found=0
+# Find a directory entry which is mounted (likely) from a different device
+# than the '/' directory.
+for m in /dev /home /proc /run /tmp; do
+  test -e "$m" \
+    && mnt_m=$( getmntpoint "$m" )  \
+    && test "$mnt_root" != "$mnt_m" \
+    || continue
+
+  found=1
+  echo "$m" > exp || framework_failure_
+
+  # Option -mount skips.
+  find / -maxdepth 1 -mount -path "$m" -print > out-m   || fail=1
+  compare /dev/null out-m || fail=1
+
+  # Option -xdev does not skip (but would skip sub-directories).
+  find / -maxdepth 1 -xdev -path "$m" -print > out-x   || fail=1
+  compare exp out-x || fail=1
+
+  # Options -mount -xdev shall skip as well (-xdev has no effect).
+  find / -maxdepth 1 -mount -xdev -path "$m" -print > out-mx  || fail=1
+  compare /dev/null out-m || fail=1
+done
+
+test $found -gt 0 \
+  || skip_ "cannot determine other device mounts in '/'"
+
+Exit $fail
diff --git a/tests/local.mk b/tests/local.mk
index d07745cd..c2198ca0 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -137,6 +137,7 @@ sh_tests = \
   tests/xargs/conflicting_opts.sh \
   tests/xargs/verbose-quote.sh \
   tests/find/arg-nan.sh \
+  tests/find/mount-vs-xdev.sh \
   $(all_root_tests)
 
 $(TEST_LOGS): $(PROGRAMS)
-- 
2.52.0

From 04738593b485e4013b49af4e8017d603af1cd567 Mon Sep 17 00:00:00 2001
From: Bernhard Voelker <[email protected]>
Date: Sun, 28 Dec 2025 17:39:22 +0100
Subject: [PATCH 4/4] find: add more -mount tests (check-root)

Add some more tests exercising bind mounts on the same device which
should not be affected by -mount or -xdev, and tests with a loopback
file system and a bind mount from there.

* tests/find/mount-vs-xdev-bind.sh: Add test.
* tests/find/mount-vs-xdev-other-fs.sh: Likewise.
* tests/local.mk (all_root_tests): Reference them.
---
 tests/find/mount-vs-xdev-bind.sh     | 77 ++++++++++++++++++++++++++++
 tests/find/mount-vs-xdev-other-fs.sh | 77 ++++++++++++++++++++++++++++
 tests/local.mk                       |  4 +-
 3 files changed, 157 insertions(+), 1 deletion(-)
 create mode 100755 tests/find/mount-vs-xdev-bind.sh
 create mode 100755 tests/find/mount-vs-xdev-other-fs.sh

diff --git a/tests/find/mount-vs-xdev-bind.sh b/tests/find/mount-vs-xdev-bind.sh
new file mode 100755
index 00000000..80104520
--- /dev/null
+++ b/tests/find/mount-vs-xdev-bind.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+# Exercise find -mount vs. -xdev behaviour for bind mounts (on same device).
+
+# Copyright (C) 2026 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; fu_path_prepend_
+print_ver_ find
+
+# The test setup requires root permissions (while the pure test run would not).
+require_root_
+
+cwd=$(pwd)
+cleanup_() {
+  cd /;
+  test -s "$cwd/mntf" \
+    && umount "$cwd/mntf"
+  umount "$cwd/mnt"
+}
+
+mkdir d mnt || framework_failure_
+> d/f || framework_failure_
+
+# Bind mounts have the same device ID; hence -mount/-xdev shall not skip them.
+mount --bind d mnt \
+  || skip_ "This test requires mount with a working --bind option."
+
+mnt_f='./mnt/f'
+echo "$mnt_f" > exp || framework_failure_
+
+find -path "$mnt_f" > out || fail=1
+compare exp out || fail=1
+
+find -xdev -path "$mnt_f" > out-x || fail=1
+compare exp out-x || fail=1
+
+find -mount -path "$mnt_f" > out-m || fail=1
+compare exp out-m || fail=1
+
+find -mount -xdev -path "$mnt_f" > out-mx || fail=1
+compare exp out-mx || fail=1
+
+# Now exercise a bind mount of a regular file. Also this has the same device ID,
+# and hence -mount -xdev shall also not affect find(1).
+echo test > file || framework_failure_
+> mntf || framework_failure_
+
+mount --bind file mntf \
+  || skip_ "This test requires mount with a working --bind option."
+
+echo './mntf' > exp || framework_failure_
+
+find -path './mntf' > out || fail=1
+compare exp out || fail=1
+
+find -xdev -path './mntf' > out-x || fail=1
+compare exp out-x || fail=1
+
+find -mount -path './mntf' > out-m || fail=1
+compare exp out-m || fail=1
+
+find -mount -xdev -path './mntf' > out-mx || fail=1
+compare exp out-mx || fail=1
+
+Exit $fail
diff --git a/tests/find/mount-vs-xdev-other-fs.sh b/tests/find/mount-vs-xdev-other-fs.sh
new file mode 100755
index 00000000..93e14aaf
--- /dev/null
+++ b/tests/find/mount-vs-xdev-other-fs.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+# Exercise find -mount vs. -xdev behaviour with another file system.
+
+# Copyright (C) 2026 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; fu_path_prepend_
+print_ver_ find
+
+# The test setup requires root permissions (while the pure test run would not).
+require_root_
+
+cwd=$(pwd)
+cleanup_() {
+  cd /
+  test -s "$cwd/mntf" \
+    && umount "$cwd/mntf"
+  umount "$cwd/mnt"
+}
+
+mkdir d mnt || framework_failure_
+
+# Mount an ext2 loopback file system at 'mnt'.
+dd if=/dev/zero of='fs' bs=8192 count=200 2>/dev/null || framework_failure_
+mkfs -t ext2 -F 'fs' || skip_ "failed to create ext2 file system"
+mount -oloop fs mnt \
+  || skip_ 'insufficient mount/ext2 support'
+
+echo test > mnt/file || framework_failure_
+echo './mnt/file' > exp || framework_failure_
+
+find              -name 'file' > out || fail=1
+find -xdev        -name 'file' > out-x || fail=1
+find -mount       -name 'file' > out-m || fail=1
+find -mount -xdev -name 'file' > out-mx || fail=1
+
+# Only the run without -mount and/or -xdev found 'mnt/file'.
+compare exp out || fail=1
+compare /dev/null out-x || fail=1
+compare /dev/null out-m || fail=1
+compare /dev/null out-mx || fail=1
+
+# Now bind-mount 'mnt/file' back on 'mntf' into the current file system.
+> mntf || framework_failure_
+mount --bind mnt/file mntf \
+  || skip_ "This test requires mount with a working --bind option."
+
+
+# Only the run without options and pure -xdev should find the file 'mntf',
+# and the runs with -mount (with or without -xdev) should ignore it.
+echo './mntf' > exp || framework_failure_
+
+find -name mntf > out || fail=1
+compare exp out || fail=1
+
+find -xdev -name mntf > out-x || fail=1
+compare exp out-x || fail=1
+
+find -mount -name mntf > out-m || fail=1
+compare /dev/null out-m || fail=1
+
+find -mount -xdev -name mntf > out-mx || fail=1
+compare /dev/null out-mx || fail=1
+
+Exit $fail
diff --git a/tests/local.mk b/tests/local.mk
index c2198ca0..bb575c1b 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -85,7 +85,9 @@ EXTRA_DIST += \
   tests/sample-test
 
 all_root_tests = \
-  tests/find/type_list.sh
+  tests/find/type_list.sh \
+  tests/find/mount-vs-xdev-bind.sh \
+  tests/find/mount-vs-xdev-other-fs.sh
 
 check_PROGRAMS = $(binary_tests)
 binary_tests = \
-- 
2.52.0

Reply via email to