Whamcloud - gitweb
LU-6215 gss: key->payload.data is an array in 4.4+ kernels 31/18731/11
authorLi Dongyang <dongyang.li@anu.edu.au>
Thu, 21 Apr 2016 14:25:28 +0000 (10:25 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 28 Apr 2016 04:23:05 +0000 (04:23 +0000)
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 <dongyang.li@anu.edu.au>
Signed-off-by: James Simmons <uja.ornl@yahoo.com>
Change-Id: I1036ab927514f0efa073d9f0136e299be8950461
Reviewed-on: http://review.whamcloud.com/18731
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Sebastien Buisson <sbuisson@ddn.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/autoconf/lustre-core.m4
lustre/ptlrpc/gss/gss_keyring.c

index 9f59979..670389e 100644 (file)
@@ -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 <linux/key.h>
+],[
+       ((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], [
index 67188f5..e8fbe50 100644 (file)
@@ -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;
 }