From 361d773a4b01c565fe510a397b8e3f520004e1e1 Mon Sep 17 00:00:00 2001 From: Vladimir Sokolovsky Date: Mon, 10 Sep 2018 17:30:15 -0500 Subject: [PATCH] Added headers and macros required by NVME target Signed-off-by: Vladimir Sokolovsky --- config/rdma.m4 | 291 ++++++++++++++++++++++++++++++++++++ include/linux/scatterlist.h | 147 ++++++++++++++++++ include/linux/string.h | 45 ++++++ 3 files changed, 483 insertions(+) create mode 100644 include/linux/scatterlist.h create mode 100644 include/linux/string.h diff --git a/config/rdma.m4 b/config/rdma.m4 index cf969ac..fdc0cdf 100644 --- a/config/rdma.m4 +++ b/config/rdma.m4 @@ -8410,6 +8410,297 @@ AC_DEFUN([LINUX_CONFIG_COMPAT], [dev_pm_qos_update_user_latency_tolerance is exported by the kernel])], []) + AC_MSG_CHECKING([if linux/bio.h bio_endio has 1 parameter]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + bio_endio(NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_ENDIO_1_PARAM, 1, + [linux/bio.h bio_endio has 1 parameter]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if bio.h bio_init has 3 parameters]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + bio_init(NULL, NULL, false); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BIO_INIT_3_PARAMS, 1, + [bio.h bio_init has 3 parameters]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if blkdev.h has __blkdev_issue_discard]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + __blkdev_issue_discard(NULL, 0, 0, 0, 0, NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE___BLKDEV_ISSUE_DISCARD, 1, + [__blkdev_issue_discard is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if blkdev.h has __blkdev_issue_zeroout]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + __blkdev_issue_zeroout(NULL, 0, 0, 0, NULL, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLKDEV_ISSUE_ZEROOUT, 1, + [__blkdev_issue_zeroout exist]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if blkdev.h has blk_poll]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + blk_poll(NULL, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_POLL, 1, + [blk_poll exist]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if linux/inet.h has inet_addr_is_any]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + inet_addr_is_any(NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_INET_ADDR_IS_ANY, 1, + [inet_addr_is_any is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if string.h has memchr_inv]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + memchr_inv(NULL, 0, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MEMCHR_INV, 1, + [memchr_inv is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if string.h has memcpy_and_pad]) + LB_LINUX_TRY_COMPILE([ + #include + ], + [ + memcpy_and_pad(NULL, 0, NULL, 0, ' '); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MEMCPY_AND_PAD, 1, + [memcpy_and_pad is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if string.h has memdup_user_nul]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + memdup_user_nul(NULL, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MEMDUP_USER_NUL, 1, + [memdup_user_nul is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if blk_types.h has REQ_IDLE]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + int flags = REQ_IDLE; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_REQ_IDLE, 1, + [blk_types.h has REQ_IDLE]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if linux/scatterlist.h sg_alloc_table_chained has 3 parameters]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + sg_alloc_table_chained(NULL, 0, NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SG_ALLOC_TABLE_CHAINED_3_PARAMS, 1, + [sg_alloc_table_chained has 3 parameters]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if linux/scatterlist.h has sgl_alloc]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + sgl_alloc(0, 0, NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SGL_ALLOC, 1, + [sgl_alloc is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if linux/scatterlist.h has sgl_free]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + sgl_free(NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SGL_FREE, 1, + [sgl_free is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if linux/scatterlist.h has sg_zero_buffer]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + sg_zero_buffer(NULL, 0, 0, 0); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SG_ZERO_BUFFER, 1, + [sg_zero_buffer is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if string.h has strnicmp]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + char a[10] = "aaa"; + char b[10] = "bbb"; + strnicmp(a, b, sizeof(a)); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STRNICMP, 1, + [strnicmp is defined]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct bio has member bi_error]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct bio b = { + .bi_error = 0, + }; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STRUCT_BIO_BI_ERROR, 1, + [struct bio has member bi_error]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct bio has member bi_iter]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct bio b = { + .bi_iter = 0, + }; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STRUCT_BIO_BI_ITER, 1, + [struct bio has member bi_iter]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if struct bio has member bi_opf]) + LB_LINUX_TRY_COMPILE([ + #include + ],[ + struct bio b = { + .bi_opf = 0, + }; + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_STRUCT_BIO_BI_OPF, 1, + [struct bio has member bi_opf]) + ],[ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([if linux/bio.h submit_bio has 1 parameter]) + LB_LINUX_TRY_COMPILE([ + #include + #include + ],[ + submit_bio(NULL); + + return 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SUBMIT_BIO_1_PARAM, 1, + [linux/bio.h submit_bio has 1 parameter]) + ],[ + AC_MSG_RESULT(no) + ]) + ]) # # COMPAT_CONFIG_HEADERS diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h new file mode 100644 index 0000000..46271a8 --- /dev/null +++ b/include/linux/scatterlist.h @@ -0,0 +1,147 @@ +#ifndef _COMPAT_LINUX_SCATTERLIST_H +#define _COMPAT_LINUX_SCATTERLIST_H + +#include "../../compat/config.h" +#include + +#include_next + +#if (KERNEL_VERSION(4, 8, 0) <= LINUX_VERSION_CODE) || \ + (defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 7 && RHEL_MINOR -0 >= 4) +#ifndef HAVE_SG_ZERO_BUFFER +/** + * sg_zero_buffer - Zero-out a part of a SG list + * @sgl: The SG list + * @nents: Number of SG entries + * @buflen: The number of bytes to zero out + * @skip: Number of bytes to skip before zeroing + * + * Returns the number of bytes zeroed. + **/ +static inline size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents, + size_t buflen, off_t skip) +{ + unsigned int offset = 0; + struct sg_mapping_iter miter; + unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG; + + sg_miter_start(&miter, sgl, nents, sg_flags); + + if (!sg_miter_skip(&miter, skip)) + return false; + + while (offset < buflen && sg_miter_next(&miter)) { + unsigned int len; + + len = min(miter.length, buflen - offset); + memset(miter.addr, 0, len); + + offset += len; + } + + sg_miter_stop(&miter); + return offset; +} +#endif /* HAVE_SG_ZERO_BUFFER */ + +#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0) */ + +#if defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 7 && RHEL_MINOR -0 >= 2 +#if !defined(HAVE_SG_ALLOC_TABLE_CHAINED_4_PARAMS) && \ + !defined(HAVE_SG_ALLOC_TABLE_CHAINED_3_PARAMS) + +#include +#include + +struct sg_pool { + size_t size; + char *name; + struct kmem_cache *slab; + mempool_t *pool; +}; + +#define SP(x) { .size = x, "sgpool-" __stringify(x) } +#if (SCSI_MAX_SG_SEGMENTS < 32) +#error SCSI_MAX_SG_SEGMENTS is too small (must be 32 or greater) +#endif +static struct sg_pool sg_pools[] = { + SP(8), + SP(16), +#if (SCSI_MAX_SG_SEGMENTS > 32) + SP(32), +#if (SCSI_MAX_SG_SEGMENTS > 64) + SP(64), +#if (SCSI_MAX_SG_SEGMENTS > 128) + SP(128), +#if (SCSI_MAX_SG_SEGMENTS > 256) +#error SCSI_MAX_SG_SEGMENTS is too large (256 MAX) +#endif +#endif +#endif +#endif + SP(SCSI_MAX_SG_SEGMENTS) +}; +#undef SP + +static inline unsigned int sg_pool_index(unsigned short nents) +{ + unsigned int index; + + BUG_ON(nents > SCSI_MAX_SG_SEGMENTS); + + if (nents <= 8) + index = 0; + else + index = get_count_order(nents) - 3; + + return index; +} + +static inline void sg_pool_free(struct scatterlist *sgl, unsigned int nents) +{ + struct sg_pool *sgp; + + sgp = sg_pools + sg_pool_index(nents); + mempool_free(sgl, sgp->pool); +} + +static inline struct scatterlist *sg_pool_alloc(unsigned int nents, gfp_t gfp_mask) +{ + struct sg_pool *sgp; + + sgp = sg_pools + sg_pool_index(nents); + return mempool_alloc(sgp->pool, gfp_mask); +} + +static inline void sg_free_table_chained(struct sg_table *table, bool first_chunk) +{ + if (first_chunk && table->orig_nents <= SCSI_MAX_SG_SEGMENTS) + return; + __sg_free_table(table, SCSI_MAX_SG_SEGMENTS, first_chunk, sg_pool_free); +} + +static inline int sg_alloc_table_chained(struct sg_table *table, int nents, + struct scatterlist *first_chunk) +{ + int ret; + + BUG_ON(!nents); + + if (first_chunk) { + if (nents <= SCSI_MAX_SG_SEGMENTS) { + table->nents = table->orig_nents = nents; + sg_init_table(table->sgl, nents); + return 0; + } + } + + ret = __sg_alloc_table(table, nents, SCSI_MAX_SG_SEGMENTS, + first_chunk, GFP_ATOMIC, sg_pool_alloc); + if (unlikely(ret)) + sg_free_table_chained(table, (bool)first_chunk); + return ret; +} +#endif +#endif /* defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 7 && RHEL_MINOR -0 >= 2 */ + +#endif /* _COMPAT_LINUX_SCATTERLIST_H */ diff --git a/include/linux/string.h b/include/linux/string.h new file mode 100644 index 0000000..5db1e33 --- /dev/null +++ b/include/linux/string.h @@ -0,0 +1,45 @@ +#ifndef _COMPAT_LINUX_STRING_H +#define _COMPAT_LINUX_STRING_H + +#include "../../compat/config.h" + +#include_next + +#ifndef HAVE_STRNICMP +#ifndef __HAVE_ARCH_STRNICMP +#define strnicmp strncasecmp +#endif +#endif /* HAVE_STRNICMP */ + +#ifndef HAVE_MEMCHR_INV +#define memchr_inv LINUX_BACKPORT(memchr_inv) +void *memchr_inv(const void *start, int c, size_t bytes); +#endif + +#ifndef HAVE_MEMDUP_USER_NUL +#define memdup_user_nul LINUX_BACKPORT(memdup_user_nul) +void *memdup_user_nul(const void __user *src, size_t len); +#endif + +#ifndef HAVE_MEMCPY_AND_PAD +/** + * memcpy_and_pad - Copy one buffer to another with padding + * @dest: Where to copy to + * @dest_len: The destination buffer size + * @src: Where to copy from + * @count: The number of bytes to copy + * @pad: Character to use for padding if space is left in destination. + */ +#define memcpy_and_pad LINUX_BACKPORT(memcpy_and_pad) +static inline void memcpy_and_pad(void *dest, size_t dest_len, + const void *src, size_t count, int pad) +{ + if (dest_len > count) { + memcpy(dest, src, count); + memset(dest + count, pad, dest_len - count); + } else + memcpy(dest, src, dest_len); +} +#endif + +#endif /* _COMPAT_LINUX_STRING_H */ -- 2.41.0