Whamcloud - gitweb
LU-12477 lustre: remove obsolete config checks
[fs/lustre-release.git] / lustre / include / lustre_compat.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32
33 #ifndef _LUSTRE_COMPAT_H
34 #define _LUSTRE_COMPAT_H
35
36 #include <linux/aio.h>
37 #include <linux/fs.h>
38 #include <linux/fs_struct.h>
39 #include <linux/namei.h>
40 #include <linux/pagemap.h>
41 #include <linux/posix_acl_xattr.h>
42 #include <linux/bio.h>
43 #include <linux/xattr.h>
44 #include <linux/workqueue.h>
45 #include <linux/blkdev.h>
46 #include <linux/slab.h>
47
48 #include <libcfs/linux/linux-fs.h>
49 #include <obd_support.h>
50
51 #ifdef HAVE_4ARGS_VFS_SYMLINK
52 #define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
53                 vfs_symlink(dir, dentry, path, mode)
54 #else
55 #define ll_vfs_symlink(dir, dentry, mnt, path, mode) \
56                        vfs_symlink(dir, dentry, path)
57 #endif
58
59 #ifndef HAVE_INIT_LIST_HEAD_RCU
60 static inline void INIT_LIST_HEAD_RCU(struct list_head *list)
61 {
62         WRITE_ONCE(list->next, list);
63         WRITE_ONCE(list->prev, list);
64 }
65 #endif
66
67 #ifdef HAVE_BVEC_ITER
68 #define bio_idx(bio)                    (bio->bi_iter.bi_idx)
69 #define bio_set_sector(bio, sector)     (bio->bi_iter.bi_sector = sector)
70 #define bvl_to_page(bvl)                (bvl->bv_page)
71 #else
72 #define bio_idx(bio)                    (bio->bi_idx)
73 #define bio_set_sector(bio, sector)     (bio->bi_sector = sector)
74 #define bio_sectors(bio)                ((bio)->bi_size >> 9)
75 #define bvl_to_page(bvl)                (bvl->bv_page)
76 #endif
77
78 #ifdef HAVE_BVEC_ITER
79 #define bio_start_sector(bio) (bio->bi_iter.bi_sector)
80 #else
81 #define bio_start_sector(bio) (bio->bi_sector)
82 #endif
83
84 #ifndef HAVE_DENTRY_D_CHILD
85 #define d_child                 d_u.d_child
86 #endif
87
88 #ifdef HAVE_DENTRY_D_U_D_ALIAS
89 #define d_alias                 d_u.d_alias
90 #endif
91
92 #ifndef HAVE_D_IN_LOOKUP
93 static inline int d_in_lookup(struct dentry *dentry)
94 {
95         return false;
96 }
97 #endif
98
99 #ifndef HAVE_VM_FAULT_T
100 #define vm_fault_t int
101 #endif
102
103 #ifndef HAVE_FOP_ITERATE_SHARED
104 #define iterate_shared iterate
105 #endif
106
107 #ifdef HAVE_OLDSIZE_TRUNCATE_PAGECACHE
108 #define ll_truncate_pagecache(inode, size) truncate_pagecache(inode, 0, size)
109 #else
110 #define ll_truncate_pagecache(inode, size) truncate_pagecache(inode, size)
111 #endif
112
113 #ifdef HAVE_VFS_RENAME_5ARGS
114 #define ll_vfs_rename(a, b, c, d) vfs_rename(a, b, c, d, NULL)
115 #elif defined HAVE_VFS_RENAME_6ARGS
116 #define ll_vfs_rename(a, b, c, d) vfs_rename(a, b, c, d, NULL, 0)
117 #else
118 #define ll_vfs_rename(a, b, c, d) vfs_rename(a, b, c, d)
119 #endif
120
121 #ifdef HAVE_VFS_UNLINK_3ARGS
122 #define ll_vfs_unlink(a, b) vfs_unlink(a, b, NULL)
123 #else
124 #define ll_vfs_unlink(a, b) vfs_unlink(a, b)
125 #endif
126
127 static inline int ll_vfs_getattr(struct path *path, struct kstat *st)
128 {
129         int rc;
130
131 #ifdef HAVE_INODEOPS_ENHANCED_GETATTR
132         rc = vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
133 #else
134         rc = vfs_getattr(path, st);
135 #endif
136         return rc;
137 }
138
139 #ifndef HAVE_D_IS_POSITIVE
140 static inline bool d_is_positive(const struct dentry *dentry)
141 {
142         return dentry->d_inode != NULL;
143 }
144 #endif
145
146 #ifndef HAVE_INODE_LOCK
147 # define inode_lock(inode) mutex_lock(&(inode)->i_mutex)
148 # define inode_unlock(inode) mutex_unlock(&(inode)->i_mutex)
149 # define inode_trylock(inode) mutex_trylock(&(inode)->i_mutex)
150 #endif
151
152 #ifndef HAVE_XA_IS_VALUE
153 static inline bool xa_is_value(void *entry)
154 {
155         return radix_tree_exceptional_entry(entry);
156 }
157 #endif
158
159 #ifndef HAVE_TRUNCATE_INODE_PAGES_FINAL
160 static inline void truncate_inode_pages_final(struct address_space *map)
161 {
162         truncate_inode_pages(map, 0);
163 }
164 #endif
165
166 #ifndef HAVE_PTR_ERR_OR_ZERO
167 static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr)
168 {
169         if (IS_ERR(ptr))
170                 return PTR_ERR(ptr);
171         else
172                 return 0;
173 }
174 #endif
175
176 #ifdef HAVE_PID_NS_FOR_CHILDREN
177 # define ll_task_pid_ns(task) \
178          ((task)->nsproxy ? ((task)->nsproxy->pid_ns_for_children) : NULL)
179 #else
180 # define ll_task_pid_ns(task) \
181          ((task)->nsproxy ? ((task)->nsproxy->pid_ns) : NULL)
182 #endif
183
184 #ifdef HAVE_FULL_NAME_HASH_3ARGS
185 # define ll_full_name_hash(salt, name, len) full_name_hash(salt, name, len)
186 #else
187 # define ll_full_name_hash(salt, name, len) full_name_hash(name, len)
188 #endif
189
190 #ifdef HAVE_STRUCT_POSIX_ACL_XATTR
191 # define posix_acl_xattr_header struct posix_acl_xattr_header
192 # define posix_acl_xattr_entry  struct posix_acl_xattr_entry
193 # define GET_POSIX_ACL_XATTR_ENTRY(head) ((void *)((head) + 1))
194 #else
195 # define GET_POSIX_ACL_XATTR_ENTRY(head) ((head)->a_entries)
196 #endif
197
198 #ifdef HAVE_IOP_XATTR
199 #define ll_setxattr     generic_setxattr
200 #define ll_getxattr     generic_getxattr
201 #define ll_removexattr  generic_removexattr
202 #endif /* HAVE_IOP_XATTR */
203
204 #ifndef HAVE_VFS_SETXATTR
205 const struct xattr_handler *get_xattr_type(const char *name);
206
207 static inline int
208 __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
209                const void *value, size_t size, int flags)
210 {
211         const struct xattr_handler *handler;
212         int rc;
213
214         handler = get_xattr_type(name);
215         if (!handler)
216                 return -EOPNOTSUPP;
217
218 #  if defined(HAVE_XATTR_HANDLER_INODE_PARAM)
219         rc = handler->set(handler, dentry, inode, name, value, size, flags);
220 #  elif defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
221         rc = handler->set(handler, dentry, name, value, size, flags);
222 #  else
223         rc = handler->set(dentry, name, value, size, flags, handler->flags);
224 #  endif /* !HAVE_XATTR_HANDLER_INODE_PARAM */
225         return rc;
226 }
227 #endif /* HAVE_VFS_SETXATTR */
228
229 #ifndef HAVE_POSIX_ACL_VALID_USER_NS
230 #define posix_acl_valid(a,b)            posix_acl_valid(b)
231 #endif
232
233 #ifdef HAVE_IOP_SET_ACL
234 #ifdef CONFIG_LUSTRE_FS_POSIX_ACL
235 #ifndef HAVE_POSIX_ACL_UPDATE_MODE
236 static inline int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
237                           struct posix_acl **acl)
238 {
239         umode_t mode = inode->i_mode;
240         int error;
241
242         error = posix_acl_equiv_mode(*acl, &mode);
243         if (error < 0)
244                 return error;
245         if (error == 0)
246                 *acl = NULL;
247         if (!in_group_p(inode->i_gid) &&
248             !capable_wrt_inode_uidgid(inode, CAP_FSETID))
249                 mode &= ~S_ISGID;
250         *mode_p = mode;
251         return 0;
252 }
253 #endif /* HAVE_POSIX_ACL_UPDATE_MODE */
254 #endif
255 #endif
256
257 #ifndef HAVE_IOV_ITER_TRUNCATE
258 static inline void iov_iter_truncate(struct iov_iter *i, u64 count)
259 {
260         if (i->count > count)
261                 i->count = count;
262 }
263 #endif
264
265 /*
266  * mount MS_* flags split from superblock SB_* flags
267  * if the SB_* flags are not available use the MS_* flags
268  */
269 #if !defined(SB_RDONLY) && defined(MS_RDONLY)
270 # define SB_RDONLY MS_RDONLY
271 #endif
272 #if !defined(SB_ACTIVE) && defined(MS_ACTIVE)
273 # define SB_ACTIVE MS_ACTIVE
274 #endif
275 #if !defined(SB_NOSEC) && defined(MS_NOSEC)
276 # define SB_NOSEC MS_NOSEC
277 #endif
278 #if !defined(SB_POSIXACL) && defined(MS_POSIXACL)
279 # define SB_POSIXACL MS_POSIXACL
280 #endif
281 #if !defined(SB_NODIRATIME) && defined(MS_NODIRATIME)
282 # define SB_NODIRATIME MS_NODIRATIME
283 #endif
284
285 #ifndef HAVE_FILE_OPERATIONS_READ_WRITE_ITER
286 static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
287 {
288         i->count = count;
289 }
290
291 static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
292 {
293         return (struct iovec) {
294                 .iov_base = iter->iov->iov_base + iter->iov_offset,
295                 .iov_len = min(iter->count,
296                                iter->iov->iov_len - iter->iov_offset),
297         };
298 }
299
300 #define iov_for_each(iov, iter, start)                                  \
301         for (iter = (start);                                            \
302              (iter).count && ((iov = iov_iter_iovec(&(iter))), 1);      \
303              iov_iter_advance(&(iter), (iov).iov_len))
304
305 static inline ssize_t
306 generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
307 {
308         struct iovec iov;
309         struct iov_iter i;
310         ssize_t bytes = 0;
311
312         iov_for_each(iov, i, *iter) {
313                 ssize_t res;
314
315                 res = generic_file_aio_read(iocb, &iov, 1, iocb->ki_pos);
316                 if (res <= 0) {
317                         if (bytes == 0)
318                                 bytes = res;
319                         break;
320                 }
321
322                 bytes += res;
323                 if (res < iov.iov_len)
324                         break;
325         }
326
327         if (bytes > 0)
328                 iov_iter_advance(iter, bytes);
329         return bytes;
330 }
331
332 static inline ssize_t
333 __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
334 {
335         struct iovec iov;
336         struct iov_iter i;
337         ssize_t bytes = 0;
338
339         /* Since LLITE updates file size at the end of I/O in
340          * vvp_io_commit_write(), append write has to be done in atomic when
341          * there are multiple segments because otherwise each iteration to
342          * __generic_file_aio_write() will see original file size */
343         if (unlikely(iocb->ki_filp->f_flags & O_APPEND && iter->nr_segs > 1)) {
344                 struct iovec *iov_copy;
345                 int count = 0;
346
347                 OBD_ALLOC(iov_copy, sizeof(*iov_copy) * iter->nr_segs);
348                 if (!iov_copy)
349                         return -ENOMEM;
350
351                 iov_for_each(iov, i, *iter)
352                         iov_copy[count++] = iov;
353
354                 bytes = __generic_file_aio_write(iocb, iov_copy, count,
355                                                  &iocb->ki_pos);
356                 OBD_FREE(iov_copy, sizeof(*iov_copy) * iter->nr_segs);
357
358                 if (bytes > 0)
359                         iov_iter_advance(iter, bytes);
360                 return bytes;
361         }
362
363         iov_for_each(iov, i, *iter) {
364                 ssize_t res;
365
366                 res = __generic_file_aio_write(iocb, &iov, 1, &iocb->ki_pos);
367                 if (res <= 0) {
368                         if (bytes == 0)
369                                 bytes = res;
370                         break;
371                 }
372
373                 bytes += res;
374                 if (res < iov.iov_len)
375                         break;
376         }
377
378         if (bytes > 0)
379                 iov_iter_advance(iter, bytes);
380         return bytes;
381 }
382 #endif /* HAVE_FILE_OPERATIONS_READ_WRITE_ITER */
383
384 static inline void __user *get_vmf_address(struct vm_fault *vmf)
385 {
386 #ifdef HAVE_VM_FAULT_ADDRESS
387         return (void __user *)vmf->address;
388 #else
389         return vmf->virtual_address;
390 #endif
391 }
392
393 #ifdef HAVE_VM_OPS_USE_VM_FAULT_ONLY
394 # define ll_filemap_fault(vma, vmf) filemap_fault(vmf)
395 #else
396 # define ll_filemap_fault(vma, vmf) filemap_fault(vma, vmf)
397 #endif
398
399 #ifndef HAVE_CURRENT_TIME
400 static inline struct timespec current_time(struct inode *inode)
401 {
402         return CURRENT_TIME;
403 }
404 #endif
405
406 #ifndef smp_store_mb
407 #define smp_store_mb(var, value)        set_mb(var, value)
408 #endif
409
410 #if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)
411 static inline unsigned short blk_integrity_interval(struct blk_integrity *bi)
412 {
413 #ifdef HAVE_INTERVAL_EXP_BLK_INTEGRITY
414         return bi->interval_exp ? 1 << bi->interval_exp : 0;
415 #elif defined(HAVE_INTERVAL_BLK_INTEGRITY)
416         return bi->interval;
417 #else
418         return bi->sector_size;
419 #endif /* !HAVE_INTERVAL_EXP_BLK_INTEGRITY */
420 }
421
422 static inline const char *blk_integrity_name(struct blk_integrity *bi)
423 {
424 #ifdef HAVE_INTERVAL_EXP_BLK_INTEGRITY
425         return bi->profile->name;
426 #else
427         return bi->name;
428 #endif
429 }
430
431 static inline unsigned int bip_size(struct bio_integrity_payload *bip)
432 {
433 #ifdef HAVE_BIP_ITER_BIO_INTEGRITY_PAYLOAD
434         return bip->bip_iter.bi_size;
435 #else
436         return bip->bip_size;
437 #endif
438 }
439 #else /* !CONFIG_BLK_DEV_INTEGRITY */
440 static inline unsigned short blk_integrity_interval(struct blk_integrity *bi)
441 {
442         return 0;
443 }
444 static inline const char *blk_integrity_name(struct blk_integrity *bi)
445 {
446         /* gcc8 dislikes when strcmp() is called against NULL */
447         return "";
448 }
449 #endif /* !CONFIG_BLK_DEV_INTEGRITY */
450
451 #ifndef INTEGRITY_FLAG_READ
452 #define INTEGRITY_FLAG_READ BLK_INTEGRITY_VERIFY
453 #endif
454
455 #ifndef INTEGRITY_FLAG_WRITE
456 #define INTEGRITY_FLAG_WRITE BLK_INTEGRITY_GENERATE
457 #endif
458
459 static inline bool bdev_integrity_enabled(struct block_device *bdev, int rw)
460 {
461 #if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY)
462         struct blk_integrity *bi = bdev_get_integrity(bdev);
463
464         if (bi == NULL)
465                 return false;
466
467 #ifdef HAVE_INTERVAL_EXP_BLK_INTEGRITY
468         if (rw == 0 && bi->profile->verify_fn != NULL &&
469             (bi->flags & INTEGRITY_FLAG_READ))
470                 return true;
471
472         if (rw == 1 && bi->profile->generate_fn != NULL &&
473             (bi->flags & INTEGRITY_FLAG_WRITE))
474                 return true;
475 #else
476         if (rw == 0 && bi->verify_fn != NULL &&
477             (bi->flags & INTEGRITY_FLAG_READ))
478                 return true;
479
480         if (rw == 1 && bi->generate_fn != NULL &&
481             (bi->flags & INTEGRITY_FLAG_WRITE))
482                 return true;
483 #endif /* !HAVE_INTERVAL_EXP_BLK_INTEGRITY */
484 #endif /* !CONFIG_BLK_DEV_INTEGRITY */
485
486         return false;
487 }
488
489 #ifdef HAVE_PAGEVEC_INIT_ONE_PARAM
490 #define ll_pagevec_init(pvec, n) pagevec_init(pvec)
491 #else
492 #define ll_pagevec_init(pvec, n) pagevec_init(pvec, n)
493 #endif
494
495 #ifdef HAVE_D_COUNT
496 #  define ll_d_count(d)         d_count(d)
497 #else
498 #  define ll_d_count(d)         ((d)->d_count)
499 #endif /* HAVE_D_COUNT */
500
501 #ifndef HAVE_IN_COMPAT_SYSCALL
502 #define in_compat_syscall       is_compat_task
503 #endif
504
505 #ifdef HAVE_I_PAGES
506 #define page_tree i_pages
507 #else
508 #define i_pages tree_lock
509 #endif
510
511 #ifndef xa_lock_irqsave
512 #define xa_lock_irqsave(lockp, flags) spin_lock_irqsave(lockp, flags)
513 #define xa_unlock_irqrestore(lockp, flags) spin_unlock_irqrestore(lockp, flags)
514 #endif
515
516 #ifndef HAVE_LOCK_PAGE_MEMCG
517 #define lock_page_memcg(page) do {} while (0)
518 #define unlock_page_memcg(page) do {} while (0)
519 #endif
520
521 #ifndef KMEM_CACHE_USERCOPY
522 #define kmem_cache_create_usercopy(name, size, align, flags, useroffset, \
523                                    usersize, ctor)                       \
524         kmem_cache_create(name, size, align, flags, ctor)
525 #endif
526
527 #ifndef HAVE_LINUX_SELINUX_IS_ENABLED
528 #define selinux_is_enabled() 1
529 #endif
530
531 #endif /* _LUSTRE_COMPAT_H */