From 859c947848fbd7a0b681da6cc90eb701583121fd Mon Sep 17 00:00:00 2001 From: Li Dongyang Date: Thu, 21 Apr 2016 10:25:28 -0400 Subject: [PATCH] LU-6215 gss: key->payload.data is an array in 4.4+ kernels Kernel 4.4 merged the type-specific data with the payload data for keys, as a result, payload.data is now an array. This patch handles the code change. Linux-commit: 146aa8b1453bd8f1ff2304ffb71b4ee0eb9acdcc Signed-off-by: Li Dongyang Signed-off-by: James Simmons Change-Id: I1036ab927514f0efa073d9f0136e299be8950461 Reviewed-on: http://review.whamcloud.com/18731 Reviewed-by: Dmitry Eremin Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin --- lustre/autoconf/lustre-core.m4 | 17 +++++++++++ lustre/ptlrpc/gss/gss_keyring.c | 67 ++++++++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 9f59979..670389e 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -2029,6 +2029,22 @@ make_request_fn_blk_qc_t, [ ]) # LC_HAVE_QC_MAKE_REQUEST_FN # +# LC_HAVE_KEY_PAYLOAD_DATA_ARRAY +# +# 4.4 kernel merged type-specific data with the payload data for keys +# +AC_DEFUN([LC_HAVE_KEY_PAYLOAD_DATA_ARRAY], [ +LB_CHECK_COMPILE([if 'struct key' has 'payload.data' as an array], +key_payload_data_array, [ + #include +],[ + ((struct key *)0)->payload.data[0] = NULL; +],[ + AC_DEFINE(HAVE_KEY_PAYLOAD_DATA_ARRAY, 1, [payload.data is an array]) +]) +]) #LC_HAVE_KEY_PAYLOAD_DATA_ARRAY + +# # LC_PROG_LINUX # # Lustre linux kernel checks @@ -2196,6 +2212,7 @@ AC_DEFUN([LC_PROG_LINUX], [ # 4.4 LC_HAVE_LOCKS_LOCK_FILE_WAIT LC_HAVE_QC_MAKE_REQUEST_FN + LC_HAVE_KEY_PAYLOAD_DATA_ARRAY # AS_IF([test "x$enable_server" != xno], [ diff --git a/lustre/ptlrpc/gss/gss_keyring.c b/lustre/ptlrpc/gss/gss_keyring.c index 67188f5..e8fbe50 100644 --- a/lustre/ptlrpc/gss/gss_keyring.c +++ b/lustre/ptlrpc/gss/gss_keyring.c @@ -348,6 +348,43 @@ static int ctx_unlist_kr(struct ptlrpc_cli_ctx *ctx, int locked) } /* + * Get specific payload. Newer kernels support 4 slots. + */ +static void * +key_get_payload(struct key *key, unsigned int index) +{ + void *key_ptr = NULL; + +#ifdef HAVE_KEY_PAYLOAD_DATA_ARRAY + key_ptr = key->payload.data[index]; +#else + if (!index) + key_ptr = key->payload.data; +#endif + return key_ptr; +} + +/* + * Set specific payload. Newer kernels support 4 slots. + */ +static int key_set_payload(struct key *key, unsigned int index, + struct ptlrpc_cli_ctx *ctx) +{ + int rc = -EINVAL; + +#ifdef HAVE_KEY_PAYLOAD_DATA_ARRAY + if (index < 4) { + key->payload.data[index] = ctx; +#else + if (!index) { + key->payload.data = ctx; +#endif + rc = 0; + } + return rc; +} + +/* * bind a key with a ctx together. * caller must hold write lock of the key, as well as ref on key & ctx. */ @@ -356,13 +393,13 @@ static void bind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx) LASSERT(atomic_read(&ctx->cc_refcount) > 0); LASSERT(atomic_read(&key->usage) > 0); LASSERT(ctx2gctx_keyring(ctx)->gck_key == NULL); - LASSERT(key->payload.data == NULL); + LASSERT(!key_get_payload(key, 0)); /* at this time context may or may not in list. */ key_get(key); atomic_inc(&ctx->cc_refcount); ctx2gctx_keyring(ctx)->gck_key = key; - key->payload.data = ctx; + LASSERT(!key_set_payload(key, 0, ctx)); } /* @@ -371,13 +408,13 @@ static void bind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx) */ static void unbind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx) { - LASSERT(key->payload.data == ctx); + LASSERT(key_get_payload(key, 0) == ctx); LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0); /* must revoke the key, or others may treat it as newly created */ key_revoke_locked(key); - key->payload.data = NULL; + key_set_payload(key, 0, NULL); ctx2gctx_keyring(ctx)->gck_key = NULL; /* once ctx get split from key, the timer is meaningless */ @@ -397,7 +434,7 @@ static void unbind_ctx_kr(struct ptlrpc_cli_ctx *ctx) struct key *key = ctx2gctx_keyring(ctx)->gck_key; if (key) { - LASSERT(key->payload.data == ctx); + LASSERT(key_get_payload(key, 0) == ctx); key_get(key); down_write(&key->sem); @@ -413,7 +450,7 @@ static void unbind_ctx_kr(struct ptlrpc_cli_ctx *ctx) */ static void unbind_key_locked(struct key *key) { - struct ptlrpc_cli_ctx *ctx = key->payload.data; + struct ptlrpc_cli_ctx *ctx = key_get_payload(key, 0); if (ctx) unbind_key_ctx(key, ctx); @@ -434,7 +471,7 @@ static void kill_ctx_kr(struct ptlrpc_cli_ctx *ctx) */ static void kill_key_locked(struct key *key) { - struct ptlrpc_cli_ctx *ctx = key->payload.data; + struct ptlrpc_cli_ctx *ctx = key_get_payload(key, 0); if (ctx && ctx_unlist_kr(ctx, 0)) unbind_key_locked(key); @@ -799,9 +836,8 @@ struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_kr(struct ptlrpc_sec *sec, * need wirtelock of key->sem to serialize them. */ down_write(&key->sem); - if (likely(key->payload.data != NULL)) { - ctx = key->payload.data; - + ctx = key_get_payload(key, 0); + if (likely(ctx)) { LASSERT(atomic_read(&ctx->cc_refcount) >= 1); LASSERT(ctx2gctx_keyring(ctx)->gck_key == key); LASSERT(atomic_read(&key->usage) >= 2); @@ -1167,7 +1203,7 @@ int sec_install_rctx_kr(struct ptlrpc_sec *sec, down_write(&key->sem); - LASSERT(key->payload.data == NULL); + LASSERT(!key_get_payload(key, 0)); cli_ctx = ctx_create_kr(sec, &vcred); if (cli_ctx == NULL) { @@ -1251,7 +1287,7 @@ int gss_kt_instantiate(struct key *key, const void *data, size_t datalen) RETURN(-EINVAL); } - if (key->payload.data != NULL) { + if (key_get_payload(key, 0)) { CERROR("key already have payload\n"); RETURN(-EINVAL); } @@ -1278,7 +1314,8 @@ int gss_kt_instantiate(struct key *key, const void *data, size_t datalen) RETURN(rc); } - CDEBUG(D_SEC, "key %p instantiated, ctx %p\n", key, key->payload.data); + CDEBUG(D_SEC, "key %p instantiated, ctx %p\n", key, + key_get_payload(key, 0)); RETURN(0); } @@ -1297,7 +1334,7 @@ int gss_kt_update(struct key *key, const void *data, size_t datalen) { __u32 datalen32 = (__u32) datalen; #endif - struct ptlrpc_cli_ctx *ctx = key->payload.data; + struct ptlrpc_cli_ctx *ctx = key_get_payload(key, 0); struct gss_cli_ctx *gctx; rawobj_t tmpobj = RAWOBJ_EMPTY; int rc; @@ -1442,7 +1479,7 @@ static void gss_kt_destroy(struct key *key) { ENTRY; - LASSERT(key->payload.data == NULL); + LASSERT(!key_get_payload(key, 0)); CDEBUG(D_SEC, "destroy key %p\n", key); EXIT; } -- 1.8.3.1