Package: zfs-dkms
Severity: important
Tags: patch

since the 4.9 kernel is now available in unstable, the following
upstream patches need to be cherry-picked for compatibility:

8ba3f2bf6a66378b36acd70e5616a78396030984
7ca25051b6470e8471b4ed454d8c66ff21338de3
0fedeedd309eca62d15fffd8bd811e2b12660e21
b8d9e26440ade0edebfa98af8cb9371810c1aeaf

please find conflict-resolved versions attached (seem to work for me,
but more eyes can't hurt). Please also note the 4.9 compat bug[1]
against spl-dkms, which should probably be handled in one go ;)

Thanks for your work on ZFS/SPL in Debian!

1: 851352
From: Chunwei Chen <[email protected]>
Date: Wed, 19 Oct 2016 11:12:20 -0700
Subject: Remove dir inode operations from zpl_inode_operations

These operations are dir specific, there's no point putting them in
zpl_inode_operations which is for regular files.

Signed-off-by: Chunwei Chen <[email protected]>
---
 module/zfs/zpl_inode.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index 06611bc39..b0c5c7040 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -642,14 +642,6 @@ zpl_revalidate(struct dentry *dentry, unsigned int flags)
 }
 
 const struct inode_operations zpl_inode_operations = {
-	.create		= zpl_create,
-	.link		= zpl_link,
-	.unlink		= zpl_unlink,
-	.symlink	= zpl_symlink,
-	.mkdir		= zpl_mkdir,
-	.rmdir		= zpl_rmdir,
-	.mknod		= zpl_mknod,
-	.rename		= zpl_rename,
 	.setattr	= zpl_setattr,
 	.getattr	= zpl_getattr,
 	.setxattr	= generic_setxattr,
From: Chunwei Chen <[email protected]>
Date: Wed, 19 Oct 2016 11:19:01 -0700
Subject: Linux 4.9 compat: iops->rename() wants flags

In Linux 4.9, torvalds/linux@2773bf0, iops->rename() and iops->rename2() are
merged together into iops->rename(), it now wants flags.

Signed-off-by: Chunwei Chen <[email protected]>
---
 config/kernel-rename.m4 | 25 +++++++++++++++++++++++++
 config/kernel.m4        |  1 +
 module/zfs/zpl_ctldir.c | 23 ++++++++++++++++++++---
 module/zfs/zpl_inode.c  | 21 +++++++++++++++++++--
 4 files changed, 65 insertions(+), 5 deletions(-)
 create mode 100644 config/kernel-rename.m4

diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
new file mode 100644
index 000000000..9f894fb4d
--- /dev/null
+++ b/config/kernel-rename.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 4.9 API change,
+dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
+dnl # flags.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
+	AC_MSG_CHECKING([whether iops->rename() wants flags])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		int rename_fn(struct inode *sip, struct dentry *sdp,
+			struct inode *tip, struct dentry *tdp,
+			unsigned int flags) { return 0; }
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.rename = rename_fn,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1, [iops->rename() wants flags])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index 4aa66cd51..4970d4c07 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -99,6 +99,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
 	ZFS_AC_KERNEL_FOLLOW_DOWN_ONE
 	ZFS_AC_KERNEL_MAKE_REQUEST_FN
 	ZFS_AC_KERNEL_GENERIC_IO_ACCT
+	ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
 
 	AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
 		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
index 069834eae..d691f670b 100644
--- a/module/zfs/zpl_ctldir.c
+++ b/module/zfs/zpl_ctldir.c
@@ -301,13 +301,17 @@ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
 }
 #endif /* HAVE_VFS_ITERATE */
 
-int
-zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
-    struct inode *tdip, struct dentry *tdentry)
+static int
+zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
+    struct inode *tdip, struct dentry *tdentry, unsigned int flags)
 {
 	cred_t *cr = CRED();
 	int error;
 
+	/* We probably don't want to support renameat2(2) in ctldir */
+	if (flags)
+		return (-EINVAL);
+
 	crhold(cr);
 	error = -zfsctl_snapdir_rename(sdip, dname(sdentry),
 	    tdip, dname(tdentry), cr, 0);
@@ -317,6 +321,15 @@ zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
 	return (error);
 }
 
+#ifndef HAVE_RENAME_WANTS_FLAGS
+static int
+zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
+    struct inode *tdip, struct dentry *tdentry)
+{
+	return (zpl_snapdir_rename2(sdip, sdentry, tdip, tdentry, 0));
+}
+#endif
+
 static int
 zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
 {
@@ -405,7 +418,11 @@ const struct file_operations zpl_fops_snapdir = {
 const struct inode_operations zpl_ops_snapdir = {
 	.lookup		= zpl_snapdir_lookup,
 	.getattr	= zpl_snapdir_getattr,
+#ifdef HAVE_RENAME_WANTS_FLAGS
+	.rename		= zpl_snapdir_rename2,
+#else
 	.rename		= zpl_snapdir_rename,
+#endif
 	.rmdir		= zpl_snapdir_rmdir,
 	.mkdir		= zpl_snapdir_mkdir,
 };
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index b0c5c7040..d3696be9c 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -349,13 +349,17 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
 }
 
 static int
-zpl_rename(struct inode *sdip, struct dentry *sdentry,
-    struct inode *tdip, struct dentry *tdentry)
+zpl_rename2(struct inode *sdip, struct dentry *sdentry,
+    struct inode *tdip, struct dentry *tdentry, unsigned int flags)
 {
 	cred_t *cr = CRED();
 	int error;
 	fstrans_cookie_t cookie;
 
+	/* We don't have renameat2(2) support */
+	if (flags)
+		return (-EINVAL);
+
 	crhold(cr);
 	cookie = spl_fstrans_mark();
 	error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0);
@@ -366,6 +370,15 @@ zpl_rename(struct inode *sdip, struct dentry *sdentry,
 	return (error);
 }
 
+#ifndef HAVE_RENAME_WANTS_FLAGS
+static int
+zpl_rename(struct inode *sdip, struct dentry *sdentry,
+    struct inode *tdip, struct dentry *tdentry)
+{
+	return (zpl_rename2(sdip, sdentry, tdip, tdentry, 0));
+}
+#endif
+
 static int
 zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
 {
@@ -674,7 +687,11 @@ const struct inode_operations zpl_dir_inode_operations = {
 	.mkdir		= zpl_mkdir,
 	.rmdir		= zpl_rmdir,
 	.mknod		= zpl_mknod,
+#ifdef HAVE_RENAME_WANTS_FLAGS
+	.rename		= zpl_rename2,
+#else
 	.rename		= zpl_rename,
+#endif
 	.setattr	= zpl_setattr,
 	.getattr	= zpl_getattr,
 	.setxattr	= generic_setxattr,
From: Chunwei Chen <[email protected]>
Date: Wed, 19 Oct 2016 11:19:17 -0700
Subject: Linux 4.9 compat: remove iops->{set,get,remove}xattr

In Linux 4.9, torvalds/linux@fd50eca, iops->{set,get,remove}xattr and
generic_{set,get,remove}xattr are removed. xattr operations will directly
go through sb->s_xattr.

Signed-off-by: Chunwei Chen <[email protected]>
---
 config/kernel-xattr-handler.m4 | 25 +++++++++++++++++++++++++
 config/kernel.m4               |  1 +
 module/zfs/zpl_inode.c         |  8 ++++++++
 3 files changed, 34 insertions(+)

diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
index dcffd4480..4ac08d8e7 100644
--- a/config/kernel-xattr-handler.m4
+++ b/config/kernel-xattr-handler.m4
@@ -58,6 +58,31 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_NAME], [
 ])
 
 dnl #
+dnl # 4.9 API change,
+dnl # iops->{set,get,remove}xattr and generic_{set,get,remove}xattr are
+dnl # removed. xattr operations will directly go through sb->s_xattr.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR], [
+	AC_MSG_CHECKING([whether generic_setxattr() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+		#include <linux/xattr.h>
+
+		static const struct inode_operations
+		    iops __attribute__ ((unused)) = {
+			.setxattr = generic_setxattr
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_GENERIC_SETXATTR, 1,
+		    [generic_setxattr() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
+dnl #
 dnl # Supported xattr handler get() interfaces checked newest to oldest.
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
diff --git a/config/kernel.m4 b/config/kernel.m4
index 4970d4c07..1b84e1acc 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -100,6 +100,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
 	ZFS_AC_KERNEL_MAKE_REQUEST_FN
 	ZFS_AC_KERNEL_GENERIC_IO_ACCT
 	ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
+	ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR
 
 	AS_IF([test "$LINUX_OBJ" != "$LINUX"], [
 		KERNELMAKE_PARAMS="$KERNELMAKE_PARAMS O=$LINUX_OBJ"
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index d3696be9c..0e795c5ba 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -657,9 +657,11 @@ zpl_revalidate(struct dentry *dentry, unsigned int flags)
 const struct inode_operations zpl_inode_operations = {
 	.setattr	= zpl_setattr,
 	.getattr	= zpl_getattr,
+#ifdef HAVE_GENERIC_SETXATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
 	.removexattr	= generic_removexattr,
+#endif
 	.listxattr	= zpl_xattr_list,
 #ifdef HAVE_INODE_TRUNCATE_RANGE
 	.truncate_range = zpl_truncate_range,
@@ -694,9 +696,11 @@ const struct inode_operations zpl_dir_inode_operations = {
 #endif
 	.setattr	= zpl_setattr,
 	.getattr	= zpl_getattr,
+#ifdef HAVE_GENERIC_SETXATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
 	.removexattr	= generic_removexattr,
+#endif
 	.listxattr	= zpl_xattr_list,
 #if defined(CONFIG_FS_POSIX_ACL)
 #if defined(HAVE_GET_ACL)
@@ -721,18 +725,22 @@ const struct inode_operations zpl_symlink_inode_operations = {
 #endif
 	.setattr	= zpl_setattr,
 	.getattr	= zpl_getattr,
+#ifdef HAVE_GENERIC_SETXATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
 	.removexattr	= generic_removexattr,
+#endif
 	.listxattr	= zpl_xattr_list,
 };
 
 const struct inode_operations zpl_special_inode_operations = {
 	.setattr	= zpl_setattr,
 	.getattr	= zpl_getattr,
+#ifdef HAVE_GENERIC_SETXATTR
 	.setxattr	= generic_setxattr,
 	.getxattr	= generic_getxattr,
 	.removexattr	= generic_removexattr,
+#endif
 	.listxattr	= zpl_xattr_list,
 #if defined(CONFIG_FS_POSIX_ACL)
 #if defined(HAVE_GET_ACL)
From: DeHackEd <[email protected]>
Date: Tue, 15 Nov 2016 12:20:46 -0500
Subject: Kernel 4.9 compat: file_operations->aio_fsync removal

Linux kernel commit 723c038475b78 removed this field.

Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: DHE <[email protected]>
Closes #5393
---
 config/kernel-aio-fsync.m4 | 21 +++++++++++++++++++++
 config/kernel.m4           |  1 +
 module/zfs/zpl_file.c      | 11 +++++++++++
 3 files changed, 33 insertions(+)
 create mode 100644 config/kernel-aio-fsync.m4

diff --git a/config/kernel-aio-fsync.m4 b/config/kernel-aio-fsync.m4
new file mode 100644
index 000000000..41b7a98a6
--- /dev/null
+++ b/config/kernel-aio-fsync.m4
@@ -0,0 +1,21 @@
+dnl #
+dnl # Linux 4.9-rc5+ ABI, removal of the .aio_fsync field
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_AIO_FSYNC], [
+	AC_MSG_CHECKING([whether fops->aio_fsync() exists])
+	ZFS_LINUX_TRY_COMPILE([
+		#include <linux/fs.h>
+
+		static const struct file_operations
+		    fops __attribute__ ((unused)) = {
+			.aio_fsync = NULL,
+		};
+	],[
+	],[
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_FILE_AIO_FSYNC, 1, [fops->aio_fsync() exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
diff --git a/config/kernel.m4 b/config/kernel.m4
index 1b84e1acc..290d71b5e 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -61,6 +61,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
 	ZFS_AC_KERNEL_NR_CACHED_OBJECTS
 	ZFS_AC_KERNEL_FREE_CACHED_OBJECTS
 	ZFS_AC_KERNEL_FALLOCATE
+	ZFS_AC_KERNEL_AIO_FSYNC
 	ZFS_AC_KERNEL_MKDIR_UMODE_T
 	ZFS_AC_KERNEL_LOOKUP_NAMEIDATA
 	ZFS_AC_KERNEL_CREATE_NAMEIDATA
diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
index a629b59dc..ccb8f8103 100644
--- a/module/zfs/zpl_file.c
+++ b/module/zfs/zpl_file.c
@@ -131,12 +131,15 @@ zpl_fsync(struct file *filp, struct dentry *dentry, int datasync)
 	return (error);
 }
 
+#ifdef HAVE_FILE_AIO_FSYNC
 static int
 zpl_aio_fsync(struct kiocb *kiocb, int datasync)
 {
 	struct file *filp = kiocb->ki_filp;
 	return (zpl_fsync(filp, filp->f_path.dentry, datasync));
 }
+#endif
+
 #elif defined(HAVE_FSYNC_WITHOUT_DENTRY)
 /*
  * Linux 2.6.35 - 3.0 API,
@@ -162,11 +165,14 @@ zpl_fsync(struct file *filp, int datasync)
 	return (error);
 }
 
+#ifdef HAVE_FILE_AIO_FSYNC
 static int
 zpl_aio_fsync(struct kiocb *kiocb, int datasync)
 {
 	return (zpl_fsync(kiocb->ki_filp, datasync));
 }
+#endif
+
 #elif defined(HAVE_FSYNC_RANGE)
 /*
  * Linux 3.1 - 3.x API,
@@ -197,11 +203,14 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
 	return (error);
 }
 
+#ifdef HAVE_FILE_AIO_FSYNC
 static int
 zpl_aio_fsync(struct kiocb *kiocb, int datasync)
 {
 	return (zpl_fsync(kiocb->ki_filp, kiocb->ki_pos, -1, datasync));
 }
+#endif
+
 #else
 #error "Unsupported fops->fsync() implementation"
 #endif
@@ -838,7 +847,9 @@ const struct file_operations zpl_file_operations = {
 #endif
 	.mmap		= zpl_mmap,
 	.fsync		= zpl_fsync,
+#ifdef HAVE_FILE_AIO_FSYNC
 	.aio_fsync	= zpl_aio_fsync,
+#endif
 #ifdef HAVE_FILE_FALLOCATE
 	.fallocate	= zpl_fallocate,
 #endif /* HAVE_FILE_FALLOCATE */

Reply via email to