[PATCH][cosmic-unstable] UBUNTU: SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH][cosmic-unstable] UBUNTU: SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3

Colin King
From: Colin Ian King <[hidden email]>

Add compat changes for 4.18 kernel, changes sync'd from SPL and ZFS
packages that contain backport of following upstream ZFS 4.18 compat fixes:

7b98f0d91f09 ("Linux compat 4.18: check_disk_size_change()")
6413c95fbd88 ("Linux 4.18 compat: inode timespec -> timespec64")

Note that we are still reliant on the upstream fix
https://patchwork.kernel.org/patch/10473337/ to land in 4.18 for
ZFS on 4.18 to build, so please apply this patch but don't enable
ZFS until this lands.

Signed-off-by: Colin Ian King <[hidden email]>
---
 spl/META                                           |   2 +-
 spl/Makefile.in                                    |   1 +
 spl/aclocal.m4                                     |   1 +
 spl/cmd/Makefile.in                                |   1 +
 spl/cmd/splat/Makefile.in                          |   1 +
 spl/cmd/splslab/Makefile.in                        |   1 +
 spl/config/kernel-inode-times.m4                   |  25 ++
 spl/config/spl-build.m4                            |   1 +
 spl/configure                                      | 132 +++++++++++
 spl/include/Makefile.in                            |   1 +
 spl/include/fs/Makefile.in                         |   1 +
 spl/include/linux/Makefile.in                      |   1 +
 spl/include/rpc/Makefile.in                        |   1 +
 spl/include/sharefs/Makefile.in                    |   1 +
 spl/include/sys/Makefile.in                        |   1 +
 spl/include/sys/condvar.h                          |   1 +
 spl/include/sys/fm/Makefile.in                     |   1 +
 spl/include/sys/fs/Makefile.in                     |   1 +
 spl/include/sys/time.h                             |  23 +-
 spl/include/sys/types.h                            |   3 -
 spl/include/sys/vnode.h                            |   6 +-
 spl/include/util/Makefile.in                       |   1 +
 spl/include/vm/Makefile.in                         |   1 +
 spl/lib/Makefile.in                                |   1 +
 spl/man/Makefile.in                                |   1 +
 spl/man/man1/Makefile.in                           |   1 +
 spl/man/man5/Makefile.in                           |   1 +
 spl/rpm/Makefile.in                                |   1 +
 spl/rpm/generic/Makefile.in                        |   1 +
 spl/rpm/redhat/Makefile.in                         |   1 +
 spl/scripts/Makefile.in                            |   1 +
 spl/spl_config.h.in                                |   3 +
 zfs/META                                           |   2 +-
 zfs/Makefile.in                                    |   4 +-
 zfs/aclocal.m4                                     |   4 +-
 zfs/config/kernel-bdev-block-device-operations.m4  |  34 ---
 .../kernel-block-device-operations-release-void.m4 |  29 ---
 zfs/config/kernel-block-device-operations.m4       |  57 +++++
 zfs/config/kernel-current-time.m4                  |   7 +-
 zfs/config/kernel-inode-times.m4                   |  25 ++
 zfs/config/kernel.m4                               |   3 +-
 zfs/configure                                      | 218 +++++++++++++----
 zfs/include/Makefile.in                            |   4 +-
 zfs/include/linux/Makefile.in                      |   4 +-
 zfs/include/linux/blkdev_compat.h                  |   1 +
 zfs/include/sys/Makefile.in                        |   4 +-
 zfs/include/sys/crypto/Makefile.in                 |   4 +-
 zfs/include/sys/dmu.h                              |   2 +-
 zfs/include/sys/dmu_objset.h                       |   2 +-
 zfs/include/sys/dsl_dir.h                          |   4 +-
 zfs/include/sys/fm/Makefile.in                     |   4 +-
 zfs/include/sys/fm/fs/Makefile.in                  |   4 +-
 zfs/include/sys/fs/Makefile.in                     |   4 +-
 zfs/include/sys/spa_impl.h                         |   2 +-
 zfs/include/sys/sysevent/Makefile.in               |   4 +-
 zfs/include/sys/xvattr.h                           |   2 +-
 zfs/include/sys/zfs_context.h                      |   9 +-
 zfs/include/sys/zfs_znode.h                        |  33 ++-
 zfs/include/sys/zpl.h                              |   9 +
 zfs/module/zfs/dmu_objset.c                        |   2 +-
 zfs/module/zfs/dsl_dir.c                           |   6 +-
 zfs/module/zfs/fm.c                                |   2 +-
 zfs/module/zfs/zfs_ctldir.c                        |   2 +-
 zfs/module/zfs/zfs_vnops.c                         |   4 +-
 zfs/module/zfs/zfs_znode.c                         |   4 +-
 zfs/module/zfs/zpl_inode.c                         |   5 +-
 zfs/module/zfs/zvol.c                              | 259 +++++++++------------
 zfs/zfs_config.h.in                                |  11 +-
 68 files changed, 664 insertions(+), 329 deletions(-)
 create mode 100644 spl/config/kernel-inode-times.m4
 delete mode 100644 zfs/config/kernel-bdev-block-device-operations.m4
 delete mode 100644 zfs/config/kernel-block-device-operations-release-void.m4
 create mode 100644 zfs/config/kernel-block-device-operations.m4
 create mode 100644 zfs/config/kernel-inode-times.m4

diff --git a/spl/META b/spl/META
index 1c7a52f..3bc9f73 100644
--- a/spl/META
+++ b/spl/META
@@ -2,7 +2,7 @@ Meta:         1
 Name:         spl
 Branch:       1.0
 Version:      0.7.9
-Release:      3ubuntu1
+Release:      3ubuntu2
 Release-Tags: relext
 License:      GPL
 Author:       OpenZFS on Linux
diff --git a/spl/Makefile.in b/spl/Makefile.in
index 9ee93e1..4768b10 100644
--- a/spl/Makefile.in
+++ b/spl/Makefile.in
@@ -133,6 +133,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/aclocal.m4 b/spl/aclocal.m4
index 73e0eec..da21f5a 100644
--- a/spl/aclocal.m4
+++ b/spl/aclocal.m4
@@ -1190,6 +1190,7 @@ m4_include([config/kernel-ctl-table-name.m4])
 m4_include([config/kernel-fallocate.m4])
 m4_include([config/kernel-group-info.m4])
 m4_include([config/kernel-inode-lock.m4])
+m4_include([config/kernel-inode-times.m4])
 m4_include([config/kernel-kmem-cache.m4])
 m4_include([config/kernel-kuidgid.m4])
 m4_include([config/kernel-pde-data.m4])
diff --git a/spl/cmd/Makefile.in b/spl/cmd/Makefile.in
index b389227..9a704a2 100644
--- a/spl/cmd/Makefile.in
+++ b/spl/cmd/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/cmd/splat/Makefile.in b/spl/cmd/splat/Makefile.in
index a90011c..beb9964 100644
--- a/spl/cmd/splat/Makefile.in
+++ b/spl/cmd/splat/Makefile.in
@@ -104,6 +104,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/cmd/splslab/Makefile.in b/spl/cmd/splslab/Makefile.in
index 082a43b..d115c72 100644
--- a/spl/cmd/splslab/Makefile.in
+++ b/spl/cmd/splslab/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/config/kernel-inode-times.m4 b/spl/config/kernel-inode-times.m4
new file mode 100644
index 0000000..3a6acd8
--- /dev/null
+++ b/spl/config/kernel-inode-times.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 4.18 API change
+dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64.
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_INODE_TIMES], [
+ AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+ SPL_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ ],[
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
+    [inode->i_*time's are timespec64])
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
diff --git a/spl/config/spl-build.m4 b/spl/config/spl-build.m4
index 5c6c02a..112c347 100644
--- a/spl/config/spl-build.m4
+++ b/spl/config/spl-build.m4
@@ -44,6 +44,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
  SPL_AC_USLEEP_RANGE
  SPL_AC_KMEM_CACHE_ALLOCFLAGS
  SPL_AC_WAIT_ON_BIT
+ SPL_AC_KERNEL_INODE_TIMES
  SPL_AC_INODE_LOCK
  SPL_AC_GROUP_INFO_GID
  SPL_AC_KMEM_CACHE_CREATE_USERCOPY
diff --git a/spl/configure b/spl/configure
index 5f9a799..c884029 100755
--- a/spl/configure
+++ b/spl/configure
@@ -14803,6 +14803,72 @@ fi
 
 
 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode->i_*time's are timespec64" >&5
+$as_echo_n "checking whether inode->i_*time's are timespec64... " >&6; }
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+ #include <linux/fs.h>
+
+int
+main (void)
+{
+
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+ echo "obj-m := conftest.o" >build/Makefile
+ modpost_flag=''
+ test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+ if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TIMESPEC64_TIMES 1" >>confdefs.h
+
+
+
+
+fi
+ rm -Rf build
+
+
+ EXTRA_KCFLAGS="$tmp_flags"
+
+
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode_lock_shared() exists" >&5
 $as_echo_n "checking whether inode_lock_shared() exists... " >&6; }
  tmp_flags="$EXTRA_KCFLAGS"
@@ -17849,6 +17915,72 @@ fi
 
 
 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode->i_*time's are timespec64" >&5
+$as_echo_n "checking whether inode->i_*time's are timespec64... " >&6; }
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+ #include <linux/fs.h>
+
+int
+main (void)
+{
+
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+ echo "obj-m := conftest.o" >build/Makefile
+ modpost_flag=''
+ test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+ if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TIMESPEC64_TIMES 1" >>confdefs.h
+
+
+
+
+fi
+ rm -Rf build
+
+
+ EXTRA_KCFLAGS="$tmp_flags"
+
+
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode_lock_shared() exists" >&5
 $as_echo_n "checking whether inode_lock_shared() exists... " >&6; }
  tmp_flags="$EXTRA_KCFLAGS"
diff --git a/spl/include/Makefile.in b/spl/include/Makefile.in
index 241e3bb..8de2b98 100644
--- a/spl/include/Makefile.in
+++ b/spl/include/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/fs/Makefile.in b/spl/include/fs/Makefile.in
index 9d02154..be87e5e 100644
--- a/spl/include/fs/Makefile.in
+++ b/spl/include/fs/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/linux/Makefile.in b/spl/include/linux/Makefile.in
index c74fa64..41a7293 100644
--- a/spl/include/linux/Makefile.in
+++ b/spl/include/linux/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/rpc/Makefile.in b/spl/include/rpc/Makefile.in
index 1ebea41..4b4be5d 100644
--- a/spl/include/rpc/Makefile.in
+++ b/spl/include/rpc/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/sharefs/Makefile.in b/spl/include/sharefs/Makefile.in
index 449c4db..7f767d8 100644
--- a/spl/include/sharefs/Makefile.in
+++ b/spl/include/sharefs/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/sys/Makefile.in b/spl/include/sys/Makefile.in
index 674490e..32f5d91 100644
--- a/spl/include/sys/Makefile.in
+++ b/spl/include/sys/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/sys/condvar.h b/spl/include/sys/condvar.h
index 5fcc906..ce3149a 100644
--- a/spl/include/sys/condvar.h
+++ b/spl/include/sys/condvar.h
@@ -31,6 +31,7 @@
 #include <sys/kmem.h>
 #include <sys/mutex.h>
 #include <sys/callo.h>
+#include <sys/time.h>
 
 /*
  * The kcondvar_t struct is protected by mutex taken externally before
diff --git a/spl/include/sys/fm/Makefile.in b/spl/include/sys/fm/Makefile.in
index 5b10aef..e88b19b 100644
--- a/spl/include/sys/fm/Makefile.in
+++ b/spl/include/sys/fm/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/sys/fs/Makefile.in b/spl/include/sys/fs/Makefile.in
index 1574323..dc759ac 100644
--- a/spl/include/sys/fs/Makefile.in
+++ b/spl/include/sys/fs/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/sys/time.h b/spl/include/sys/time.h
index ddda6de..1777246 100644
--- a/spl/include/sys/time.h
+++ b/spl/include/sys/time.h
@@ -54,13 +54,26 @@
 
 static const int hz = HZ;
 
+typedef longlong_t hrtime_t;
+typedef struct timespec timespec_t;
+
 #define TIMESPEC_OVERFLOW(ts) \
  ((ts)->tv_sec < TIME_MIN || (ts)->tv_sec > TIME_MAX)
 
+#if defined(HAVE_INODE_TIMESPEC64_TIMES)
+typedef struct timespec64 inode_timespec_t;
+#else
+typedef struct timespec inode_timespec_t;
+#endif
+
 static inline void
-gethrestime(timestruc_t *now)
+gethrestime(inode_timespec_t *ts)
 {
- *now = current_kernel_time();
+#if defined(HAVE_INODE_TIMESPEC64_TIMES)
+ *ts = current_kernel_time64();
+#else
+ *ts = current_kernel_time();
+#endif
 }
 
 static inline time_t
@@ -74,9 +87,9 @@ gethrestime_sec(void)
 static inline hrtime_t
 gethrtime(void)
 {
- struct timespec now;
- getrawmonotonic(&now);
- return (((hrtime_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec);
+ struct timespec ts;
+ getrawmonotonic(&ts);
+ return (((hrtime_t)ts.tv_sec * NSEC_PER_SEC) + ts.tv_nsec);
 }
 
 #endif  /* _SPL_TIME_H */
diff --git a/spl/include/sys/types.h b/spl/include/sys/types.h
index 2fe63b7..b958462 100644
--- a/spl/include/sys/types.h
+++ b/spl/include/sys/types.h
@@ -49,9 +49,6 @@ typedef long long offset_t;
 typedef struct task_struct kthread_t;
 typedef struct task_struct proc_t;
 typedef short pri_t;
-typedef struct timespec timestruc_t; /* definition per SVr4 */
-typedef struct timespec timespec_t;
-typedef longlong_t hrtime_t;
 typedef unsigned short ushort_t;
 typedef u_longlong_t len_t;
 typedef longlong_t diskaddr_t;
diff --git a/spl/include/sys/vnode.h b/spl/include/sys/vnode.h
index 0ed4794..87f12d6 100644
--- a/spl/include/sys/vnode.h
+++ b/spl/include/sys/vnode.h
@@ -129,9 +129,9 @@ typedef struct vattr {
  long va_nodeid; /* node # */
  uint32_t va_nlink; /* # links */
  uint64_t va_size; /* file size */
- struct timespec va_atime; /* last acc */
- struct timespec va_mtime; /* last mod */
- struct timespec va_ctime; /* last chg */
+ inode_timespec_t va_atime; /* last acc */
+ inode_timespec_t va_mtime; /* last mod */
+ inode_timespec_t va_ctime; /* last chg */
  dev_t va_rdev; /* dev */
  uint64_t va_nblocks; /* space used */
  uint32_t va_blksize; /* block size */
diff --git a/spl/include/util/Makefile.in b/spl/include/util/Makefile.in
index 7f79e07..28d81c3 100644
--- a/spl/include/util/Makefile.in
+++ b/spl/include/util/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/include/vm/Makefile.in b/spl/include/vm/Makefile.in
index d757da6..7dcba44 100644
--- a/spl/include/vm/Makefile.in
+++ b/spl/include/vm/Makefile.in
@@ -95,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/lib/Makefile.in b/spl/lib/Makefile.in
index c4ec3ea..ea21eb1 100644
--- a/spl/lib/Makefile.in
+++ b/spl/lib/Makefile.in
@@ -103,6 +103,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/man/Makefile.in b/spl/man/Makefile.in
index 82f3cb2..d97856c 100644
--- a/spl/man/Makefile.in
+++ b/spl/man/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/man/man1/Makefile.in b/spl/man/man1/Makefile.in
index 100b20d..a927e44 100644
--- a/spl/man/man1/Makefile.in
+++ b/spl/man/man1/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/man/man5/Makefile.in b/spl/man/man5/Makefile.in
index e15da91..df617f4 100644
--- a/spl/man/man5/Makefile.in
+++ b/spl/man/man5/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/rpm/Makefile.in b/spl/rpm/Makefile.in
index d9f5194..28422fb 100644
--- a/spl/rpm/Makefile.in
+++ b/spl/rpm/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/rpm/generic/Makefile.in b/spl/rpm/generic/Makefile.in
index 7f15e2b..6263c6d 100644
--- a/spl/rpm/generic/Makefile.in
+++ b/spl/rpm/generic/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/rpm/redhat/Makefile.in b/spl/rpm/redhat/Makefile.in
index d491803..6e9fca1 100644
--- a/spl/rpm/redhat/Makefile.in
+++ b/spl/rpm/redhat/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/scripts/Makefile.in b/spl/scripts/Makefile.in
index 4cfd2b1..d2fbec7 100644
--- a/spl/scripts/Makefile.in
+++ b/spl/scripts/Makefile.in
@@ -94,6 +94,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/kernel-ctl-table-name.m4 \
  $(top_srcdir)/config/kernel-fallocate.m4 \
  $(top_srcdir)/config/kernel-group-info.m4 \
  $(top_srcdir)/config/kernel-inode-lock.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-kmem-cache.m4 \
  $(top_srcdir)/config/kernel-kuidgid.m4 \
  $(top_srcdir)/config/kernel-pde-data.m4 \
diff --git a/spl/spl_config.h.in b/spl/spl_config.h.in
index 427f0de..75d1295 100644
--- a/spl/spl_config.h.in
+++ b/spl/spl_config.h.in
@@ -57,6 +57,9 @@
 /* yes */
 #undef HAVE_INODE_LOCK_SHARED
 
+/* inode->i_*time's are timespec64 */
+#undef HAVE_INODE_TIMESPEC64_TIMES
+
 /* truncate_range() inode operation is available */
 #undef HAVE_INODE_TRUNCATE_RANGE
 
diff --git a/zfs/META b/zfs/META
index 4bd2905..374dda5 100644
--- a/zfs/META
+++ b/zfs/META
@@ -2,7 +2,7 @@ Meta:         1
 Name:         zfs
 Branch:       1.0
 Version:      0.7.9
-Release:      3ubuntu1
+Release:      3ubuntu3
 Release-Tags: relext
 License:      CDDL
 Author:       OpenZFS on Linux
diff --git a/zfs/Makefile.in b/zfs/Makefile.in
index 35ce941..a0e3b69 100644
--- a/zfs/Makefile.in
+++ b/zfs/Makefile.in
@@ -108,7 +108,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -127,7 +126,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -161,6 +160,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/aclocal.m4 b/zfs/aclocal.m4
index ebaf028..36b234f 100644
--- a/zfs/aclocal.m4
+++ b/zfs/aclocal.m4
@@ -1215,7 +1215,6 @@ m4_include([config/kernel-acl-refcount.m4])
 m4_include([config/kernel-acl.m4])
 m4_include([config/kernel-aio-fsync.m4])
 m4_include([config/kernel-automount.m4])
-m4_include([config/kernel-bdev-block-device-operations.m4])
 m4_include([config/kernel-bdev-logical-size.m4])
 m4_include([config/kernel-bdev-physical-size.m4])
 m4_include([config/kernel-bdi.m4])
@@ -1234,7 +1233,7 @@ m4_include([config/kernel-blk-queue-max-segments.m4])
 m4_include([config/kernel-blk-queue-unplug.m4])
 m4_include([config/kernel-blkdev-get-by-path.m4])
 m4_include([config/kernel-blkdev-get.m4])
-m4_include([config/kernel-block-device-operations-release-void.m4])
+m4_include([config/kernel-block-device-operations.m4])
 m4_include([config/kernel-clear-inode.m4])
 m4_include([config/kernel-commit-metadata.m4])
 m4_include([config/kernel-create-nameidata.m4])
@@ -1268,6 +1267,7 @@ m4_include([config/kernel-global_page_state.m4])
 m4_include([config/kernel-inode-getattr.m4])
 m4_include([config/kernel-inode-set-flags.m4])
 m4_include([config/kernel-inode-set-iversion.m4])
+m4_include([config/kernel-inode-times.m4])
 m4_include([config/kernel-insert-inode-locked.m4])
 m4_include([config/kernel-invalidate-bdev-args.m4])
 m4_include([config/kernel-is_owner_or_cap.m4])
diff --git a/zfs/config/kernel-bdev-block-device-operations.m4 b/zfs/config/kernel-bdev-block-device-operations.m4
deleted file mode 100644
index faacc195..0000000
--- a/zfs/config/kernel-bdev-block-device-operations.m4
+++ /dev/null
@@ -1,34 +0,0 @@
-dnl #
-dnl # 2.6.x API change
-dnl #
-AC_DEFUN([ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS], [
- AC_MSG_CHECKING([block device operation prototypes])
- tmp_flags="$EXTRA_KCFLAGS"
- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
- ZFS_LINUX_TRY_COMPILE([
- #include <linux/blkdev.h>
-
- int blk_open(struct block_device *bdev, fmode_t mode)
-    { return 0; }
- int blk_ioctl(struct block_device *bdev, fmode_t mode,
-    unsigned x, unsigned long y) { return 0; }
- int blk_compat_ioctl(struct block_device * bdev, fmode_t mode,
-    unsigned x, unsigned long y) { return 0; }
-
- static const struct block_device_operations
-    bops __attribute__ ((unused)) = {
- .open = blk_open,
- .release = NULL,
- .ioctl = blk_ioctl,
- .compat_ioctl = blk_compat_ioctl,
- };
- ],[
- ],[
- AC_MSG_RESULT(struct block_device)
- AC_DEFINE(HAVE_BDEV_BLOCK_DEVICE_OPERATIONS, 1,
-          [struct block_device_operations use bdevs])
- ],[
- AC_MSG_RESULT(struct inode)
- ])
- EXTRA_KCFLAGS="$tmp_flags"
-])
diff --git a/zfs/config/kernel-block-device-operations-release-void.m4 b/zfs/config/kernel-block-device-operations-release-void.m4
deleted file mode 100644
index a73f858..0000000
--- a/zfs/config/kernel-block-device-operations-release-void.m4
+++ /dev/null
@@ -1,29 +0,0 @@
-dnl #
-dnl # 3.10.x API change
-dnl #
-AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
- AC_MSG_CHECKING([whether block_device_operations.release is void])
- tmp_flags="$EXTRA_KCFLAGS"
- EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
- ZFS_LINUX_TRY_COMPILE([
- #include <linux/blkdev.h>
-
- void blk_release(struct gendisk *g, fmode_t mode) { return; }
-
- static const struct block_device_operations
-    bops __attribute__ ((unused)) = {
- .open = NULL,
- .release = blk_release,
- .ioctl = NULL,
- .compat_ioctl = NULL,
- };
- ],[
- ],[
- AC_MSG_RESULT(void)
- AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID, 1,
-          [struct block_device_operations.release returns void])
- ],[
- AC_MSG_RESULT(int)
- ])
- EXTRA_KCFLAGS="$tmp_flags"
-])
diff --git a/zfs/config/kernel-block-device-operations.m4 b/zfs/config/kernel-block-device-operations.m4
new file mode 100644
index 0000000..5f2811c
--- /dev/null
+++ b/zfs/config/kernel-block-device-operations.m4
@@ -0,0 +1,57 @@
+dnl #
+dnl # 2.6.38 API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS], [
+ AC_MSG_CHECKING([whether bops->check_events() exists])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/blkdev.h>
+
+ unsigned int blk_check_events(struct gendisk *disk,
+    unsigned int clearing) { return (0); }
+
+ static const struct block_device_operations
+    bops __attribute__ ((unused)) = {
+ .check_events = blk_check_events,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS, 1,
+    [bops->check_events() exists])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
+
+dnl #
+dnl # 3.10.x API change
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [
+ AC_MSG_CHECKING([whether bops->release() is void])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/blkdev.h>
+
+ void blk_release(struct gendisk *g, fmode_t mode) { return; }
+
+ static const struct block_device_operations
+    bops __attribute__ ((unused)) = {
+ .open = NULL,
+ .release = blk_release,
+ .ioctl = NULL,
+ .compat_ioctl = NULL,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(void)
+ AC_DEFINE(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID, 1,
+          [bops->release() returns void])
+ ],[
+ AC_MSG_RESULT(int)
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
diff --git a/zfs/config/kernel-current-time.m4 b/zfs/config/kernel-current-time.m4
index 2ede9ff..c7d5c9b 100644
--- a/zfs/config/kernel-current-time.m4
+++ b/zfs/config/kernel-current-time.m4
@@ -1,15 +1,14 @@
 dnl #
 dnl # 4.9, current_time() added
+dnl # 4.18, return type changed from timespec to timespec64
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_CURRENT_TIME],
  [AC_MSG_CHECKING([whether current_time() exists])
  ZFS_LINUX_TRY_COMPILE_SYMBOL([
  #include <linux/fs.h>
  ], [
- struct inode ip;
- struct timespec now __attribute__ ((unused));
-
- now = current_time(&ip);
+ struct inode ip __attribute__ ((unused));
+ ip.i_atime = current_time(&ip);
  ], [current_time], [fs/inode.c], [
  AC_MSG_RESULT(yes)
  AC_DEFINE(HAVE_CURRENT_TIME, 1, [current_time() exists])
diff --git a/zfs/config/kernel-inode-times.m4 b/zfs/config/kernel-inode-times.m4
new file mode 100644
index 0000000..f581841
--- /dev/null
+++ b/zfs/config/kernel-inode-times.m4
@@ -0,0 +1,25 @@
+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_INODE_TIMES], [
+ AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ ],[
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
+    [inode->i_*time's are timespec64])
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
diff --git a/zfs/config/kernel.m4 b/zfs/config/kernel.m4
index 375e4b7..bac5f23 100644
--- a/zfs/config/kernel.m4
+++ b/zfs/config/kernel.m4
@@ -12,7 +12,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
  ZFS_AC_KERNEL_CURRENT_BIO_TAIL
  ZFS_AC_KERNEL_SUPER_USER_NS
  ZFS_AC_KERNEL_SUBMIT_BIO
- ZFS_AC_KERNEL_BDEV_BLOCK_DEVICE_OPERATIONS
+ ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
  ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
  ZFS_AC_KERNEL_TYPE_FMODE_T
  ZFS_AC_KERNEL_3ARG_BLKDEV_GET
@@ -60,6 +60,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
  ZFS_AC_KERNEL_POSIX_ACL_CHMOD
  ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
  ZFS_AC_KERNEL_POSIX_ACL_VALID_WITH_NS
+ ZFS_AC_KERNEL_INODE_TIMES
  ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION
  ZFS_AC_KERNEL_INODE_OPERATIONS_PERMISSION_WITH_NAMEIDATA
  ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL
diff --git a/zfs/configure b/zfs/configure
index 27f37db..a95b294 100755
--- a/zfs/configure
+++ b/zfs/configure
@@ -15131,8 +15131,8 @@ fi
 
 
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking block device operation prototypes" >&5
-$as_echo_n "checking block device operation prototypes... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bops->check_events() exists" >&5
+$as_echo_n "checking whether bops->check_events() exists... " >&6; }
  tmp_flags="$EXTRA_KCFLAGS"
  EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
 
@@ -15142,19 +15142,12 @@ cat confdefs.h - <<_ACEOF >conftest.c
 
  #include <linux/blkdev.h>
 
- int blk_open(struct block_device *bdev, fmode_t mode)
-    { return 0; }
- int blk_ioctl(struct block_device *bdev, fmode_t mode,
-    unsigned x, unsigned long y) { return 0; }
- int blk_compat_ioctl(struct block_device * bdev, fmode_t mode,
-    unsigned x, unsigned long y) { return 0; }
+ unsigned int blk_check_events(struct gendisk *disk,
+    unsigned int clearing) { return (0); }
 
  static const struct block_device_operations
     bops __attribute__ ((unused)) = {
- .open = blk_open,
- .release = NULL,
- .ioctl = blk_ioctl,
- .compat_ioctl = blk_compat_ioctl,
+ .check_events = blk_check_events,
  };
 
 int
@@ -15191,18 +15184,18 @@ _ACEOF
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; }; then :
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: struct block_device" >&5
-$as_echo "struct block_device" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
-$as_echo "#define HAVE_BDEV_BLOCK_DEVICE_OPERATIONS 1" >>confdefs.h
+$as_echo "#define HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS 1" >>confdefs.h
 
 
 else
   $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: struct inode" >&5
-$as_echo "struct inode" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
 
 
@@ -15213,8 +15206,8 @@ fi
  EXTRA_KCFLAGS="$tmp_flags"
 
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether block_device_operations.release is void" >&5
-$as_echo_n "checking whether block_device_operations.release is void... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bops->release() is void" >&5
+$as_echo_n "checking whether bops->release() is void... " >&6; }
  tmp_flags="$EXTRA_KCFLAGS"
  EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
 
@@ -19842,6 +19835,78 @@ fi
 
 
 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode->i_*time's are timespec64" >&5
+$as_echo_n "checking whether inode->i_*time's are timespec64... " >&6; }
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+ #include <linux/fs.h>
+
+int
+main (void)
+{
+
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+ echo "obj-m := conftest.o" >build/Makefile
+ modpost_flag=''
+ test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+ if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $FRAME_LARGER_THAN $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TIMESPEC64_TIMES 1" >>confdefs.h
+
+
+
+
+fi
+ rm -Rf build
+
+
+ EXTRA_KCFLAGS="$tmp_flags"
+
+
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->permission() exists" >&5
 $as_echo_n "checking whether iops->permission() exists... " >&6; }
 
@@ -26466,10 +26531,8 @@ int
 main (void)
 {
 
- struct inode ip;
- struct timespec now __attribute__ ((unused));
-
- now = current_time(&ip);
+ struct inode ip __attribute__ ((unused));
+ ip.i_atime = current_time(&ip);
 
   ;
   return 0;
@@ -30702,8 +30765,8 @@ fi
 
 
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking block device operation prototypes" >&5
-$as_echo_n "checking block device operation prototypes... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bops->check_events() exists" >&5
+$as_echo_n "checking whether bops->check_events() exists... " >&6; }
  tmp_flags="$EXTRA_KCFLAGS"
  EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
 
@@ -30713,19 +30776,12 @@ cat confdefs.h - <<_ACEOF >conftest.c
 
  #include <linux/blkdev.h>
 
- int blk_open(struct block_device *bdev, fmode_t mode)
-    { return 0; }
- int blk_ioctl(struct block_device *bdev, fmode_t mode,
-    unsigned x, unsigned long y) { return 0; }
- int blk_compat_ioctl(struct block_device * bdev, fmode_t mode,
-    unsigned x, unsigned long y) { return 0; }
+ unsigned int blk_check_events(struct gendisk *disk,
+    unsigned int clearing) { return (0); }
 
  static const struct block_device_operations
     bops __attribute__ ((unused)) = {
- .open = blk_open,
- .release = NULL,
- .ioctl = blk_ioctl,
- .compat_ioctl = blk_compat_ioctl,
+ .check_events = blk_check_events,
  };
 
 int
@@ -30762,18 +30818,18 @@ _ACEOF
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; }; then :
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: struct block_device" >&5
-$as_echo "struct block_device" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 
-$as_echo "#define HAVE_BDEV_BLOCK_DEVICE_OPERATIONS 1" >>confdefs.h
+$as_echo "#define HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS 1" >>confdefs.h
 
 
 else
   $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: struct inode" >&5
-$as_echo "struct inode" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 
 
 
@@ -30784,8 +30840,8 @@ fi
  EXTRA_KCFLAGS="$tmp_flags"
 
 
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether block_device_operations.release is void" >&5
-$as_echo_n "checking whether block_device_operations.release is void... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bops->release() is void" >&5
+$as_echo_n "checking whether bops->release() is void... " >&6; }
  tmp_flags="$EXTRA_KCFLAGS"
  EXTRA_KCFLAGS="${NO_UNUSED_BUT_SET_VARIABLE}"
 
@@ -35413,6 +35469,78 @@ fi
 
 
 
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inode->i_*time's are timespec64" >&5
+$as_echo_n "checking whether inode->i_*time's are timespec64... " >&6; }
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+
+
+ #include <linux/fs.h>
+
+int
+main (void)
+{
+
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+
+  ;
+  return 0;
+}
+
+_ACEOF
+
+
+
+cat - <<_ACEOF >conftest.h
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build && touch build/conftest.mod.c
+ echo "obj-m := conftest.o" >build/Makefile
+ modpost_flag=''
+ test "x$enable_linux_builtin" = xyes && modpost_flag='modpost=true' # fake modpost stage
+ if { ac_try='cp conftest.c conftest.h build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror $FRAME_LARGER_THAN $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build $modpost_flag'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; } >/dev/null && { ac_try='test -s build/conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_INODE_TIMESPEC64_TIMES 1" >>confdefs.h
+
+
+
+
+fi
+ rm -Rf build
+
+
+ EXTRA_KCFLAGS="$tmp_flags"
+
+
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iops->permission() exists" >&5
 $as_echo_n "checking whether iops->permission() exists... " >&6; }
 
@@ -42037,10 +42165,8 @@ int
 main (void)
 {
 
- struct inode ip;
- struct timespec now __attribute__ ((unused));
-
- now = current_time(&ip);
+ struct inode ip __attribute__ ((unused));
+ ip.i_atime = current_time(&ip);
 
   ;
   return 0;
diff --git a/zfs/include/Makefile.in b/zfs/include/Makefile.in
index e5639ded..dae65eb 100644
--- a/zfs/include/Makefile.in
+++ b/zfs/include/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/linux/Makefile.in b/zfs/include/linux/Makefile.in
index 28472c9..ae3ea2d 100644
--- a/zfs/include/linux/Makefile.in
+++ b/zfs/include/linux/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/linux/blkdev_compat.h b/zfs/include/linux/blkdev_compat.h
index f99980a..27f0566 100644
--- a/zfs/include/linux/blkdev_compat.h
+++ b/zfs/include/linux/blkdev_compat.h
@@ -32,6 +32,7 @@
 #include <linux/blkdev.h>
 #include <linux/elevator.h>
 #include <linux/backing-dev.h>
+#include <linux/msdos_fs.h> /* for SECTOR_* */
 
 #ifndef HAVE_FMODE_T
 typedef unsigned __bitwise__ fmode_t;
diff --git a/zfs/include/sys/Makefile.in b/zfs/include/sys/Makefile.in
index a92d48e..6cab49f 100644
--- a/zfs/include/sys/Makefile.in
+++ b/zfs/include/sys/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/sys/crypto/Makefile.in b/zfs/include/sys/crypto/Makefile.in
index db1ef75..b1b1991 100644
--- a/zfs/include/sys/crypto/Makefile.in
+++ b/zfs/include/sys/crypto/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/sys/dmu.h b/zfs/include/sys/dmu.h
index bcdf7d6..755a905 100644
--- a/zfs/include/sys/dmu.h
+++ b/zfs/include/sys/dmu.h
@@ -891,7 +891,7 @@ uint64_t dmu_objset_fsid_guid(objset_t *os);
 /*
  * Get the [cm]time for an objset's snapshot dir
  */
-timestruc_t dmu_objset_snap_cmtime(objset_t *os);
+inode_timespec_t dmu_objset_snap_cmtime(objset_t *os);
 
 int dmu_objset_is_snapshot(objset_t *os);
 
diff --git a/zfs/include/sys/dmu_objset.h b/zfs/include/sys/dmu_objset.h
index a836e03..531e81d 100644
--- a/zfs/include/sys/dmu_objset.h
+++ b/zfs/include/sys/dmu_objset.h
@@ -179,7 +179,7 @@ int dmu_objset_find_dp(struct dsl_pool *dp, uint64_t ddobj,
     int func(struct dsl_pool *, struct dsl_dataset *, void *),
     void *arg, int flags);
 void dmu_objset_evict_dbufs(objset_t *os);
-timestruc_t dmu_objset_snap_cmtime(objset_t *os);
+inode_timespec_t dmu_objset_snap_cmtime(objset_t *os);
 
 /* called from dsl */
 void dmu_objset_sync(objset_t *os, zio_t *zio, dmu_tx_t *tx);
diff --git a/zfs/include/sys/dsl_dir.h b/zfs/include/sys/dsl_dir.h
index 69b0b6a..80e83fd 100644
--- a/zfs/include/sys/dsl_dir.h
+++ b/zfs/include/sys/dsl_dir.h
@@ -103,7 +103,7 @@ struct dsl_dir {
  /* Protected by dd_lock */
  kmutex_t dd_lock;
  list_t dd_props; /* list of dsl_prop_record_t's */
- timestruc_t dd_snap_cmtime; /* last time snapshot namespace changed */
+ inode_timespec_t dd_snap_cmtime; /* last snapshot namespace change */
  uint64_t dd_origin_txg;
 
  /* gross estimate of space used by in-flight tx's */
@@ -159,7 +159,7 @@ boolean_t dsl_dir_is_clone(dsl_dir_t *dd);
 void dsl_dir_new_refreservation(dsl_dir_t *dd, struct dsl_dataset *ds,
     uint64_t reservation, cred_t *cr, dmu_tx_t *tx);
 void dsl_dir_snap_cmtime_update(dsl_dir_t *dd);
-timestruc_t dsl_dir_snap_cmtime(dsl_dir_t *dd);
+inode_timespec_t dsl_dir_snap_cmtime(dsl_dir_t *dd);
 void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value,
     dmu_tx_t *tx);
 void dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx);
diff --git a/zfs/include/sys/fm/Makefile.in b/zfs/include/sys/fm/Makefile.in
index 011627c..2f198b7 100644
--- a/zfs/include/sys/fm/Makefile.in
+++ b/zfs/include/sys/fm/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/sys/fm/fs/Makefile.in b/zfs/include/sys/fm/fs/Makefile.in
index 6c1bc15..2cd6842 100644
--- a/zfs/include/sys/fm/fs/Makefile.in
+++ b/zfs/include/sys/fm/fs/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/sys/fs/Makefile.in b/zfs/include/sys/fs/Makefile.in
index ec5ef4e..b69fdb5 100644
--- a/zfs/include/sys/fs/Makefile.in
+++ b/zfs/include/sys/fs/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/sys/spa_impl.h b/zfs/include/sys/spa_impl.h
index b1e78c1..fa7490a 100644
--- a/zfs/include/sys/spa_impl.h
+++ b/zfs/include/sys/spa_impl.h
@@ -153,7 +153,7 @@ struct spa {
  uint64_t spa_freeze_txg; /* freeze pool at this txg */
  uint64_t spa_load_max_txg; /* best initial ub_txg */
  uint64_t spa_claim_max_txg; /* highest claimed birth txg */
- timespec_t spa_loaded_ts; /* 1st successful open time */
+ inode_timespec_t spa_loaded_ts; /* 1st successful open time */
  objset_t *spa_meta_objset; /* copy of dp->dp_meta_objset */
  kmutex_t spa_evicting_os_lock; /* Evicting objset list lock */
  list_t spa_evicting_os_list; /* Objsets being evicted. */
diff --git a/zfs/include/sys/sysevent/Makefile.in b/zfs/include/sys/sysevent/Makefile.in
index 137b3b3..6945deb 100644
--- a/zfs/include/sys/sysevent/Makefile.in
+++ b/zfs/include/sys/sysevent/Makefile.in
@@ -100,7 +100,6 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-acl.m4 \
  $(top_srcdir)/config/kernel-aio-fsync.m4 \
  $(top_srcdir)/config/kernel-automount.m4 \
- $(top_srcdir)/config/kernel-bdev-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-bdev-logical-size.m4 \
  $(top_srcdir)/config/kernel-bdev-physical-size.m4 \
  $(top_srcdir)/config/kernel-bdi.m4 \
@@ -119,7 +118,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-blk-queue-unplug.m4 \
  $(top_srcdir)/config/kernel-blkdev-get-by-path.m4 \
  $(top_srcdir)/config/kernel-blkdev-get.m4 \
- $(top_srcdir)/config/kernel-block-device-operations-release-void.m4 \
+ $(top_srcdir)/config/kernel-block-device-operations.m4 \
  $(top_srcdir)/config/kernel-clear-inode.m4 \
  $(top_srcdir)/config/kernel-commit-metadata.m4 \
  $(top_srcdir)/config/kernel-create-nameidata.m4 \
@@ -153,6 +152,7 @@ am__aclocal_m4_deps = $(top_srcdir)/config/always-arch.m4 \
  $(top_srcdir)/config/kernel-inode-getattr.m4 \
  $(top_srcdir)/config/kernel-inode-set-flags.m4 \
  $(top_srcdir)/config/kernel-inode-set-iversion.m4 \
+ $(top_srcdir)/config/kernel-inode-times.m4 \
  $(top_srcdir)/config/kernel-insert-inode-locked.m4 \
  $(top_srcdir)/config/kernel-invalidate-bdev-args.m4 \
  $(top_srcdir)/config/kernel-is_owner_or_cap.m4 \
diff --git a/zfs/include/sys/xvattr.h b/zfs/include/sys/xvattr.h
index 4779b63..5d38927 100644
--- a/zfs/include/sys/xvattr.h
+++ b/zfs/include/sys/xvattr.h
@@ -47,7 +47,7 @@
  * Structure of all optional attributes.
  */
 typedef struct xoptattr {
- timestruc_t xoa_createtime; /* Create time of file */
+ inode_timespec_t xoa_createtime; /* Create time of file */
  uint8_t xoa_archive;
  uint8_t xoa_system;
  uint8_t xoa_readonly;
diff --git a/zfs/include/sys/zfs_context.h b/zfs/include/sys/zfs_context.h
index 4fe3534..68c58f9 100644
--- a/zfs/include/sys/zfs_context.h
+++ b/zfs/include/sys/zfs_context.h
@@ -527,7 +527,7 @@ extern char *vn_dumpdir;
 #define AV_SCANSTAMP_SZ 32 /* length of anti-virus scanstamp */
 
 typedef struct xoptattr {
- timestruc_t xoa_createtime; /* Create time of file */
+ inode_timespec_t xoa_createtime; /* Create time of file */
  uint8_t xoa_archive;
  uint8_t xoa_system;
  uint8_t xoa_readonly;
@@ -640,13 +640,6 @@ extern void delay(clock_t ticks);
 #define USEC_TO_TICK(usec) ((usec) / (MICROSEC / hz))
 #define NSEC_TO_TICK(usec) ((usec) / (NANOSEC / hz))
 
-#define gethrestime_sec() time(NULL)
-#define gethrestime(t) \
- do {\
- (t)->tv_sec = gethrestime_sec();\
- (t)->tv_nsec = 0;\
- } while (0);
-
 #define max_ncpus 64
 #define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
 
diff --git a/zfs/include/sys/zfs_znode.h b/zfs/include/sys/zfs_znode.h
index c292f03..26d1eb3 100644
--- a/zfs/include/sys/zfs_znode.h
+++ b/zfs/include/sys/zfs_znode.h
@@ -270,19 +270,36 @@ typedef struct znode_hold {
 
 extern unsigned int zfs_object_mutex_size;
 
-/* Encode ZFS stored time values from a struct timespec */
+/*
+ * Encode ZFS stored time values from a struct timespec / struct timespec64.
+ */
 #define ZFS_TIME_ENCODE(tp, stmp) \
-{ \
+do { \
  (stmp)[0] = (uint64_t)(tp)->tv_sec; \
  (stmp)[1] = (uint64_t)(tp)->tv_nsec; \
-}
+} while (0)
 
-/* Decode ZFS stored time values to a struct timespec */
+#if defined(HAVE_INODE_TIMESPEC64_TIMES)
+/*
+ * Decode ZFS stored time values to a struct timespec64
+ * 4.18 and newer kernels.
+ */
 #define ZFS_TIME_DECODE(tp, stmp) \
-{ \
- (tp)->tv_sec = (time_t)(stmp)[0]; \
- (tp)->tv_nsec = (long)(stmp)[1]; \
-}
+do { \
+ (tp)->tv_sec = (time64_t)(stmp)[0]; \
+ (tp)->tv_nsec = (long)(stmp)[1]; \
+} while (0)
+#else
+/*
+ * Decode ZFS stored time values to a struct timespec
+ * 4.17 and older kernels.
+ */
+#define ZFS_TIME_DECODE(tp, stmp) \
+do { \
+ (tp)->tv_sec = (time_t)(stmp)[0]; \
+ (tp)->tv_nsec = (long)(stmp)[1]; \
+} while (0)
+#endif /* HAVE_INODE_TIMESPEC64_TIMES */
 
 /*
  * Timestamp defines
diff --git a/zfs/include/sys/zpl.h b/zfs/include/sys/zpl.h
index 65ed431..e433fbc 100644
--- a/zfs/include/sys/zpl.h
+++ b/zfs/include/sys/zpl.h
@@ -189,4 +189,13 @@ zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx)
 }
 #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)
+#else
+#define zpl_inode_timespec_trunc(ts, gran) timespec_trunc(ts, gran)
+#endif
+
 #endif /* _SYS_ZPL_H */
diff --git a/zfs/module/zfs/dmu_objset.c b/zfs/module/zfs/dmu_objset.c
index 3425d54..449ebed 100644
--- a/zfs/module/zfs/dmu_objset.c
+++ b/zfs/module/zfs/dmu_objset.c
@@ -860,7 +860,7 @@ dmu_objset_evict_done(objset_t *os)
  kmem_free(os, sizeof (objset_t));
 }
 
-timestruc_t
+inode_timespec_t
 dmu_objset_snap_cmtime(objset_t *os)
 {
  return (dsl_dir_snap_cmtime(os->os_dsl_dataset->ds_dir));
diff --git a/zfs/module/zfs/dsl_dir.c b/zfs/module/zfs/dsl_dir.c
index a3ef589..deecf6b 100644
--- a/zfs/module/zfs/dsl_dir.c
+++ b/zfs/module/zfs/dsl_dir.c
@@ -1975,10 +1975,10 @@ dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd,
  return (0);
 }
 
-timestruc_t
+inode_timespec_t
 dsl_dir_snap_cmtime(dsl_dir_t *dd)
 {
- timestruc_t t;
+ inode_timespec_t t;
 
  mutex_enter(&dd->dd_lock);
  t = dd->dd_snap_cmtime;
@@ -1990,7 +1990,7 @@ dsl_dir_snap_cmtime(dsl_dir_t *dd)
 void
 dsl_dir_snap_cmtime_update(dsl_dir_t *dd)
 {
- timestruc_t t;
+ inode_timespec_t t;
 
  gethrestime(&t);
  mutex_enter(&dd->dd_lock);
diff --git a/zfs/module/zfs/fm.c b/zfs/module/zfs/fm.c
index cb14814..9d26cc9 100644
--- a/zfs/module/zfs/fm.c
+++ b/zfs/module/zfs/fm.c
@@ -508,8 +508,8 @@ zfs_zevent_insert(zevent_t *ev)
 int
 zfs_zevent_post(nvlist_t *nvl, nvlist_t *detector, zevent_cb_t *cb)
 {
+ inode_timespec_t tv;
  int64_t tv_array[2];
- timestruc_t tv;
  uint64_t eid;
  size_t nvl_size = 0;
  zevent_t *ev;
diff --git a/zfs/module/zfs/zfs_ctldir.c b/zfs/module/zfs/zfs_ctldir.c
index 3b5fb19..3ff2c10 100644
--- a/zfs/module/zfs/zfs_ctldir.c
+++ b/zfs/module/zfs/zfs_ctldir.c
@@ -451,7 +451,7 @@ static struct inode *
 zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
     const struct file_operations *fops, const struct inode_operations *ops)
 {
- struct timespec now;
+ inode_timespec_t now;
  struct inode *ip;
  znode_t *zp;
 
diff --git a/zfs/module/zfs/zfs_vnops.c b/zfs/module/zfs/zfs_vnops.c
index 0d2b61a..34ea751 100644
--- a/zfs/module/zfs/zfs_vnops.c
+++ b/zfs/module/zfs/zfs_vnops.c
@@ -3158,7 +3158,7 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
 
  if (mask & (ATTR_MTIME | ATTR_SIZE)) {
  ZFS_TIME_ENCODE(&vap->va_mtime, mtime);
- ZTOI(zp)->i_mtime = timespec_trunc(vap->va_mtime,
+ ZTOI(zp)->i_mtime = zpl_inode_timespec_trunc(vap->va_mtime,
     ZTOI(zp)->i_sb->s_time_gran);
 
  SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL,
@@ -3167,7 +3167,7 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
 
  if (mask & (ATTR_CTIME | ATTR_SIZE)) {
  ZFS_TIME_ENCODE(&vap->va_ctime, ctime);
- ZTOI(zp)->i_ctime = timespec_trunc(vap->va_ctime,
+ ZTOI(zp)->i_ctime = zpl_inode_timespec_trunc(vap->va_ctime,
     ZTOI(zp)->i_sb->s_time_gran);
  SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL,
     ctime, sizeof (ctime));
diff --git a/zfs/module/zfs/zfs_znode.c b/zfs/module/zfs/zfs_znode.c
index f508a24..e222c79 100644
--- a/zfs/module/zfs/zfs_znode.c
+++ b/zfs/module/zfs/zfs_znode.c
@@ -700,7 +700,7 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
  uint64_t rdev = 0;
  zfsvfs_t *zfsvfs = ZTOZSB(dzp);
  dmu_buf_t *db;
- timestruc_t now;
+ inode_timespec_t now;
  uint64_t gen, obj;
  int bonuslen;
  int dnodesize;
@@ -1349,7 +1349,7 @@ void
 zfs_tstamp_update_setup(znode_t *zp, uint_t flag, uint64_t mtime[2],
     uint64_t ctime[2])
 {
- timestruc_t now;
+ inode_timespec_t now;
 
  gethrestime(&now);
 
diff --git a/zfs/module/zfs/zpl_inode.c b/zfs/module/zfs/zpl_inode.c
index 3b5643d..41b91ca 100644
--- a/zfs/module/zfs/zpl_inode.c
+++ b/zfs/module/zfs/zpl_inode.c
@@ -384,9 +384,10 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
  vap->va_mtime = ia->ia_mtime;
  vap->va_ctime = ia->ia_ctime;
 
- if (vap->va_mask & ATTR_ATIME)
- ip->i_atime = timespec_trunc(ia->ia_atime,
+ if (vap->va_mask & ATTR_ATIME) {
+ ip->i_atime = zpl_inode_timespec_trunc(ia->ia_atime,
     ip->i_sb->s_time_gran);
+ }
 
  cookie = spl_fstrans_mark();
  error = -zfs_setattr(ip, vap, 0, cr);
diff --git a/zfs/module/zfs/zvol.c b/zfs/module/zfs/zvol.c
index ffa5fac..03f9563 100644
--- a/zfs/module/zfs/zvol.c
+++ b/zfs/module/zfs/zvol.c
@@ -99,7 +99,7 @@ unsigned long zvol_max_discard_blocks = 16384;
 unsigned int zvol_volmode = ZFS_VOLMODE_GEOM;
 
 static taskq_t *zvol_taskq;
-static kmutex_t zvol_state_lock;
+static krwlock_t zvol_state_lock;
 static list_t zvol_state_list;
 
 #define ZVOL_HT_SIZE 1024
@@ -176,17 +176,17 @@ zvol_find_by_dev(dev_t dev)
 {
  zvol_state_t *zv;
 
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_READER);
  for (zv = list_head(&zvol_state_list); zv != NULL;
     zv = list_next(&zvol_state_list, zv)) {
  mutex_enter(&zv->zv_state_lock);
  if (zv->zv_dev == dev) {
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
  return (zv);
  }
  mutex_exit(&zv->zv_state_lock);
  }
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 
  return (NULL);
 }
@@ -204,7 +204,7 @@ zvol_find_by_name_hash(const char *name, uint64_t hash, int mode)
  zvol_state_t *zv;
  struct hlist_node *p = NULL;
 
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_READER);
  hlist_for_each(p, ZVOL_HT_HEAD(hash)) {
  zv = hlist_entry(p, zvol_state_t, zv_hlink);
  mutex_enter(&zv->zv_state_lock);
@@ -227,12 +227,12 @@ zvol_find_by_name_hash(const char *name, uint64_t hash, int mode)
     strncmp(zv->zv_name, name, MAXNAMELEN)
     == 0);
  }
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
  return (zv);
  }
  mutex_exit(&zv->zv_state_lock);
  }
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 
  return (NULL);
 }
@@ -339,24 +339,6 @@ zvol_get_stats(objset_t *os, nvlist_t *nv)
  return (SET_ERROR(error));
 }
 
-static void
-zvol_size_changed(zvol_state_t *zv, uint64_t volsize)
-{
- struct block_device *bdev;
-
- ASSERT(MUTEX_HELD(&zv->zv_state_lock));
-
- bdev = bdget_disk(zv->zv_disk, 0);
- if (bdev == NULL)
- return;
-
- set_capacity(zv->zv_disk, volsize >> 9);
- zv->zv_volsize = volsize;
- check_disk_size_change(zv->zv_disk, bdev);
-
- bdput(bdev);
-}
-
 /*
  * Sanity check volume size.
  */
@@ -409,31 +391,17 @@ zvol_update_volsize(uint64_t volsize, objset_t *os)
  return (error);
 }
 
-static int
-zvol_update_live_volsize(zvol_state_t *zv, uint64_t volsize)
-{
- zvol_size_changed(zv, volsize);
-
- /*
- * We should post a event here describing the expansion.  However,
- * the zfs_ereport_post() interface doesn't nicely support posting
- * events for zvols, it assumes events relate to vdevs or zios.
- */
-
- return (0);
-}
-
 /*
- * Set ZFS_PROP_VOLSIZE set entry point.
+ * Set ZFS_PROP_VOLSIZE set entry point.  Note that modifying the volume
+ * size will result in a udev "change" event being generated.
  */
 int
 zvol_set_volsize(const char *name, uint64_t volsize)
 {
- zvol_state_t *zv = NULL;
  objset_t *os = NULL;
- int error;
- dmu_object_info_t *doi;
+ struct gendisk *disk = NULL;
  uint64_t readonly;
+ int error;
  boolean_t owned = B_FALSE;
 
  error = dsl_prop_get_integer(name,
@@ -443,7 +411,7 @@ zvol_set_volsize(const char *name, uint64_t volsize)
  if (readonly)
  return (SET_ERROR(EROFS));
 
- zv = zvol_find_by_name(name, RW_READER);
+ zvol_state_t *zv = zvol_find_by_name(name, RW_READER);
 
  ASSERT(zv == NULL || (MUTEX_HELD(&zv->zv_state_lock) &&
     RW_READ_HELD(&zv->zv_suspend_lock)));
@@ -464,16 +432,18 @@ zvol_set_volsize(const char *name, uint64_t volsize)
  os = zv->zv_objset;
  }
 
- doi = kmem_alloc(sizeof (dmu_object_info_t), KM_SLEEP);
+ dmu_object_info_t *doi = kmem_alloc(sizeof (*doi), KM_SLEEP);
 
  if ((error = dmu_object_info(os, ZVOL_OBJ, doi)) ||
     (error = zvol_check_volsize(volsize, doi->doi_data_block_size)))
  goto out;
 
  error = zvol_update_volsize(volsize, os);
-
- if (error == 0 && zv != NULL)
- error = zvol_update_live_volsize(zv, volsize);
+ if (error == 0 && zv != NULL) {
+ zv->zv_volsize = volsize;
+ zv->zv_changed = 1;
+ disk = zv->zv_disk;
+ }
 out:
  kmem_free(doi, sizeof (dmu_object_info_t));
 
@@ -488,6 +458,9 @@ zvol_set_volsize(const char *name, uint64_t volsize)
  if (zv != NULL)
  mutex_exit(&zv->zv_state_lock);
 
+ if (disk != NULL)
+ revalidate_disk(disk);
+
  return (SET_ERROR(error));
 }
 
@@ -543,8 +516,8 @@ zvol_set_volblocksize(const char *name, uint64_t volblocksize)
  if (zv == NULL)
  return (SET_ERROR(ENXIO));
 
- ASSERT(MUTEX_HELD(&zv->zv_state_lock) &&
-    RW_READ_HELD(&zv->zv_suspend_lock));
+ ASSERT(MUTEX_HELD(&zv->zv_state_lock));
+ ASSERT(RW_READ_HELD(&zv->zv_suspend_lock));
 
  if (zv->zv_flags & ZVOL_RDONLY) {
  mutex_exit(&zv->zv_state_lock);
@@ -1120,7 +1093,7 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
 static void
 zvol_insert(zvol_state_t *zv)
 {
- ASSERT(MUTEX_HELD(&zvol_state_lock));
+ ASSERT(RW_WRITE_HELD(&zvol_state_lock));
  ASSERT3U(MINOR(zv->zv_dev) & ZVOL_MINOR_MASK, ==, 0);
  list_insert_head(&zvol_state_list, zv);
  hlist_add_head(&zv->zv_hlink, ZVOL_HT_HEAD(zv->zv_hash));
@@ -1132,7 +1105,7 @@ zvol_insert(zvol_state_t *zv)
 static void
 zvol_remove(zvol_state_t *zv)
 {
- ASSERT(MUTEX_HELD(&zvol_state_lock));
+ ASSERT(RW_WRITE_HELD(&zvol_state_lock));
  list_remove(&zvol_state_list, zv);
  hlist_del(&zv->zv_hlink);
 }
@@ -1148,8 +1121,8 @@ zvol_setup_zv(zvol_state_t *zv)
  uint64_t ro;
  objset_t *os = zv->zv_objset;
 
- ASSERT(MUTEX_HELD(&zv->zv_state_lock) &&
-    RW_LOCK_HELD(&zv->zv_suspend_lock));
+ ASSERT(MUTEX_HELD(&zv->zv_state_lock));
+ ASSERT(RW_LOCK_HELD(&zv->zv_suspend_lock));
 
  error = dsl_prop_get_integer(zv->zv_name, "readonly", &ro, NULL);
  if (error)
@@ -1227,8 +1200,8 @@ zvol_suspend(const char *name)
  return (NULL);
 
  /* block all I/O, release in zvol_resume. */
- ASSERT(MUTEX_HELD(&zv->zv_state_lock) &&
-    RW_WRITE_HELD(&zv->zv_suspend_lock));
+ ASSERT(MUTEX_HELD(&zv->zv_state_lock));
+ ASSERT(RW_WRITE_HELD(&zv->zv_suspend_lock));
 
  atomic_inc(&zv->zv_suspend_ref);
 
@@ -1349,9 +1322,7 @@ zvol_open(struct block_device *bdev, fmode_t flag)
  int error = 0;
  boolean_t drop_suspend = B_TRUE;
 
- ASSERT(!MUTEX_HELD(&zvol_state_lock));
-
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_READER);
  /*
  * Obtain a copy of private_data under the zvol_state_lock to make
  * sure that either the result of zvol free code path setting
@@ -1360,7 +1331,7 @@ zvol_open(struct block_device *bdev, fmode_t flag)
  */
  zv = bdev->bd_disk->private_data;
  if (zv == NULL) {
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
  return (SET_ERROR(-ENXIO));
  }
 
@@ -1384,7 +1355,7 @@ zvol_open(struct block_device *bdev, fmode_t flag)
  } else {
  drop_suspend = B_FALSE;
  }
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 
  ASSERT(MUTEX_HELD(&zv->zv_state_lock));
  ASSERT(zv->zv_open_count != 0 || RW_READ_HELD(&zv->zv_suspend_lock));
@@ -1402,11 +1373,18 @@ zvol_open(struct block_device *bdev, fmode_t flag)
 
  zv->zv_open_count++;
 
+ mutex_exit(&zv->zv_state_lock);
+ if (drop_suspend)
+ rw_exit(&zv->zv_suspend_lock);
+
  check_disk_change(bdev);
 
+ return (0);
+
 out_open_count:
  if (zv->zv_open_count == 0)
  zvol_last_close(zv);
+
 out_mutex:
  mutex_exit(&zv->zv_state_lock);
  if (drop_suspend)
@@ -1427,9 +1405,7 @@ zvol_release(struct gendisk *disk, fmode_t mode)
  zvol_state_t *zv;
  boolean_t drop_suspend = B_TRUE;
 
- ASSERT(!MUTEX_HELD(&zvol_state_lock));
-
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_READER);
  zv = disk->private_data;
 
  mutex_enter(&zv->zv_state_lock);
@@ -1453,7 +1429,7 @@ zvol_release(struct gendisk *disk, fmode_t mode)
  } else {
  drop_suspend = B_FALSE;
  }
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 
  ASSERT(MUTEX_HELD(&zv->zv_state_lock));
  ASSERT(zv->zv_open_count != 1 || RW_READ_HELD(&zv->zv_suspend_lock));
@@ -1479,7 +1455,7 @@ zvol_ioctl(struct block_device *bdev, fmode_t mode,
  zvol_state_t *zv = bdev->bd_disk->private_data;
  int error = 0;
 
- ASSERT(zv && zv->zv_open_count > 0);
+ ASSERT3U(zv->zv_open_count, >, 0);
 
  switch (cmd) {
  case BLKFLSBUF:
@@ -1519,23 +1495,62 @@ zvol_compat_ioctl(struct block_device *bdev, fmode_t mode,
 #define zvol_compat_ioctl NULL
 #endif
 
+/*
+ * Linux 2.6.38 preferred interface.
+ */
+#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
+static unsigned int
+zvol_check_events(struct gendisk *disk, unsigned int clearing)
+{
+ unsigned int mask = 0;
+
+ rw_enter(&zvol_state_lock, RW_READER);
+
+ zvol_state_t *zv = disk->private_data;
+ if (zv != NULL) {
+ mutex_enter(&zv->zv_state_lock);
+ mask = zv->zv_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
+ zv->zv_changed = 0;
+ mutex_exit(&zv->zv_state_lock);
+ }
+
+ rw_exit(&zvol_state_lock);
+
+ return (mask);
+}
+#else
 static int zvol_media_changed(struct gendisk *disk)
 {
+ int changed = 0;
+
+ rw_enter(&zvol_state_lock, RW_READER);
+
  zvol_state_t *zv = disk->private_data;
+ if (zv != NULL) {
+ mutex_enter(&zv->zv_state_lock);
+ changed = zv->zv_changed;
+ zv->zv_changed = 0;
+ mutex_exit(&zv->zv_state_lock);
+ }
 
- ASSERT(zv && zv->zv_open_count > 0);
+ rw_exit(&zvol_state_lock);
 
- return (zv->zv_changed);
+ return (changed);
 }
+#endif
 
 static int zvol_revalidate_disk(struct gendisk *disk)
 {
- zvol_state_t *zv = disk->private_data;
+ rw_enter(&zvol_state_lock, RW_READER);
 
- ASSERT(zv && zv->zv_open_count > 0);
+ zvol_state_t *zv = disk->private_data;
+ if (zv != NULL) {
+ mutex_enter(&zv->zv_state_lock);
+ set_capacity(zv->zv_disk, zv->zv_volsize >> SECTOR_BITS);
+ mutex_exit(&zv->zv_state_lock);
+ }
 
- zv->zv_changed = 0;
- set_capacity(zv->zv_disk, zv->zv_volsize >> 9);
+ rw_exit(&zvol_state_lock);
 
  return (0);
 }
@@ -1552,7 +1567,7 @@ zvol_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  zvol_state_t *zv = bdev->bd_disk->private_data;
  sector_t sectors;
 
- ASSERT(zv && zv->zv_open_count > 0);
+ ASSERT3U(zv->zv_open_count, >, 0);
 
  sectors = get_capacity(zv->zv_disk);
 
@@ -1585,68 +1600,20 @@ zvol_probe(dev_t dev, int *part, void *arg)
  return (kobj);
 }
 
-#ifdef HAVE_BDEV_BLOCK_DEVICE_OPERATIONS
 static struct block_device_operations zvol_ops = {
  .open = zvol_open,
  .release = zvol_release,
  .ioctl = zvol_ioctl,
  .compat_ioctl = zvol_compat_ioctl,
- .media_changed = zvol_media_changed,
- .revalidate_disk = zvol_revalidate_disk,
- .getgeo = zvol_getgeo,
- .owner = THIS_MODULE,
-};
-
-#else /* HAVE_BDEV_BLOCK_DEVICE_OPERATIONS */
-
-static int
-zvol_open_by_inode(struct inode *inode, struct file *file)
-{
- return (zvol_open(inode->i_bdev, file->f_mode));
-}
-
-static int
-zvol_release_by_inode(struct inode *inode, struct file *file)
-{
- return (zvol_release(inode->i_bdev->bd_disk, file->f_mode));
-}
-
-static int
-zvol_ioctl_by_inode(struct inode *inode, struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
- if (file == NULL || inode == NULL)
- return (SET_ERROR(-EINVAL));
-
- return (zvol_ioctl(inode->i_bdev, file->f_mode, cmd, arg));
-}
-
-#ifdef CONFIG_COMPAT
-static long
-zvol_compat_ioctl_by_inode(struct file *file,
-    unsigned int cmd, unsigned long arg)
-{
- if (file == NULL)
- return (SET_ERROR(-EINVAL));
-
- return (zvol_compat_ioctl(file->f_dentry->d_inode->i_bdev,
-    file->f_mode, cmd, arg));
-}
+#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
+ .check_events = zvol_check_events,
 #else
-#define zvol_compat_ioctl_by_inode NULL
-#endif
-
-static struct block_device_operations zvol_ops = {
- .open = zvol_open_by_inode,
- .release = zvol_release_by_inode,
- .ioctl = zvol_ioctl_by_inode,
- .compat_ioctl = zvol_compat_ioctl_by_inode,
  .media_changed = zvol_media_changed,
+#endif
  .revalidate_disk = zvol_revalidate_disk,
  .getgeo = zvol_getgeo,
  .owner = THIS_MODULE,
 };
-#endif /* HAVE_BDEV_BLOCK_DEVICE_OPERATIONS */
 
 /*
  * Allocate memory for a new zvol_state_t and setup the required
@@ -1699,6 +1666,10 @@ zvol_alloc(dev_t dev, const char *name)
  rw_init(&zv->zv_suspend_lock, NULL, RW_DEFAULT, NULL);
 
  zv->zv_disk->major = zvol_major;
+#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
+ zv->zv_disk->events = DISK_EVENT_MEDIA_CHANGE;
+#endif
+
  if (volmode == ZFS_VOLMODE_DEV) {
  /*
  * ZFS_VOLMODE_DEV disable partitioning on ZVOL devices: set
@@ -1743,7 +1714,6 @@ zvol_free(void *arg)
 {
  zvol_state_t *zv = arg;
 
- ASSERT(!MUTEX_HELD(&zvol_state_lock));
  ASSERT(!RW_LOCK_HELD(&zv->zv_suspend_lock));
  ASSERT(!MUTEX_HELD(&zv->zv_state_lock));
  ASSERT(zv->zv_open_count == 0);
@@ -1870,9 +1840,9 @@ zvol_create_minor_impl(const char *name)
  kmem_free(doi, sizeof (dmu_object_info_t));
 
  if (error == 0) {
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_WRITER);
  zvol_insert(zv);
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
  add_disk(zv->zv_disk);
  } else {
  ida_simple_remove(&zvol_ida, idx);
@@ -1889,7 +1859,7 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname)
 {
  int readonly = get_disk_ro(zv->zv_disk);
 
- ASSERT(MUTEX_HELD(&zvol_state_lock));
+ ASSERT(RW_LOCK_HELD(&zvol_state_lock));
  ASSERT(MUTEX_HELD(&zv->zv_state_lock));
 
  strlcpy(zv->zv_name, newname, sizeof (zv->zv_name));
@@ -2129,7 +2099,7 @@ zvol_remove_minors_impl(const char *name)
  list_create(&free_list, sizeof (zvol_state_t),
     offsetof(zvol_state_t, zv_next));
 
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_WRITER);
 
  for (zv = list_head(&zvol_state_list); zv != NULL; zv = zv_next) {
  zv_next = list_next(&zvol_state_list, zv);
@@ -2154,15 +2124,15 @@ zvol_remove_minors_impl(const char *name)
  zvol_remove(zv);
 
  /*
- * clear this while holding zvol_state_lock so
- * zvol_open won't open it
+ * Cleared while holding zvol_state_lock as a writer
+ * which will prevent zvol_open() from opening it.
  */
  zv->zv_disk->private_data = NULL;
 
  /* Drop zv_state_lock before zvol_free() */
  mutex_exit(&zv->zv_state_lock);
 
- /* try parallel zv_free, if failed do it in place */
+ /* Try parallel zv_free, if failed do it in place */
  t = taskq_dispatch(system_taskq, zvol_free, zv,
     TQ_SLEEP);
  if (t == TASKQID_INVALID)
@@ -2173,11 +2143,9 @@ zvol_remove_minors_impl(const char *name)
  mutex_exit(&zv->zv_state_lock);
  }
  }
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 
- /*
- * Drop zvol_state_lock before calling zvol_free()
- */
+ /* Drop zvol_state_lock before calling zvol_free() */
  while ((zv = list_head(&free_list)) != NULL) {
  list_remove(&free_list, zv);
  zvol_free(zv);
@@ -2196,7 +2164,7 @@ zvol_remove_minor_impl(const char *name)
  if (zvol_inhibit_dev)
  return;
 
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_WRITER);
 
  for (zv = list_head(&zvol_state_list); zv != NULL; zv = zv_next) {
  zv_next = list_next(&zvol_state_list, zv);
@@ -2216,7 +2184,10 @@ zvol_remove_minor_impl(const char *name)
  }
  zvol_remove(zv);
 
- /* clear this so zvol_open won't open it */
+ /*
+ * Cleared while holding zvol_state_lock as a writer
+ * which will prevent zvol_open() from opening it.
+ */
  zv->zv_disk->private_data = NULL;
 
  mutex_exit(&zv->zv_state_lock);
@@ -2227,7 +2198,7 @@ zvol_remove_minor_impl(const char *name)
  }
 
  /* Drop zvol_state_lock before calling zvol_free() */
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 
  if (zv != NULL)
  zvol_free(zv);
@@ -2248,7 +2219,7 @@ zvol_rename_minors_impl(const char *oldname, const char *newname)
  oldnamelen = strlen(oldname);
  newnamelen = strlen(newname);
 
- mutex_enter(&zvol_state_lock);
+ rw_enter(&zvol_state_lock, RW_READER);
 
  for (zv = list_head(&zvol_state_list); zv != NULL; zv = zv_next) {
  zv_next = list_next(&zvol_state_list, zv);
@@ -2276,7 +2247,7 @@ zvol_rename_minors_impl(const char *oldname, const char *newname)
  mutex_exit(&zv->zv_state_lock);
  }
 
- mutex_exit(&zvol_state_lock);
+ rw_exit(&zvol_state_lock);
 }
 
 typedef struct zvol_snapdev_cb_arg {
@@ -2653,7 +2624,7 @@ zvol_init(void)
 
  list_create(&zvol_state_list, sizeof (zvol_state_t),
     offsetof(zvol_state_t, zv_next));
- mutex_init(&zvol_state_lock, NULL, MUTEX_DEFAULT, NULL);
+ rw_init(&zvol_state_lock, NULL, RW_DEFAULT, NULL);
  ida_init(&zvol_ida);
 
  zvol_taskq = taskq_create(ZVOL_DRIVER, threads, maxclsyspri,
@@ -2690,7 +2661,7 @@ zvol_init(void)
  taskq_destroy(zvol_taskq);
 out:
  ida_destroy(&zvol_ida);
- mutex_destroy(&zvol_state_lock);
+ rw_destroy(&zvol_state_lock);
  list_destroy(&zvol_state_list);
 
  return (SET_ERROR(error));
@@ -2707,7 +2678,7 @@ zvol_fini(void)
 
  taskq_destroy(zvol_taskq);
  list_destroy(&zvol_state_list);
- mutex_destroy(&zvol_state_lock);
+ rw_destroy(&zvol_state_lock);
 
  ida_destroy(&zvol_ida);
 }
diff --git a/zfs/zfs_config.h.in b/zfs/zfs_config.h.in
index d51466e..6ec914f 100644
--- a/zfs/zfs_config.h.in
+++ b/zfs/zfs_config.h.in
@@ -72,9 +72,6 @@
 /* Define if host toolchain supports AVX512VL */
 #undef HAVE_AVX512VL
 
-/* struct block_device_operations use bdevs */
-#undef HAVE_BDEV_BLOCK_DEVICE_OPERATIONS
-
 /* bdev_logical_block_size() is available */
 #undef HAVE_BDEV_LOGICAL_BLOCK_SIZE
 
@@ -141,7 +138,10 @@
 /* blk_queue_write_cache() is GPL-only */
 #undef HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY
 
-/* struct block_device_operations.release returns void */
+/* bops->check_events() exists */
+#undef HAVE_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
+
+/* bops->release() returns void */
 #undef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
 
 /* security_inode_init_security wants callback */
@@ -303,6 +303,9 @@
 /* inode_set_iversion() exists */
 #undef HAVE_INODE_SET_IVERSION
 
+/* inode->i_*time's are timespec64 */
+#undef HAVE_INODE_TIMESPEC64_TIMES
+
 /* iops->truncate_range() exists */
 #undef HAVE_INODE_TRUNCATE_RANGE
 
--
2.7.4


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED: [PATCH][cosmic-unstable] UBUNTU: SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3

Seth Forshee
On Wed, Jul 11, 2018 at 08:37:33AM +0100, Colin King wrote:

> From: Colin Ian King <[hidden email]>
>
> Add compat changes for 4.18 kernel, changes sync'd from SPL and ZFS
> packages that contain backport of following upstream ZFS 4.18 compat fixes:
>
> 7b98f0d91f09 ("Linux compat 4.18: check_disk_size_change()")
> 6413c95fbd88 ("Linux 4.18 compat: inode timespec -> timespec64")
>
> Note that we are still reliant on the upstream fix
> https://patchwork.kernel.org/patch/10473337/ to land in 4.18 for
> ZFS on 4.18 to build, so please apply this patch but don't enable
> ZFS until this lands.
>
> Signed-off-by: Colin Ian King <[hidden email]>

Applied to cosmic/master-next and unstable/master, thanks!      

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team