From 2516a8782158a1d420aa00ce5f470a33cc7ec2ca Mon Sep 17 00:00:00 2001 From: Matthew Macy Date: Thu, 10 Oct 2019 15:59:34 -0700 Subject: Move get_temporary_prop to platform code Temporary property handling at the VFS layer requires platform specific code. Reviewed-by: Sean Eric Fagan Reviewed-by: Brian Behlendorf Reviewed-by: Jorgen Lundman Signed-off-by: Matt Macy Closes #9401 --- include/os/linux/zfs/sys/zfs_vfsops.h | 2 + module/os/linux/zfs/zfs_vfsops.c | 75 +++++++++++++++++++++++++++++ module/zfs/zcp_get.c | 88 +++-------------------------------- 3 files changed, 84 insertions(+), 81 deletions(-) diff --git a/include/os/linux/zfs/sys/zfs_vfsops.h b/include/os/linux/zfs/sys/zfs_vfsops.h index 34d957bcb..3a959996f 100644 --- a/include/os/linux/zfs/sys/zfs_vfsops.h +++ b/include/os/linux/zfs/sys/zfs_vfsops.h @@ -224,6 +224,8 @@ extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp); extern int zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp); extern int zfs_prune(struct super_block *sb, unsigned long nr_to_scan, int *objects); +extern int zfs_get_temporary_prop(dsl_dataset_t *ds, zfs_prop_t zfs_prop, + uint64_t *val, char *setpoint); #ifdef __cplusplus } diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index c77a23759..d0771fa6f 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -533,6 +533,81 @@ unregister: return (error); } +/* + * Takes a dataset, a property, a value and that value's setpoint as + * found in the ZAP. Checks if the property has been changed in the vfs. + * If so, val and setpoint will be overwritten with updated content. + * Otherwise, they are left unchanged. + */ +int +zfs_get_temporary_prop(dsl_dataset_t *ds, zfs_prop_t zfs_prop, uint64_t *val, + char *setpoint) +{ + int error; + zfsvfs_t *zfvp; + vfs_t *vfsp; + objset_t *os; + uint64_t tmp = *val; + + error = dmu_objset_from_ds(ds, &os); + if (error != 0) + return (error); + + if (dmu_objset_type(os) != DMU_OST_ZFS) + return (EINVAL); + + mutex_enter(&os->os_user_ptr_lock); + zfvp = dmu_objset_get_user(os); + mutex_exit(&os->os_user_ptr_lock); + if (zfvp == NULL) + return (ESRCH); + + vfsp = zfvp->z_vfs; + + switch (zfs_prop) { + case ZFS_PROP_ATIME: + if (vfsp->vfs_do_atime) + tmp = vfsp->vfs_atime; + break; + case ZFS_PROP_RELATIME: + if (vfsp->vfs_do_relatime) + tmp = vfsp->vfs_relatime; + break; + case ZFS_PROP_DEVICES: + if (vfsp->vfs_do_devices) + tmp = vfsp->vfs_devices; + break; + case ZFS_PROP_EXEC: + if (vfsp->vfs_do_exec) + tmp = vfsp->vfs_exec; + break; + case ZFS_PROP_SETUID: + if (vfsp->vfs_do_setuid) + tmp = vfsp->vfs_setuid; + break; + case ZFS_PROP_READONLY: + if (vfsp->vfs_do_readonly) + tmp = vfsp->vfs_readonly; + break; + case ZFS_PROP_XATTR: + if (vfsp->vfs_do_xattr) + tmp = vfsp->vfs_xattr; + break; + case ZFS_PROP_NBMAND: + if (vfsp->vfs_do_nbmand) + tmp = vfsp->vfs_nbmand; + break; + default: + return (ENOENT); + } + + if (tmp != *val) { + (void) strcpy(setpoint, "temporary"); + *val = tmp; + } + return (0); +} + static int zfs_space_delta_cb(dmu_object_type_t bonustype, void *data, uint64_t *userp, uint64_t *groupp, uint64_t *projectp) diff --git a/module/zfs/zcp_get.c b/module/zfs/zcp_get.c index 974d3328c..fdf566d27 100644 --- a/module/zfs/zcp_get.c +++ b/module/zfs/zcp_get.c @@ -212,85 +212,6 @@ get_dsl_dir_prop(dsl_dataset_t *ds, zfs_prop_t zfs_prop, return (0); } -/* - * Takes a dataset, a property, a value and that value's setpoint as - * found in the ZAP. Checks if the property has been changed in the vfs. - * If so, val and setpoint will be overwritten with updated content. - * Otherwise, they are left unchanged. - */ -static int -get_temporary_prop(dsl_dataset_t *ds, zfs_prop_t zfs_prop, uint64_t *val, - char *setpoint) -{ -#if !defined(_KERNEL) - return (0); -#else - int error; - zfsvfs_t *zfvp; - vfs_t *vfsp; - objset_t *os; - uint64_t tmp = *val; - - error = dmu_objset_from_ds(ds, &os); - if (error != 0) - return (error); - - if (dmu_objset_type(os) != DMU_OST_ZFS) - return (EINVAL); - - mutex_enter(&os->os_user_ptr_lock); - zfvp = dmu_objset_get_user(os); - mutex_exit(&os->os_user_ptr_lock); - if (zfvp == NULL) - return (ESRCH); - - vfsp = zfvp->z_vfs; - - switch (zfs_prop) { - case ZFS_PROP_ATIME: - if (vfsp->vfs_do_atime) - tmp = vfsp->vfs_atime; - break; - case ZFS_PROP_RELATIME: - if (vfsp->vfs_do_relatime) - tmp = vfsp->vfs_relatime; - break; - case ZFS_PROP_DEVICES: - if (vfsp->vfs_do_devices) - tmp = vfsp->vfs_devices; - break; - case ZFS_PROP_EXEC: - if (vfsp->vfs_do_exec) - tmp = vfsp->vfs_exec; - break; - case ZFS_PROP_SETUID: - if (vfsp->vfs_do_setuid) - tmp = vfsp->vfs_setuid; - break; - case ZFS_PROP_READONLY: - if (vfsp->vfs_do_readonly) - tmp = vfsp->vfs_readonly; - break; - case ZFS_PROP_XATTR: - if (vfsp->vfs_do_xattr) - tmp = vfsp->vfs_xattr; - break; - case ZFS_PROP_NBMAND: - if (vfsp->vfs_do_nbmand) - tmp = vfsp->vfs_nbmand; - break; - default: - return (ENOENT); - } - - if (tmp != *val) { - (void) strcpy(setpoint, "temporary"); - *val = tmp; - } - return (0); -#endif -} - /* * Check if the property we're looking for is stored at the dsl_dataset or * dsl_dir level. If so, push the property value and source onto the lua stack @@ -547,9 +468,14 @@ get_zap_prop(lua_State *state, dsl_dataset_t *ds, zfs_prop_t zfs_prop) error = dsl_prop_get_ds(ds, prop_name, sizeof (numval), 1, &numval, setpoint); +#ifdef _KERNEL /* Fill in temporary value for prop, if applicable */ - (void) get_temporary_prop(ds, zfs_prop, &numval, setpoint); - + (void) zfs_get_temporary_prop(ds, zfs_prop, &numval, setpoint); +#else + return (luaL_error(state, + "temporary properties only supported in kernel mode", + prop_name)); +#endif /* Push value to lua stack */ if (prop_type == PROP_TYPE_INDEX) { const char *propval; -- cgit v1.2.3