[packages/zfs] - compatibility fixes for linux 4.7 - rel 2
baggins
baggins at pld-linux.org
Tue Aug 2 07:20:02 CEST 2016
commit 4d103c199aae0c8e521baf654733bd6b425ae1e3
Author: Jan Rękorajski <baggins at pld-linux.org>
Date: Tue Aug 2 07:19:46 2016 +0200
- compatibility fixes for linux 4.7
- rel 2
linux-4.7.patch | 731 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
zfs.spec | 4 +-
2 files changed, 734 insertions(+), 1 deletion(-)
---
diff --git a/zfs.spec b/zfs.spec
index 02c6b7e..0d56ca6 100644
--- a/zfs.spec
+++ b/zfs.spec
@@ -26,8 +26,8 @@ exit 1
%define _duplicate_files_terminate_build 0
+%define rel 2
%define pname zfs
-%define rel 1
Summary: Native Linux port of the ZFS filesystem
Summary(pl.UTF-8): Natywny linuksowy port systemu plików ZFS
Name: %{pname}%{?_pld_builder:%{?with_kernel:-kernel}}%{_alt_kernel}
@@ -39,6 +39,7 @@ Source0: http://archive.zfsonlinux.org/downloads/zfsonlinux/zfs/%{pname}-%{versi
# Source0-md5: b470c0426da6e1e3513f5166c907218d
Patch0: %{pname}-link.patch
Patch1: x32.patch
+Patch2: linux-4.7.patch
URL: http://zfsonlinux.org/
BuildRequires: autoconf >= 2.50
BuildRequires: automake
@@ -219,6 +220,7 @@ p=`pwd`\
%setup -q -n %{pname}-%{version}
%patch0 -p1
%patch1 -p1
+%patch2 -p1
%build
%{__libtoolize}
diff --git a/linux-4.7.patch b/linux-4.7.patch
new file mode 100644
index 0000000..4891997
--- /dev/null
+++ b/linux-4.7.patch
@@ -0,0 +1,731 @@
+From fd4c7b7a73fda391f94f58530c86ffa5b2ef8e6f Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Wed, 18 May 2016 13:44:13 -0700
+Subject: [PATCH] Linux 4.7 compat: handler->get() takes both dentry and inode
+
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Issue #4665
+---
+ config/kernel-xattr-handler.m4 | 77 +++++++++++++++++++++++++++---------------
+ include/linux/xattr_compat.h | 15 +++++++-
+ 2 files changed, 64 insertions(+), 28 deletions(-)
+
+diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
+index f614287..638557e 100644
+--- a/config/kernel-xattr-handler.m4
++++ b/config/kernel-xattr-handler.m4
+@@ -62,18 +62,17 @@ dnl # Supported xattr handler get() interfaces checked newest to oldest.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ dnl #
+- dnl # 4.4 API change,
+- dnl # The xattr_handler->get() callback was changed to take a
+- dnl # attr_handler, and handler_flags argument was removed and
+- dnl # should be accessed by handler->flags.
++ dnl # 4.7 API change,
++ dnl # The xattr_handler->get() callback was changed to take both
++ dnl # dentry and inode.
+ dnl #
+- AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
++ AC_MSG_CHECKING([whether xattr_handler->get() wants both dentry and inode])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+ int get(const struct xattr_handler *handler,
+- struct dentry *dentry, const char *name,
+- void *buffer, size_t size) { return 0; }
++ struct dentry *dentry, struct inode *inode,
++ const char *name, void *buffer, size_t size) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .get = get,
+@@ -81,23 +80,22 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
++ AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
+ [xattr_handler->get() wants xattr_handler])
+ ],[
+ dnl #
+- dnl # 2.6.33 API change,
+- dnl # The xattr_handler->get() callback was changed to take
+- dnl # a dentry instead of an inode, and a handler_flags
+- dnl # argument was added.
++ dnl # 4.4 API change,
++ dnl # The xattr_handler->get() callback was changed to take a
++ dnl # attr_handler, and handler_flags argument was removed and
++ dnl # should be accessed by handler->flags.
+ dnl #
+- AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
++ AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+- int get(struct dentry *dentry, const char *name,
+- void *buffer, size_t size, int handler_flags)
+- { return 0; }
++ int get(const struct xattr_handler *handler,
++ struct dentry *dentry, const char *name,
++ void *buffer, size_t size) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .get = get,
+@@ -105,20 +103,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
+- [xattr_handler->get() wants dentry])
++ AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
++ [xattr_handler->get() wants xattr_handler])
+ ],[
+ dnl #
+- dnl # 2.6.32 API
++ dnl # 2.6.33 API change,
++ dnl # The xattr_handler->get() callback was changed to take
++ dnl # a dentry instead of an inode, and a handler_flags
++ dnl # argument was added.
+ dnl #
+ AC_MSG_RESULT(no)
+- AC_MSG_CHECKING(
+- [whether xattr_handler->get() wants inode])
++ AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+- int get(struct inode *ip, const char *name,
+- void *buffer, size_t size) { return 0; }
++ int get(struct dentry *dentry, const char *name,
++ void *buffer, size_t size, int handler_flags)
++ { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .get = get,
+@@ -126,10 +127,32 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
+- [xattr_handler->get() wants inode])
++ AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
++ [xattr_handler->get() wants dentry])
+ ],[
+- AC_MSG_ERROR([no; please file a bug report])
++ dnl #
++ dnl # 2.6.32 API
++ dnl #
++ AC_MSG_RESULT(no)
++ AC_MSG_CHECKING(
++ [whether xattr_handler->get() wants inode])
++ ZFS_LINUX_TRY_COMPILE([
++ #include <linux/xattr.h>
++
++ int get(struct inode *ip, const char *name,
++ void *buffer, size_t size) { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .get = get,
++ };
++ ],[
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
++ [xattr_handler->get() wants inode])
++ ],[
++ AC_MSG_ERROR([no; please file a bug report])
++ ])
+ ])
+ ])
+ ])
+diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
+index 5e19ea1..451b654 100644
+--- a/include/linux/xattr_compat.h
++++ b/include/linux/xattr_compat.h
+@@ -102,12 +102,25 @@ fn(struct inode *ip, char *list, size_t list_size, \
+ #endif
+
+ /*
++ * 4.7 API change,
++ * The xattr_handler->get() callback was changed to take a both dentry and
++ * inode, because the dentry might not be attached to an inode yet.
++ */
++#if defined(HAVE_XATTR_GET_DENTRY_INODE)
++#define ZPL_XATTR_GET_WRAPPER(fn) \
++static int \
++fn(const struct xattr_handler *handler, struct dentry *dentry, \
++ struct inode *inode, const char *name, void *buffer, size_t size) \
++{ \
++ return (__ ## fn(inode, name, buffer, size)); \
++}
++/*
+ * 4.4 API change,
+ * The xattr_handler->get() callback was changed to take a xattr_handler,
+ * and handler_flags argument was removed and should be accessed by
+ * handler->flags.
+ */
+-#if defined(HAVE_XATTR_GET_HANDLER)
++#elif defined(HAVE_XATTR_GET_HANDLER)
+ #define ZPL_XATTR_GET_WRAPPER(fn) \
+ static int \
+ fn(const struct xattr_handler *handler, struct dentry *dentry, \
+From 68e8f59afb0fa1b388c7dbb8720ac6756d390146 Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Wed, 18 May 2016 13:45:39 -0700
+Subject: [PATCH] Linux 4.7 compat: replace blk_queue_flush with
+ blk_queue_write_cache
+
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Issue #4665
+---
+ config/kernel-blk-queue-flush.m4 | 55 ++++++++++++++++++++++++++++++++++------
+ include/linux/blkdev_compat.h | 27 ++++++++++++++++++++
+ module/zfs/zvol.c | 4 ++-
+ 3 files changed, 77 insertions(+), 9 deletions(-)
+
+diff --git a/config/kernel-blk-queue-flush.m4 b/config/kernel-blk-queue-flush.m4
+index bb74ea1..1baab83 100644
+--- a/config/kernel-blk-queue-flush.m4
++++ b/config/kernel-blk-queue-flush.m4
+@@ -22,25 +22,64 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
+ [blk_queue_flush() is available])
++
++ AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
++ ZFS_LINUX_TRY_COMPILE([
++ #include <linux/module.h>
++ #include <linux/blkdev.h>
++
++ MODULE_LICENSE("$ZFS_META_LICENSE");
++ ],[
++ struct request_queue *q = NULL;
++ (void) blk_queue_flush(q, REQ_FLUSH);
++ ],[
++ AC_MSG_RESULT(no)
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
++ [blk_queue_flush() is GPL-only])
++ ])
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+
+- AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
++ dnl #
++ dnl # 4.7 API change
++ dnl # Replace blk_queue_flush with blk_queue_write_cache
++ dnl #
++ AC_MSG_CHECKING([whether blk_queue_write_cache() exists])
+ ZFS_LINUX_TRY_COMPILE([
+- #include <linux/module.h>
++ #include <linux/kernel.h>
+ #include <linux/blkdev.h>
+
+- MODULE_LICENSE("$ZFS_META_LICENSE");
+ ],[
+ struct request_queue *q = NULL;
+- (void) blk_queue_flush(q, REQ_FLUSH);
+- ],[
+- AC_MSG_RESULT(no)
++ blk_queue_write_cache(q, true, true);
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
+- [blk_queue_flush() is GPL-only])
++ AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1,
++ [blk_queue_write_cache() exists])
++
++ AC_MSG_CHECKING([whether blk_queue_write_cache() is GPL-only])
++ ZFS_LINUX_TRY_COMPILE([
++ #include <linux/kernel.h>
++ #include <linux/module.h>
++ #include <linux/blkdev.h>
++
++ MODULE_LICENSE("$ZFS_META_LICENSE");
++ ],[
++ struct request_queue *q = NULL;
++ blk_queue_write_cache(q, true, true);
++ ],[
++ AC_MSG_RESULT(no)
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1,
++ [blk_queue_write_cache() is GPL-only])
++ ])
++ ],[
++ AC_MSG_RESULT(no)
+ ])
++
+ EXTRA_KCFLAGS="$tmp_flags"
+ ])
+diff --git a/include/linux/blkdev_compat.h b/include/linux/blkdev_compat.h
+index 0cb0720..42b474b 100644
+--- a/include/linux/blkdev_compat.h
++++ b/include/linux/blkdev_compat.h
+@@ -52,6 +52,33 @@ __blk_queue_flush(struct request_queue *q, unsigned int flags)
+ q->flush_flags = flags & (REQ_FLUSH | REQ_FUA);
+ }
+ #endif /* HAVE_BLK_QUEUE_FLUSH && HAVE_BLK_QUEUE_FLUSH_GPL_ONLY */
++
++/*
++ * 4.7 API change,
++ * The blk_queue_write_cache() interface has replaced blk_queue_flush()
++ * interface. However, while the new interface is GPL-only. Thus if the
++ * GPL-only version is detected we implement our own trivial helper
++ * compatibility funcion.
++ */
++#if defined(HAVE_BLK_QUEUE_WRITE_CACHE) && \
++ defined(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY)
++#define blk_queue_write_cache __blk_queue_write_cache
++static inline void
++__blk_queue_write_cache(struct request_queue *q, bool wc, bool fua)
++{
++ spin_lock_irq(q->queue_lock);
++ if (wc)
++ queue_flag_set(QUEUE_FLAG_WC, q);
++ else
++ queue_flag_clear(QUEUE_FLAG_WC, q);
++ if (fua)
++ queue_flag_set(QUEUE_FLAG_FUA, q);
++ else
++ queue_flag_clear(QUEUE_FLAG_FUA, q);
++ spin_unlock_irq(q->queue_lock);
++}
++#endif
++
+ /*
+ * Most of the blk_* macros were removed in 2.6.36. Ostensibly this was
+ * done to improve readability and allow easier grepping. However, from
+diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
+index be6aea8..9c89493 100644
+--- a/module/zfs/zvol.c
++++ b/module/zfs/zvol.c
+@@ -1291,7 +1291,9 @@ zvol_alloc(dev_t dev, const char *name)
+
+ blk_queue_make_request(zv->zv_queue, zvol_request);
+
+-#ifdef HAVE_BLK_QUEUE_FLUSH
++#ifdef HAVE_BLK_QUEUE_WRITE_CACHE
++ blk_queue_write_cache(zv->zv_queue, B_TRUE, B_TRUE);
++#elif defined(HAVE_BLK_QUEUE_FLUSH)
+ blk_queue_flush(zv->zv_queue, VDEV_REQ_FLUSH | VDEV_REQ_FUA);
+ #else
+ blk_queue_ordered(zv->zv_queue, QUEUE_ORDERED_DRAIN, NULL);
+From 9baaa7deae45c8556dfd79b2011234da5cb37b3a Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <david.chen at osnexus.com>
+Date: Wed, 18 May 2016 14:30:20 -0700
+Subject: [PATCH] Linux 4.7 compat: use iterate_shared for concurrent readdir
+
+Register iterate_shared if it exists so the kernel will used shared
+lock and allowing concurrent readdir.
+
+Also, use shared lock when doing llseek with SEEK_DATA or SEEK_HOLE
+to allow concurrent seeking.
+
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Closes #4664
+Closes #4665
+---
+ config/kernel-vfs-iterate.m4 | 49 +++++++++++++++++++++++++++++++-------------
+ include/sys/zpl.h | 2 +-
+ module/zfs/zpl_ctldir.c | 18 ++++++++++------
+ module/zfs/zpl_file.c | 10 +++++----
+ 4 files changed, 54 insertions(+), 25 deletions(-)
+
+diff --git a/config/kernel-vfs-iterate.m4 b/config/kernel-vfs-iterate.m4
+index c2c6562..7b1599e 100644
+--- a/config/kernel-vfs-iterate.m4
++++ b/config/kernel-vfs-iterate.m4
+@@ -1,8 +1,8 @@
+-dnl #
+-dnl # 3.11 API change
+-dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
+- AC_MSG_CHECKING([whether fops->iterate() is available])
++ dnl #
++ dnl # 4.7 API change
++ dnl #
++ AC_MSG_CHECKING([whether fops->iterate_shared() is available])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ int iterate(struct file *filp, struct dir_context * context)
+@@ -10,34 +10,55 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
+
+ static const struct file_operations fops
+ __attribute__ ((unused)) = {
+- .iterate = iterate,
++ .iterate_shared = iterate,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_VFS_ITERATE, 1,
+- [fops->iterate() is available])
++ AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1,
++ [fops->iterate_shared() is available])
+ ],[
+ AC_MSG_RESULT(no)
+
+- AC_MSG_CHECKING([whether fops->readdir() is available])
++ dnl #
++ dnl # 3.11 API change
++ dnl #
++ AC_MSG_CHECKING([whether fops->iterate() is available])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+- int readdir(struct file *filp, void *entry, filldir_t func)
++ int iterate(struct file *filp, struct dir_context * context)
+ { return 0; }
+
+ static const struct file_operations fops
+ __attribute__ ((unused)) = {
+- .readdir = readdir,
++ .iterate = iterate,
+ };
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_VFS_READDIR, 1,
+- [fops->readdir() is available])
++ AC_DEFINE(HAVE_VFS_ITERATE, 1,
++ [fops->iterate() is available])
+ ],[
+- AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
+- ])
++ AC_MSG_RESULT(no)
++
++ AC_MSG_CHECKING([whether fops->readdir() is available])
++ ZFS_LINUX_TRY_COMPILE([
++ #include <linux/fs.h>
++ int readdir(struct file *filp, void *entry, filldir_t func)
++ { return 0; }
+
++ static const struct file_operations fops
++ __attribute__ ((unused)) = {
++ .readdir = readdir,
++ };
++ ],[
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_VFS_READDIR, 1,
++ [fops->readdir() is available])
++ ],[
++ AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
++ ])
++ ])
+ ])
+ ])
+diff --git a/include/sys/zpl.h b/include/sys/zpl.h
+index 54b35e0..c608548 100644
+--- a/include/sys/zpl.h
++++ b/include/sys/zpl.h
+@@ -123,7 +123,7 @@ extern const struct inode_operations zpl_ops_snapdirs;
+ extern const struct file_operations zpl_fops_shares;
+ extern const struct inode_operations zpl_ops_shares;
+
+-#ifdef HAVE_VFS_ITERATE
++#if defined(HAVE_VFS_ITERATE) || defined(HAVE_VFS_ITERATE_SHARED)
+
+ #define DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \
+ .actor = _actor, \
+diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
+index dd02e9e..069834e 100644
+--- a/module/zfs/zpl_ctldir.c
++++ b/module/zfs/zpl_ctldir.c
+@@ -81,7 +81,7 @@ zpl_root_iterate(struct file *filp, struct dir_context *ctx)
+ return (error);
+ }
+
+-#if !defined(HAVE_VFS_ITERATE)
++#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
+ static int
+ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+@@ -144,7 +144,9 @@ const struct file_operations zpl_fops_root = {
+ .open = zpl_common_open,
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+-#ifdef HAVE_VFS_ITERATE
++#ifdef HAVE_VFS_ITERATE_SHARED
++ .iterate_shared = zpl_root_iterate,
++#elif defined(HAVE_VFS_ITERATE)
+ .iterate = zpl_root_iterate,
+ #else
+ .readdir = zpl_root_readdir,
+@@ -285,7 +287,7 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
+ return (error);
+ }
+
+-#if !defined(HAVE_VFS_ITERATE)
++#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
+ static int
+ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+@@ -385,7 +387,9 @@ const struct file_operations zpl_fops_snapdir = {
+ .open = zpl_common_open,
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+-#ifdef HAVE_VFS_ITERATE
++#ifdef HAVE_VFS_ITERATE_SHARED
++ .iterate_shared = zpl_snapdir_iterate,
++#elif defined(HAVE_VFS_ITERATE)
+ .iterate = zpl_snapdir_iterate,
+ #else
+ .readdir = zpl_snapdir_readdir,
+@@ -472,7 +476,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
+ return (error);
+ }
+
+-#if !defined(HAVE_VFS_ITERATE)
++#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
+ static int
+ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+@@ -525,7 +529,9 @@ const struct file_operations zpl_fops_shares = {
+ .open = zpl_common_open,
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+-#ifdef HAVE_VFS_ITERATE
++#ifdef HAVE_VFS_ITERATE_SHARED
++ .iterate_shared = zpl_shares_iterate,
++#elif defined(HAVE_VFS_ITERATE)
+ .iterate = zpl_shares_iterate,
+ #else
+ .readdir = zpl_shares_readdir,
+diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
+index 36153cb..4481237 100644
+--- a/module/zfs/zpl_file.c
++++ b/module/zfs/zpl_file.c
+@@ -93,7 +93,7 @@ zpl_iterate(struct file *filp, struct dir_context *ctx)
+ return (error);
+ }
+
+-#if !defined(HAVE_VFS_ITERATE)
++#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
+ static int
+ zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ {
+@@ -421,13 +421,13 @@ zpl_llseek(struct file *filp, loff_t offset, int whence)
+ loff_t maxbytes = ip->i_sb->s_maxbytes;
+ loff_t error;
+
+- spl_inode_lock(ip);
++ spl_inode_lock_shared(ip);
+ cookie = spl_fstrans_mark();
+ error = -zfs_holey(ip, whence, &offset);
+ spl_fstrans_unmark(cookie);
+ if (error == 0)
+ error = lseek_execute(filp, ip, offset, maxbytes);
+- spl_inode_unlock(ip);
++ spl_inode_unlock_shared(ip);
+
+ return (error);
+ }
+@@ -853,7 +853,9 @@ const struct file_operations zpl_file_operations = {
+ const struct file_operations zpl_dir_file_operations = {
+ .llseek = generic_file_llseek,
+ .read = generic_read_dir,
+-#ifdef HAVE_VFS_ITERATE
++#ifdef HAVE_VFS_ITERATE_SHARED
++ .iterate_shared = zpl_iterate,
++#elif defined(HAVE_VFS_ITERATE)
+ .iterate = zpl_iterate,
+ #else
+ .readdir = zpl_readdir,
+From 8fbbc6b4cf13f73d517ec4e826a7069a958fa5ba Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1 at llnl.gov>
+Date: Wed, 1 Jun 2016 18:10:06 -0700
+Subject: [PATCH] Linux 4.7 compat: handler->set() takes both dentry and inode
+
+Counterpart to fd4c7b7, the same approach was taken to resolve
+the compatibility issue.
+
+Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Chunwei Chen <david.chen at osnexus.com>
+Closes #4717
+Issue #4665
+---
+ config/kernel-xattr-handler.m4 | 83 +++++++++++++++++++++++++++---------------
+ include/linux/xattr_compat.h | 16 +++++++-
+ 2 files changed, 69 insertions(+), 30 deletions(-)
+
+diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
+index 638557e..dcffd44 100644
+--- a/config/kernel-xattr-handler.m4
++++ b/config/kernel-xattr-handler.m4
+@@ -81,7 +81,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
+- [xattr_handler->get() wants xattr_handler])
++ [xattr_handler->get() wants both dentry and inode])
+ ],[
+ dnl #
+ dnl # 4.4 API change,
+@@ -163,18 +163,18 @@ dnl # Supported xattr handler set() interfaces checked newest to oldest.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ dnl #
+- dnl # 4.4 API change,
+- dnl # The xattr_handler->set() callback was changed to take a
+- dnl # xattr_handler, and handler_flags argument was removed and
+- dnl # should be accessed by handler->flags.
++ dnl # 4.7 API change,
++ dnl # The xattr_handler->set() callback was changed to take both
++ dnl # dentry and inode.
+ dnl #
+- AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
++ AC_MSG_CHECKING([whether xattr_handler->set() wants both dentry and inode])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+ int set(const struct xattr_handler *handler,
+- struct dentry *dentry, const char *name,
+- const void *buffer, size_t size, int flags)
++ struct dentry *dentry, struct inode *inode,
++ const char *name, const void *buffer,
++ size_t size, int flags)
+ { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+@@ -183,23 +183,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
+- [xattr_handler->set() wants xattr_handler])
++ AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
++ [xattr_handler->set() wants both dentry and inode])
+ ],[
+ dnl #
+- dnl # 2.6.33 API change,
++ dnl # 4.4 API change,
+ dnl # The xattr_handler->set() callback was changed to take a
+- dnl # dentry instead of an inode, and a handler_flags
+- dnl # argument was added.
++ dnl # xattr_handler, and handler_flags argument was removed and
++ dnl # should be accessed by handler->flags.
+ dnl #
+- AC_MSG_RESULT(no)
+- AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
++ AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+- int set(struct dentry *dentry, const char *name,
+- const void *buffer, size_t size, int flags,
+- int handler_flags) { return 0; }
++ int set(const struct xattr_handler *handler,
++ struct dentry *dentry, const char *name,
++ const void *buffer, size_t size, int flags)
++ { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .set = set,
+@@ -207,21 +207,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
+- [xattr_handler->set() wants dentry])
++ AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
++ [xattr_handler->set() wants xattr_handler])
+ ],[
+ dnl #
+- dnl # 2.6.32 API
++ dnl # 2.6.33 API change,
++ dnl # The xattr_handler->set() callback was changed to take a
++ dnl # dentry instead of an inode, and a handler_flags
++ dnl # argument was added.
+ dnl #
+ AC_MSG_RESULT(no)
+- AC_MSG_CHECKING(
+- [whether xattr_handler->set() wants inode])
++ AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
+ ZFS_LINUX_TRY_COMPILE([
+ #include <linux/xattr.h>
+
+- int set(struct inode *ip, const char *name,
+- const void *buffer, size_t size, int flags)
+- { return 0; }
++ int set(struct dentry *dentry, const char *name,
++ const void *buffer, size_t size, int flags,
++ int handler_flags) { return 0; }
+ static const struct xattr_handler
+ xops __attribute__ ((unused)) = {
+ .set = set,
+@@ -229,10 +231,33 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ ],[
+ ],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
+- [xattr_handler->set() wants inode])
++ AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
++ [xattr_handler->set() wants dentry])
+ ],[
+- AC_MSG_ERROR([no; please file a bug report])
++ dnl #
++ dnl # 2.6.32 API
++ dnl #
++ AC_MSG_RESULT(no)
++ AC_MSG_CHECKING(
++ [whether xattr_handler->set() wants inode])
++ ZFS_LINUX_TRY_COMPILE([
++ #include <linux/xattr.h>
++
++ int set(struct inode *ip, const char *name,
++ const void *buffer, size_t size, int flags)
++ { return 0; }
++ static const struct xattr_handler
++ xops __attribute__ ((unused)) = {
++ .set = set,
++ };
++ ],[
++ ],[
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
++ [xattr_handler->set() wants inode])
++ ],[
++ AC_MSG_ERROR([no; please file a bug report])
++ ])
+ ])
+ ])
+ ])
+diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
+index 451b654..b1c4293 100644
+--- a/include/linux/xattr_compat.h
++++ b/include/linux/xattr_compat.h
+@@ -154,12 +154,26 @@ fn(struct inode *ip, const char *name, void *buffer, size_t size) \
+ #endif
+
+ /*
++ * 4.7 API change,
++ * The xattr_handler->set() callback was changed to take a both dentry and
++ * inode, because the dentry might not be attached to an inode yet.
++ */
++#if defined(HAVE_XATTR_SET_DENTRY_INODE)
++#define ZPL_XATTR_SET_WRAPPER(fn) \
++static int \
++fn(const struct xattr_handler *handler, struct dentry *dentry, \
++ struct inode *inode, const char *name, const void *buffer, \
++ size_t size, int flags) \
++{ \
++ return (__ ## fn(inode, name, buffer, size, flags)); \
++}
++/*
+ * 4.4 API change,
+ * The xattr_handler->set() callback was changed to take a xattr_handler,
+ * and handler_flags argument was removed and should be accessed by
+ * handler->flags.
+ */
+-#if defined(HAVE_XATTR_SET_HANDLER)
++#elif defined(HAVE_XATTR_SET_HANDLER)
+ #define ZPL_XATTR_SET_WRAPPER(fn) \
+ static int \
+ fn(const struct xattr_handler *handler, struct dentry *dentry, \
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/zfs.git/commitdiff/4d103c199aae0c8e521baf654733bd6b425ae1e3
More information about the pld-cvs-commit
mailing list