diff --git a/include/sys/zfs_ioctl_impl.h b/include/sys/zfs_ioctl_impl.h index 787475cf39..5774e9e0e3 100644 --- a/include/sys/zfs_ioctl_impl.h +++ b/include/sys/zfs_ioctl_impl.h @@ -82,6 +82,7 @@ void zfs_ioctl_register(const char *, zfs_ioc_t, zfs_ioc_func_t *, boolean_t, boolean_t, const zfs_ioc_key_t *, size_t); uint64_t zfs_max_nvlist_src_size_os(void); +void zfs_ioctl_update_mount_cache(const char *dsname); void zfs_ioctl_init_os(void); boolean_t zfs_vfs_held(zfsvfs_t *); diff --git a/lib/libspl/os/freebsd/mnttab.c b/lib/libspl/os/freebsd/mnttab.c index 5b9e6429d9..bd3e3e4e3e 100644 --- a/lib/libspl/os/freebsd/mnttab.c +++ b/lib/libspl/os/freebsd/mnttab.c @@ -140,14 +140,14 @@ statfs_init(void) free(gsfs); gsfs = NULL; } - allfs = getfsstat(NULL, 0, MNT_WAIT); + allfs = getfsstat(NULL, 0, MNT_NOWAIT); if (allfs == -1) goto fail; gsfs = malloc(sizeof (gsfs[0]) * allfs * 2); if (gsfs == NULL) goto fail; allfs = getfsstat(gsfs, (long)(sizeof (gsfs[0]) * allfs * 2), - MNT_WAIT); + MNT_NOWAIT); if (allfs == -1) goto fail; sfs = realloc(gsfs, allfs * sizeof (gsfs[0])); diff --git a/module/os/freebsd/zfs/zfs_ioctl_os.c b/module/os/freebsd/zfs/zfs_ioctl_os.c index 0e0c16033b..7f7e2b72c5 100644 --- a/module/os/freebsd/zfs/zfs_ioctl_os.c +++ b/module/os/freebsd/zfs/zfs_ioctl_os.c @@ -138,6 +138,23 @@ zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) return (error); } +/* Update the VFS's cache of mountpoint properties */ +void +zfs_ioctl_update_mount_cache(const char *dsname) +{ + zfsvfs_t *zfsvfs; + + if (getzfsvfs(dsname, &zfsvfs) == 0) { + struct mount *mp = zfsvfs->z_vfs; + VFS_STATFS(mp, &mp->mnt_stat); + zfs_vfs_rele(zfsvfs); + } + /* + * Ignore errors; we can't do anything useful if either getzfsvfs or + * VFS_STATFS fails. + */ +} + uint64_t zfs_max_nvlist_src_size_os(void) { diff --git a/module/os/linux/zfs/zfs_ioctl_os.c b/module/os/linux/zfs/zfs_ioctl_os.c index 812f9c0ea1..79b9d777dc 100644 --- a/module/os/linux/zfs/zfs_ioctl_os.c +++ b/module/os/linux/zfs/zfs_ioctl_os.c @@ -212,6 +212,12 @@ zfs_max_nvlist_src_size_os(void) return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024)); } +/* Update the VFS's cache of mountpoint properties */ +void +zfs_ioctl_update_mount_cache(const char *dsname) +{ +} + void zfs_ioctl_init_os(void) { diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 7f929df167..b0eee81beb 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -2521,6 +2521,26 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, return (err); } +static boolean_t +zfs_is_namespace_prop(zfs_prop_t prop) +{ + switch (prop) { + + case ZFS_PROP_ATIME: + case ZFS_PROP_RELATIME: + case ZFS_PROP_DEVICES: + case ZFS_PROP_EXEC: + case ZFS_PROP_SETUID: + case ZFS_PROP_READONLY: + case ZFS_PROP_XATTR: + case ZFS_PROP_NBMAND: + return (B_TRUE); + + default: + return (B_FALSE); + } +} + /* * This function is best effort. If it fails to set any of the given properties, * it continues to set as many as it can and returns the last error @@ -2540,6 +2560,7 @@ zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl, int rv = 0; uint64_t intval; const char *strval; + boolean_t should_update_mount_cache = B_FALSE; nvlist_t *genericnvl = fnvlist_alloc(); nvlist_t *retrynvl = fnvlist_alloc(); @@ -2637,6 +2658,9 @@ retry: fnvlist_add_int32(errlist, propname, err); rv = err; } + + if (zfs_is_namespace_prop(prop)) + should_update_mount_cache = B_TRUE; } if (nvl != retrynvl && !nvlist_empty(retrynvl)) { @@ -2685,6 +2709,9 @@ retry: } } } + if (should_update_mount_cache) + zfs_ioctl_update_mount_cache(dsname); + nvlist_free(genericnvl); nvlist_free(retrynvl);