File k5.6.3.patch of Package zfs08x

diff -Npaur a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4
--- a/config/kernel-inode-times.m4	2020-01-22 16:49:01.000000000 -0500
+++ b/config/kernel-inode-times.m4	2020-02-27 12:40:52.273139053 -0500
@@ -1,8 +1,22 @@
-dnl #
-dnl # 4.18 API change
-dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64.
-dnl #
 AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES], [
+
+	dnl #
+	dnl # 5.6 API change
+	dnl # timespec64_trunc() replaced by timestamp_truncate() interface.
+	dnl #
+	ZFS_LINUX_TEST_SRC([timestamp_truncate], [
+		#include <linux/fs.h>
+	],[
+		struct timespec64 ts;
+		struct inode ip;
+
+		ts = timestamp_truncate(ts, &ip);
+	])
+
+	dnl #
+	dnl # 4.18 API change
+	dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64.
+	dnl #
 	ZFS_LINUX_TEST_SRC([inode_times], [
 		#include <linux/fs.h>
 	],[
@@ -15,6 +29,15 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_TIMES]
 ])
 
 AC_DEFUN([ZFS_AC_KERNEL_INODE_TIMES], [
+	AC_MSG_CHECKING([whether timestamp_truncate() exists])
+	ZFS_LINUX_TEST_RESULT([timestamp_truncate], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_INODE_TIMESTAMP_TRUNCATE, 1,
+		    [timestamp_truncate() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+
 	AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
 	ZFS_LINUX_TEST_RESULT([inode_times], [
 		AC_MSG_RESULT(no)
diff -Npaur a/config/kernel-ktime_get_coarse_real_ts64.m4 b/config/kernel-ktime_get_coarse_real_ts64.m4
--- a/config/kernel-ktime_get_coarse_real_ts64.m4	2020-01-22 16:49:01.000000000 -0500
+++ b/config/kernel-ktime_get_coarse_real_ts64.m4	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-dnl #
-dnl # 4.18: ktime_get_coarse_real_ts64() added.  Use it in place of
-dnl # current_kernel_time64().
-dnl #
-AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64], [
-	ZFS_LINUX_TEST_SRC([ktime_get_coarse_real_ts64], [
-		#include <linux/mm.h>
-	], [
-		struct timespec64 ts;
-		ktime_get_coarse_real_ts64(&ts);
-	])
-])
-
-AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64], [
-	AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists])
-	ZFS_LINUX_TEST_RESULT([ktime_get_coarse_real_ts64], [
-		AC_MSG_RESULT(yes)
-		AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1,
-		    [ktime_get_coarse_real_ts64() exists])
-	], [
-		AC_MSG_RESULT(no)
-	])
-])
diff -Npaur a/config/kernel-ktime.m4 b/config/kernel-ktime.m4
--- a/config/kernel-ktime.m4	1969-12-31 19:00:00.000000000 -0500
+++ b/config/kernel-ktime.m4	2020-02-27 12:40:52.273139053 -0500
@@ -0,0 +1,55 @@
+dnl #
+dnl # 4.18: ktime_get_coarse_real_ts64() replaces current_kernel_time64().
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64], [
+	ZFS_LINUX_TEST_SRC([ktime_get_coarse_real_ts64], [
+		#include <linux/mm.h>
+	], [
+		struct timespec64 ts;
+		ktime_get_coarse_real_ts64(&ts);
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64], [
+	AC_MSG_CHECKING([whether ktime_get_coarse_real_ts64() exists])
+	ZFS_LINUX_TEST_RESULT([ktime_get_coarse_real_ts64], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_KTIME_GET_COARSE_REAL_TS64, 1,
+		    [ktime_get_coarse_real_ts64() exists])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
+dnl # 4.18: ktime_get_raw_ts64() replaces getrawmonotonic64().
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME_GET_RAW_TS64], [
+	ZFS_LINUX_TEST_SRC([ktime_get_raw_ts64], [
+		#include <linux/mm.h>
+	], [
+		struct timespec64 ts;
+		ktime_get_raw_ts64(&ts);
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_KTIME_GET_RAW_TS64], [
+	AC_MSG_CHECKING([whether ktime_get_raw_ts64() exists])
+	ZFS_LINUX_TEST_RESULT([ktime_get_raw_ts64], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_KTIME_GET_RAW_TS64, 1,
+		    [ktime_get_raw_ts64() exists])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_SRC_KTIME], [
+	ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64
+	ZFS_AC_KERNEL_SRC_KTIME_GET_RAW_TS64
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_KTIME], [
+	ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64
+	ZFS_AC_KERNEL_KTIME_GET_RAW_TS64
+])
diff -Npaur a/config/kernel.m4 b/config/kernel.m4
--- a/config/kernel.m4	2020-01-22 16:49:04.000000000 -0500
+++ b/config/kernel.m4	2020-02-27 12:42:32.805701403 -0500
@@ -54,6 +54,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
 	ZFS_AC_KERNEL_SRC_CURRENT_BIO_TAIL
 	ZFS_AC_KERNEL_SRC_SUPER_USER_NS
 	ZFS_AC_KERNEL_SRC_SUBMIT_BIO
+	ZFS_AC_KERNEL_SRC_PROC_OPERATIONS
 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS
 	ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
 	ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
@@ -136,7 +137,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
 	ZFS_AC_KERNEL_SRC_CURRENT_TIME
 	ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
 	ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
-	ZFS_AC_KERNEL_SRC_KTIME_GET_COARSE_REAL_TS64
+	ZFS_AC_KERNEL_SRC_KTIME
 	ZFS_AC_KERNEL_SRC_TOTALRAM_PAGES_FUNC
 	ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
 	ZFS_AC_KERNEL_SRC_KSTRTOUL
@@ -169,6 +170,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
 	ZFS_AC_KERNEL_TIMER_SETUP
 	ZFS_AC_KERNEL_CURRENT_BIO_TAIL
 	ZFS_AC_KERNEL_SUPER_USER_NS
+	ZFS_AC_KERNEL_PROC_OPERATIONS
 	ZFS_AC_KERNEL_SUBMIT_BIO
 	ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS
 	ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH
@@ -252,7 +254,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
 	ZFS_AC_KERNEL_CURRENT_TIME
 	ZFS_AC_KERNEL_USERNS_CAPABILITIES
 	ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
-	ZFS_AC_KERNEL_KTIME_GET_COARSE_REAL_TS64
+	ZFS_AC_KERNEL_KTIME
 	ZFS_AC_KERNEL_TOTALRAM_PAGES_FUNC
 	ZFS_AC_KERNEL_TOTALHIGH_PAGES
 	ZFS_AC_KERNEL_KSTRTOUL
diff -Npaur a/config/kernel-proc-operations.m4 b/config/kernel-proc-operations.m4
--- a/config/kernel-proc-operations.m4	1969-12-31 19:00:00.000000000 -0500
+++ b/config/kernel-proc-operations.m4	2020-02-27 12:40:52.273139053 -0500
@@ -0,0 +1,41 @@
+dnl #
+dnl # 5.6 API Change
+dnl # The proc_ops structure was introduced to replace the use of
+dnl # of the file_operations structure when registering proc handlers.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_PROC_OPERATIONS], [
+	ZFS_LINUX_TEST_SRC([proc_ops_struct], [
+		#include <linux/proc_fs.h>
+
+		int test_open(struct inode *ip, struct file *fp) { return 0; }
+		ssize_t test_read(struct file *fp, char __user *ptr,
+		    size_t size, loff_t *offp) { return 0; }
+		ssize_t test_write(struct file *fp, const char __user *ptr,
+		    size_t size, loff_t *offp) { return 0; }
+		loff_t test_lseek(struct file *fp, loff_t off, int flag)
+		    { return 0; }
+		int test_release(struct inode *ip, struct file *fp)
+		    { return 0; }
+
+		const struct proc_ops test_ops __attribute__ ((unused)) = {
+			.proc_open      = test_open,
+			.proc_read      = test_read,
+			.proc_write	= test_write,
+			.proc_lseek     = test_lseek,
+			.proc_release   = test_release,
+		};
+	], [
+		struct proc_dir_entry *entry __attribute__ ((unused)) =
+		    proc_create_data("test", 0444, NULL, &test_ops, NULL);
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_PROC_OPERATIONS], [
+	AC_MSG_CHECKING([whether proc_ops structure exists])
+	ZFS_LINUX_TEST_RESULT([proc_ops_struct], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_PROC_OPS_STRUCT, 1, [proc_ops structure exists])
+	], [
+		AC_MSG_RESULT(no)
+	])
+])
diff -Npaur a/include/spl/sys/kstat.h b/include/spl/sys/kstat.h
--- a/include/spl/sys/kstat.h	2020-01-13 17:17:11.000000000 -0500
+++ b/include/spl/sys/kstat.h	2020-02-27 12:40:52.273139053 -0500
@@ -152,6 +152,12 @@ typedef struct kstat_named_s {
 #define	KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.string.addr.ptr)
 #define	KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.string.len)
 
+#ifdef HAVE_PROC_OPS_STRUCT
+typedef struct proc_ops kstat_proc_op_t;
+#else
+typedef struct file_operations kstat_proc_op_t;
+#endif
+
 typedef struct kstat_intr {
 	uint_t intrs[KSTAT_NUM_INTRS];
 } kstat_intr_t;
@@ -197,7 +203,7 @@ extern void kstat_proc_entry_init(kstat_
     const char *module, const char *name);
 extern void kstat_proc_entry_delete(kstat_proc_entry_t *kpep);
 extern void kstat_proc_entry_install(kstat_proc_entry_t *kpep, mode_t mode,
-    const struct file_operations *file_ops, void *data);
+    const kstat_proc_op_t *file_ops, void *data);
 
 extern void __kstat_install(kstat_t *ksp);
 extern void __kstat_delete(kstat_t *ksp);
diff -Npaur a/include/spl/sys/time.h b/include/spl/sys/time.h
--- a/include/spl/sys/time.h	2020-01-13 17:17:11.000000000 -0500
+++ b/include/spl/sys/time.h	2020-02-27 12:40:52.277139075 -0500
@@ -85,7 +85,7 @@ gethrestime(inode_timespec_t *ts)
 #endif
 }
 
-static inline time_t
+static inline uint64_t
 gethrestime_sec(void)
 {
 #if defined(HAVE_INODE_TIMESPEC64_TIMES)
@@ -105,8 +105,13 @@ gethrestime_sec(void)
 static inline hrtime_t
 gethrtime(void)
 {
+#if defined(HAVE_KTIME_GET_RAW_TS64)
+	struct timespec64 ts;
+	ktime_get_raw_ts64(&ts);
+#else
 	struct timespec ts;
 	getrawmonotonic(&ts);
+#endif
 	return (((hrtime_t)ts.tv_sec * NSEC_PER_SEC) + ts.tv_nsec);
 }
 
diff -Npaur a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h
--- a/include/sys/vdev_impl.h	2020-01-13 17:17:11.000000000 -0500
+++ b/include/sys/vdev_impl.h	2020-02-27 12:40:52.277139075 -0500
@@ -274,7 +274,7 @@ struct vdev {
 	range_tree_t	*vdev_initialize_tree;	/* valid while initializing */
 	uint64_t	vdev_initialize_bytes_est;
 	uint64_t	vdev_initialize_bytes_done;
-	time_t		vdev_initialize_action_time;	/* start and end time */
+	uint64_t	vdev_initialize_action_time;	/* start and end time */
 
 	/* TRIM related */
 	boolean_t	vdev_trim_exit_wanted;
@@ -295,7 +295,7 @@ struct vdev {
 	uint64_t	vdev_trim_rate;		/* requested rate (bytes/sec) */
 	uint64_t	vdev_trim_partial;	/* requested partial TRIM */
 	uint64_t	vdev_trim_secure;	/* requested secure TRIM */
-	time_t		vdev_trim_action_time;	/* start and end time */
+	uint64_t	vdev_trim_action_time;	/* start and end time */
 
 	/* for limiting outstanding I/Os (initialize and TRIM) */
 	kmutex_t	vdev_initialize_io_lock;
diff -Npaur a/include/sys/zpl.h b/include/sys/zpl.h
--- a/include/sys/zpl.h	2020-01-13 17:17:11.000000000 -0500
+++ b/include/sys/zpl.h	2020-02-27 12:40:52.277139075 -0500
@@ -188,13 +188,14 @@ zpl_dir_emit_dots(struct file *file, zpl
 }
 #endif /* HAVE_VFS_ITERATE */
 
-/*
- * Linux 4.18, inode times converted from timespec to timespec64.
- */
-#if defined(HAVE_INODE_TIMESPEC64_TIMES)
-#define	zpl_inode_timespec_trunc(ts, gran)	timespec64_trunc(ts, gran)
+#if defined(HAVE_INODE_TIMESTAMP_TRUNCATE)
+#define	zpl_inode_timestamp_truncate(ts, ip)	timestamp_truncate(ts, ip)
+#elif defined(HAVE_INODE_TIMESPEC64_TIMES)
+#define	zpl_inode_timestamp_truncate(ts, ip)	\
+	timespec64_trunc(ts, (ip)->i_sb->s_time_gran)
 #else
-#define	zpl_inode_timespec_trunc(ts, gran)	timespec_trunc(ts, gran)
+#define	zpl_inode_timestamp_truncate(ts, ip)	\
+	timespec_trunc(ts, (ip)->i_sb->s_time_gran)
 #endif
 
 #endif	/* _SYS_ZPL_H */
diff -Npaur a/META b/META
--- a/META	2020-02-26 08:50:05.000000000 -0500
+++ b/META	2020-02-27 12:40:52.277139075 -0500
@@ -6,5 +6,5 @@ Release:      1ubuntu5
 Release-Tags:  relext
 License:       CDDL
 Author:        OpenZFS on Linux
-Linux-Maximum: 5.4
+Linux-Maximum: 5.6
 Linux-Minimum: 2.6.32
diff -Npaur a/module/spl/spl-kstat.c b/module/spl/spl-kstat.c
--- a/module/spl/spl-kstat.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/spl/spl-kstat.c	2020-02-27 12:40:52.277139075 -0500
@@ -507,12 +507,20 @@ proc_kstat_write(struct file *filp, cons
 	return (len);
 }
 
-static struct file_operations proc_kstat_operations = {
+static const kstat_proc_op_t proc_kstat_operations = {
+#ifdef HAVE_PROC_OPS_STRUCT
+	.proc_open	= proc_kstat_open,
+	.proc_write	= proc_kstat_write,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= seq_release,
+#else
 	.open		= proc_kstat_open,
 	.write		= proc_kstat_write,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= seq_release,
+#endif
 };
 
 void
@@ -656,7 +664,7 @@ kstat_detect_collision(kstat_proc_entry_
  */
 void
 kstat_proc_entry_install(kstat_proc_entry_t *kpep, mode_t mode,
-    const struct file_operations *file_ops, void *data)
+    const kstat_proc_op_t *proc_ops, void *data)
 {
 	kstat_module_t *module;
 	kstat_proc_entry_t *tmp = NULL;
@@ -690,7 +698,7 @@ kstat_proc_entry_install(kstat_proc_entr
 
 	kpep->kpe_owner = module;
 	kpep->kpe_proc = proc_create_data(kpep->kpe_name, mode,
-	    module->ksm_proc, file_ops, data);
+	    module->ksm_proc, proc_ops, data);
 	if (kpep->kpe_proc == NULL) {
 		list_del_init(&kpep->kpe_list);
 		if (list_empty(&module->ksm_kstat_list))
diff -Npaur a/module/spl/spl-proc.c b/module/spl/spl-proc.c
--- a/module/spl/spl-proc.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/spl/spl-proc.c	2020-02-27 12:40:52.277139075 -0500
@@ -532,11 +532,18 @@ proc_slab_open(struct inode *inode, stru
 	return (seq_open(filp, &slab_seq_ops));
 }
 
-static struct file_operations proc_slab_operations = {
-	.open	   = proc_slab_open,
-	.read	   = seq_read,
-	.llseek	 = seq_lseek,
+static const kstat_proc_op_t proc_slab_operations = {
+#ifdef HAVE_PROC_OPS_STRUCT
+	.proc_open	= proc_slab_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= seq_release,
+#else
+	.open		= proc_slab_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
 	.release	= seq_release,
+#endif
 };
 
 static void
@@ -571,18 +578,32 @@ proc_taskq_open(struct inode *inode, str
 	return (seq_open(filp, &taskq_seq_ops));
 }
 
-static struct file_operations proc_taskq_all_operations = {
+static const kstat_proc_op_t proc_taskq_all_operations = {
+#ifdef HAVE_PROC_OPS_STRUCT
+	.proc_open	= proc_taskq_all_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= seq_release,
+#else
 	.open		= proc_taskq_all_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= seq_release,
+#endif
 };
 
-static struct file_operations proc_taskq_operations = {
+static const kstat_proc_op_t proc_taskq_operations = {
+#ifdef HAVE_PROC_OPS_STRUCT
+	.proc_open	= proc_taskq_open,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= seq_release,
+#else
 	.open		= proc_taskq_open,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= seq_release,
+#endif
 };
 
 static struct ctl_table spl_kmem_table[] = {
diff -Npaur a/module/spl/spl-procfs-list.c b/module/spl/spl-procfs-list.c
--- a/module/spl/spl-procfs-list.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/spl/spl-procfs-list.c	2020-02-27 12:40:52.277139075 -0500
@@ -185,13 +185,20 @@ procfs_list_write(struct file *filp, con
 	return (len);
 }
 
-static struct file_operations procfs_list_operations = {
-	.owner		= THIS_MODULE,
+static const kstat_proc_op_t procfs_list_operations = {
+#ifdef HAVE_PROC_OPS_STRUCT
+	.proc_open	= procfs_list_open,
+	.proc_write	= procfs_list_write,
+	.proc_read	= seq_read,
+	.proc_lseek	= seq_lseek,
+	.proc_release	= seq_release_private,
+#else
 	.open		= procfs_list_open,
 	.write		= procfs_list_write,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= seq_release_private,
+#endif
 };
 
 /*
diff -Npaur a/module/zfs/vdev_initialize.c b/module/zfs/vdev_initialize.c
--- a/module/zfs/vdev_initialize.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/zfs/vdev_initialize.c	2020-02-27 12:40:52.277139075 -0500
@@ -700,7 +700,7 @@ vdev_initialize_restart(vdev_t *vd)
 		    vd->vdev_leaf_zap, VDEV_LEAF_ZAP_INITIALIZE_ACTION_TIME,
 		    sizeof (timestamp), 1, &timestamp);
 		ASSERT(err == 0 || err == ENOENT);
-		vd->vdev_initialize_action_time = (time_t)timestamp;
+		vd->vdev_initialize_action_time = timestamp;
 
 		if (vd->vdev_initialize_state == VDEV_INITIALIZE_SUSPENDED ||
 		    vd->vdev_offline) {
diff -Npaur a/module/zfs/vdev_trim.c b/module/zfs/vdev_trim.c
--- a/module/zfs/vdev_trim.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/zfs/vdev_trim.c	2020-02-27 12:40:52.277139075 -0500
@@ -1046,7 +1046,7 @@ vdev_trim_restart(vdev_t *vd)
 		    vd->vdev_leaf_zap, VDEV_LEAF_ZAP_TRIM_ACTION_TIME,
 		    sizeof (timestamp), 1, &timestamp);
 		ASSERT(err == 0 || err == ENOENT);
-		vd->vdev_trim_action_time = (time_t)timestamp;
+		vd->vdev_trim_action_time = timestamp;
 
 		if (vd->vdev_trim_state == VDEV_TRIM_SUSPENDED ||
 		    vd->vdev_offline) {
diff -Npaur a/module/zfs/zfs_debug.c b/module/zfs/zfs_debug.c
--- a/module/zfs/zfs_debug.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/zfs/zfs_debug.c	2020-02-27 12:40:52.277139075 -0500
@@ -27,7 +27,7 @@
 
 typedef struct zfs_dbgmsg {
 	procfs_list_node_t	zdm_node;
-	time_t			zdm_timestamp;
+	uint64_t		zdm_timestamp;
 	int			zdm_size;
 	char			zdm_msg[1]; /* variable length allocation */
 } zfs_dbgmsg_t;
diff -Npaur a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
--- a/module/zfs/zfs_vnops.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/zfs/zfs_vnops.c	2020-02-27 12:40:52.277139075 -0500
@@ -3415,8 +3415,8 @@ top:
 
 	if (mask & (ATTR_MTIME | ATTR_SIZE)) {
 		ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
-		ZTOI(zp)->i_mtime = zpl_inode_timespec_trunc(vap->va_mtime,
-		    ZTOI(zp)->i_sb->s_time_gran);
+		ZTOI(zp)->i_mtime = zpl_inode_timestamp_truncate(
+		    vap->va_mtime, ZTOI(zp));
 
 		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL,
 		    mtime, sizeof (mtime));
@@ -3424,8 +3424,8 @@ top:
 
 	if (mask & (ATTR_CTIME | ATTR_SIZE)) {
 		ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
-		ZTOI(zp)->i_ctime = zpl_inode_timespec_trunc(vap->va_ctime,
-		    ZTOI(zp)->i_sb->s_time_gran);
+		ZTOI(zp)->i_ctime = zpl_inode_timestamp_truncate(vap->va_ctime,
+		    ZTOI(zp));
 		SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
 		    ctime, sizeof (ctime));
 	}
diff -Npaur a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
--- a/module/zfs/zpl_inode.c	2020-02-26 08:50:05.000000000 -0500
+++ b/module/zfs/zpl_inode.c	2020-02-27 12:40:52.277139075 -0500
@@ -390,10 +390,8 @@ zpl_setattr(struct dentry *dentry, struc
 	vap->va_mtime = ia->ia_mtime;
 	vap->va_ctime = ia->ia_ctime;
 
-	if (vap->va_mask & ATTR_ATIME) {
-		ip->i_atime = zpl_inode_timespec_trunc(ia->ia_atime,
-		    ip->i_sb->s_time_gran);
-	}
+	if (vap->va_mask & ATTR_ATIME)
+		ip->i_atime = zpl_inode_timestamp_truncate(ia->ia_atime, ip);
 
 	cookie = spl_fstrans_mark();
 	error = -zfs_setattr(ip, vap, 0, cr);