]> git.pld-linux.org Git - packages/zfs.git/blame_incremental - linux-4.7.patch
- compatibility fixes for linux 4.7
[packages/zfs.git] / linux-4.7.patch
... / ...
CommitLineData
1From fd4c7b7a73fda391f94f58530c86ffa5b2ef8e6f Mon Sep 17 00:00:00 2001
2From: Chunwei Chen <david.chen@osnexus.com>
3Date: Wed, 18 May 2016 13:44:13 -0700
4Subject: [PATCH] Linux 4.7 compat: handler->get() takes both dentry and inode
5
6Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
7Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
8Issue #4665
9---
10 config/kernel-xattr-handler.m4 | 77 +++++++++++++++++++++++++++---------------
11 include/linux/xattr_compat.h | 15 +++++++-
12 2 files changed, 64 insertions(+), 28 deletions(-)
13
14diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
15index 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.
19 dnl #
20 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
21 dnl #
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.
29 dnl #
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>
34
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)) = {
42 .get = get,
43@@ -81,23 +80,22 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
44 ],[
45 ],[
46 AC_MSG_RESULT(yes)
47- AC_DEFINE(HAVE_XATTR_GET_HANDLER, 1,
48+ AC_DEFINE(HAVE_XATTR_GET_DENTRY_INODE, 1,
49 [xattr_handler->get() wants xattr_handler])
50 ],[
51 dnl #
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.
60 dnl #
61- AC_MSG_RESULT(no)
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>
66
67- int get(struct dentry *dentry, const char *name,
68- void *buffer, size_t size, int handler_flags)
69- { return 0; }
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)) = {
75 .get = get,
76@@ -105,20 +103,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
77 ],[
78 ],[
79 AC_MSG_RESULT(yes)
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])
84 ],[
85 dnl #
86- dnl # 2.6.32 API
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.
91 dnl #
92 AC_MSG_RESULT(no)
93- AC_MSG_CHECKING(
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>
98
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)
103+ { return 0; }
104 static const struct xattr_handler
105 xops __attribute__ ((unused)) = {
106 .get = get,
107@@ -126,10 +127,32 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET], [
108 ],[
109 ],[
110 AC_MSG_RESULT(yes)
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])
115 ],[
116- AC_MSG_ERROR([no; please file a bug report])
117+ dnl #
118+ dnl # 2.6.32 API
119+ dnl #
120+ AC_MSG_RESULT(no)
121+ AC_MSG_CHECKING(
122+ [whether xattr_handler->get() wants inode])
123+ ZFS_LINUX_TRY_COMPILE([
124+ #include <linux/xattr.h>
125+
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)) = {
130+ .get = get,
131+ };
132+ ],[
133+ ],[
134+ AC_MSG_RESULT(yes)
135+ AC_DEFINE(HAVE_XATTR_GET_INODE, 1,
136+ [xattr_handler->get() wants inode])
137+ ],[
138+ AC_MSG_ERROR([no; please file a bug report])
139+ ])
140 ])
141 ])
142 ])
143diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
144index 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, \
148 #endif
149
150 /*
151+ * 4.7 API change,
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.
154+ */
155+#if defined(HAVE_XATTR_GET_DENTRY_INODE)
156+#define ZPL_XATTR_GET_WRAPPER(fn) \
157+static int \
158+fn(const struct xattr_handler *handler, struct dentry *dentry, \
159+ struct inode *inode, const char *name, void *buffer, size_t size) \
160+{ \
161+ return (__ ## fn(inode, name, buffer, size)); \
162+}
163+/*
164 * 4.4 API change,
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
167 * handler->flags.
168 */
169-#if defined(HAVE_XATTR_GET_HANDLER)
170+#elif defined(HAVE_XATTR_GET_HANDLER)
171 #define ZPL_XATTR_GET_WRAPPER(fn) \
172 static int \
173 fn(const struct xattr_handler *handler, struct dentry *dentry, \
174From 68e8f59afb0fa1b388c7dbb8720ac6756d390146 Mon Sep 17 00:00:00 2001
175From: Chunwei Chen <david.chen@osnexus.com>
176Date: Wed, 18 May 2016 13:45:39 -0700
177Subject: [PATCH] Linux 4.7 compat: replace blk_queue_flush with
178 blk_queue_write_cache
179
180Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
181Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
182Issue #4665
183---
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(-)
188
189diff --git a/config/kernel-blk-queue-flush.m4 b/config/kernel-blk-queue-flush.m4
190index 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], [
194 AC_MSG_RESULT(yes)
195 AC_DEFINE(HAVE_BLK_QUEUE_FLUSH, 1,
196 [blk_queue_flush() is available])
197+
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>
202+
203+ MODULE_LICENSE("$ZFS_META_LICENSE");
204+ ],[
205+ struct request_queue *q = NULL;
206+ (void) blk_queue_flush(q, REQ_FLUSH);
207+ ],[
208+ AC_MSG_RESULT(no)
209+ ],[
210+ AC_MSG_RESULT(yes)
211+ AC_DEFINE(HAVE_BLK_QUEUE_FLUSH_GPL_ONLY, 1,
212+ [blk_queue_flush() is GPL-only])
213+ ])
214 ],[
215 AC_MSG_RESULT(no)
216 ])
217
218- AC_MSG_CHECKING([whether blk_queue_flush() is GPL-only])
219+ dnl #
220+ dnl # 4.7 API change
221+ dnl # Replace blk_queue_flush with blk_queue_write_cache
222+ dnl #
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>
228
229- MODULE_LICENSE("$ZFS_META_LICENSE");
230 ],[
231 struct request_queue *q = NULL;
232- (void) blk_queue_flush(q, REQ_FLUSH);
233- ],[
234- AC_MSG_RESULT(no)
235+ blk_queue_write_cache(q, true, true);
236 ],[
237 AC_MSG_RESULT(yes)
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])
242+
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>
248+
249+ MODULE_LICENSE("$ZFS_META_LICENSE");
250+ ],[
251+ struct request_queue *q = NULL;
252+ blk_queue_write_cache(q, true, true);
253+ ],[
254+ AC_MSG_RESULT(no)
255+ ],[
256+ AC_MSG_RESULT(yes)
257+ AC_DEFINE(HAVE_BLK_QUEUE_WRITE_CACHE_GPL_ONLY, 1,
258+ [blk_queue_write_cache() is GPL-only])
259+ ])
260+ ],[
261+ AC_MSG_RESULT(no)
262 ])
263+
264 EXTRA_KCFLAGS="$tmp_flags"
265 ])
266diff --git a/include/linux/blkdev_compat.h b/include/linux/blkdev_compat.h
267index 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);
272 }
273 #endif /* HAVE_BLK_QUEUE_FLUSH && HAVE_BLK_QUEUE_FLUSH_GPL_ONLY */
274+
275+/*
276+ * 4.7 API change,
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.
281+ */
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
285+static inline void
286+__blk_queue_write_cache(struct request_queue *q, bool wc, bool fua)
287+{
288+ spin_lock_irq(q->queue_lock);
289+ if (wc)
290+ queue_flag_set(QUEUE_FLAG_WC, q);
291+ else
292+ queue_flag_clear(QUEUE_FLAG_WC, q);
293+ if (fua)
294+ queue_flag_set(QUEUE_FLAG_FUA, q);
295+ else
296+ queue_flag_clear(QUEUE_FLAG_FUA, q);
297+ spin_unlock_irq(q->queue_lock);
298+}
299+#endif
300+
301 /*
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
304diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
305index 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)
309
310 blk_queue_make_request(zv->zv_queue, zvol_request);
311
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);
317 #else
318 blk_queue_ordered(zv->zv_queue, QUEUE_ORDERED_DRAIN, NULL);
319From 9baaa7deae45c8556dfd79b2011234da5cb37b3a Mon Sep 17 00:00:00 2001
320From: Chunwei Chen <david.chen@osnexus.com>
321Date: Wed, 18 May 2016 14:30:20 -0700
322Subject: [PATCH] Linux 4.7 compat: use iterate_shared for concurrent readdir
323
324Register iterate_shared if it exists so the kernel will used shared
325lock and allowing concurrent readdir.
326
327Also, use shared lock when doing llseek with SEEK_DATA or SEEK_HOLE
328to allow concurrent seeking.
329
330Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
331Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
332Closes #4664
333Closes #4665
334---
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(-)
340
341diff --git a/config/kernel-vfs-iterate.m4 b/config/kernel-vfs-iterate.m4
342index c2c6562..7b1599e 100644
343--- a/config/kernel-vfs-iterate.m4
344+++ b/config/kernel-vfs-iterate.m4
345@@ -1,8 +1,8 @@
346-dnl #
347-dnl # 3.11 API change
348-dnl #
349 AC_DEFUN([ZFS_AC_KERNEL_VFS_ITERATE], [
350- AC_MSG_CHECKING([whether fops->iterate() is available])
351+ dnl #
352+ dnl # 4.7 API change
353+ dnl #
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], [
359
360 static const struct file_operations fops
361 __attribute__ ((unused)) = {
362- .iterate = iterate,
363+ .iterate_shared = iterate,
364 };
365 ],[
366 ],[
367 AC_MSG_RESULT(yes)
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])
372 ],[
373 AC_MSG_RESULT(no)
374
375- AC_MSG_CHECKING([whether fops->readdir() is available])
376+ dnl #
377+ dnl # 3.11 API change
378+ dnl #
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)
384 { return 0; }
385
386 static const struct file_operations fops
387 __attribute__ ((unused)) = {
388- .readdir = readdir,
389+ .iterate = iterate,
390 };
391 ],[
392 ],[
393 AC_MSG_RESULT(yes)
394- AC_DEFINE(HAVE_VFS_READDIR, 1,
395- [fops->readdir() is available])
396+ AC_DEFINE(HAVE_VFS_ITERATE, 1,
397+ [fops->iterate() is available])
398 ],[
399- AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
400- ])
401+ AC_MSG_RESULT(no)
402+
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)
407+ { return 0; }
408
409+ static const struct file_operations fops
410+ __attribute__ ((unused)) = {
411+ .readdir = readdir,
412+ };
413+ ],[
414+ ],[
415+ AC_MSG_RESULT(yes)
416+ AC_DEFINE(HAVE_VFS_READDIR, 1,
417+ [fops->readdir() is available])
418+ ],[
419+ AC_MSG_ERROR(no; file a bug report with ZFSOnLinux)
420+ ])
421+ ])
422 ])
423 ])
424diff --git a/include/sys/zpl.h b/include/sys/zpl.h
425index 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;
431
432-#ifdef HAVE_VFS_ITERATE
433+#if defined(HAVE_VFS_ITERATE) || defined(HAVE_VFS_ITERATE_SHARED)
434
435 #define DIR_CONTEXT_INIT(_dirent, _actor, _pos) { \
436 .actor = _actor, \
437diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
438index 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)
442 return (error);
443 }
444
445-#if !defined(HAVE_VFS_ITERATE)
446+#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
447 static int
448 zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
449 {
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,
459 #else
460 .readdir = zpl_root_readdir,
461@@ -285,7 +287,7 @@ zpl_snapdir_iterate(struct file *filp, struct dir_context *ctx)
462 return (error);
463 }
464
465-#if !defined(HAVE_VFS_ITERATE)
466+#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
467 static int
468 zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
469 {
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,
479 #else
480 .readdir = zpl_snapdir_readdir,
481@@ -472,7 +476,7 @@ zpl_shares_iterate(struct file *filp, struct dir_context *ctx)
482 return (error);
483 }
484
485-#if !defined(HAVE_VFS_ITERATE)
486+#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
487 static int
488 zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
489 {
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,
499 #else
500 .readdir = zpl_shares_readdir,
501diff --git a/module/zfs/zpl_file.c b/module/zfs/zpl_file.c
502index 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)
506 return (error);
507 }
508
509-#if !defined(HAVE_VFS_ITERATE)
510+#if !defined(HAVE_VFS_ITERATE) && !defined(HAVE_VFS_ITERATE_SHARED)
511 static int
512 zpl_readdir(struct file *filp, void *dirent, filldir_t filldir)
513 {
514@@ -421,13 +421,13 @@ zpl_llseek(struct file *filp, loff_t offset, int whence)
515 loff_t maxbytes = ip->i_sb->s_maxbytes;
516 loff_t error;
517
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);
523 if (error == 0)
524 error = lseek_execute(filp, ip, offset, maxbytes);
525- spl_inode_unlock(ip);
526+ spl_inode_unlock_shared(ip);
527
528 return (error);
529 }
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,
539 #else
540 .readdir = zpl_readdir,
541From 8fbbc6b4cf13f73d517ec4e826a7069a958fa5ba Mon Sep 17 00:00:00 2001
542From: Brian Behlendorf <behlendorf1@llnl.gov>
543Date: Wed, 1 Jun 2016 18:10:06 -0700
544Subject: [PATCH] Linux 4.7 compat: handler->set() takes both dentry and inode
545
546Counterpart to fd4c7b7, the same approach was taken to resolve
547the compatibility issue.
548
549Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
550Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
551Closes #4717
552Issue #4665
553---
554 config/kernel-xattr-handler.m4 | 83 +++++++++++++++++++++++++++---------------
555 include/linux/xattr_compat.h | 16 +++++++-
556 2 files changed, 69 insertions(+), 30 deletions(-)
557
558diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
559index 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], [
563 ],[
564 AC_MSG_RESULT(yes)
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])
568 ],[
569 dnl #
570 dnl # 4.4 API change,
571@@ -163,18 +163,18 @@ dnl # Supported xattr handler set() interfaces checked newest to oldest.
572 dnl #
573 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
574 dnl #
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.
582 dnl #
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>
587
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)
594 { return 0; }
595 static const struct xattr_handler
596 xops __attribute__ ((unused)) = {
597@@ -183,23 +183,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
598 ],[
599 ],[
600 AC_MSG_RESULT(yes)
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])
605 ],[
606 dnl #
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.
614 dnl #
615- AC_MSG_RESULT(no)
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>
620
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)
627+ { return 0; }
628 static const struct xattr_handler
629 xops __attribute__ ((unused)) = {
630 .set = set,
631@@ -207,21 +207,23 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
632 ],[
633 ],[
634 AC_MSG_RESULT(yes)
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])
639 ],[
640 dnl #
641- dnl # 2.6.32 API
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.
646 dnl #
647 AC_MSG_RESULT(no)
648- AC_MSG_CHECKING(
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>
653
654- int set(struct inode *ip, const char *name,
655- const void *buffer, size_t size, int flags)
656- { return 0; }
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)) = {
662 .set = set,
663@@ -229,10 +231,33 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
664 ],[
665 ],[
666 AC_MSG_RESULT(yes)
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])
671 ],[
672- AC_MSG_ERROR([no; please file a bug report])
673+ dnl #
674+ dnl # 2.6.32 API
675+ dnl #
676+ AC_MSG_RESULT(no)
677+ AC_MSG_CHECKING(
678+ [whether xattr_handler->set() wants inode])
679+ ZFS_LINUX_TRY_COMPILE([
680+ #include <linux/xattr.h>
681+
682+ int set(struct inode *ip, const char *name,
683+ const void *buffer, size_t size, int flags)
684+ { return 0; }
685+ static const struct xattr_handler
686+ xops __attribute__ ((unused)) = {
687+ .set = set,
688+ };
689+ ],[
690+ ],[
691+ AC_MSG_RESULT(yes)
692+ AC_DEFINE(HAVE_XATTR_SET_INODE, 1,
693+ [xattr_handler->set() wants inode])
694+ ],[
695+ AC_MSG_ERROR([no; please file a bug report])
696+ ])
697 ])
698 ])
699 ])
700diff --git a/include/linux/xattr_compat.h b/include/linux/xattr_compat.h
701index 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) \
705 #endif
706
707 /*
708+ * 4.7 API change,
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.
711+ */
712+#if defined(HAVE_XATTR_SET_DENTRY_INODE)
713+#define ZPL_XATTR_SET_WRAPPER(fn) \
714+static int \
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) \
718+{ \
719+ return (__ ## fn(inode, name, buffer, size, flags)); \
720+}
721+/*
722 * 4.4 API change,
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
725 * handler->flags.
726 */
727-#if defined(HAVE_XATTR_SET_HANDLER)
728+#elif defined(HAVE_XATTR_SET_HANDLER)
729 #define ZPL_XATTR_SET_WRAPPER(fn) \
730 static int \
731 fn(const struct xattr_handler *handler, struct dentry *dentry, \
This page took 0.066148 seconds and 4 git commands to generate.