libzfs: use mount_setattr for selective remount including legacy mounts

When a namespace property is changed via zfs set, libzfs remounts the
filesystem to propagate the new VFS mount flags. The current approach
uses mount(2) with MS_REMOUNT, which reads all namespace properties
from ZFS and applies them together. This has two problems:

1. Linux VFS resets unspecified per-mount flags on remount. If an
   administrator sets a temporary flag (e.g. mount -o remount,noatime),
   a subsequent zfs set on any namespace property clobbers it.

2. Two concurrent zfs set operations on different namespace properties
   can overwrite each other's mount flags.

Additionally, legacy datasets (mountpoint=legacy) were never remounted
on namespace property changes since zfs_is_mountable() returns false
for them.

Add zfs_mount_setattr() which uses mount_setattr(2) to selectively
update only the mount flags that correspond to the changed property.
For legacy datasets, /proc/mounts is iterated to update all
mountpoints. On kernels without mount_setattr (ENOSYS), non-legacy
datasets fall back to a full remount; legacy mounts are skipped to
avoid clobbering temporary flags.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #18257
This commit is contained in:
Ameer Hamza
2026-03-09 23:06:22 +05:00
committed by GitHub
parent d45c8d6489
commit 1eace59060
7 changed files with 247 additions and 26 deletions
+27
View File
@@ -0,0 +1,27 @@
dnl # SPDX-License-Identifier: CDDL-1.0
dnl #
dnl # Check for mount_setattr() and struct mount_attr availability
dnl #
AC_DEFUN([ZFS_AC_CONFIG_USER_MOUNT_SETATTR], [
AC_CHECK_FUNC([mount_setattr], [
AC_MSG_CHECKING([for struct mount_attr])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([[
#include <sys/mount.h>
]], [[
struct mount_attr attr = {
.attr_set = MOUNT_ATTR_RDONLY,
.attr_clr = MOUNT_ATTR_NOEXEC,
};
(void) attr;
]])
], [
AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_MOUNT_SETATTR], [1],
[mount_setattr() and struct mount_attr
are available])
], [
AC_MSG_RESULT([no])
])
])
])
+1
View File
@@ -20,6 +20,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [
ZFS_AC_CONFIG_USER_LIBUUID
ZFS_AC_CONFIG_USER_LIBBLKID
ZFS_AC_CONFIG_USER_STATX
ZFS_AC_CONFIG_USER_MOUNT_SETATTR
])
ZFS_AC_CONFIG_USER_LIBTIRPC
ZFS_AC_CONFIG_USER_LIBCRYPTO