1 From fd4c7b7a73fda391f94f58530c86ffa5b2ef8e6f Mon Sep 17 00:00:00 2001
2 From: Chunwei Chen <david.chen@osnexus.com>
3 Date: Wed, 18 May 2016 13:44:13 -0700
4 Subject: [PATCH] Linux 4.7 compat: handler->get() takes both dentry and inode
6 Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
7 Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
10 config/kernel-xattr-handler.m4 | 77 +++++++++++++++++++++++++++---------------
11 include/linux/xattr_compat.h | 15 +++++++-
12 2 files changed, 64 insertions(+), 28 deletions(-)
14 diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
15 index f614287..638557e 100644
16 --- a/config/kernel-xattr-handler.m4
17 +++ b/config/kernel-xattr-handler.m4
18 @@ -62,18 +62,17 @@ dnl # Supported xattr handler get() interfaces checked newest to oldest.
20 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
22 - dnl # 4.4 API change,
23 - dnl # The xattr_handler->get() callback was changed to take a
24 - dnl # attr_handler, and handler_flags argument was removed and
25 - dnl # should be accessed by handler->flags.
26 + dnl # 4.7 API change,
27 + dnl # The xattr_handler->get() callback was changed to take both
28 + dnl # dentry and inode.
30 - AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
31 + AC_MSG_CHECKING([whether xattr_handler->get() wants both dentry and inode])
32 ZFS_LINUX_TRY_COMPILE([
33 #include <linux/xattr.h>
35 int get(const struct xattr_handler *handler,
36 - struct dentry *dentry, const char *name,
37 - void *buffer, size_t size) { return 0; }
38 + struct dentry *dentry, struct inode *inode,
39 + const char *name, void *buffer, size_t size) { return 0; }
40 static const struct xattr_handler
41 xops __attribute__ ((unused)) = {
43 @@ -81,23 +80,22 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
47 - AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
48 + AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
49 [xattr_handler->get() wants xattr_handler])
52 - dnl # 2.6.33 API change,
53 - dnl # The xattr_handler->get() callback was changed to take
54 - dnl # a dentry instead of an inode, and a handler_flags
55 - dnl # argument was added.
56 + dnl # 4.4 API change,
57 + dnl # The xattr_handler->get() callback was changed to take a
58 + dnl # attr_handler, and handler_flags argument was removed and
59 + dnl # should be accessed by handler->flags.
62 - AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
63 + AC_MSG_CHECKING([whether xattr_handler->get() wants xattr_handler])
64 ZFS_LINUX_TRY_COMPILE([
65 #include <linux/xattr.h>
67 - int get(struct dentry *dentry, const char *name,
68 - void *buffer, size_t size, int handler_flags)
70 + int get(const struct xattr_handler *handler,
71 + struct dentry *dentry, const char *name,
72 + void *buffer, size_t size) { return 0; }
73 static const struct xattr_handler
74 xops __attribute__ ((unused)) = {
76 @@ -105,20 +103,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
80 - AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
81 - [xattr_handler->get() wants dentry])
82 + AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
83 + [xattr_handler->get() wants xattr_handler])
87 + dnl # 2.6.33 API change,
88 + dnl # The xattr_handler->get() callback was changed to take
89 + dnl # a dentry instead of an inode, and a handler_flags
90 + dnl # argument was added.
94 - [whether xattr_handler->get() wants inode])
95 + AC_MSG_CHECKING([whether xattr_handler->get() wants dentry])
96 ZFS_LINUX_TRY_COMPILE([
97 #include <linux/xattr.h>
99 - int get(struct inode *ip, const char *name,
100 - void *buffer, size_t size) { return 0; }
101 + int get(struct dentry *dentry, const char *name,
102 + void *buffer, size_t size, int handler_flags)
104 static const struct xattr_handler
105 xops __attribute__ ((unused)) = {
107 @@ -126,10 +127,32 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
111 - AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
112 - [xattr_handler->get() wants inode])
113 + AC_DEFINE(HAVE_XATTR_GET_DENTRY, 1,
114 + [xattr_handler->get() wants dentry])
116 - AC_MSG_ERROR([no; please file a bug report])
122 + [whether xattr_handler->get() wants inode])
123 + ZFS_LINUX_TRY_COMPILE([
124 + #include <linux/xattr.h>
126 + int get(struct inode *ip, const char *name,
127 + void *buffer, size_t size) { return 0; }
128 + static const struct xattr_handler
129 + xops __attribute__ ((unused)) = {
135 + AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
136 + [xattr_handler->get() wants inode])
138 + AC_MSG_ERROR([no; please file a bug report])
143 diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
144 index 5e19ea1..451b654 100644
145 --- a/include/linux/xattr_compat.h
146 +++ b/include/linux/xattr_compat.h
147 @@ -102,12 +102,25 @@ fn(struct inode *ip, char *list, size_t list_size, \
152 + * The xattr_handler->get() callback was changed to take a both dentry and
153 + * inode, because the dentry might not be attached to an inode yet.
155 +#if defined(HAVE_XATTR_GET_DENTRY_INODE)
156 +#define ZPL_XATTR_GET_WRAPPER(fn) \
158 +fn(const struct xattr_handler *handler, struct dentry *dentry, \
159 + struct inode *inode, const char *name, void *buffer, size_t size) \
161 + return (__ ## fn(inode, name, buffer, size)); \
165 * The xattr_handler->get() callback was changed to take a xattr_handler,
166 * and handler_flags argument was removed and should be accessed by
169 -#if defined(HAVE_XATTR_GET_HANDLER)
170 +#elif defined(HAVE_XATTR_GET_HANDLER)
171 #define ZPL_XATTR_GET_WRAPPER(fn) \
173 fn(const struct xattr_handler *handler, struct dentry *dentry, \
174 From 68e8f59afb0fa1b388c7dbb8720ac6756d390146 Mon Sep 17 00:00:00 2001
175 From: Chunwei Chen <david.chen@osnexus.com>
176 Date: Wed, 18 May 2016 13:45:39 -0700
177 Subject: [PATCH] Linux 4.7 compat: replace blk_queue_flush with
178 blk_queue_write_cache
180 Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
181 Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
184 config/kernel-blk-queue-flush.m4 | 55 ++++++++++++++++++++++++++++++++++------
185 include/linux/blkdev_compat.h | 27 ++++++++++++++++++++
186 module/zfs/zvol.c | 4 ++-
187 3 files changed, 77 insertions(+), 9 deletions(-)
189 diff --git a/config/kernel-blk-queue-flush.m4 b/config/kernel-blk-queue-flush.m4
190 index bb74ea1..1baab83 100644
191 --- a/config/kernel-blk-queue-flush.m4
192 +++ b/config/kernel-blk-queue-flush.m4
193 @@ -22,25 +22,64 @@ AC_DEFUN([ZFS_AC_KERNEL_BLK_QUEUE_FLUSH], [
195 AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
196 [blk_queue_flush() is available])
198 + AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
199 + ZFS_LINUX_TRY_COMPILE([
200 + #include <linux/module.h>
201 + #include <linux/blkdev.h>
203 + MODULE_LICENSE("$ZFS_META_LICENSE");
205 + struct request_queue *q = NULL;
206 + (void) blk_queue_flush(q, REQ_FLUSH);
211 + AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
212 + [blk_queue_flush() is GPL-only])
218 - AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
220 + dnl # 4.7 API change
221 + dnl # Replace blk_queue_flush with blk_queue_write_cache
223 + AC_MSG_CHECKING([whether blk_queue_write_cache() exists])
224 ZFS_LINUX_TRY_COMPILE([
225 - #include <linux/module.h>
226 + #include <linux/kernel.h>
227 #include <linux/blkdev.h>
229 - MODULE_LICENSE("$ZFS_META_LICENSE");
231 struct request_queue *q = NULL;
232 - (void) blk_queue_flush(q, REQ_FLUSH);
235 + blk_queue_write_cache(q, true, true);
238 - AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
239 - [blk_queue_flush() is GPL-only])
240 + AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE, 1,
241 + [blk_queue_write_cache() exists])
243 + AC_MSG_CHECKING([whether blk_queue_write_cache() is GPL-only])
244 + ZFS_LINUX_TRY_COMPILE([
245 + #include <linux/kernel.h>
246 + #include <linux/module.h>
247 + #include <linux/blkdev.h>
249 + MODULE_LICENSE("$ZFS_META_LICENSE");
251 + struct request_queue *q = NULL;
252 + blk_queue_write_cache(q, true, true);
257 + AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1,
258 + [blk_queue_write_cache() is GPL-only])
264 EXTRA_KCFLAGS="$tmp_flags"
266 diff --git a/include/linux/blkdev_compat.h b/include/linux/blkdev_compat.h
267 index 0cb0720..42b474b 100644
268 --- a/include/linux/blkdev_compat.h
269 +++ b/include/linux/blkdev_compat.h
270 @@ -52,6 +52,33 @@ __blk_queue_flush(struct request_queue *q, unsigned int flags)
271 q->flush_flags = flags & (REQ_FLUSH | REQ_FUA);
273 #endif /* HAVE_BLK_QUEUE_FLUSH && HAVE_BLK_QUEUE_FLUSH_GPL_ONLY */
277 + * The blk_queue_write_cache() interface has replaced blk_queue_flush()
278 + * interface. However, while the new interface is GPL-only. Thus if the
279 + * GPL-only version is detected we implement our own trivial helper
280 + * compatibility funcion.
282 +#if defined(HAVE_BLK_QUEUE_WRITE_CACHE) && \
283 + defined(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY)
284 +#define blk_queue_write_cache __blk_queue_write_cache
286 +__blk_queue_write_cache(struct request_queue *q, bool wc, bool fua)
288 + spin_lock_irq(q->queue_lock);
290 + queue_flag_set(QUEUE_FLAG_WC, q);
292 + queue_flag_clear(QUEUE_FLAG_WC, q);
294 + queue_flag_set(QUEUE_FLAG_FUA, q);
296 + queue_flag_clear(QUEUE_FLAG_FUA, q);
297 + spin_unlock_irq(q->queue_lock);
302 * Most of the blk_* macros were removed in 2.6.36. Ostensibly this was
303 * done to improve readability and allow easier grepping. However, from
304 diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
305 index be6aea8..9c89493 100644
306 --- a/module/zfs/zvol.c
307 +++ b/module/zfs/zvol.c
308 @@ -1291,7 +1291,9 @@ zvol_alloc(dev_t dev, const char *name)
310 blk_queue_make_request(zv->zv_queue, zvol_request);
312 -#ifdef HAVE_BLK_QUEUE_FLUSH
313 +#ifdef HAVE_BLK_QUEUE_WRITE_CACHE
314 + blk_queue_write_cache(zv->zv_queue, B_TRUE, B_TRUE);
315 +#elif defined(HAVE_BLK_QUEUE_FLUSH)
316 blk_queue_flush(zv->zv_queue, VDEV_REQ_FLUSH | VDEV_REQ_FUA);
318 blk_queue_ordered(zv->zv_queue, QUEUE_ORDERED_DRAIN, NULL);
319 From 9baaa7deae45c8556dfd79b2011234da5cb37b3a Mon Sep 17 00:00:00 2001
320 From: Chunwei Chen <david.chen@osnexus.com>
321 Date: Wed, 18 May 2016 14:30:20 -0700
322 Subject: [PATCH] Linux 4.7 compat: use iterate_shared for concurrent readdir
324 Register iterate_shared if it exists so the kernel will used shared
325 lock and allowing concurrent readdir.
327 Also, use shared lock when doing llseek with SEEK_DATA or SEEK_HOLE
328 to allow concurrent seeking.
330 Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
331 Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
335 config/kernel-vfs-iterate.m4 | 49 +++++++++++++++++++++++++++++++-------------
336 include/sys/zpl.h | 2 +-
337 module/zfs/zpl_ctldir.c | 18 ++++++++++------
338 module/zfs/zpl_file.c | 10 +++++----
339 4 files changed, 54 insertions(+), 25 deletions(-)
341 diff --git a/config/kernel-vfs-iterate.m4 b/config/kernel-vfs-iterate.m4
342 index c2c6562..7b1599e 100644
343 --- a/config/kernel-vfs-iterate.m4
344 +++ b/config/kernel-vfs-iterate.m4
347 -dnl # 3.11 API change
349 AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
350 - AC_MSG_CHECKING([whether fops->iterate() is available])
352 + dnl # 4.7 API change
354 + AC_MSG_CHECKING([whether fops->iterate_shared() is available])
355 ZFS_LINUX_TRY_COMPILE([
356 #include <linux/fs.h>
357 int iterate(struct file *filp, struct dir_context * context)
358 @@ -10,34 +10,55 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
360 static const struct file_operations fops
361 __attribute__ ((unused)) = {
362 - .iterate = iterate,
363 + .iterate_shared = iterate,
368 - AC_DEFINE(HAVE_VFS_ITERATE, 1,
369 - [fops->iterate() is available])
370 + AC_DEFINE(HAVE_VFS_ITERATE_SHARED, 1,
371 + [fops->iterate_shared() is available])
375 - AC_MSG_CHECKING([whether fops->readdir() is available])
377 + dnl # 3.11 API change
379 + AC_MSG_CHECKING([whether fops->iterate() is available])
380 ZFS_LINUX_TRY_COMPILE([
381 #include <linux/fs.h>
382 - int readdir(struct file *filp, void *entry, filldir_t func)
383 + int iterate(struct file *filp, struct dir_context * context)
386 static const struct file_operations fops
387 __attribute__ ((unused)) = {
388 - .readdir = readdir,
389 + .iterate = iterate,
394 - AC_DEFINE(HAVE_VFS_READDIR, 1,
395 - [fops->readdir() is available])
396 + AC_DEFINE(HAVE_VFS_ITERATE, 1,
397 + [fops->iterate() is available])
399 - AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
403 + AC_MSG_CHECKING([whether fops->readdir() is available])
404 + ZFS_LINUX_TRY_COMPILE([
405 + #include <linux/fs.h>
406 + int readdir(struct file *filp, void *entry, filldir_t func)
409 + static const struct file_operations fops
410 + __attribute__ ((unused)) = {
411 + .readdir = readdir,
416 + AC_DEFINE(HAVE_VFS_READDIR, 1,
417 + [fops->readdir() is available])
419 + AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
424 diff --git a/include/sys/zpl.h b/include/sys/zpl.h
425 index 54b35e0..c608548 100644
426 --- a/include/sys/zpl.h
427 +++ b/include/sys/zpl.h
428 @@ -123,7 +123,7 @@ extern const struct inode_operations zpl_ops_snapdirs;
429 extern const struct file_operations zpl_fops_shares;
430 extern const struct inode_operations zpl_ops_shares;
432 -#ifdef HAVE_VFS_ITERATE
433 +#if defined(HAVE_VFS_ITERATE) || defined(HAVE_VFS_ITERATE_SHARED)
435 #define DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \
437 diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
438 index dd02e9e..069834e 100644
439 --- a/module/zfs/zpl_ctldir.c
440 +++ b/module/zfs/zpl_ctldir.c
441 @@ -81,7 +81,7 @@ zpl_root_iterate(struct file *filp, struct dir_context *ctx)
445 -#if !defined(HAVE_VFS_ITERATE)
446 +#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
448 zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
450 @@ -144,7 +144,9 @@ const struct file_operations zpl_fops_root = {
451 .open = zpl_common_open,
452 .llseek = generic_file_llseek,
453 .read = generic_read_dir,
454 -#ifdef HAVE_VFS_ITERATE
455 +#ifdef HAVE_VFS_ITERATE_SHARED
456 + .iterate_shared = zpl_root_iterate,
457 +#elif defined(HAVE_VFS_ITERATE)
458 .iterate = zpl_root_iterate,
460 .readdir = zpl_root_readdir,
461 @@ -285,7 +287,7 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
465 -#if !defined(HAVE_VFS_ITERATE)
466 +#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
468 zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
470 @@ -385,7 +387,9 @@ const struct file_operations zpl_fops_snapdir = {
471 .open = zpl_common_open,
472 .llseek = generic_file_llseek,
473 .read = generic_read_dir,
474 -#ifdef HAVE_VFS_ITERATE
475 +#ifdef HAVE_VFS_ITERATE_SHARED
476 + .iterate_shared = zpl_snapdir_iterate,
477 +#elif defined(HAVE_VFS_ITERATE)
478 .iterate = zpl_snapdir_iterate,
480 .readdir = zpl_snapdir_readdir,
481 @@ -472,7 +476,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
485 -#if !defined(HAVE_VFS_ITERATE)
486 +#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
488 zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
490 @@ -525,7 +529,9 @@ const struct file_operations zpl_fops_shares = {
491 .open = zpl_common_open,
492 .llseek = generic_file_llseek,
493 .read = generic_read_dir,
494 -#ifdef HAVE_VFS_ITERATE
495 +#ifdef HAVE_VFS_ITERATE_SHARED
496 + .iterate_shared = zpl_shares_iterate,
497 +#elif defined(HAVE_VFS_ITERATE)
498 .iterate = zpl_shares_iterate,
500 .readdir = zpl_shares_readdir,
501 diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
502 index 36153cb..4481237 100644
503 --- a/module/zfs/zpl_file.c
504 +++ b/module/zfs/zpl_file.c
505 @@ -93,7 +93,7 @@ zpl_iterate(struct file *filp, struct dir_context *ctx)
509 -#if !defined(HAVE_VFS_ITERATE)
510 +#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
512 zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
514 @@ -421,13 +421,13 @@ zpl_llseek(struct file *filp, loff_t offset, int whence)
515 loff_t maxbytes = ip->i_sb->s_maxbytes;
518 - spl_inode_lock(ip);
519 + spl_inode_lock_shared(ip);
520 cookie = spl_fstrans_mark();
521 error = -zfs_holey(ip, whence, &offset);
522 spl_fstrans_unmark(cookie);
524 error = lseek_execute(filp, ip, offset, maxbytes);
525 - spl_inode_unlock(ip);
526 + spl_inode_unlock_shared(ip);
530 @@ -853,7 +853,9 @@ const struct file_operations zpl_file_operations = {
531 const struct file_operations zpl_dir_file_operations = {
532 .llseek = generic_file_llseek,
533 .read = generic_read_dir,
534 -#ifdef HAVE_VFS_ITERATE
535 +#ifdef HAVE_VFS_ITERATE_SHARED
536 + .iterate_shared = zpl_iterate,
537 +#elif defined(HAVE_VFS_ITERATE)
538 .iterate = zpl_iterate,
540 .readdir = zpl_readdir,
541 From 8fbbc6b4cf13f73d517ec4e826a7069a958fa5ba Mon Sep 17 00:00:00 2001
542 From: Brian Behlendorf <behlendorf1@llnl.gov>
543 Date: Wed, 1 Jun 2016 18:10:06 -0700
544 Subject: [PATCH] Linux 4.7 compat: handler->set() takes both dentry and inode
546 Counterpart to fd4c7b7, the same approach was taken to resolve
547 the compatibility issue.
549 Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
550 Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
554 config/kernel-xattr-handler.m4 | 83 +++++++++++++++++++++++++++---------------
555 include/linux/xattr_compat.h | 16 +++++++-
556 2 files changed, 69 insertions(+), 30 deletions(-)
558 diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
559 index 638557e..dcffd44 100644
560 --- a/config/kernel-xattr-handler.m4
561 +++ b/config/kernel-xattr-handler.m4
562 @@ -81,7 +81,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
565 AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
566 - [xattr_handler->get() wants xattr_handler])
567 + [xattr_handler->get() wants both dentry and inode])
570 dnl # 4.4 API change,
571 @@ -163,18 +163,18 @@ dnl # Supported xattr handler set() interfaces checked newest to oldest.
573 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
575 - dnl # 4.4 API change,
576 - dnl # The xattr_handler->set() callback was changed to take a
577 - dnl # xattr_handler, and handler_flags argument was removed and
578 - dnl # should be accessed by handler->flags.
579 + dnl # 4.7 API change,
580 + dnl # The xattr_handler->set() callback was changed to take both
581 + dnl # dentry and inode.
583 - AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
584 + AC_MSG_CHECKING([whether xattr_handler->set() wants both dentry and inode])
585 ZFS_LINUX_TRY_COMPILE([
586 #include <linux/xattr.h>
588 int set(const struct xattr_handler *handler,
589 - struct dentry *dentry, const char *name,
590 - const void *buffer, size_t size, int flags)
591 + struct dentry *dentry, struct inode *inode,
592 + const char *name, const void *buffer,
593 + size_t size, int flags)
595 static const struct xattr_handler
596 xops __attribute__ ((unused)) = {
597 @@ -183,23 +183,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
601 - AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
602 - [xattr_handler->set() wants xattr_handler])
603 + AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
604 + [xattr_handler->set() wants both dentry and inode])
607 - dnl # 2.6.33 API change,
608 + dnl # 4.4 API change,
609 dnl # The xattr_handler->set() callback was changed to take a
610 - dnl # dentry instead of an inode, and a handler_flags
611 - dnl # argument was added.
612 + dnl # xattr_handler, and handler_flags argument was removed and
613 + dnl # should be accessed by handler->flags.
616 - AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
617 + AC_MSG_CHECKING([whether xattr_handler->set() wants xattr_handler])
618 ZFS_LINUX_TRY_COMPILE([
619 #include <linux/xattr.h>
621 - int set(struct dentry *dentry, const char *name,
622 - const void *buffer, size_t size, int flags,
623 - int handler_flags) { return 0; }
624 + int set(const struct xattr_handler *handler,
625 + struct dentry *dentry, const char *name,
626 + const void *buffer, size_t size, int flags)
628 static const struct xattr_handler
629 xops __attribute__ ((unused)) = {
631 @@ -207,21 +207,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
635 - AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
636 - [xattr_handler->set() wants dentry])
637 + AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
638 + [xattr_handler->set() wants xattr_handler])
642 + dnl # 2.6.33 API change,
643 + dnl # The xattr_handler->set() callback was changed to take a
644 + dnl # dentry instead of an inode, and a handler_flags
645 + dnl # argument was added.
649 - [whether xattr_handler->set() wants inode])
650 + AC_MSG_CHECKING([whether xattr_handler->set() wants dentry])
651 ZFS_LINUX_TRY_COMPILE([
652 #include <linux/xattr.h>
654 - int set(struct inode *ip, const char *name,
655 - const void *buffer, size_t size, int flags)
657 + int set(struct dentry *dentry, const char *name,
658 + const void *buffer, size_t size, int flags,
659 + int handler_flags) { return 0; }
660 static const struct xattr_handler
661 xops __attribute__ ((unused)) = {
663 @@ -229,10 +231,33 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
667 - AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
668 - [xattr_handler->set() wants inode])
669 + AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
670 + [xattr_handler->set() wants dentry])
672 - AC_MSG_ERROR([no; please file a bug report])
678 + [whether xattr_handler->set() wants inode])
679 + ZFS_LINUX_TRY_COMPILE([
680 + #include <linux/xattr.h>
682 + int set(struct inode *ip, const char *name,
683 + const void *buffer, size_t size, int flags)
685 + static const struct xattr_handler
686 + xops __attribute__ ((unused)) = {
692 + AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
693 + [xattr_handler->set() wants inode])
695 + AC_MSG_ERROR([no; please file a bug report])
700 diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
701 index 451b654..b1c4293 100644
702 --- a/include/linux/xattr_compat.h
703 +++ b/include/linux/xattr_compat.h
704 @@ -154,12 +154,26 @@ fn(struct inode *ip, const char *name, void *buffer, size_t size) \
709 + * The xattr_handler->set() callback was changed to take a both dentry and
710 + * inode, because the dentry might not be attached to an inode yet.
712 +#if defined(HAVE_XATTR_SET_DENTRY_INODE)
713 +#define ZPL_XATTR_SET_WRAPPER(fn) \
715 +fn(const struct xattr_handler *handler, struct dentry *dentry, \
716 + struct inode *inode, const char *name, const void *buffer, \
717 + size_t size, int flags) \
719 + return (__ ## fn(inode, name, buffer, size, flags)); \
723 * The xattr_handler->set() callback was changed to take a xattr_handler,
724 * and handler_flags argument was removed and should be accessed by
727 -#if defined(HAVE_XATTR_SET_HANDLER)
728 +#elif defined(HAVE_XATTR_SET_HANDLER)
729 #define ZPL_XATTR_SET_WRAPPER(fn) \
731 fn(const struct xattr_handler *handler, struct dentry *dentry, \