]> git.pld-linux.org Git - packages/zfs.git/blame - kernel-4.11.patch
- upstream fixes for kernel 4.11
[packages/zfs.git] / kernel-4.11.patch
CommitLineData
0994e9e8
JR
1From 4859fe796c5b03687a7b2ab3735b882c4f5cad66 Mon Sep 17 00:00:00 2001
2From: Olaf Faaland <faaland1@llnl.gov>
3Date: Tue, 28 Feb 2017 16:10:18 -0800
4Subject: [PATCH] Linux 4.11 compat: avoid refcount_t name conflict
5
6Linux 4.11 introduces a new type, refcount_t, which conflicts with the
7type of the same name defined within ZFS.
8
9Rename the ZFS type zfs_refcount_t. Within the ZFS code, use a macro to
10cause references to refcount_t to be changed to zfs_refcount_t at
11compile time. This reduces conflicts when later landing OpenZFS
12patches.
13
14Reviewed-by: George Melikov <mail@gmelikov.ru>
15Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
16Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
17Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
18Closes #5823
19Closes #5842
20---
21 include/sys/refcount.h | 17 ++++++++++++++---
22 module/zfs/refcount.c | 2 +-
23 2 files changed, 15 insertions(+), 4 deletions(-)
24
25diff --git a/include/sys/refcount.h b/include/sys/refcount.h
26index 3f50cdd..a96220b 100644
27--- a/include/sys/refcount.h
28+++ b/include/sys/refcount.h
29@@ -41,6 +41,17 @@ extern "C" {
30 */
31 #define FTAG ((char *)__func__)
32
33+/*
34+ * Starting with 4.11, torvalds/linux@f405df5, the linux kernel defines a
35+ * refcount_t type of its own. The macro below effectively changes references
36+ * in the ZFS code from refcount_t to zfs_refcount_t at compile time, so that
37+ * existing code need not be altered, reducing conflicts when landing openZFS
38+ * patches.
39+ */
40+
41+#define refcount_t zfs_refcount_t
42+#define refcount_add zfs_refcount_add
43+
44 #ifdef ZFS_DEBUG
45 typedef struct reference {
46 list_node_t ref_link;
47@@ -56,7 +67,7 @@ typedef struct refcount {
48 list_t rc_removed;
49 int64_t rc_count;
50 int64_t rc_removed_count;
51-} refcount_t;
52+} zfs_refcount_t;
53
54 /* Note: refcount_t must be initialized with refcount_create[_untracked]() */
55
56@@ -67,7 +78,7 @@ void refcount_destroy(refcount_t *rc);
57 void refcount_destroy_many(refcount_t *rc, uint64_t number);
58 int refcount_is_zero(refcount_t *rc);
59 int64_t refcount_count(refcount_t *rc);
60-int64_t refcount_add(refcount_t *rc, void *holder_tag);
61+int64_t zfs_refcount_add(refcount_t *rc, void *holder_tag);
62 int64_t refcount_remove(refcount_t *rc, void *holder_tag);
63 int64_t refcount_add_many(refcount_t *rc, uint64_t number, void *holder_tag);
64 int64_t refcount_remove_many(refcount_t *rc, uint64_t number, void *holder_tag);
65@@ -92,7 +103,7 @@ typedef struct refcount {
66 #define refcount_destroy_many(rc, number) ((rc)->rc_count = 0)
67 #define refcount_is_zero(rc) ((rc)->rc_count == 0)
68 #define refcount_count(rc) ((rc)->rc_count)
69-#define refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
70+#define zfs_refcount_add(rc, holder) atomic_add_64_nv(&(rc)->rc_count, 1)
71 #define refcount_remove(rc, holder) atomic_add_64_nv(&(rc)->rc_count, -1)
72 #define refcount_add_many(rc, number, holder) \
73 atomic_add_64_nv(&(rc)->rc_count, number)
74diff --git a/module/zfs/refcount.c b/module/zfs/refcount.c
75index b338747..a151ace 100644
76--- a/module/zfs/refcount.c
77+++ b/module/zfs/refcount.c
78@@ -143,7 +143,7 @@ refcount_add_many(refcount_t *rc, uint64_t number, void *holder)
79 }
80
81 int64_t
82-refcount_add(refcount_t *rc, void *holder)
83+zfs_refcount_add(refcount_t *rc, void *holder)
84 {
85 return (refcount_add_many(rc, 1, holder));
86 }
87From a3478c074752610814f894375c3d947ece4938fe Mon Sep 17 00:00:00 2001
88From: Olaf Faaland <faaland1@llnl.gov>
89Date: Mon, 20 Mar 2017 17:51:16 -0700
90Subject: [PATCH] Linux 4.11 compat: iops.getattr and friends
91
92In torvalds/linux@a528d35, there are changes to the getattr family of functions,
93struct kstat, and the interface of inode_operations .getattr.
94
95The inode_operations .getattr and simple_getattr() interface changed to:
96
97int (*getattr) (const struct path *, struct dentry *, struct kstat *,
98 u32 request_mask, unsigned int query_flags)
99
100The request_mask argument indicates which field(s) the caller intends to use.
101Fields the caller has not specified via request_mask may be set in the returned
102struct anyway, but their values may be approximate.
103
104The query_flags argument indicates whether the filesystem must update
105the attributes from the backing store.
106
107Currently both fields are ignored. It is possible that getattr-related
108functions within zfs could be optimized based on the request_mask.
109
110struct kstat includes new fields:
111u32 result_mask; /* What fields the user got */
112u64 attributes; /* See STATX_ATTR_* flags */
113struct timespec btime; /* File creation time */
114
115Fields attribute and btime are cleared; the result_mask reflects this. These
116appear to be optional based on simple_getattr() and vfs_getattr() within the
117kernel, which take the same approach.
118
119Reviewed-by: Chunwei Chen <david.chen@osnexus.com>
120Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
121Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
122Closes #5875
123---
124 config/kernel-inode-getattr.m4 | 67 ++++++++++++++++++++++++++++++++++++++++++
125 config/kernel.m4 | 1 +
126 include/linux/vfs_compat.h | 43 +++++++++++++++++++++++++++
127 module/zfs/zpl_ctldir.c | 35 +++++++++++-----------
128 module/zfs/zpl_inode.c | 11 +++++--
129 5 files changed, 138 insertions(+), 19 deletions(-)
130 create mode 100644 config/kernel-inode-getattr.m4
131
132diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
133new file mode 100644
134index 0000000..f10e0b2
135--- /dev/null
136+++ b/config/kernel-inode-getattr.m4
137@@ -0,0 +1,67 @@
138+dnl #
139+dnl # Linux 4.11 API
140+dnl # See torvalds/linux@a528d35
141+dnl #
142+AC_DEFUN([ZFS_AC_PATH_KERNEL_IOPS_GETATTR], [
143+ AC_MSG_CHECKING([whether iops->getattr() takes a path])
144+ ZFS_LINUX_TRY_COMPILE([
145+ #include <linux/fs.h>
146+
147+ int test_getattr(
148+ const struct path *p, struct kstat *k,
149+ u32 request_mask, unsigned int query_flags)
150+ { return 0; }
151+
152+ static const struct inode_operations
153+ iops __attribute__ ((unused)) = {
154+ .getattr = test_getattr,
155+ };
156+ ],[
157+ ],[
158+ AC_MSG_RESULT(yes)
159+ AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
160+ [iops->getattr() takes a path])
161+ ],[
162+ AC_MSG_RESULT(no)
163+ ])
164+])
165+
166+
167+
168+dnl #
169+dnl # Linux 3.9 - 4.10 API
170+dnl #
171+AC_DEFUN([ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR], [
172+ AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
173+ ZFS_LINUX_TRY_COMPILE([
174+ #include <linux/fs.h>
175+
176+ int test_getattr(
177+ struct vfsmount *mnt, struct dentry *d,
178+ struct kstat *k)
179+ { return 0; }
180+
181+ static const struct inode_operations
182+ iops __attribute__ ((unused)) = {
183+ .getattr = test_getattr,
184+ };
185+ ],[
186+ ],[
187+ AC_MSG_RESULT(yes)
188+ AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
189+ [iops->getattr() takes a vfsmount])
190+ ],[
191+ AC_MSG_RESULT(no)
192+ ])
193+])
194+
195+
196+dnl #
197+dnl # The interface of the getattr callback from the inode_operations
198+dnl # structure changed. Also, the interface of the simple_getattr()
199+dnl # function provided by the kernel changed.
200+dnl #
201+AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR], [
202+ ZFS_AC_PATH_KERNEL_IOPS_GETATTR
203+ ZFS_AC_VFSMOUNT_KERNEL_IOPS_GETATTR
204+])
205diff --git a/config/kernel.m4 b/config/kernel.m4
206index 0b50a54..25271ce 100644
207--- a/config/kernel.m4
208+++ b/config/kernel.m4
209@@ -59,6 +59,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [
210 ZFS_AC_KERNEL_INODE_OPERATIONS_CHECK_ACL_WITH_FLAGS
211 ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
212 ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
213+ ZFS_AC_KERNEL_INODE_OPERATIONS_GETATTR
214 ZFS_AC_KERNEL_GET_ACL_HANDLE_CACHE
215 ZFS_AC_KERNEL_SHOW_OPTIONS
216 ZFS_AC_KERNEL_FILE_INODE
217diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h
218index baa2980..cd22b52 100644
219--- a/include/linux/vfs_compat.h
220+++ b/include/linux/vfs_compat.h
221@@ -454,4 +454,47 @@ setattr_prepare(struct dentry *dentry, struct iattr *ia)
222 }
223 #endif
224
225+/*
226+ * 4.11 API change
227+ * These macros are defined by kernel 4.11. We define them so that the same
228+ * code builds under kernels < 4.11 and >= 4.11. The macros are set to 0 so
229+ * that it will create obvious failures if they are accidentally used when built
230+ * against a kernel >= 4.11.
231+ */
232+
233+#ifndef STATX_BASIC_STATS
234+#define STATX_BASIC_STATS 0
235+#endif
236+
237+#ifndef AT_STATX_SYNC_AS_STAT
238+#define AT_STATX_SYNC_AS_STAT 0
239+#endif
240+
241+/*
242+ * 4.11 API change
243+ * 4.11 takes struct path *, < 4.11 takes vfsmount *
244+ */
245+
246+#ifdef HAVE_VFSMOUNT_IOPS_GETATTR
247+#define ZPL_GETATTR_WRAPPER(func) \
248+static int \
249+func(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) \
250+{ \
251+ struct path path = { .mnt = mnt, .dentry = dentry }; \
252+ return func##_impl(&path, stat, STATX_BASIC_STATS, \
253+ AT_STATX_SYNC_AS_STAT); \
254+}
255+#elif defined(HAVE_PATH_IOPS_GETATTR)
256+#define ZPL_GETATTR_WRAPPER(func) \
257+static int \
258+func(const struct path *path, struct kstat *stat, u32 request_mask, \
259+ unsigned int query_flags) \
260+{ \
261+ return (func##_impl(path, stat, request_mask, query_flags)); \
262+}
263+#else
264+#error
265+#endif
266+
267+
268 #endif /* _ZFS_VFS_H */
269diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
270index b6a3b66..bd8af39 100644
271--- a/module/zfs/zpl_ctldir.c
272+++ b/module/zfs/zpl_ctldir.c
273@@ -100,16 +100,15 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
274 */
275 /* ARGSUSED */
276 static int
277-zpl_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
278- struct kstat *stat)
279+zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
280+ u32 request_mask, unsigned int query_flags)
281 {
282- int error;
283-
284- error = simple_getattr(mnt, dentry, stat);
285+ generic_fillattr(path->dentry->d_inode, stat);
286 stat->atime = CURRENT_TIME;
287
288- return (error);
289+ return (0);
290 }
291+ZPL_GETATTR_WRAPPER(zpl_root_getattr);
292
293 static struct dentry *
294 #ifdef HAVE_LOOKUP_NAMEIDATA
295@@ -375,21 +374,22 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, zpl_umode_t mode)
296 */
297 /* ARGSUSED */
298 static int
299-zpl_snapdir_getattr(struct vfsmount *mnt, struct dentry *dentry,
300- struct kstat *stat)
301+zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
302+ u32 request_mask, unsigned int query_flags)
303 {
304- zfs_sb_t *zsb = ITOZSB(dentry->d_inode);
305- int error;
306+ zfs_sb_t *zsb = ITOZSB(path->dentry->d_inode);
307
308 ZFS_ENTER(zsb);
309- error = simple_getattr(mnt, dentry, stat);
310+ generic_fillattr(path->dentry->d_inode, stat);
311+
312 stat->nlink = stat->size = 2;
313 stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zsb->z_os);
314 stat->atime = CURRENT_TIME;
315 ZFS_EXIT(zsb);
316
317- return (error);
318+ return (0);
319 }
320+ZPL_GETATTR_WRAPPER(zpl_snapdir_getattr);
321
322 /*
323 * The '.zfs/snapshot' directory file operations. These mainly control
324@@ -509,10 +509,10 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
325
326 /* ARGSUSED */
327 static int
328-zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
329- struct kstat *stat)
330+zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
331+ u32 request_mask, unsigned int query_flags)
332 {
333- struct inode *ip = dentry->d_inode;
334+ struct inode *ip = path->dentry->d_inode;
335 zfs_sb_t *zsb = ITOZSB(ip);
336 znode_t *dzp;
337 int error;
338@@ -520,11 +520,11 @@ zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
339 ZFS_ENTER(zsb);
340
341 if (zsb->z_shares_dir == 0) {
342- error = simple_getattr(mnt, dentry, stat);
343+ generic_fillattr(path->dentry->d_inode, stat);
344 stat->nlink = stat->size = 2;
345 stat->atime = CURRENT_TIME;
346 ZFS_EXIT(zsb);
347- return (error);
348+ return (0);
349 }
350
351 error = -zfs_zget(zsb, zsb->z_shares_dir, &dzp);
352@@ -538,6 +538,7 @@ zpl_shares_getattr(struct vfsmount *mnt, struct dentry *dentry,
353
354 return (error);
355 }
356+ZPL_GETATTR_WRAPPER(zpl_shares_getattr);
357
358 /*
359 * The '.zfs/shares' directory file operations.
360diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
361index 2e438ea..8351ab5 100644
362--- a/module/zfs/zpl_inode.c
363+++ b/module/zfs/zpl_inode.c
364@@ -340,18 +340,25 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
365 }
366
367 static int
368-zpl_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
369+zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
370+ unsigned int query_flags)
371 {
372 int error;
373 fstrans_cookie_t cookie;
374
375 cookie = spl_fstrans_mark();
376- error = -zfs_getattr_fast(dentry->d_inode, stat);
377+
378+ /*
379+ * XXX request_mask and query_flags currently ignored.
380+ */
381+
382+ error = -zfs_getattr_fast(path->dentry->d_inode, stat);
383 spl_fstrans_unmark(cookie);
384 ASSERT3S(error, <=, 0);
385
386 return (error);
387 }
388+ZPL_GETATTR_WRAPPER(zpl_getattr);
389
390 static int
391 zpl_setattr(struct dentry *dentry, struct iattr *ia)
This page took 0.149668 seconds and 4 git commands to generate.