X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Finclude%2Flustre_compat.h;h=284f4ee39250a30158882cdca8bcaf7bbf2203dc;hb=5ca5b19e8efdfede8ec3405eaced7202984f396b;hp=9918a7a1af745df9054482fd6d0636f4c59997cd;hpb=bca975c7fa261ffb926e8a18d5869b886c65f447;p=fs%2Flustre-release.git diff --git a/lustre/include/lustre_compat.h b/lustre/include/lustre_compat.h index 9918a7a..284f4ee 100644 --- a/lustre/include/lustre_compat.h +++ b/lustre/include/lustre_compat.h @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2014, Intel Corporation. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -37,10 +33,19 @@ #ifndef _LUSTRE_COMPAT_H #define _LUSTRE_COMPAT_H +#include +#include #include #include +#include +#include +#include +#include +#include +#include #include +#include #ifdef HAVE_FS_STRUCT_RWLOCK # define LOCK_FS_STRUCT(fs) write_lock(&(fs)->lock) @@ -50,30 +55,33 @@ # define UNLOCK_FS_STRUCT(fs) spin_unlock(&(fs)->lock) #endif +#ifdef HAVE_FS_STRUCT_SEQCOUNT +# define WRITE_FS_SEQ_BEGIN(fs) write_seqcount_begin(&(fs)->seq) +# define WRITE_FS_SEQ_END(fs) write_seqcount_end(&(fs)->seq) +#else +# define WRITE_FS_SEQ_BEGIN(fs) +# define WRITE_FS_SEQ_END(fs) +#endif static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, struct dentry *dentry) { - struct path path; - struct path old_pwd; - - path.mnt = mnt; - path.dentry = dentry; - LOCK_FS_STRUCT(fs); - old_pwd = fs->pwd; - path_get(&path); - fs->pwd = path; - UNLOCK_FS_STRUCT(fs); - - if (old_pwd.dentry) - path_put(&old_pwd); + struct path path; + struct path old_pwd; + + path.mnt = mnt; + path.dentry = dentry; + path_get(&path); + LOCK_FS_STRUCT(fs); + WRITE_FS_SEQ_BEGIN(fs); + old_pwd = fs->pwd; + fs->pwd = path; + WRITE_FS_SEQ_END(fs); + UNLOCK_FS_STRUCT(fs); + + if (old_pwd.dentry) + path_put(&old_pwd); } -/* - * set ATTR_BLOCKS to a high value to avoid any risk of collision with other - * ATTR_* attributes (see bug 13828) - */ -#define ATTR_BLOCKS (1 << 27) - #define current_ngroups current_cred()->group_info->ngroups #define current_groups current_cred()->group_info->small_block @@ -91,8 +99,6 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, #define MODULE_ALIAS_FS(name) #endif -#define LTIME_S(time) (time.tv_sec) - #ifdef HAVE_GENERIC_PERMISSION_2ARGS # define ll_generic_permission(inode, mask, flags, check_acl) \ generic_permission(inode, mask) @@ -123,50 +129,25 @@ static inline void ll_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, #ifdef HAVE_INODE_DIO_WAIT /* inode_dio_wait(i) use as-is for write lock */ # define inode_dio_write_done(i) do {} while (0) /* for write unlock */ -# define inode_dio_read(i) atomic_inc(&(i)->i_dio_count) -/* inode_dio_done(i) use as-is for read unlock */ #else # define inode_dio_wait(i) down_write(&(i)->i_alloc_sem) # define inode_dio_write_done(i) up_write(&(i)->i_alloc_sem) -# define inode_dio_read(i) down_read(&(i)->i_alloc_sem) -# define inode_dio_done(i) up_read(&(i)->i_alloc_sem) #endif #ifndef FS_HAS_FIEMAP #define FS_HAS_FIEMAP (0) #endif -/* add a lustre compatible layer for crypto API */ -#include -static inline int ll_crypto_hmac(struct crypto_hash *tfm, - u8 *key, unsigned int *keylen, - struct scatterlist *sg, - unsigned int size, u8 *result) -{ - struct hash_desc desc; - int rv; - desc.tfm = tfm; - desc.flags = 0; - rv = crypto_hash_setkey(desc.tfm, key, *keylen); - if (rv) { - CERROR("failed to hash setkey: %d\n", rv); - return rv; - } - return crypto_hash_digest(&desc, sg, size, result); -} - -static inline -unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) -{ - return crypto_blkcipher_tfm(tfm)->__crt_alg->cra_blkcipher.min_keysize; -} - #ifndef HAVE_SIMPLE_SETATTR #define simple_setattr(dentry, ops) inode_setattr((dentry)->d_inode, ops) #endif -#ifndef SLAB_DESTROY_BY_RCU -#define SLAB_DESTROY_BY_RCU 0 +#ifndef HAVE_INIT_LIST_HEAD_RCU +static inline void INIT_LIST_HEAD_RCU(struct list_head *list) +{ + WRITE_ONCE(list->next, list); + WRITE_ONCE(list->prev, list); +} #endif #ifndef HAVE_DQUOT_SUSPEND @@ -188,6 +169,7 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) #ifdef HAVE_BVEC_ITER #define bio_idx(bio) (bio->bi_iter.bi_idx) #define bio_set_sector(bio, sector) (bio->bi_iter.bi_sector = sector) +#define bvl_to_page(bvl) (bvl->bv_page) #else #define bio_idx(bio) (bio->bi_idx) #define bio_set_sector(bio, sector) (bio->bi_sector = sector) @@ -195,7 +177,13 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) #ifndef HAVE_BIO_END_SECTOR #define bio_end_sector(bio) (bio->bi_sector + bio_sectors(bio)) #endif -#define bvec_iter_page(bvec, iter) (*bvec->bv_page) +#define bvl_to_page(bvl) (bvl->bv_page) +#endif + +#ifdef HAVE_BVEC_ITER +#define bio_start_sector(bio) (bio->bi_iter.bi_sector) +#else +#define bio_start_sector(bio) (bio->bi_sector) #endif #ifndef HAVE_BLK_QUEUE_MAX_SEGMENTS @@ -207,6 +195,14 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) #define queue_max_hw_segments(rq) queue_max_segments(rq) #endif +#ifdef HAVE_BLK_PLUG +#define DECLARE_PLUG(plug) struct blk_plug plug +#else /* !HAVE_BLK_PLUG */ +#define DECLARE_PLUG(name) +#define blk_start_plug(plug) do {} while (0) +#define blk_finish_plug(plug) do {} while (0) +#endif + #ifdef HAVE_KMAP_ATOMIC_HAS_1ARG #define ll_kmap_atomic(a, b) kmap_atomic(a) #define ll_kunmap_atomic(a, b) kunmap_atomic(a) @@ -219,27 +215,42 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) #define clear_inode(i) end_writeback(i) #endif -#ifdef HAVE_DENTRY_D_ALIAS_HLIST +#ifndef HAVE_DENTRY_D_CHILD +#define d_child d_u.d_child +#endif + +#ifdef HAVE_DENTRY_D_U_D_ALIAS +#define d_alias d_u.d_alias +#endif + +#ifndef DATA_FOR_LLITE_IS_LIST #define ll_d_hlist_node hlist_node #define ll_d_hlist_empty(list) hlist_empty(list) #define ll_d_hlist_entry(ptr, type, name) hlist_entry(ptr.first, type, name) #define ll_d_hlist_for_each(tmp, i_dentry) hlist_for_each(tmp, i_dentry) -#ifdef HAVE_HLIST_FOR_EACH_3ARG -#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \ - p = NULL; hlist_for_each_entry(dentry, i_dentry, alias) -#else -#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \ - hlist_for_each_entry(dentry, p, i_dentry, alias) -#endif +# ifdef HAVE_HLIST_FOR_EACH_3ARG +# define ll_d_hlist_for_each_entry(dentry, p, i_dentry) \ + p = NULL; hlist_for_each_entry(dentry, i_dentry, d_alias) +# else +# define ll_d_hlist_for_each_entry(dentry, p, i_dentry) \ + hlist_for_each_entry(dentry, p, i_dentry, d_alias) +# endif #define DECLARE_LL_D_HLIST_NODE_PTR(name) struct ll_d_hlist_node *name #else #define ll_d_hlist_node list_head #define ll_d_hlist_empty(list) list_empty(list) #define ll_d_hlist_entry(ptr, type, name) list_entry(ptr.next, type, name) #define ll_d_hlist_for_each(tmp, i_dentry) list_for_each(tmp, i_dentry) -#define ll_d_hlist_for_each_entry(dentry, p, i_dentry, alias) \ - list_for_each_entry(dentry, i_dentry, alias) +#define ll_d_hlist_for_each_entry(dentry, p, i_dentry) \ + list_for_each_entry(dentry, i_dentry, d_alias) #define DECLARE_LL_D_HLIST_NODE_PTR(name) /* nothing */ +#endif /* !DATA_FOR_LLITE_IS_LIST */ + +#ifndef HAVE_D_IN_LOOKUP +static inline int d_in_lookup(struct dentry *dentry) +{ + return false; +} #endif #ifndef QUOTA_OK @@ -274,6 +285,14 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) # define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET) #endif +#ifndef XATTR_NAME_POSIX_ACL_ACCESS +# define XATTR_NAME_POSIX_ACL_ACCESS POSIX_ACL_XATTR_ACCESS +#endif + +#ifndef XATTR_NAME_POSIX_ACL_DEFAULT +# define XATTR_NAME_POSIX_ACL_DEFAULT POSIX_ACL_XATTR_DEFAULT +#endif + #ifndef HAVE_LM_XXX_LOCK_MANAGER_OPS # define lm_compare_owner fl_compare_owner #endif @@ -293,14 +312,6 @@ static inline int ll_namei_to_lookup_intent_flag(int flag) return flag; } -#ifdef HAVE_VOID_MAKE_REQUEST_FN -# define ll_mrf_ret void -# define LL_MRF_RETURN(rc) -#else -# define ll_mrf_ret int -# define LL_MRF_RETURN(rc) RETURN(rc) -#endif - #include #ifndef HAVE_PROTECT_I_NLINK static inline void set_nlink(struct inode *inode, unsigned int nlink) @@ -340,6 +351,13 @@ static inline struct dentry *d_make_root(struct inode *root) # define set_file_inode(file, inode) #endif +#ifndef HAVE_FILE_INODE +static inline struct inode *file_inode(const struct file *file) +{ + return file->f_path.dentry->d_inode; +} +#endif + #ifdef HAVE_OLDSIZE_TRUNCATE_PAGECACHE #define ll_truncate_pagecache(inode, size) truncate_pagecache(inode, 0, size) #else @@ -360,6 +378,43 @@ static inline struct dentry *d_make_root(struct inode *root) #define ll_vfs_unlink(a, b) vfs_unlink(a, b) #endif +#ifndef HAVE_INODE_OWNER_OR_CAPABLE +#define inode_owner_or_capable(inode) is_owner_or_cap(inode) +#endif + +static inline int ll_vfs_getattr(struct path *path, struct kstat *st) +{ + int rc; + +#ifdef HAVE_INODEOPS_ENHANCED_GETATTR + rc = vfs_getattr(path, st, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT); +#elif defined HAVE_VFS_GETATTR_2ARGS + rc = vfs_getattr(path, st); +#else + rc = vfs_getattr(path->mnt, path->dentry, st); +#endif + return rc; +} + +#ifndef HAVE_D_IS_POSITIVE +static inline bool d_is_positive(const struct dentry *dentry) +{ + return dentry->d_inode != NULL; +} +#endif + +#ifdef HAVE_VFS_CREATE_USE_NAMEIDATA +# define LL_VFS_CREATE_FALSE NULL +#else +# define LL_VFS_CREATE_FALSE false +#endif + +#ifndef HAVE_INODE_LOCK +# define inode_lock(inode) mutex_lock(&(inode)->i_mutex) +# define inode_unlock(inode) mutex_unlock(&(inode)->i_mutex) +# define inode_trylock(inode) mutex_trylock(&(inode)->i_mutex) +#endif + #ifndef HAVE_RADIX_EXCEPTION_ENTRY static inline int radix_tree_exceptional_entry(void *arg) { @@ -371,11 +426,16 @@ static inline int radix_tree_exceptional_entry(void *arg) static inline void truncate_inode_pages_final(struct address_space *map) { truncate_inode_pages(map, 0); - /* Workaround for LU-118 */ - if (map->nrpages) { - spin_lock_irq(&map->tree_lock); - spin_unlock_irq(&map->tree_lock); - } /* Workaround end */ +} +#endif + +#ifndef HAVE_PTR_ERR_OR_ZERO +static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) +{ + if (IS_ERR(ptr)) + return PTR_ERR(ptr); + else + return 0; } #endif @@ -383,4 +443,391 @@ static inline void truncate_inode_pages_final(struct address_space *map) #define SIZE_MAX (~(size_t)0) #endif +#ifdef HAVE_SECURITY_IINITSEC_CALLBACK +# define ll_security_inode_init_security(inode, dir, name, value, len, \ + initxattrs, dentry) \ + security_inode_init_security(inode, dir, &((dentry)->d_name), \ + initxattrs, dentry) +#elif defined HAVE_SECURITY_IINITSEC_QSTR +# define ll_security_inode_init_security(inode, dir, name, value, len, \ + initxattrs, dentry) \ + security_inode_init_security(inode, dir, &((dentry)->d_name), \ + name, value, len) +#else /* !HAVE_SECURITY_IINITSEC_CALLBACK && !HAVE_SECURITY_IINITSEC_QSTR */ +# define ll_security_inode_init_security(inode, dir, name, value, len, \ + initxattrs, dentry) \ + security_inode_init_security(inode, dir, name, value, len) +#endif + +#ifndef bio_for_each_segment_all /* since kernel version 3.9 */ +#ifdef HAVE_BVEC_ITER +#define bio_for_each_segment_all(bv, bio, it) \ + for (it = 0, bv = (bio)->bi_io_vec; it < (bio)->bi_vcnt; it++, bv++) +#else +#define bio_for_each_segment_all(bv, bio, it) bio_for_each_segment(bv, bio, it) +#endif +#endif + +#ifdef HAVE_PID_NS_FOR_CHILDREN +# define ll_task_pid_ns(task) ((task)->nsproxy->pid_ns_for_children) +#else +# define ll_task_pid_ns(task) ((task)->nsproxy->pid_ns) +#endif + +#ifdef HAVE_FULL_NAME_HASH_3ARGS +# define ll_full_name_hash(salt, name, len) full_name_hash(salt, name, len) +#else +# define ll_full_name_hash(salt, name, len) full_name_hash(name, len) +#endif + +#ifdef HAVE_STRUCT_POSIX_ACL_XATTR +# define posix_acl_xattr_header struct posix_acl_xattr_header +# define posix_acl_xattr_entry struct posix_acl_xattr_entry +# define GET_POSIX_ACL_XATTR_ENTRY(head) ((void *)((head) + 1)) +#else +# define GET_POSIX_ACL_XATTR_ENTRY(head) ((head)->a_entries) +#endif + +#ifdef HAVE_IOP_XATTR +#ifdef HAVE_XATTR_HANDLER_FLAGS +#define ll_setxattr generic_setxattr +#define ll_getxattr generic_getxattr +#define ll_removexattr generic_removexattr +#else +int ll_setxattr(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags); +ssize_t ll_getxattr(struct dentry *dentry, const char *name, + void *buf, size_t buf_size); +int ll_removexattr(struct dentry *dentry, const char *name); +#endif /* ! HAVE_XATTR_HANDLER_FLAGS */ +#endif /* HAVE_IOP_XATTR */ + +#ifndef HAVE_VFS_SETXATTR +const struct xattr_handler *get_xattr_type(const char *name); + +static inline int +__vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name, + const void *value, size_t size, int flags) +{ +# ifdef HAVE_XATTR_HANDLER_FLAGS + const struct xattr_handler *handler; + int rc; + + handler = get_xattr_type(name); + if (!handler) + return -EOPNOTSUPP; + +# if defined(HAVE_XATTR_HANDLER_INODE_PARAM) + rc = handler->set(handler, dentry, inode, name, value, size, flags); +# elif defined(HAVE_XATTR_HANDLER_SIMPLIFIED) + rc = handler->set(handler, dentry, name, value, size, flags); +# else + rc = handler->set(dentry, name, value, size, flags, handler->flags); +# endif /* !HAVE_XATTR_HANDLER_INODE_PARAM */ + return rc; +# else /* !HAVE_XATTR_HANDLER_FLAGS */ + return ll_setxattr(dentry, name, value, size, flags); +# endif /* HAVE_XATTR_HANDLER_FLAGS */ +} +#endif /* HAVE_VFS_SETXATTR */ + +#ifdef HAVE_IOP_SET_ACL +#ifdef CONFIG_FS_POSIX_ACL +#ifndef HAVE_POSIX_ACL_UPDATE_MODE +static inline int posix_acl_update_mode(struct inode *inode, umode_t *mode_p, + struct posix_acl **acl) +{ + umode_t mode = inode->i_mode; + int error; + + error = posix_acl_equiv_mode(*acl, &mode); + if (error < 0) + return error; + if (error == 0) + *acl = NULL; + if (!in_group_p(inode->i_gid) && + !capable_wrt_inode_uidgid(inode, CAP_FSETID)) + mode &= ~S_ISGID; + *mode_p = mode; + return 0; +} +#endif /* HAVE_POSIX_ACL_UPDATE_MODE */ +#endif +#endif + +#ifndef HAVE_IOV_ITER_TRUNCATE +static inline void iov_iter_truncate(struct iov_iter *i, u64 count) +{ + if (i->count > count) + i->count = count; +} +#endif + +#ifndef HAVE_IS_SXID +static inline bool is_sxid(umode_t mode) +{ + return (mode & S_ISUID) || ((mode & S_ISGID) && (mode & S_IXGRP)); +} +#endif + +#ifndef IS_NOSEC +#define IS_NOSEC(inode) (!is_sxid(inode->i_mode)) +#endif + +#ifndef MS_NOSEC +static inline void inode_has_no_xattr(struct inode *inode) +{ + return; +} +#endif + +#ifndef HAVE_FILE_OPERATIONS_READ_WRITE_ITER +static inline void iov_iter_reexpand(struct iov_iter *i, size_t count) +{ + i->count = count; +} + +static inline struct iovec iov_iter_iovec(const struct iov_iter *iter) +{ + return (struct iovec) { + .iov_base = iter->iov->iov_base + iter->iov_offset, + .iov_len = min(iter->count, + iter->iov->iov_len - iter->iov_offset), + }; +} + +#define iov_for_each(iov, iter, start) \ + for (iter = (start); \ + (iter).count && ((iov = iov_iter_iovec(&(iter))), 1); \ + iov_iter_advance(&(iter), (iov).iov_len)) + +static inline ssize_t +generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct iovec iov; + struct iov_iter i; + ssize_t bytes = 0; + + iov_for_each(iov, i, *iter) { + ssize_t res; + + res = generic_file_aio_read(iocb, &iov, 1, iocb->ki_pos); + if (res <= 0) { + if (bytes == 0) + bytes = res; + break; + } + + bytes += res; + if (res < iov.iov_len) + break; + } + + if (bytes > 0) + iov_iter_advance(iter, bytes); + return bytes; +} + +static inline ssize_t +__generic_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct iovec iov; + struct iov_iter i; + ssize_t bytes = 0; + + /* Since LLITE updates file size at the end of I/O in + * vvp_io_commit_write(), append write has to be done in atomic when + * there are multiple segments because otherwise each iteration to + * __generic_file_aio_write() will see original file size */ + if (unlikely(iocb->ki_filp->f_flags & O_APPEND && iter->nr_segs > 1)) { + struct iovec *iov_copy; + int count = 0; + + OBD_ALLOC(iov_copy, sizeof(*iov_copy) * iter->nr_segs); + if (!iov_copy) + return -ENOMEM; + + iov_for_each(iov, i, *iter) + iov_copy[count++] = iov; + + bytes = __generic_file_aio_write(iocb, iov_copy, count, + &iocb->ki_pos); + OBD_FREE(iov_copy, sizeof(*iov_copy) * iter->nr_segs); + + if (bytes > 0) + iov_iter_advance(iter, bytes); + return bytes; + } + + iov_for_each(iov, i, *iter) { + ssize_t res; + + res = __generic_file_aio_write(iocb, &iov, 1, &iocb->ki_pos); + if (res <= 0) { + if (bytes == 0) + bytes = res; + break; + } + + bytes += res; + if (res < iov.iov_len) + break; + } + + if (bytes > 0) + iov_iter_advance(iter, bytes); + return bytes; +} +#endif /* HAVE_FILE_OPERATIONS_READ_WRITE_ITER */ + +static inline void __user *get_vmf_address(struct vm_fault *vmf) +{ +#ifdef HAVE_VM_FAULT_ADDRESS + return (void __user *)vmf->address; +#else + return vmf->virtual_address; +#endif +} + +#ifdef HAVE_VM_OPS_USE_VM_FAULT_ONLY +# define ll_filemap_fault(vma, vmf) filemap_fault(vmf) +#else +# define ll_filemap_fault(vma, vmf) filemap_fault(vma, vmf) +#endif + +#ifndef HAVE_CURRENT_TIME +static inline struct timespec current_time(struct inode *inode) +{ + return CURRENT_TIME; +} +#endif + +#ifndef time_after32 +/** + * time_after32 - compare two 32-bit relative times + * @a: the time which may be after @b + * @b: the time which may be before @a + * + * time_after32(a, b) returns true if the time @a is after time @b. + * time_before32(b, a) returns true if the time @b is before time @a. + * + * Similar to time_after(), compare two 32-bit timestamps for relative + * times. This is useful for comparing 32-bit seconds values that can't + * be converted to 64-bit values (e.g. due to disk format or wire protocol + * issues) when it is known that the times are less than 68 years apart. + */ +#define time_after32(a, b) ((s32)((u32)(b) - (u32)(a)) < 0) +#define time_before32(b, a) time_after32(a, b) + +#endif + +#ifndef __GFP_COLD +#define __GFP_COLD 0 +#endif + +#ifndef alloc_workqueue +#define alloc_workqueue(name, flags, max_active) create_workqueue(name) +#endif + +#ifndef smp_store_mb +#define smp_store_mb(var, value) set_mb(var, value) +#endif + +#ifndef READ_ONCE +#define READ_ONCE ACCESS_ONCE +#endif + +#if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) +static inline unsigned short blk_integrity_interval(struct blk_integrity *bi) +{ +#ifdef HAVE_INTERVAL_EXP_BLK_INTEGRITY + return bi->interval_exp ? 1 << bi->interval_exp : 0; +#elif defined(HAVE_INTERVAL_BLK_INTEGRITY) + return bi->interval; +#else + return bi->sector_size; +#endif /* !HAVE_INTERVAL_EXP_BLK_INTEGRITY */ +} + +static inline const char *blk_integrity_name(struct blk_integrity *bi) +{ +#ifdef HAVE_INTERVAL_EXP_BLK_INTEGRITY + return bi->profile->name; +#else + return bi->name; +#endif +} + +static inline unsigned int bip_size(struct bio_integrity_payload *bip) +{ +#ifdef HAVE_BIP_ITER_BIO_INTEGRITY_PAYLOAD + return bip->bip_iter.bi_size; +#else + return bip->bip_size; +#endif +} +#else /* !CONFIG_BLK_DEV_INTEGRITY */ +static inline unsigned short blk_integrity_interval(struct blk_integrity *bi) +{ + return 0; +} +static inline const char *blk_integrity_name(struct blk_integrity *bi) +{ + /* gcc8 dislikes when strcmp() is called against NULL */ + return ""; +} +#endif /* !CONFIG_BLK_DEV_INTEGRITY */ + +#ifndef INTEGRITY_FLAG_READ +#define INTEGRITY_FLAG_READ BLK_INTEGRITY_VERIFY +#endif + +#ifndef INTEGRITY_FLAG_WRITE +#define INTEGRITY_FLAG_WRITE BLK_INTEGRITY_GENERATE +#endif + +static inline bool bdev_integrity_enabled(struct block_device *bdev, int rw) +{ +#if IS_ENABLED(CONFIG_BLK_DEV_INTEGRITY) + struct blk_integrity *bi = bdev_get_integrity(bdev); + + if (bi == NULL) + return false; + +#ifdef HAVE_INTERVAL_EXP_BLK_INTEGRITY + if (rw == 0 && bi->profile->verify_fn != NULL && + (bi->flags & INTEGRITY_FLAG_READ)) + return true; + + if (rw == 1 && bi->profile->generate_fn != NULL && + (bi->flags & INTEGRITY_FLAG_WRITE)) + return true; +#else + if (rw == 0 && bi->verify_fn != NULL && + (bi->flags & INTEGRITY_FLAG_READ)) + return true; + + if (rw == 1 && bi->generate_fn != NULL && + (bi->flags & INTEGRITY_FLAG_WRITE)) + return true; +#endif /* !HAVE_INTERVAL_EXP_BLK_INTEGRITY */ +#endif /* !CONFIG_BLK_DEV_INTEGRITY */ + + return false; +} + +#ifdef HAVE_PAGEVEC_INIT_ONE_PARAM +#define ll_pagevec_init(pvec, n) pagevec_init(pvec) +#else +#define ll_pagevec_init(pvec, n) pagevec_init(pvec, n) +#endif + +#ifdef HAVE_I_PAGES +#define page_tree i_pages +#else +#define i_pages tree_lock +#define xa_lock_irq(lockp) spin_lock_irq(lockp) +#define xa_unlock_irq(lockp) spin_unlock_irq(lockp) +#endif + #endif /* _LUSTRE_COMPAT_H */