]> git.pld-linux.org Git - packages/zfs.git/blob - kernel-4.11.patch
- upstream fixes for kernel 4.11
[packages/zfs.git] / kernel-4.11.patch
1 From 4859fe796c5b03687a7b2ab3735b882c4f5cad66 Mon Sep 17 00:00:00 2001
2 From: Olaf Faaland <faaland1@llnl.gov>
3 Date: Tue, 28 Feb 2017 16:10:18 -0800
4 Subject: [PATCH] Linux 4.11 compat: avoid refcount_t name conflict
5
6 Linux 4.11 introduces a new type, refcount_t, which conflicts with the
7 type of the same name defined within ZFS.
8
9 Rename the ZFS type zfs_refcount_t.  Within the ZFS code, use a macro to
10 cause references to refcount_t to be changed to zfs_refcount_t at
11 compile time.  This reduces conflicts when later landing OpenZFS
12 patches.
13
14 Reviewed-by: George Melikov <mail@gmelikov.ru>
15 Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
16 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
17 Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
18 Closes #5823
19 Closes #5842
20 ---
21  include/sys/refcount.h | 17 ++++++++++++++---
22  module/zfs/refcount.c  |  2 +-
23  2 files changed, 15 insertions(+), 4 deletions(-)
24
25 diff --git a/include/sys/refcount.h b/include/sys/refcount.h
26 index 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)
74 diff --git a/module/zfs/refcount.c b/module/zfs/refcount.c
75 index 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  }
87 From a3478c074752610814f894375c3d947ece4938fe Mon Sep 17 00:00:00 2001
88 From: Olaf Faaland <faaland1@llnl.gov>
89 Date: Mon, 20 Mar 2017 17:51:16 -0700
90 Subject: [PATCH] Linux 4.11 compat: iops.getattr and friends
91
92 In torvalds/linux@a528d35, there are changes to the getattr family of functions,
93 struct kstat, and the interface of inode_operations .getattr.
94
95 The inode_operations .getattr and simple_getattr() interface changed to:
96
97 int (*getattr) (const struct path *, struct dentry *, struct kstat *,
98     u32 request_mask, unsigned int query_flags)
99
100 The request_mask argument indicates which field(s) the caller intends to use.
101 Fields the caller has not specified via request_mask may be set in the returned
102 struct anyway, but their values may be approximate.
103
104 The query_flags argument indicates whether the filesystem must update
105 the attributes from the backing store.
106
107 Currently both fields are ignored.  It is possible that getattr-related
108 functions within zfs could be optimized based on the request_mask.
109
110 struct kstat includes new fields:
111 u32               result_mask;  /* What fields the user got */
112 u64               attributes;   /* See STATX_ATTR_* flags */
113 struct timespec   btime;        /* File creation time */
114
115 Fields attribute and btime are cleared; the result_mask reflects this.  These
116 appear to be optional based on simple_getattr() and vfs_getattr() within the
117 kernel, which take the same approach.
118
119 Reviewed-by: Chunwei Chen <david.chen@osnexus.com>
120 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
121 Signed-off-by: Olaf Faaland <faaland1@llnl.gov>
122 Closes #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
132 diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
133 new file mode 100644
134 index 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 +])
205 diff --git a/config/kernel.m4 b/config/kernel.m4
206 index 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
217 diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h
218 index 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 */
269 diff --git a/module/zfs/zpl_ctldir.c b/module/zfs/zpl_ctldir.c
270 index 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.
360 diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
361 index 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.065024 seconds and 3 git commands to generate.