Linux userland API discussions
 help / color / mirror / Atom feed
* [PATCH v3 09/12] man/man2/open_tree.2: document "new" mount API
From: Aleksa Sarai @ 2025-08-08 20:39 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Michael T. Kerrisk, Alexander Viro, Jan Kara, Askar Safin,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner, Aleksa Sarai
In-Reply-To: <20250809-new-mount-api-v3-0-f61405c80f34@cyphar.com>

This is loosely based on the original documentation written by David
Howells and later maintained by Christian Brauner, but has been
rewritten to be more from a user perspective (as well as fixing a few
critical mistakes).

Co-authored-by: David Howells <dhowells@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Co-authored-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
 man/man2/open_tree.2 | 471 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 471 insertions(+)

diff --git a/man/man2/open_tree.2 b/man/man2/open_tree.2
new file mode 100644
index 0000000000000000000000000000000000000000..07aac7616107d16d05cc71ba7db6aee35f3a9cc6
--- /dev/null
+++ b/man/man2/open_tree.2
@@ -0,0 +1,471 @@
+.\" Copyright, the authors of the Linux man-pages project
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH open_tree 2 (date) "Linux man-pages (unreleased)"
+.SH NAME
+open_tree \- open path or create detached mount object and attach to fd
+.SH LIBRARY
+Standard C library
+.RI ( libc ,\~ \-lc )
+.SH SYNOPSIS
+.nf
+.BR "#include <fcntl.h>" "          /* Definition of " AT_* " constants */"
+.B #include <sys/mount.h>
+.P
+.BI "int open_tree(int " dirfd ", const char *" path ", unsigned int " flags ");"
+.fi
+.SH DESCRIPTION
+The
+.BR open_tree ()
+system call is part of
+the suite of file descriptor based mount facilities in Linux.
+.IP \[bu] 3
+If
+.I flags
+contains
+.BR \%OPEN_TREE_CLONE ,
+.BR open_tree ()
+creates a detached mount object
+which consists of a bind-mount of
+the path specified by the
+.IR path .
+A new file descriptor
+associated with the detached mount object
+is then returned.
+The mount object is equivalent to a bind-mount
+that would be created by
+.BR mount (2)
+called with
+.BR MS_BIND ,
+except that it is tied to a file descriptor
+and is not mounted onto the filesystem.
+.IP
+As with file descriptors returned from
+.BR fsmount (2),
+the resultant file descriptor can then be used with
+.BR move_mount (2),
+.BR mount_setattr (2),
+or other such system calls to do further mount operations.
+This mount object will be unmounted and destroyed
+when the file descriptor is closed
+if it was not otherwise attached to a mount point
+by calling
+.BR move_mount (2).
+.IP \[bu]
+If
+.I flags
+does not contain
+.BR \%OPEN_TREE_CLONE ,
+.BR open_tree ()
+returns a file descriptor
+that is exactly equivalent to
+one produced by
+.BR openat (2)
+when called with the same
+.I dirfd
+and
+.IR path .
+.P
+In either case, the resultant file descriptor
+acts the same as one produced by
+.BR open (2)
+with
+.BR O_PATH ,
+meaning it can also be used as a
+.I dirfd
+argument to
+"*at()" system calls.
+.P
+As with "*at()" system calls,
+.BR open_tree ()
+uses the
+.I dirfd
+argument in conjunction with the
+.I path
+argument to determine the path to operate on, as follows:
+.IP \[bu] 3
+If the pathname given in
+.I path
+is absolute, then
+.I dirfd
+is ignored.
+.IP \[bu]
+If the pathname given in
+.I path
+is relative and
+.I dirfd
+is the special value
+.BR \%AT_FDCWD ,
+then
+.I path
+is interpreted relative to
+the current working directory
+of the calling process (like
+.BR open (2)).
+.IP \[bu]
+If the pathname given in
+.I path
+is relative,
+then it is interpreted relative to
+the directory referred to by the file descriptor
+.I dirfd
+(rather than relative to
+the current working directory
+of the calling process,
+as is done by
+.BR open (2)
+for a relative pathname).
+In this case,
+.I dirfd
+must be a directory
+that was opened for reading
+.RB ( O_RDONLY )
+or using the
+.B O_PATH
+flag.
+.IP \[bu]
+If
+.I path
+is an empty string,
+and
+.I flags
+contains
+.BR \%AT_EMPTY_PATH ,
+then the file descriptor
+.I dirfd
+is operated on directly.
+In this case,
+.I dirfd
+may refer to any type of file,
+not just a directory.
+.P
+.I flags
+can be used to control aspects of the path lookup
+and properties of the returned file descriptor.
+A value for
+.I flags
+is constructed by bitwise ORing
+zero or more of the following constants:
+.RS
+.TP
+.B AT_EMPTY_PATH
+If
+.I path
+is an empty string, operate on the file referred to by
+.I dirfd
+(which may have been obtained from
+.BR open (2),
+.BR fsmount(2),
+or from another
+.BR open_tree ()
+call).
+In this case,
+.I dirfd
+may refer to any type of file, not just a directory.
+If
+.I dirfd
+is
+.BR \%AT_FDCWD ,
+.BR open_tree ()
+will operate on the current working directory
+of the calling process.
+This flag is Linux-specific; define
+.B \%_GNU_SOURCE
+to obtain its definition.
+.TP
+.B AT_NO_AUTOMOUNT
+Do not automount any automount points encountered
+while resolving
+.IR path .
+This allows you to create a handle to the automount point itself,
+rather than the location it would mount.
+This flag has no effect if the mount point has already been mounted over.
+This flag is Linux-specific; define
+.B \%_GNU_SOURCE
+to obtain its definition.
+.TP
+.B AT_SYMLINK_NOFOLLOW
+If
+.I path
+is a symbolic link, do not dereference it; instead,
+create either a handle to the link itself
+or a bind-mount of it.
+The resultant file descriptor is indistinguishable from one produced by
+.BR openat (2)
+with
+.BR \%O_PATH | O_NOFOLLLOW .
+.TP
+.B OPEN_TREE_CLOEXEC
+Set the close-on-exec
+.RB ( FD_CLOEXEC )
+flag on the new file descriptor.
+See the description of the
+.B O_CLOEXEC
+flag in
+.BR open (2)
+for reasons why this may be useful.
+.TP
+.B OPEN_TREE_CLONE
+Rather than creating an
+.BR openat (2)-style
+.B O_PATH
+file descriptor,
+create a bind-mount of
+.I path
+(akin to
+.IR "mount --bind" )
+as a detached mount object.
+In order to do this operation,
+the calling process must have the
+.BR \%CAP_SYS_ADMIN
+capability.
+.TP
+.B AT_RECURSIVE
+Create a recursive bind-mount of the path
+(akin to
+.IR "mount --rbind" )
+as a detached mount object.
+This flag is only permitted in conjunction with
+.BR \%OPEN_TREE_CLONE .
+.SH RETURN VALUE
+On success, a new file descriptor is returned.
+On error, \-1 is returned, and
+.I errno
+is set to indicate the error.
+.SH ERRORS
+.TP
+.B EACCES
+Search permission is denied for one of the directories
+in the path prefix of
+.IR path .
+(See also
+.BR path_resolution (7).)
+.TP
+.B EBADF
+.I path
+is relative but
+.I dirfd
+is neither
+.B \%AT_FDCWD
+nor a valid file descriptor.
+.TP
+.B EFAULT
+.I path
+is NULL
+or a pointer to a location
+outside the calling process's accessible address space.
+.TP
+.B EINVAL
+Invalid flag specified in
+.IR flags .
+.TP
+.B ELOOP
+Too many symbolic links encountered when resolving
+.IR path .
+.TP
+.B EMFILE
+The calling process has too many open files to create more.
+.TP
+.B ENAMETOOLONG
+.I path
+is longer than
+.BR PATH_MAX .
+.TP
+.B ENFILE
+The system has too many open files to create more.
+.TP
+.B ENOENT
+A component of
+.I path
+does not exist, or is a dangling symbolic link.
+.TP
+.B ENOENT
+.I path
+is an empty string, but
+.B AT_EMPTY_PATH
+is not specified in
+.IR flags .
+.TP
+.B ENOTDIR
+A component of the path prefix of
+.I path
+is not a directory, or
+.I path
+is relative and
+.I dirfd
+is a file descriptor referring to a file other than a directory.
+.TP
+.B ENOSPC
+The "anonymous" mount namespace
+necessary to contain the
+.B \%OPEN_TREE_CLONE
+detached bind-mount mount object
+could not be allocated,
+as doing so would exceed
+the configured per-user limit on
+the number of mount namespaces in the current user namespace.
+(See also
+.BR namespaces (7).)
+.TP
+.B ENOMEM
+The kernel could not allocate sufficient memory to complete the operation.
+.TP
+.B EPERM
+.I flags
+contains
+.B \%OPEN_TREE_CLONE
+but the calling process does not have the required
+.B CAP_SYS_ADMIN
+capability.
+.SH STANDARDS
+Linux.
+.SH HISTORY
+Linux 5.2.
+.\" commit a07b20004793d8926f78d63eb5980559f7813404
+.\" commit 400913252d09f9cfb8cce33daee43167921fc343
+glibc 2.36.
+.SH NOTES
+.SS Anonymous mount namespaces
+The bind-mount mount objects created by
+.BR open_tree ()
+with
+.B \%OPEN_TREE_CLONE
+are not attached to the mount namespace of the calling process.
+Instead, each mount object is attached to
+a newly allocated "anonymous" mount namespace
+associated with the calling process.
+.P
+One of the side-effects of this is that
+(unlike bind-mounts created with
+.BR mount (2)),
+mount propagation
+(as described in
+.BR mount_namespaces (7))
+will not be applied to bind-mounts created by
+.BR open_tree ()
+until the bind-mount is attached with
+.BR move_mount (2),
+at which point the mount
+will be associated with the mount namespace
+where it was mounted
+and mount propagation will resume.
+.SH EXAMPLES
+The following examples show how
+.BR open_tree ()
+can be used in place of more traditional
+.BR mount (2)
+calls with
+.BR MS_BIND .
+.P
+.in +4n
+.EX
+int srcfd = open_tree(AT_FDCWD, "/var", OPEN_TREE_CLONE);
+move_mount(srcfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH);
+.EE
+.in
+.P
+First,
+a detached bind-mount mount object of
+.I /var
+is created and attached to the file descriptor
+.IR srcfd .
+Then, the mount object is attached to
+.I /mnt
+using
+.BR move_mount (2)
+with
+.B \%MOVE_MOUNT_F_EMPTY_PATH
+to request that the detached mount object attached to the file descriptor
+.I srcfd
+be moved (and thus attached) to
+.IR /mnt .
+.P
+The above procedure is functionally equivalent to
+the following mount operation using
+.BR mount (2):
+.P
+.in +4n
+.EX
+mount("/var", "/mnt", NULL, MS_BIND, NULL);
+.EE
+.in
+.P
+.B \%OPEN_TREE_CLONE
+can be combined with
+.B \%AT_RECURSIVE
+to create recursive detached bind-mount mount objects,
+which in turn can be attached to mount points
+to create recursive bind-mounts.
+.P
+.in +4n
+.EX
+int srcfd = open_tree(AT_FDCWD, "/var", OPEN_TREE_CLONE | AT_RECURSIVE);
+move_mount(srcfd, "", AT_FDCWD, "/mnt", MOVE_MOUNT_F_EMPTY_PATH);
+.EE
+.in
+.P
+The above procedure is functionally equivalent to
+the following mount operation using
+.BR mount (2):
+.P
+.in +4n
+.EX
+mount("/var", "/mnt", NULL, MS_BIND | MS_REC, NULL);
+.EE
+.in
+.P
+One of the primary benefits of using
+.BR open_tree ()
+and
+.BR move_mount (2)
+over the traditional
+.BR mount (2)
+is that operating with
+.IR dirfd -style
+file descriptors is far easier and more intuitive.
+.P
+.in +4n
+.EX
+int srcfd = open_tree(100, "", AT_EMPTY_PATH | OPEN_TREE_CLONE);
+move_mount(srcfd, "", 200, "foo", MOVE_MOUNT_F_EMPTY_PATH);
+.EE
+.in
+.P
+The above procedure is roughly equivalent to
+the following mount operation using
+.BR mount (2):
+.P
+.in +4n
+.EX
+mount("/proc/self/fd/100", "/proc/self/fd/200/foo", NULL, MS_BIND, NULL);
+.EE
+.in
+.P
+In addition, you can use the file descriptor returned by
+.BR open_tree ()
+as the
+.I dirfd
+argument to any "*at()" system calls:
+.P
+.in +4n
+.EX
+int dirfd, fd;
+\&
+dirfd = open_tree(AT_FDCWD, "/etc", OPEN_TREE_CLONE);
+fd = openat(dirfd, "passwd", O_RDONLY);
+fchmodat(dirfd, "shadow", 0000, 0);
+close(dirfd);
+close(fd);
+/* The bind-mount is now destroyed. */
+.EE
+.in
+.SH SEE ALSO
+.BR fsconfig (2),
+.BR fsmount (2),
+.BR fsopen (2),
+.BR fspick (2),
+.BR mount (2),
+.BR mount_setattr (2),
+.BR move_mount (2),
+.BR mount_namespaces (7)

-- 
2.50.1


^ permalink raw reply related

* [PATCH v3 10/12] man/man2/mount_setattr.2: mirror opening sentence from fsopen(2)
From: Aleksa Sarai @ 2025-08-08 20:39 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Michael T. Kerrisk, Alexander Viro, Jan Kara, Askar Safin,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner, Aleksa Sarai
In-Reply-To: <20250809-new-mount-api-v3-0-f61405c80f34@cyphar.com>

All of the other new mount API docs have this lead-in sentence in order
to make this set of APIs feel a little bit more cohesive.  Despite being
a bit of a latecomer, mount_setattr(2) is definitely part of this family
of APIs and so deserves the same treatment.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
 man/man2/mount_setattr.2 | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/man/man2/mount_setattr.2 b/man/man2/mount_setattr.2
index 46fcba927dd8c0959c898b9ba790ae298f514398..d98e7d70870c082144dfa47e31ddf091c8545e4f 100644
--- a/man/man2/mount_setattr.2
+++ b/man/man2/mount_setattr.2
@@ -19,7 +19,11 @@ .SH SYNOPSIS
 .SH DESCRIPTION
 The
 .BR mount_setattr ()
-system call changes the mount properties of a mount or an entire mount tree.
+system call is part of
+the suite of file descriptor based mount facilities in Linux.
+.P
+.BR mount_setattr ()
+changes the mount properties of a mount or an entire mount tree.
 If
 .I path
 is relative,

-- 
2.50.1


^ permalink raw reply related

* [PATCH v3 11/12] man/man2/open_tree{,_attr}.2: document new open_tree_attr() API
From: Aleksa Sarai @ 2025-08-08 20:39 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Michael T. Kerrisk, Alexander Viro, Jan Kara, Askar Safin,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner, Aleksa Sarai
In-Reply-To: <20250809-new-mount-api-v3-0-f61405c80f34@cyphar.com>

This is a new API added in Linux 6.15, and is effectively just a minor
expansion of open_tree(2) in order to allow for MOUNT_ATTR_IDMAP to be
changed for an existing ID-mapped mount.  glibc does not yet have a
wrapper for this.

Cc: Christian Brauner <brauner@kernel.org>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
 man/man2/open_tree.2      | 122 ++++++++++++++++++++++++++++++++++++++++++++++
 man/man2/open_tree_attr.2 |   1 +
 2 files changed, 123 insertions(+)

diff --git a/man/man2/open_tree.2 b/man/man2/open_tree.2
index 07aac7616107d16d05cc71ba7db6aee35f3a9cc6..f671c401b1f1e2926f7948d6fe5041b7848125ac 100644
--- a/man/man2/open_tree.2
+++ b/man/man2/open_tree.2
@@ -14,7 +14,19 @@ .SH SYNOPSIS
 .B #include <sys/mount.h>
 .P
 .BI "int open_tree(int " dirfd ", const char *" path ", unsigned int " flags ");"
+.P
+.BR "#include <sys/syscall.h>" "    /* Definition of " SYS_* " constants */"
+.P
+.BI "int syscall(SYS_open_tree_attr, int " dirfd ", const char *" path ","
+.BI "            unsigned int " flags ", struct mount_attr *" attr ", \
+size_t " size ");"
 .fi
+.P
+.IR Note :
+glibc provides no wrapper for
+.BR open_tree_attr (),
+necessitating the use of
+.BR syscall (2).
 .SH DESCRIPTION
 The
 .BR open_tree ()
@@ -228,6 +240,111 @@ .SH DESCRIPTION
 as a detached mount object.
 This flag is only permitted in conjunction with
 .BR \%OPEN_TREE_CLONE .
+.SS open_tree_attr()
+The
+.BR open_tree_attr ()
+system call operates in exactly the same way as
+.BR open_tree (),
+except for the differences described here.
+.P
+After performing the same operation as with
+.BR open_tree (),
+(before returning the resulting file descriptor)
+.BR open_tree_attr ()
+will apply the mount attribute changes described in
+.I attr
+to the returned file descriptor.
+(See
+.BR mount_attr (2type)
+for a description of the
+.I mount_attr
+structure.
+As described in
+.BR mount_setattr (2),
+.I size
+must be set to
+.I sizeof(struct mount_attr)
+in order to support future extensions.)
+.P
+The application of
+.I attr
+to the resultant file descriptor
+has identical semantics to
+.BR mount_setattr (2),
+except for the following extensions and general caveats:
+.IP \[bu] 3
+Unlike
+.BR mount_setattr (2)
+called with a regular
+.B OPEN_TREE_CLONE
+detached mount object from
+.BR open_tree (),
+.BR open_tree_attr ()
+can specify a different setting for
+.B \%MOUNT_ATTR_IDMAP
+to the original mount object cloned with
+.BR OPEN_TREE_CLONE .
+.IP
+Adding
+.B \%MOUNT_ATTR_IDMAP
+to
+.I attr.attr_clr
+will disable ID-mapping for the new mount object;
+adding
+.B \%MOUNT_ATTR_IDMAP
+to
+.I attr.attr_set
+will configure the mount object to have the ID-mapping defined by
+the user namespace referenced by the file descriptor
+.IR attr.userns_fd .
+(The semantics of which are identical to when
+.BR mount_setattr (2)
+is used to configure
+.BR \%MOUNT_ATTR_IDMAP .)
+.IP
+Changing or removing the mapping
+of an ID-mapped mount is only permitted
+if a new detached mount object is being created with
+.I flags
+including
+.BR \%OPEN_TREE_CLONE .
+.IP \[bu]
+If
+.I flags
+contains
+.BR \%AT_RECURSIVE ,
+then the attributes described in
+.I attr
+are applied recursively
+(just as when
+.BR mount_setattr (2)
+is called with
+.BR \%AT_RECURSIVE ).
+However, this applies in addition to the
+.BR open_tree ()-specific
+behaviour regarding
+.BR \%AT_RECURSIVE ,
+and thus
+.I flags
+must also contain
+.BR \% OPEN_TREE_CLONE .
+.P
+Note that if
+.I flags
+does not contain
+.BR \% OPEN_TREE_CLONE ,
+.BR open_tree_attr ()
+will attempt to modify the mount attributes of
+the mount object attached at
+the path described by
+.I dirfd
+and
+.IR path .
+As with
+.BR mount_setattr (2),
+if said path is not a mount point,
+.BR open_tree_attr ()
+will return an error.
 .SH RETURN VALUE
 On success, a new file descriptor is returned.
 On error, \-1 is returned, and
@@ -321,10 +438,15 @@ .SH ERRORS
 .SH STANDARDS
 Linux.
 .SH HISTORY
+.SS open_tree()
 Linux 5.2.
 .\" commit a07b20004793d8926f78d63eb5980559f7813404
 .\" commit 400913252d09f9cfb8cce33daee43167921fc343
 glibc 2.36.
+.SS open_tree_attr()
+Linux 6.15.
+.\" commit c4a16820d90199409c9bf01c4f794e1e9e8d8fd8
+.\" commit 7a54947e727b6df840780a66c970395ed9734ebe
 .SH NOTES
 .SS Anonymous mount namespaces
 The bind-mount mount objects created by
diff --git a/man/man2/open_tree_attr.2 b/man/man2/open_tree_attr.2
new file mode 100644
index 0000000000000000000000000000000000000000..e57269bbd269bcce0b0a974425644ba75e379f2f
--- /dev/null
+++ b/man/man2/open_tree_attr.2
@@ -0,0 +1 @@
+.so man2/open_tree.2

-- 
2.50.1


^ permalink raw reply related

* [PATCH v3 12/12] man/man2/{fsconfig,mount_setattr}.2: add note about attribute-parameter distinction
From: Aleksa Sarai @ 2025-08-08 20:39 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: Michael T. Kerrisk, Alexander Viro, Jan Kara, Askar Safin,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner, Aleksa Sarai
In-Reply-To: <20250809-new-mount-api-v3-0-f61405c80f34@cyphar.com>

This was not particularly well documented in mount(8) nor mount(2), and
since this is a fairly notable aspect of the new mount API, we should
probably add some words about it.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
 man/man2/fsconfig.2      | 11 +++++++++++
 man/man2/mount_setattr.2 | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/man/man2/fsconfig.2 b/man/man2/fsconfig.2
index 97c9aff0e0c195e6028e1c7bd70e40905ba9f994..a7642e1633541bf8f5cd537db22987a4ec70da06 100644
--- a/man/man2/fsconfig.2
+++ b/man/man2/fsconfig.2
@@ -522,6 +522,17 @@ .SS Generic filesystem parameters
 Linux Security Modules (LSMs)
 are also generic with respect to the underlying filesystem.
 See the documentation for the LSM you wish to configure for more details.
+.SS Mount attributes and filesystem parameters
+Some filesystem parameters
+(traditionally associated with
+.BR mount (8)-style
+options)
+are also mount attributes.
+.P
+For a description of the distinction between
+mount attributes and filesystem parameters,
+see the "Mount attributes and filesystem parameters" subsection of
+.BR mount_setattr (2).
 .SH CAVEATS
 .SS Filesystem parameter types
 As a result of
diff --git a/man/man2/mount_setattr.2 b/man/man2/mount_setattr.2
index d98e7d70870c082144dfa47e31ddf091c8545e4f..2927b012eed1569e0d78a2fb91815f364fca124d 100644
--- a/man/man2/mount_setattr.2
+++ b/man/man2/mount_setattr.2
@@ -790,6 +790,43 @@ .SS ID-mapped mounts
 .BR chown (2)
 system call changes the ownership globally and permanently.
 .\"
+.SS Mount attributes and filesystem parameters
+Some mount attributes
+(traditionally associated with
+.BR mount (8)-style
+options)
+are also filesystem parameters.
+For example, the
+.I -o ro
+option to
+.BR mount (8)
+can refer to the
+"read-only" filesystem parameter,
+or the "read-only" mount attribute.
+.P
+The distinction between these two kinds of option is that
+mount object attributes are applied per-mount-object
+(allowing different mount objects
+derived from a given filesystem instance
+to have different attributes),
+while filesystem instance parameters
+("superblock flags" in kernel-developer parlance)
+apply to all mount objects
+derived from the same filesystem instance.
+.P
+When using
+.BR mount (2),
+the line between these two types of mount options was blurred.
+However, with
+.BR mount_setattr ()
+and
+.BR fsconfig (2),
+the distinction is made much clearer.
+Mount attributes are configured with
+.BR mount_setattr (),
+while filesystem parameters can be configured using
+.BR fsconfig (2).
+.\"
 .SS Extensibility
 In order to allow for future extensibility,
 .BR mount_setattr ()

-- 
2.50.1


^ permalink raw reply related

* Re: [PATCH v2 01/11] mount_setattr.2: document glibc >= 2.36 syscall wrappers
From: Alejandro Colomar @ 2025-08-09 10:42 UTC (permalink / raw)
  To: Aleksa Sarai
  Cc: Askar Safin, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <2025-08-08.1754653930-iffy-pickled-agencies-mother-K0e7Hn@cyphar.com>

[-- Attachment #1: Type: text/plain, Size: 1558 bytes --]

Hi Aleksa, Askar,

On Fri, Aug 08, 2025 at 09:55:10PM +1000, Aleksa Sarai wrote:
> On 2025-08-08, Askar Safin <safinaskar@zohomail.com> wrote:
> > When I render "mount_setattr" from this (v2) pathset, I see weird quote mark. I. e.:
> > 
> > $ MANWIDTH=10000 man /path/to/mount_setattr.2
> > ...
> > SYNOPSIS
> >        #include <fcntl.h>       /* Definition of AT_* constants */
> >        #include <sys/mount.h>
> > 
> >        int mount_setattr(int dirfd, const char *path, unsigned int flags,
> >                          struct mount_attr *attr, size_t size);"
> > ...
> 
> Ah, my bad. "make -R lint-man" told me to put end quotes on the synopsis
> lines, but I missed that there was a separate quote missing. This should
> fix it:
> 
> diff --git a/man/man2/mount_setattr.2 b/man/man2/mount_setattr.2
> index d44fafc93a20..46fcba927dd8 100644
> --- a/man/man2/mount_setattr.2
> +++ b/man/man2/mount_setattr.2
> @@ -14,7 +14,7 @@ .SH SYNOPSIS
>  .B #include <sys/mount.h>
>  .P
>  .BI "int mount_setattr(int " dirfd ", const char *" path ", unsigned int " flags ","
> -.BI "                  struct mount_attr *" attr ", size_t " size );"
> +.BI "                  struct mount_attr *" attr ", size_t " size ");"

Actually, I'd use

.BI "                  struct mount_attr *" attr ", size_t " size );

>  .fi
>  .SH DESCRIPTION
>  The

Hmmm, thanks for the catch!  My CI server is down until I come back home
and have a chance to fix it.


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 01/11] mount_setattr.2: document glibc >= 2.36 syscall wrappers
From: Alejandro Colomar @ 2025-08-09 10:44 UTC (permalink / raw)
  To: Aleksa Sarai
  Cc: Askar Safin, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <j57inuu7wzzh2tm7sxfnhdogg4u7f4gf3vktmla4qlafuknh3p@ypu3peu3g5k6>

[-- Attachment #1: Type: text/plain, Size: 2318 bytes --]

Hi Aleksa, Askar,

On Sat, Aug 09, 2025 at 12:42:58PM +0200, Alejandro Colomar wrote:
> Hi Aleksa, Askar,
> 
> On Fri, Aug 08, 2025 at 09:55:10PM +1000, Aleksa Sarai wrote:
> > On 2025-08-08, Askar Safin <safinaskar@zohomail.com> wrote:
> > > When I render "mount_setattr" from this (v2) pathset, I see weird quote mark. I. e.:
> > > 
> > > $ MANWIDTH=10000 man /path/to/mount_setattr.2
> > > ...
> > > SYNOPSIS
> > >        #include <fcntl.h>       /* Definition of AT_* constants */
> > >        #include <sys/mount.h>
> > > 
> > >        int mount_setattr(int dirfd, const char *path, unsigned int flags,
> > >                          struct mount_attr *attr, size_t size);"
> > > ...
> > 
> > Ah, my bad. "make -R lint-man" told me to put end quotes on the synopsis
> > lines, but I missed that there was a separate quote missing. This should
> > fix it:
> > 
> > diff --git a/man/man2/mount_setattr.2 b/man/man2/mount_setattr.2
> > index d44fafc93a20..46fcba927dd8 100644
> > --- a/man/man2/mount_setattr.2
> > +++ b/man/man2/mount_setattr.2
> > @@ -14,7 +14,7 @@ .SH SYNOPSIS
> >  .B #include <sys/mount.h>
> >  .P
> >  .BI "int mount_setattr(int " dirfd ", const char *" path ", unsigned int " flags ","
> > -.BI "                  struct mount_attr *" attr ", size_t " size );"
> > +.BI "                  struct mount_attr *" attr ", size_t " size ");"
> 
> Actually, I'd use
> 
> .BI "                  struct mount_attr *" attr ", size_t " size );

I've pushed this as a fix.  As a sanity check:

	$ diffman-git HEAD
	--- HEAD^:man/man2/mount_setattr.2
	+++ HEAD:man/man2/mount_setattr.2
	@@ -11,7 +11,7 @@
		#include <sys/mount.h>
	 
		int mount_setattr(int dirfd, const char *path, unsigned int flags,
	-                         struct mount_attr *attr, size_t size);"
	+                         struct mount_attr *attr, size_t size);
	 
	 DESCRIPTION
		The mount_setattr() system call changes the mount properties of a mount


Have a lovely day!
Alex

> 
> >  .fi
> >  .SH DESCRIPTION
> >  The
> 
> Hmmm, thanks for the catch!  My CI server is down until I come back home
> and have a chance to fix it.
> 
> 
> Have a lovely day!
> Alex
> 
> -- 
> <https://www.alejandro-colomar.es/>



-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4 1/2] man/man2/mremap.2: describe multiple mapping move
From: Alejandro Colomar @ 2025-08-09 14:25 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <53e4284ffe80a63260c957369ccacea8f5c16adc.1754414738.git.lorenzo.stoakes@oracle.com>

[-- Attachment #1: Type: text/plain, Size: 6007 bytes --]

Hi Lorenzo,

On Tue, Aug 05, 2025 at 06:31:55PM +0100, Lorenzo Stoakes wrote:
> Document the new behaviour introduced in Linux 6.17 whereby it is now
> possible to move multiple mappings in a single operation, as long as the
> operation is purely a move, that is old_size is equal to new_size and
> MREMAP_FIXED is specified.
> 
> To make things clearer, also describe this 'pure move' operation, before
> expanding upon it to describe the newly introduced behaviour.

Can we split this further into two commits?

> 
> This change also explains the limitations of of this method and the
> possibility of partial failure.
> 
> Finally, we pluralise language where it makes sense to so the documentation
> does not contradict either this new capability nor the pre-existing edge
> case.
> 
> Example code is enclosed below demonstrating the behaviour which is now
> possible:
> 
> int main(void)
> {
> 	unsigned long page_size = sysconf(_SC_PAGESIZE);
> 	void *ptr = mmap(NULL, 10 * page_size, PROT_READ | PROT_WRITE,
> 			 MAP_ANON | MAP_PRIVATE, -1, 0);
> 	void *tgt_ptr = mmap(NULL, 10 * page_size, PROT_NONE,
> 			     MAP_ANON | MAP_PRIVATE, -1, 0);
> 	int i;
> 
> 	if (ptr == MAP_FAILED || tgt_ptr == MAP_FAILED) {
> 		perror("mmap");
> 		return EXIT_FAILURE;
> 	}
> 
> 	/* Unmap every other page. */
> 	for (i = 1; i < 10; i += 2)
> 		munmap(ptr + i * page_size, page_size);
> 
> 	/* Now move all 5 distinct mappings to tgt_ptr. */
> 	ptr = mremap(ptr, 10 * page_size, 10 * page_size,
> 		     MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr);
> 	if (ptr == MAP_FAILED) {
> 		perror("mremap");
> 		return EXIT_FAILURE;
> 	}
> 
> 	return EXIT_SUCCESS;
> }
> 
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> ---
>  man/man2/mremap.2 | 84 ++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 73 insertions(+), 11 deletions(-)
> 
> diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
> index 2168ca728..6ba51310c 100644
> --- a/man/man2/mremap.2
> +++ b/man/man2/mremap.2
> @@ -25,18 +25,47 @@ moving it at the same time (controlled by the
>  argument and
>  the available virtual address space).
>  .P
> +Mappings can also simply be moved
> +(without any resizing)
> +by specifying equal
> +.I old_size
> +and
> +.I new_size
> +and using the
> +.B MREMAP_FIXED
> +flag
> +(see below).
> +Since Linux 6.17,
> +while
> +.I old_address
> +must reside within a mapping,

I don't understand this.  What does it mean that old_address must reside
within a mapping?  It's a point, not a size, so I'm not sure I
understand it.

> +.I old_size
> +may span multiple mappings
> +which do not have to be
> +adjacent to one another when
> +performing a move like this.
> +The
> +.B MREMAP_DONTUNMAP
> +flag may be specified.
> +.P
> +If the operation is not
> +simply moving mappings,
> +then
> +.I old_size
> +must span only a single mapping.
> +.P
>  .I old_address
> -is the old address of the virtual memory block that you
> -want to expand (or shrink).
> +is the old address of the first virtual memory block that you
> +want to expand, shrink, and/or move.
>  Note that
>  .I old_address
>  has to be page aligned.
>  .I old_size
> -is the old size of the
> -virtual memory block.
> +is the size of the range containing
> +virtual memory blocks to be manipulated.
>  .I new_size
>  is the requested size of the
> -virtual memory block after the resize.
> +virtual memory blocks after the resize.
>  An optional fifth argument,
>  .IR new_address ,
>  may be provided; see the description of
> @@ -105,13 +134,43 @@ If
>  is specified, then
>  .B MREMAP_MAYMOVE
>  must also be specified.
> +.IP
> +Since Linux 6.17,
> +if
> +.I old_size
> +is equal to
> +.I new_size
> +and
> +.B MREMAP_FIXED
> +is specified, then
> +.I old_size
> +may span beyond the mapping in which
> +.I old_address
> +resides.
> +In this case,
> +gaps between mappings in the original range
> +are maintained in the new range.
> +The whole operation is performed atomically
> +unless an error arises,
> +in which case the operation may be partially
> +completed,
> +that is,
> +some mappings may be moved and others not.
> +.IP
> +

Why this blank?


Cheers,
Alex

> +Moving multiple mappings is not permitted if
> +any of those mappings have either
> +been registered with
> +.BR userfaultfd (2) ,
> +or map drivers that
> +specify their own custom address mapping logic.
>  .TP
>  .BR MREMAP_DONTUNMAP " (since Linux 5.7)"
>  .\" commit e346b3813067d4b17383f975f197a9aa28a3b077
>  This flag, which must be used in conjunction with
>  .BR MREMAP_MAYMOVE ,
> -remaps a mapping to a new address but does not unmap the mapping at
> -.IR old_address .
> +remaps mappings to a new address but does not unmap them
> +from their original address.
>  .IP
>  The
>  .B MREMAP_DONTUNMAP
> @@ -149,13 +208,13 @@ mapped.
>  See NOTES for some possible applications of
>  .BR MREMAP_DONTUNMAP .
>  .P
> -If the memory segment specified by
> +If the memory segments specified by
>  .I old_address
>  and
>  .I old_size
> -is locked (using
> +are locked (using
>  .BR mlock (2)
> -or similar), then this lock is maintained when the segment is
> +or similar), then this lock is maintained when the segments are
>  resized and/or relocated.
>  As a consequence, the amount of memory locked by the process may change.
>  .SH RETURN VALUE
> @@ -188,7 +247,10 @@ virtual memory address for this process.
>  You can also get
>  .B EFAULT
>  even if there exist mappings that cover the
> -whole address space requested, but those mappings are of different types.
> +whole address space requested, but those mappings are of different types,
> +and the
> +.BR mremap ()
> +operation being performed does not support this.
>  .TP
>  .B EINVAL
>  An invalid argument was given.
> -- 
> 2.50.1
> 

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4 2/2] man/man2/mremap.2: describe previously undocumented shrink behaviour
From: Alejandro Colomar @ 2025-08-09 14:33 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <c7ba8ba09b1c0b015134c54824788ef4aa47fd46.1754414738.git.lorenzo.stoakes@oracle.com>

[-- Attachment #1: Type: text/plain, Size: 2334 bytes --]

Hi Lorenzo,

On Tue, Aug 05, 2025 at 06:31:56PM +0100, Lorenzo Stoakes wrote:
> There is pre-existing logic that appears to be undocumented for an mremap()
> shrink operation, where it turns out that the usual 'input range must span
> a single mapping' requirement no longer applies.
> 
> In fact, it turns out that the input range specified by [old_address,
> old_address + old_size) may span any number of mappings.
> 
> If shrinking in-place (that is, neither the MREMAP_FIXED nor
> MREMAP_DONTUNMAP flags are specified), then the new span may also span any
> number of VMAs - [old_address, old_address + new_size).
> 
> If shrinking and moving, the range specified by [old_address, old_address +
> new_size) must span a single VMA.
> 
> There must be at least one VMA contained within the [old_address,
> old_address + old_size) range, and old_address must be within the range of
> a VMA.
> 
> Explicitly document this.
> 
> Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>

Since this is documenting old behavior, could we have this patch before
the patch documenting new behavior?  Or do you prefer it in this order?


Cheers,
Alex

> ---
>  man/man2/mremap.2 | 31 +++++++++++++++++++++++++++++--
>  1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
> index 6ba51310c..631c835b8 100644
> --- a/man/man2/mremap.2
> +++ b/man/man2/mremap.2
> @@ -48,8 +48,35 @@ The
>  .B MREMAP_DONTUNMAP
>  flag may be specified.
>  .P
> -If the operation is not
> -simply moving mappings,
> +Equally, if the operation performs a shrink,
> +that is if
> +.I old_size
> +is greater than
> +.IR new_size ,
> +then
> +.I old_size
> +may also span multiple mappings
> +which do not have to be
> +adjacent to one another.
> +If this shrink is performed
> +in-place,
> +that is,
> +neither
> +.BR MREMAP_FIXED ,
> +nor
> +.B MREMAP_DONTUNMAP
> +are specified,
> +.I new_size
> +may also span multiple VMAs.
> +However, if the range is moved,
> +then
> +.I new_size
> +must span only a single mapping.
> +.P
> +If the operation is neither a
> +.B MREMAP_FIXED
> +move
> +nor a shrink,
>  then
>  .I old_size
>  must span only a single mapping.
> -- 
> 2.50.1
> 

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v3 00/12] man2: document "new" mount API
From: Askar Safin @ 2025-08-09 15:04 UTC (permalink / raw)
  To: Aleksa Sarai, Alejandro Colomar
  Cc: Michael T. Kerrisk, Alexander Viro, Jan Kara, G. Branden Robinson,
	linux-man, linux-api, linux-fsdevel, linux-kernel, David Howells,
	Christian Brauner
In-Reply-To: <20250809-new-mount-api-v3-0-f61405c80f34@cyphar.com>

I plan to do a lot of testing of "new" mount API on my computer.
It is quiet possible that I will find some bugs in these manpages during testing.
(I already found some, but I'm not sure.)
I think this will take 3-7 days.
So, Alejandro Colomar, please, don't merge this patchset until then.

--
Askar Safin
https://types.pl/@safinaskar


^ permalink raw reply

* Re: [PATCH v3 00/12] man2: document "new" mount API
From: Alejandro Colomar @ 2025-08-09 15:11 UTC (permalink / raw)
  To: Askar Safin
  Cc: Aleksa Sarai, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <1988f5c48ef.e4a6fe4950444.5375980219736330538@zohomail.com>

[-- Attachment #1: Type: text/plain, Size: 461 bytes --]

Hi Askar,

On Sat, Aug 09, 2025 at 07:04:06PM +0400, Askar Safin wrote:
> I plan to do a lot of testing of "new" mount API on my computer.
> It is quiet possible that I will find some bugs in these manpages during testing.
> (I already found some, but I'm not sure.)
> I think this will take 3-7 days.
> So, Alejandro Colomar, please, don't merge this patchset until then.

Sure, thanks!


Cheers,
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v3 00/12] man2: document "new" mount API
From: Aleksa Sarai @ 2025-08-09 17:32 UTC (permalink / raw)
  To: Askar Safin
  Cc: Alejandro Colomar, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <1988f5c48ef.e4a6fe4950444.5375980219736330538@zohomail.com>

[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]

On 2025-08-09, Askar Safin <safinaskar@zohomail.com> wrote:
> I plan to do a lot of testing of "new" mount API on my computer.
> It is quiet possible that I will find some bugs in these manpages during testing.
> (I already found some, but I'm not sure.)
> I think this will take 3-7 days.
> So, Alejandro Colomar, please, don't merge this patchset until then.

I don't plan to work on this again for the next week at least (I've
already spent over a week on these docs -- writing, rewriting, and then
rewriting once more for good measure; I've started seeing groff in my
nightmares...), so I will go through review comments after you're done.

There are some rough edges on these APIs I found while writing these
docs, so I plan to fix those this cycle if possible (hopefully those
aren't the bugs you said you found in the docs). Two of the fixes have
already been merged in the vfs tree for 6.18 (the -ENODATA handling bug,
as well as a bug in open_tree_attr() that would've let userspace trigger
UAFs). (Once 6.18 is out, I will send a follow-up patchset to document
the fixes.)

FYI, I've already fixed the few ".BR \% FOO" typos. (My terminal font
doesn't have a bold typeface, so when reviewing the rendered man-pages,
mistakes involving .B are hard to spot.)

-- 
Aleksa Sarai
Senior Software Engineer (Containers)
SUSE Linux GmbH
https://www.cyphar.com/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v4 1/2] man/man2/mremap.2: describe multiple mapping move
From: Lorenzo Stoakes @ 2025-08-11  5:30 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <ekjakm6zburrawhk34smm3fd43zufzguisfean4hmv7vyjp7fq@uvy6n47qbydl>

On Sat, Aug 09, 2025 at 04:25:18PM +0200, Alejandro Colomar wrote:
> Hi Lorenzo,
>
> On Tue, Aug 05, 2025 at 06:31:55PM +0100, Lorenzo Stoakes wrote:
> > Document the new behaviour introduced in Linux 6.17 whereby it is now
> > possible to move multiple mappings in a single operation, as long as the
> > operation is purely a move, that is old_size is equal to new_size and
> > MREMAP_FIXED is specified.
> >
> > To make things clearer, also describe this 'pure move' operation, before
> > expanding upon it to describe the newly introduced behaviour.
>
> Can we split this further into two commits?

OK can do.

>
> >
> > This change also explains the limitations of of this method and the
> > possibility of partial failure.
> >
> > Finally, we pluralise language where it makes sense to so the documentation
> > does not contradict either this new capability nor the pre-existing edge
> > case.
> >
> > Example code is enclosed below demonstrating the behaviour which is now
> > possible:
> >
> > int main(void)
> > {
> > 	unsigned long page_size = sysconf(_SC_PAGESIZE);
> > 	void *ptr = mmap(NULL, 10 * page_size, PROT_READ | PROT_WRITE,
> > 			 MAP_ANON | MAP_PRIVATE, -1, 0);
> > 	void *tgt_ptr = mmap(NULL, 10 * page_size, PROT_NONE,
> > 			     MAP_ANON | MAP_PRIVATE, -1, 0);
> > 	int i;
> >
> > 	if (ptr == MAP_FAILED || tgt_ptr == MAP_FAILED) {
> > 		perror("mmap");
> > 		return EXIT_FAILURE;
> > 	}
> >
> > 	/* Unmap every other page. */
> > 	for (i = 1; i < 10; i += 2)
> > 		munmap(ptr + i * page_size, page_size);
> >
> > 	/* Now move all 5 distinct mappings to tgt_ptr. */
> > 	ptr = mremap(ptr, 10 * page_size, 10 * page_size,
> > 		     MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr);
> > 	if (ptr == MAP_FAILED) {
> > 		perror("mremap");
> > 		return EXIT_FAILURE;
> > 	}
> >
> > 	return EXIT_SUCCESS;
> > }
> >
> > Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
> > ---
> >  man/man2/mremap.2 | 84 ++++++++++++++++++++++++++++++++++++++++-------
> >  1 file changed, 73 insertions(+), 11 deletions(-)
> >
> > diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
> > index 2168ca728..6ba51310c 100644
> > --- a/man/man2/mremap.2
> > +++ b/man/man2/mremap.2
> > @@ -25,18 +25,47 @@ moving it at the same time (controlled by the
> >  argument and
> >  the available virtual address space).
> >  .P
> > +Mappings can also simply be moved
> > +(without any resizing)
> > +by specifying equal
> > +.I old_size
> > +and
> > +.I new_size
> > +and using the
> > +.B MREMAP_FIXED
> > +flag
> > +(see below).
> > +Since Linux 6.17,
> > +while
> > +.I old_address
> > +must reside within a mapping,
>
> I don't understand this.  What does it mean that old_address must reside
> within a mapping?  It's a point, not a size, so I'm not sure I
> understand it.

I think if it were a size it would be more confusing no?

It's an address, the address must be located within an existing memory mapping.

Will replace with 'located' for clarity.

>
> > +.I old_size
> > +may span multiple mappings
> > +which do not have to be
> > +adjacent to one another when
> > +performing a move like this.
> > +The
> > +.B MREMAP_DONTUNMAP
> > +flag may be specified.
> > +.P
> > +If the operation is not
> > +simply moving mappings,
> > +then
> > +.I old_size
> > +must span only a single mapping.
> > +.P
> >  .I old_address
> > -is the old address of the virtual memory block that you
> > -want to expand (or shrink).
> > +is the old address of the first virtual memory block that you
> > +want to expand, shrink, and/or move.
> >  Note that
> >  .I old_address
> >  has to be page aligned.
> >  .I old_size
> > -is the old size of the
> > -virtual memory block.
> > +is the size of the range containing
> > +virtual memory blocks to be manipulated.
> >  .I new_size
> >  is the requested size of the
> > -virtual memory block after the resize.
> > +virtual memory blocks after the resize.
> >  An optional fifth argument,
> >  .IR new_address ,
> >  may be provided; see the description of
> > @@ -105,13 +134,43 @@ If
> >  is specified, then
> >  .B MREMAP_MAYMOVE
> >  must also be specified.
> > +.IP
> > +Since Linux 6.17,
> > +if
> > +.I old_size
> > +is equal to
> > +.I new_size
> > +and
> > +.B MREMAP_FIXED
> > +is specified, then
> > +.I old_size
> > +may span beyond the mapping in which
> > +.I old_address
> > +resides.
> > +In this case,
> > +gaps between mappings in the original range
> > +are maintained in the new range.
> > +The whole operation is performed atomically
> > +unless an error arises,
> > +in which case the operation may be partially
> > +completed,
> > +that is,
> > +some mappings may be moved and others not.
> > +.IP
> > +
>
> Why this blank?

Oops that was a mistake, will fix on respin.

>
>
> Cheers,
> Alex
>
> > +Moving multiple mappings is not permitted if
> > +any of those mappings have either
> > +been registered with
> > +.BR userfaultfd (2) ,
> > +or map drivers that
> > +specify their own custom address mapping logic.
> >  .TP
> >  .BR MREMAP_DONTUNMAP " (since Linux 5.7)"
> >  .\" commit e346b3813067d4b17383f975f197a9aa28a3b077
> >  This flag, which must be used in conjunction with
> >  .BR MREMAP_MAYMOVE ,
> > -remaps a mapping to a new address but does not unmap the mapping at
> > -.IR old_address .
> > +remaps mappings to a new address but does not unmap them
> > +from their original address.
> >  .IP
> >  The
> >  .B MREMAP_DONTUNMAP
> > @@ -149,13 +208,13 @@ mapped.
> >  See NOTES for some possible applications of
> >  .BR MREMAP_DONTUNMAP .
> >  .P
> > -If the memory segment specified by
> > +If the memory segments specified by
> >  .I old_address
> >  and
> >  .I old_size
> > -is locked (using
> > +are locked (using
> >  .BR mlock (2)
> > -or similar), then this lock is maintained when the segment is
> > +or similar), then this lock is maintained when the segments are
> >  resized and/or relocated.
> >  As a consequence, the amount of memory locked by the process may change.
> >  .SH RETURN VALUE
> > @@ -188,7 +247,10 @@ virtual memory address for this process.
> >  You can also get
> >  .B EFAULT
> >  even if there exist mappings that cover the
> > -whole address space requested, but those mappings are of different types.
> > +whole address space requested, but those mappings are of different types,
> > +and the
> > +.BR mremap ()
> > +operation being performed does not support this.
> >  .TP
> >  .B EINVAL
> >  An invalid argument was given.
> > --
> > 2.50.1
> >
>
> --
> <https://www.alejandro-colomar.es/>

^ permalink raw reply

* Re: [PATCH v4 2/2] man/man2/mremap.2: describe previously undocumented shrink behaviour
From: Lorenzo Stoakes @ 2025-08-11  5:31 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <iolucvrp6is43yjulbluchhw5wy6urq2gtwmcelg5atwuv63se@ovzuthfrup26>

On Sat, Aug 09, 2025 at 04:33:12PM +0200, Alejandro Colomar wrote:
> Hi Lorenzo,
>
> On Tue, Aug 05, 2025 at 06:31:56PM +0100, Lorenzo Stoakes wrote:
> > There is pre-existing logic that appears to be undocumented for an mremap()
> > shrink operation, where it turns out that the usual 'input range must span
> > a single mapping' requirement no longer applies.
> >
> > In fact, it turns out that the input range specified by [old_address,
> > old_address + old_size) may span any number of mappings.
> >
> > If shrinking in-place (that is, neither the MREMAP_FIXED nor
> > MREMAP_DONTUNMAP flags are specified), then the new span may also span any
> > number of VMAs - [old_address, old_address + new_size).
> >
> > If shrinking and moving, the range specified by [old_address, old_address +
> > new_size) must span a single VMA.
> >
> > There must be at least one VMA contained within the [old_address,
> > old_address + old_size) range, and old_address must be within the range of
> > a VMA.
> >
> > Explicitly document this.
> >
> > Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
>
> Since this is documenting old behavior, could we have this patch before
> the patch documenting new behavior?  Or do you prefer it in this order?

I think it's fine in this order, it's more convenient for me as it'd be a pain
to re-order otherwise, and we've waited ~20 years (or longer?) to document this
so a delay in ordering is probably fine :P

Cheers, Lorenzo

>
>
> Cheers,
> Alex
>
> > ---
> >  man/man2/mremap.2 | 31 +++++++++++++++++++++++++++++--
> >  1 file changed, 29 insertions(+), 2 deletions(-)
> >
> > diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
> > index 6ba51310c..631c835b8 100644
> > --- a/man/man2/mremap.2
> > +++ b/man/man2/mremap.2
> > @@ -48,8 +48,35 @@ The
> >  .B MREMAP_DONTUNMAP
> >  flag may be specified.
> >  .P
> > -If the operation is not
> > -simply moving mappings,
> > +Equally, if the operation performs a shrink,
> > +that is if
> > +.I old_size
> > +is greater than
> > +.IR new_size ,
> > +then
> > +.I old_size
> > +may also span multiple mappings
> > +which do not have to be
> > +adjacent to one another.
> > +If this shrink is performed
> > +in-place,
> > +that is,
> > +neither
> > +.BR MREMAP_FIXED ,
> > +nor
> > +.B MREMAP_DONTUNMAP
> > +are specified,
> > +.I new_size
> > +may also span multiple VMAs.
> > +However, if the range is moved,
> > +then
> > +.I new_size
> > +must span only a single mapping.
> > +.P
> > +If the operation is neither a
> > +.B MREMAP_FIXED
> > +move
> > +nor a shrink,
> >  then
> >  .I old_size
> >  must span only a single mapping.
> > --
> > 2.50.1
> >
>
> --
> <https://www.alejandro-colomar.es/>

^ permalink raw reply

* Re: [PATCH v4 1/2] man/man2/mremap.2: describe multiple mapping move
From: Alejandro Colomar @ 2025-08-11  9:20 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <664b00e3-69a0-498a-a7dd-a3d294c0c188@lucifer.local>

[-- Attachment #1: Type: text/plain, Size: 1212 bytes --]

Hi Lorenzo,

On Mon, Aug 11, 2025 at 06:30:38AM +0100, Lorenzo Stoakes wrote:
> > > +Mappings can also simply be moved
> > > +(without any resizing)
> > > +by specifying equal
> > > +.I old_size
> > > +and
> > > +.I new_size
> > > +and using the
> > > +.B MREMAP_FIXED
> > > +flag
> > > +(see below).
> > > +Since Linux 6.17,
> > > +while
> > > +.I old_address
> > > +must reside within a mapping,
> >
> > I don't understand this.  What does it mean that old_address must reside
> > within a mapping?  It's a point, not a size, so I'm not sure I
> > understand it.
> 
> I think if it were a size it would be more confusing no?
> 
> It's an address, the address must be located within an existing memory mapping.

What I don't understand is: how could you not comply with that?  Could
you pass some old_address that is in two mappings?  Being a single
address, that would be impossible, right?

> Will replace with 'located' for clarity.
> 
> >
> > > +.I old_size
> > > +may span multiple mappings
> > > +which do not have to be
> > > +adjacent to one another when
> > > +performing a move like this.


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4 2/2] man/man2/mremap.2: describe previously undocumented shrink behaviour
From: Alejandro Colomar @ 2025-08-11  9:20 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <0b0928a3-03b0-4a36-817b-b75c1f5c78f9@lucifer.local>

[-- Attachment #1: Type: text/plain, Size: 552 bytes --]

On Mon, Aug 11, 2025 at 06:31:25AM +0100, Lorenzo Stoakes wrote:
> > Since this is documenting old behavior, could we have this patch before
> > the patch documenting new behavior?  Or do you prefer it in this order?
> 
> I think it's fine in this order, it's more convenient for me as it'd be a pain
> to re-order otherwise, and we've waited ~20 years (or longer?) to document this
> so a delay in ordering is probably fine :P
> 
> Cheers, Lorenzo

Okay, that's fine.  Thanks!


Cheers,
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4 1/2] man/man2/mremap.2: describe multiple mapping move
From: Lorenzo Stoakes @ 2025-08-11  9:25 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <iny6ro5f37vcthqwscklqx73jscahodilug5d6umleyzq6a67k@ecoey5ud3aer>

On Mon, Aug 11, 2025 at 11:20:05AM +0200, Alejandro Colomar wrote:
> Hi Lorenzo,
>
> On Mon, Aug 11, 2025 at 06:30:38AM +0100, Lorenzo Stoakes wrote:
> > > > +Mappings can also simply be moved
> > > > +(without any resizing)
> > > > +by specifying equal
> > > > +.I old_size
> > > > +and
> > > > +.I new_size
> > > > +and using the
> > > > +.B MREMAP_FIXED
> > > > +flag
> > > > +(see below).
> > > > +Since Linux 6.17,
> > > > +while
> > > > +.I old_address
> > > > +must reside within a mapping,
> > >
> > > I don't understand this.  What does it mean that old_address must reside
> > > within a mapping?  It's a point, not a size, so I'm not sure I
> > > understand it.
> >
> > I think if it were a size it would be more confusing no?
> >
> > It's an address, the address must be located within an existing memory mapping.
>
> What I don't understand is: how could you not comply with that?  Could
> you pass some old_address that is in two mappings?  Being a single
> address, that would be impossible, right?

It can be in an unmapped area. It's either in an unmapped area or a mapped one.

I could simply reword this as 'old_address must be mapped'?

>
> > Will replace with 'located' for clarity.
> >
> > >
> > > > +.I old_size
> > > > +may span multiple mappings
> > > > +which do not have to be
> > > > +adjacent to one another when
> > > > +performing a move like this.
>
>
> Have a lovely day!
> Alex
>
> --
> <https://www.alejandro-colomar.es/>

^ permalink raw reply

* Re: [PATCH v4 1/2] man/man2/mremap.2: describe multiple mapping move
From: Alejandro Colomar @ 2025-08-11  9:37 UTC (permalink / raw)
  To: Lorenzo Stoakes
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <39fb9e1b-b806-47da-a711-20c6cc12913a@lucifer.local>

[-- Attachment #1: Type: text/plain, Size: 1766 bytes --]

On Mon, Aug 11, 2025 at 10:25:56AM +0100, Lorenzo Stoakes wrote:
> On Mon, Aug 11, 2025 at 11:20:05AM +0200, Alejandro Colomar wrote:
> > Hi Lorenzo,
> >
> > On Mon, Aug 11, 2025 at 06:30:38AM +0100, Lorenzo Stoakes wrote:
> > > > > +Mappings can also simply be moved
> > > > > +(without any resizing)
> > > > > +by specifying equal
> > > > > +.I old_size
> > > > > +and
> > > > > +.I new_size
> > > > > +and using the
> > > > > +.B MREMAP_FIXED
> > > > > +flag
> > > > > +(see below).
> > > > > +Since Linux 6.17,
> > > > > +while
> > > > > +.I old_address
> > > > > +must reside within a mapping,
> > > >
> > > > I don't understand this.  What does it mean that old_address must reside
> > > > within a mapping?  It's a point, not a size, so I'm not sure I
> > > > understand it.
> > >
> > > I think if it were a size it would be more confusing no?
> > >
> > > It's an address, the address must be located within an existing memory mapping.
> >
> > What I don't understand is: how could you not comply with that?  Could
> > you pass some old_address that is in two mappings?  Being a single
> > address, that would be impossible, right?
> 
> It can be in an unmapped area. It's either in an unmapped area or a mapped one.
> 
> I could simply reword this as 'old_address must be mapped'?

Yup, that seems better.  Thanks!

Cheers,
Alex

> > > Will replace with 'located' for clarity.
> > >
> > > >
> > > > > +.I old_size
> > > > > +may span multiple mappings
> > > > > +which do not have to be
> > > > > +adjacent to one another when
> > > > > +performing a move like this.
> >
> >
> > Have a lovely day!
> > Alex
> >
> > --
> > <https://www.alejandro-colomar.es/>

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v3 00/12] man2: document "new" mount API
From: Alejandro Colomar @ 2025-08-11 11:27 UTC (permalink / raw)
  To: Aleksa Sarai
  Cc: Askar Safin, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <2025-08-09.1754760145-silky-magic-obituary-sting-3OnpC7@cyphar.com>

[-- Attachment #1: Type: text/plain, Size: 2154 bytes --]

Hi Aleksa,

On Sun, Aug 10, 2025 at 03:32:25AM +1000, Aleksa Sarai wrote:
> On 2025-08-09, Askar Safin <safinaskar@zohomail.com> wrote:
> > I plan to do a lot of testing of "new" mount API on my computer.
> > It is quiet possible that I will find some bugs in these manpages during testing.
> > (I already found some, but I'm not sure.)
> > I think this will take 3-7 days.
> > So, Alejandro Colomar, please, don't merge this patchset until then.
> 
> I don't plan to work on this again for the next week at least (I've
> already spent over a week on these docs -- writing, rewriting, and then
> rewriting once more for good measure; I've started seeing groff in my
> nightmares...), so I will go through review comments after you're done.
>
> There are some rough edges on these APIs I found while writing these
> docs, so I plan to fix those this cycle if possible (hopefully those
> aren't the bugs you said you found in the docs). Two of the fixes have
> already been merged in the vfs tree for 6.18 (the -ENODATA handling bug,
> as well as a bug in open_tree_attr() that would've let userspace trigger
> UAFs). (Once 6.18 is out, I will send a follow-up patchset to document
> the fixes.)
> 
> FYI, I've already fixed the few ".BR \% FOO" typos. (My terminal font
> doesn't have a bold typeface, so when reviewing the rendered man-pages,
> mistakes involving .B are hard to spot.)

You can review in PDF if you want.  See the pdfman(1) script under
src/bin/.  It's quite portable:

	$ cat src/bin/pdfman 
	#!/bin/bash
	#
	# Copyright, the authors of the Linux man-pages project
	# SPDX-License-Identifier: GPL-3.0-or-later

	set -Eeuo pipefail;
	shopt -s lastpipe;

	printf '%s\n' "${!#}.XXXXXX" \
	| sed 's,.*/,,' \
	| xargs mktemp -t \
	| read -r tmp;

	man -Tpdf "$@" >"$tmp";
	xdg-open "$tmp";

It works essentially like man(1), so you can pass any man(7) file as its
argument to read it as a PDF.

(You may or may not have it available in your system, if your distro
 packages a recent enough version of the project.)


Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* [PATCH v5 0/3] man/man2/mremap.2: describe multiple mapping move, shrink
From: Lorenzo Stoakes @ 2025-08-11 14:59 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api

We have added new functionality to mremap() in Linux 6.17, permitting the
move of multiple VMAs when performing a move alone (that is - providing
MREMAP_MAYMOVE | MREMAP_FIXED flags and specifying old_size == new_size).

We document this new feature.

Additionally, we document previously undocumented behaviour around
shrinking of input VMA ranges which permits the input range to span
multiple VMAs.

v5:
* Reword point about 'old_address' needing to be in a mapped range more clearly
  as per Alejandro.
* Update wording accordingly around this, e.g. referencing unmapped areas
  between mappings to be consistent.
* Minor wording fixup stating that the MREMAP_DONTUNMAP flag may _also_ be
  specified.
* Separated out adding a section on 'pure' moves and describing the new
  behaviour, as per Alejandro.
* Update the commit message of 2/3 to reflect the above.
* Removed erroneously introduced blank line in 2/3 as per Alejandro.

v4:
* Update description of newly discovered mremap() behaviour to highlight the
  fact that, if in-place, [old_address, old_address + new_length) may span
  multiple VMAs also.
* Fix up commit message for 2/2 to correct typo on specified range.
* Added code sample to 1/2 as per Alejandro.
https://lore.kernel.org/all/cover.1754414738.git.lorenzo.stoakes@oracle.com/

v3:
* Use more precise language around mremap() move description as per Jann.
* Fix some typos in commit messages.
https://lore.kernel.org/all/cover.1753795807.git.lorenzo.stoakes@oracle.com/

v2:
* Split out the two man page changes as requested by Alejandro.
https://lore.kernel.org/all/cover.1753711160.git.lorenzo.stoakes@oracle.com/

v1:
https://lore.kernel.org/all/20250723174634.75054-1-lorenzo.stoakes@oracle.com/

Lorenzo Stoakes (3):
  man/man2/mremap.2: explicitly document the simple move operation
  man/man2/mremap.2: describe multiple mapping move
  man/man2/mremap.2: describe previously undocumented shrink behaviour

 man/man2/mremap.2 | 109 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 98 insertions(+), 11 deletions(-)

--
2.50.1

^ permalink raw reply

* [PATCH v5 2/3] man/man2/mremap.2: describe multiple mapping move
From: Lorenzo Stoakes @ 2025-08-11 14:59 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <cover.1754924278.git.lorenzo.stoakes@oracle.com>

Document the new behaviour introduced in Linux 6.17 whereby it is now
possible to move multiple mappings in a single operation, as long as the
operation is purely a move, that is old_size is equal to new_size and
MREMAP_FIXED is specified.

This change also explains the limitations of of this method and the
possibility of partial failure.

Finally, we pluralise language where it makes sense to so the documentation
does not contradict either this new capability nor the pre-existing edge
case.

Example code is enclosed below demonstrating the behaviour which is now
possible:

int main(void)
{
	unsigned long page_size = sysconf(_SC_PAGESIZE);
	void *ptr = mmap(NULL, 10 * page_size, PROT_READ | PROT_WRITE,
			 MAP_ANON | MAP_PRIVATE, -1, 0);
	void *tgt_ptr = mmap(NULL, 10 * page_size, PROT_NONE,
			     MAP_ANON | MAP_PRIVATE, -1, 0);
	int i;

	if (ptr == MAP_FAILED || tgt_ptr == MAP_FAILED) {
		perror("mmap");
		return EXIT_FAILURE;
	}

	/* Unmap every other page. */
	for (i = 1; i < 10; i += 2)
		munmap(ptr + i * page_size, page_size);

	/* Now move all 5 distinct mappings to tgt_ptr. */
	ptr = mremap(ptr, 10 * page_size, 10 * page_size,
		     MREMAP_MAYMOVE | MREMAP_FIXED, tgt_ptr);
	if (ptr == MAP_FAILED) {
		perror("mremap");
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}

Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
 man/man2/mremap.2 | 68 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 57 insertions(+), 11 deletions(-)

diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
index 4e3c8e54e..6d14bf627 100644
--- a/man/man2/mremap.2
+++ b/man/man2/mremap.2
@@ -35,22 +35,36 @@ and using the
 .B MREMAP_FIXED
 flag
 (see below).
+Since Linux 6.17,
+while
+.I old_address
+must be mapped,
+.I old_size
+may span multiple mappings
+including unmapped areas between
+them when performing a move like this.
 The
 .B MREMAP_DONTUNMAP
 flag may also be specified.
 .P
+If the operation is not
+simply moving mappings,
+then
+.I old_size
+must span only a single mapping.
+.P
 .I old_address
-is the old address of the virtual memory block that you
-want to expand (or shrink).
+is the old address of the first virtual memory block that you
+want to expand, shrink, and/or move.
 Note that
 .I old_address
 has to be page aligned.
 .I old_size
-is the old size of the
-virtual memory block.
+is the size of the range containing
+virtual memory blocks to be manipulated.
 .I new_size
 is the requested size of the
-virtual memory block after the resize.
+virtual memory blocks after the resize.
 An optional fifth argument,
 .IR new_address ,
 may be provided; see the description of
@@ -119,13 +133,42 @@ If
 is specified, then
 .B MREMAP_MAYMOVE
 must also be specified.
+.IP
+Since Linux 6.17,
+if
+.I old_size
+is equal to
+.I new_size
+and
+.B MREMAP_FIXED
+is specified, then
+.I old_size
+may span beyond the mapping in which
+.I old_address
+resides.
+In this case,
+gaps between mappings in the original range
+are maintained in the new range.
+The whole operation is performed atomically
+unless an error arises,
+in which case the operation may be partially
+completed,
+that is,
+some mappings may be moved and others not.
+.IP
+Moving multiple mappings is not permitted if
+any of those mappings have either
+been registered with
+.BR userfaultfd (2) ,
+or map drivers that
+specify their own custom address mapping logic.
 .TP
 .BR MREMAP_DONTUNMAP " (since Linux 5.7)"
 .\" commit e346b3813067d4b17383f975f197a9aa28a3b077
 This flag, which must be used in conjunction with
 .BR MREMAP_MAYMOVE ,
-remaps a mapping to a new address but does not unmap the mapping at
-.IR old_address .
+remaps mappings to a new address but does not unmap them
+from their original address.
 .IP
 The
 .B MREMAP_DONTUNMAP
@@ -163,13 +206,13 @@ mapped.
 See NOTES for some possible applications of
 .BR MREMAP_DONTUNMAP .
 .P
-If the memory segment specified by
+If the memory segments specified by
 .I old_address
 and
 .I old_size
-is locked (using
+are locked (using
 .BR mlock (2)
-or similar), then this lock is maintained when the segment is
+or similar), then this lock is maintained when the segments are
 resized and/or relocated.
 As a consequence, the amount of memory locked by the process may change.
 .SH RETURN VALUE
@@ -202,7 +245,10 @@ virtual memory address for this process.
 You can also get
 .B EFAULT
 even if there exist mappings that cover the
-whole address space requested, but those mappings are of different types.
+whole address space requested, but those mappings are of different types,
+and the
+.BR mremap ()
+operation being performed does not support this.
 .TP
 .B EINVAL
 An invalid argument was given.
-- 
2.50.1


^ permalink raw reply related

* [PATCH v5 1/3] man/man2/mremap.2: explicitly document the simple move operation
From: Lorenzo Stoakes @ 2025-08-11 14:59 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <cover.1754924278.git.lorenzo.stoakes@oracle.com>

In preparation for discussing newly introduced mremap() behaviour to permit
the move of multiple mappings at once, add a section to the mremap.2 man
page to describe these operations in general.

Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
 man/man2/mremap.2 | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
index 2168ca728..4e3c8e54e 100644
--- a/man/man2/mremap.2
+++ b/man/man2/mremap.2
@@ -25,6 +25,20 @@ moving it at the same time (controlled by the
 argument and
 the available virtual address space).
 .P
+Mappings can also simply be moved
+(without any resizing)
+by specifying equal
+.I old_size
+and
+.I new_size
+and using the
+.B MREMAP_FIXED
+flag
+(see below).
+The
+.B MREMAP_DONTUNMAP
+flag may also be specified.
+.P
 .I old_address
 is the old address of the virtual memory block that you
 want to expand (or shrink).
-- 
2.50.1


^ permalink raw reply related

* [PATCH v5 3/3] man/man2/mremap.2: describe previously undocumented shrink behaviour
From: Lorenzo Stoakes @ 2025-08-11 14:59 UTC (permalink / raw)
  To: Alejandro Colomar
  Cc: linux-man, Andrew Morton, Peter Xu, Alexander Viro,
	Christian Brauner, Jan Kara, Liam R . Howlett, Vlastimil Babka,
	Jann Horn, Pedro Falcato, Rik van Riel, linux-mm, linux-kernel,
	linux-api
In-Reply-To: <cover.1754924278.git.lorenzo.stoakes@oracle.com>

There is pre-existing logic that appears to be undocumented for an mremap()
shrink operation, where it turns out that the usual 'input range must span
a single mapping' requirement no longer applies.

In fact, it turns out that the input range specified by [old_address,
old_address + old_size) may span any number of mappings.

If shrinking in-place (that is, neither the MREMAP_FIXED nor
MREMAP_DONTUNMAP flags are specified), then the new span may also span any
number of VMAs - [old_address, old_address + new_size).

If shrinking and moving, the range specified by [old_address, old_address +
new_size) must span a single VMA.

There must be at least one VMA contained within the [old_address,
old_address + old_size) range, and old_address must be within the range of
a VMA.

Explicitly document this.

Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
 man/man2/mremap.2 | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/man/man2/mremap.2 b/man/man2/mremap.2
index 6d14bf627..53d4eda29 100644
--- a/man/man2/mremap.2
+++ b/man/man2/mremap.2
@@ -47,8 +47,35 @@ The
 .B MREMAP_DONTUNMAP
 flag may also be specified.
 .P
-If the operation is not
-simply moving mappings,
+Equally, if the operation performs a shrink,
+that is if
+.I old_size
+is greater than
+.IR new_size ,
+then
+.I old_size
+may also span multiple mappings
+which do not have to be
+adjacent to one another.
+If this shrink is performed
+in-place,
+that is,
+neither
+.BR MREMAP_FIXED ,
+nor
+.B MREMAP_DONTUNMAP
+are specified,
+.I new_size
+may also span multiple VMAs.
+However, if the range is moved,
+then
+.I new_size
+must span only a single mapping.
+.P
+If the operation is neither a
+.B MREMAP_FIXED
+move
+nor a shrink,
 then
 .I old_size
 must span only a single mapping.
-- 
2.50.1


^ permalink raw reply related

* Re: [PATCH v3 26/30] mm: shmem: use SHMEM_F_* flags instead of VM_* flags
From: Vipin Sharma @ 2025-08-11 23:11 UTC (permalink / raw)
  To: Pasha Tatashin
  Cc: pratyush, jasonmiu, graf, changyuanl, rppt, dmatlack, rientjes,
	corbet, rdunlap, ilpo.jarvinen, kanie, ojeda, aliceryhl,
	masahiroy, akpm, tj, yoann.congal, mmaurer, roman.gushchin,
	chenridong, axboe, mark.rutland, jannh, vincent.guittot, hannes,
	dan.j.williams, david, joel.granados, rostedt, anna.schumaker,
	song, zhangguopeng, linux, linux-kernel, linux-doc, linux-mm,
	gregkh, tglx, mingo, bp, dave.hansen, x86, hpa, rafael, dakr,
	bartosz.golaszewski, cw00.choi, myungjoo.ham, yesanishhere,
	Jonathan.Cameron, quic_zijuhu, aleksander.lobakin, ira.weiny,
	andriy.shevchenko, leon, lukas, bhelgaas, wagi, djeffery,
	stuart.w.hayes, ptyadav, lennart, brauner, linux-api,
	linux-fsdevel, saeedm, ajayachandra, jgg, parav, leonro, witu
In-Reply-To: <20250807014442.3829950-27-pasha.tatashin@soleen.com>

On 2025-08-07 01:44:32, Pasha Tatashin wrote:
> From: Pratyush Yadav <ptyadav@amazon.de>
> @@ -3123,7 +3123,9 @@ static struct inode *__shmem_get_inode(struct mnt_idmap *idmap,
>  	spin_lock_init(&info->lock);
>  	atomic_set(&info->stop_eviction, 0);
>  	info->seals = F_SEAL_SEAL;
> -	info->flags = flags & VM_NORESERVE;
> +	info->flags = 0;

This is not needed as the 'info' is being set to 0 just above
spin_lock_init.

> +	if (flags & VM_NORESERVE)
> +		info->flags |= SHMEM_F_NORESERVE;

As info->flags will be 0, this can be just direct assignment '='.

>  	info->i_crtime = inode_get_mtime(inode);
>  	info->fsflags = (dir == NULL) ? 0 :
>  		SHMEM_I(dir)->fsflags & SHMEM_FL_INHERITED;
> @@ -5862,8 +5864,10 @@ static inline struct inode *shmem_get_inode(struct mnt_idmap *idmap,
>  /* common code */
>  
>  static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name,
> -			loff_t size, unsigned long flags, unsigned int i_flags)
> +				       loff_t size, unsigned long vm_flags,
> +				       unsigned int i_flags)

Nit: Might be just my editor, but this alignment seems off.

>  {
> +	unsigned long flags = (vm_flags & VM_NORESERVE) ? SHMEM_F_NORESERVE : 0;
>  	struct inode *inode;
>  	struct file *res;
>  
> @@ -5880,7 +5884,7 @@ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name,
>  		return ERR_PTR(-ENOMEM);
>  
>  	inode = shmem_get_inode(&nop_mnt_idmap, mnt->mnt_sb, NULL,
> -				S_IFREG | S_IRWXUGO, 0, flags);
> +				S_IFREG | S_IRWXUGO, 0, vm_flags);
>  	if (IS_ERR(inode)) {
>  		shmem_unacct_size(flags, size);
>  		return ERR_CAST(inode);
> -- 
> 2.50.1.565.gc32cd1483b-goog
> 

^ permalink raw reply

* Re: [PATCH v3 07/12] man/man2/fsmount.2: document "new" mount API
From: Askar Safin @ 2025-08-12  9:16 UTC (permalink / raw)
  To: Aleksa Sarai
  Cc: Alejandro Colomar, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <20250809-new-mount-api-v3-7-f61405c80f34@cyphar.com>

fsmount:
> Unlike open_tree(2) with OPEN_TREE_CLONE, fsmount() can only be called once in the lifetime of a filesystem instance to produce a mount object.

I don't understand what you meant here. This phrase in its current form is wrong.
Consider this scenario: we did this:
fsopen(...)
fsconfig(..., FSCONFIG_SET_STRING, "source", ...)
fsconfig(..., FSCONFIG_CMD_CREATE, ...)
fsmount(...)
fsopen(...)
fsconfig(..., FSCONFIG_SET_STRING, "source", ...)
fsconfig(..., FSCONFIG_CMD_CREATE, ...)
fsmount(...)

We used FSCONFIG_CMD_CREATE here as opposed to FSCONFIG_CMD_CREATE_EXCL, thus
it is possible that second fsmount will return mount for the same superblock.
Thus that statement "fsmount() can only be called once in the lifetime of a filesystem instance to produce a mount object"
is not true.

--
Askar Safin
https://types.pl/@safinaskar


^ permalink raw reply

* Re: [PATCH v3 08/12] man/man2/move_mount.2: document "new" mount API
From: Askar Safin @ 2025-08-12 10:00 UTC (permalink / raw)
  To: Aleksa Sarai
  Cc: Alejandro Colomar, Michael T. Kerrisk, Alexander Viro, Jan Kara,
	G. Branden Robinson, linux-man, linux-api, linux-fsdevel,
	linux-kernel, David Howells, Christian Brauner
In-Reply-To: <20250809-new-mount-api-v3-8-f61405c80f34@cyphar.com>

move_mount for v2 contained this:
> Mounts cannot be moved beneath the rootfs

In v3 you changed this to this:
> Mount objects cannot be attached beneath the filesystem root

You made this phrase worse.

"Filesystem root" can be understood as "root of superblock".
So, please, change this to "root directory" or something.

> This would create a new bind-mount of /home/cyphar as attached mount object, and then attach
You meant "as detached mount object"

Also: I see that you addressed all my v2 comments. Thank you!

--
Askar Safin
https://types.pl/@safinaskar


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox