From 4d103c199aae0c8e521baf654733bd6b425ae1e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Tue, 2 Aug 2016 07:19:46 +0200 Subject: [PATCH] - compatibility fixes for linux 4.7 - rel 2 --- linux-4.7.patch | 731 ++++++++++++++++++++++++++++++++++++++++++++++++ zfs.spec | 4 +- 2 files changed, 734 insertions(+), 1 deletion(-) create mode 100644 linux-4.7.patch 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 +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 +Signed-off-by: Brian Behlendorf +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 + + 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 + +- 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 + +- 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 ++ ++ 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 +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 +Signed-off-by: Brian Behlendorf +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 ++ #include ++ ++ 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 ++ #include + #include + +- 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 ++ #include ++ #include ++ ++ 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 +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 +Signed-off-by: Brian Behlendorf +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 + 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 +- 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 ++ 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 +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 +Signed-off-by: Chunwei Chen +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 + + 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 + +- 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 + +- 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 ++ ++ 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, \ 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} -- 2.43.0