From 9b73c02192b3e16c322402e8c080e660ba2c457c Mon Sep 17 00:00:00 2001
From: ericm <ericm>
Date: Wed, 19 Sep 2007 22:08:58 +0000
Subject: [PATCH] branch: HEAD land b1_8_gssfix (20070919_1543): various gss
 fixes (b11841)

---
 lustre/include/lustre_import.h                |   1 -
 lustre/include/lustre_net.h                   |   4 +-
 lustre/include/lustre_sec.h                   | 161 +++--
 lustre/ldlm/ldlm_lib.c                        |  10 +-
 lustre/ldlm/ldlm_lockd.c                      |   3 +
 lustre/osc/osc_request.c                      |   7 +-
 lustre/ost/ost_handler.c                      |  18 +-
 lustre/ptlrpc/client.c                        |   4 +-
 lustre/ptlrpc/gss/gss_bulk.c                  |  92 +--
 lustre/ptlrpc/gss/gss_cli_upcall.c            |  45 +-
 lustre/ptlrpc/gss/gss_internal.h              |  57 +-
 lustre/ptlrpc/gss/gss_keyring.c               | 207 ++++---
 lustre/ptlrpc/gss/gss_krb5_mech.c             |  28 +-
 lustre/ptlrpc/gss/gss_mech_switch.c           |   2 +-
 lustre/ptlrpc/gss/gss_pipefs.c                |  53 +-
 lustre/ptlrpc/gss/gss_rawobj.c                |   1 +
 lustre/ptlrpc/gss/gss_svc_upcall.c            |  78 +--
 lustre/ptlrpc/gss/sec_gss.c                   | 585 ++++++++++++------
 lustre/ptlrpc/import.c                        |   4 -
 lustre/ptlrpc/ptlrpc_internal.h               |   2 -
 lustre/ptlrpc/sec.c                           | 118 ++--
 lustre/ptlrpc/sec_bulk.c                      |  13 +-
 lustre/ptlrpc/sec_gc.c                        |  60 +-
 lustre/ptlrpc/sec_lproc.c                     |  23 +-
 lustre/ptlrpc/sec_null.c                      |   4 +-
 lustre/ptlrpc/sec_plain.c                     |  69 ++-
 lustre/ptlrpc/service.c                       |   8 +
 lustre/tests/disk1_4.zip                      | Bin 216468 -> 170785 bytes
 lustre/tests/insanity.sh                      |   1 +
 lustre/tests/recovery-small.sh                |   1 +
 lustre/tests/sanity-gss.sh                    |  27 +-
 lustre/tests/sanity-sec.sh                    |   2 +-
 lustre/tests/sanity.sh                        |   7 +-
 lustre/tests/sanityN.sh                       |   2 +-
 lustre/tests/test-framework.sh                |  20 +-
 lustre/utils/gss/lgss_utils.c                 |   2 +-
 lustre/utils/gss/lsupport.c                   |   6 +
 lustre/utils/gss/lsupport.h                   |   2 +
 lustre/utils/gss/nfs-utils-1.0.11-lustre.diff |  89 +--
 lustre/utils/gss/svcgssd_main_loop.c          |   2 +-
 lustre/utils/gss/svcgssd_proc.c               |   9 +-
 41 files changed, 1053 insertions(+), 774 deletions(-)

diff --git a/lustre/include/lustre_import.h b/lustre/include/lustre_import.h
index 542d073b14..76197c9ec0 100644
--- a/lustre/include/lustre_import.h
+++ b/lustre/include/lustre_import.h
@@ -81,7 +81,6 @@ struct obd_import {
         struct lustre_handle      imp_remote_handle;
         cfs_time_t                imp_next_ping;   /* jiffies */
         __u64                     imp_last_success_conn;   /* jiffies, 64-bit */
-        cfs_time_t                imp_next_reconnect;      /* seconds */
 
         /* all available obd_import_conn linked here */
         struct list_head          imp_conn_list;
diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h
index b51977018e..34ced38054 100644
--- a/lustre/include/lustre_net.h
+++ b/lustre/include/lustre_net.h
@@ -340,7 +340,9 @@ struct ptlrpc_request {
                                  rq_auth_gss:1,      /* authenticated by gss */
                                  rq_auth_remote:1,   /* authed as remote user */
                                  rq_auth_usr_root:1, /* authed as root */
-                                 rq_auth_usr_mdt:1;  /* authed as mdt */
+                                 rq_auth_usr_mdt:1,  /* authed as mdt */
+                                 /* doesn't expect reply FIXME */
+                                 rq_no_reply:1;
 
         uid_t                    rq_auth_uid;        /* authed uid */
         uid_t                    rq_auth_mapped_uid; /* authed uid mapped to */
diff --git a/lustre/include/lustre_sec.h b/lustre/include/lustre_sec.h
index 8ce5ab3e48..e9fe8547f3 100644
--- a/lustre/include/lustre_sec.h
+++ b/lustre/include/lustre_sec.h
@@ -27,6 +27,7 @@
  */
 struct key;
 struct obd_import;
+struct obd_export;
 struct ptlrpc_request;
 struct ptlrpc_reply_state;
 struct ptlrpc_bulk_desc;
@@ -46,7 +47,7 @@ struct ptlrpc_ctx_ops;
 /*
  * flavor constants
  */
-enum sptlrpc_policies {
+enum sptlrpc_policy {
         SPTLRPC_POLICY_NULL             = 0,
         SPTLRPC_POLICY_PLAIN            = 1,
         SPTLRPC_POLICY_GSS              = 2,
@@ -54,26 +55,27 @@ enum sptlrpc_policies {
         SPTLRPC_POLICY_MAX,
 };
 
-enum sptlrpc_subpolicy_null {
-        SPTLRPC_SUBPOLICY_NULL          = 0,
-        SPTLRPC_SUBPOLICY_NULL_MAX,
+enum sptlrpc_mech_null {
+        SPTLRPC_MECH_NULL               = 0,
+        SPTLRPC_MECH_NULL_MAX,
 };
 
-enum sptlrpc_subpolicy_plain {
-        SPTLRPC_SUBPOLICY_PLAIN         = 0,
-        SPTLRPC_SUBPOLICY_PLAIN_MAX,
+enum sptlrpc_mech_plain {
+        SPTLRPC_MECH_PLAIN              = 0,
+        SPTLRPC_MECH_PLAIN_MAX,
 };
 
-enum sptlrpc_subpolicy_gss {
-        SPTLRPC_SUBPOLICY_GSS_NONE      = 0,
-        SPTLRPC_SUBPOLICY_GSS_KRB5      = 1,
-        SPTLRPC_SUBPOLICY_GSS_MAX,
+enum sptlrpc_mech_gss {
+        SPTLRPC_MECH_GSS_NULL           = 0,
+        SPTLRPC_MECH_GSS_KRB5           = 1,
+        SPTLRPC_MECH_GSS_MAX,
 };
 
 enum sptlrpc_service_type {
-        SPTLRPC_SVC_NONE                = 0,    /* no security */
-        SPTLRPC_SVC_AUTH                = 1,    /* authentication */
-        SPTLRPC_SVC_PRIV                = 2,    /* privacy */
+        SPTLRPC_SVC_NULL                = 0,    /* no security */
+        SPTLRPC_SVC_AUTH                = 1,    /* auth only */
+        SPTLRPC_SVC_INTG                = 2,    /* integrity */
+        SPTLRPC_SVC_PRIV                = 3,    /* privacy */
         SPTLRPC_SVC_MAX,
 };
 
@@ -84,61 +86,52 @@ enum sptlrpc_service_type {
 typedef __u32 ptlrpc_sec_flavor_t;
 
 /*
- *  8b (reserved) | 8b (flags) | 6b (policy) | 6b (subpolicy) | 4b (svc)
+ *  8b (reserved)            | 8b (flags)
+ *  4b (reserved) | 4b (svc) | 4b (mech)  | 4b (policy)
  */
+#define SEC_FLAVOR_POLICY_OFFSET        (0)
+#define SEC_FLAVOR_MECH_OFFSET          (4)
+#define SEC_FLAVOR_SVC_OFFSET           (8)
+#define SEC_FLAVOR_RESERVE1_OFFSET      (12)
 #define SEC_FLAVOR_FLAGS_OFFSET         (16)
-#define SEC_FLAVOR_POLICY_OFFSET        (10)
-#define SEC_FLAVOR_SUBPOLICY_OFFSET     (4)
-#define SEC_FLAVOR_SVC_OFFSET           (0)
 
-#define SEC_MAKE_RPC_FLAVOR(policy, subpolicy, svc)                     \
+#define SEC_MAKE_RPC_FLAVOR(policy, mech, svc)                          \
         (((__u32)(policy) << SEC_FLAVOR_POLICY_OFFSET) |                \
-         ((__u32)(subpolicy) << SEC_FLAVOR_SUBPOLICY_OFFSET) |          \
+         ((__u32)(mech) << SEC_FLAVOR_MECH_OFFSET) |                    \
          ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET))
 
-#define SEC_MAKE_RPC_SUBFLAVOR(subpolicy, svc)                          \
-        (((__u32)(subpolicy) << SEC_FLAVOR_SUBPOLICY_OFFSET) |          \
-         ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET))
+#define SEC_MAKE_RPC_SUBFLAVOR(mech, svc)                               \
+        ((__u32)(mech) |                                                \
+         ((__u32)(svc) <<                                               \
+                (SEC_FLAVOR_SVC_OFFSET - SEC_FLAVOR_MECH_OFFSET)))
+
+#define SEC_FLAVOR_SUB(flavor)                                          \
+        ((((__u32)(flavor)) >> SEC_FLAVOR_MECH_OFFSET) & 0xFF)
 
 #define SEC_FLAVOR_POLICY(flavor)                                       \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_POLICY_OFFSET) & 0x3F)
-#define SEC_FLAVOR_SUBPOLICY(flavor)                                    \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_SUBPOLICY_OFFSET) & 0x3F)
+        ((((__u32)(flavor)) >> SEC_FLAVOR_POLICY_OFFSET) & 0xF)
+#define SEC_FLAVOR_MECH(flavor)                                         \
+        ((((__u32)(flavor)) >> SEC_FLAVOR_MECH_OFFSET) & 0xF)
 #define SEC_FLAVOR_SVC(flavor)                                          \
         ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xF)
-#define SEC_FLAVOR_SUB(flavor)                                          \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0x3FF)
 
 #define SEC_FLAVOR_RPC(f)                                               \
-        (((__u32) f) & ((1 << SEC_FLAVOR_FLAGS_OFFSET) - 1))
-
-/*
- * general gss flavors
- */
-#define SPTLRPC_FLVR_GSS_NONE                                   \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_SUBPOLICY_GSS_NONE,         \
-                            SPTLRPC_SVC_NONE)
-#define SPTLRPC_FLVR_GSS_AUTH                                   \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_SUBPOLICY_GSS_NONE,         \
-                            SPTLRPC_SVC_AUTH)
-#define SPTLRPC_FLVR_GSS_PRIV                                   \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_SUBPOLICY_GSS_NONE,         \
-                            SPTLRPC_SVC_PRIV)
+        (((__u32) (f)) & ((1 << SEC_FLAVOR_RESERVE1_OFFSET) - 1))
 
 /*
  * gss subflavors
  */
-#define SPTLRPC_SUBFLVR_KRB5                                    \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_SUBPOLICY_GSS_KRB5,      \
-                               SPTLRPC_SVC_NONE)
-#define SPTLRPC_SUBFLVR_KRB5I                                   \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_SUBPOLICY_GSS_KRB5,      \
+#define SPTLRPC_SUBFLVR_KRB5N                                   \
+        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
+                               SPTLRPC_SVC_NULL)
+#define SPTLRPC_SUBFLVR_KRB5A                                   \
+        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
                                SPTLRPC_SVC_AUTH)
+#define SPTLRPC_SUBFLVR_KRB5I                                   \
+        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
+                               SPTLRPC_SVC_INTG)
 #define SPTLRPC_SUBFLVR_KRB5P                                   \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_SUBPOLICY_GSS_KRB5,      \
+        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
                                SPTLRPC_SVC_PRIV)
 
 /*
@@ -146,23 +139,27 @@ typedef __u32 ptlrpc_sec_flavor_t;
  */
 #define SPTLRPC_FLVR_NULL                                       \
         SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_NULL,                \
-                            SPTLRPC_SUBPOLICY_NULL,             \
-                            SPTLRPC_SVC_NONE)
+                            SPTLRPC_MECH_NULL,                  \
+                            SPTLRPC_SVC_NULL)
 #define SPTLRPC_FLVR_PLAIN                                      \
         SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_PLAIN,               \
-                            SPTLRPC_SUBPOLICY_PLAIN,            \
-                            SPTLRPC_SVC_NONE)
-#define SPTLRPC_FLVR_KRB5                                       \
+                            SPTLRPC_MECH_PLAIN,                 \
+                            SPTLRPC_SVC_NULL)
+#define SPTLRPC_FLVR_KRB5N                                      \
         SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_SUBPOLICY_GSS_KRB5,         \
-                            SPTLRPC_SVC_NONE)
-#define SPTLRPC_FLVR_KRB5I                                      \
+                            SPTLRPC_MECH_GSS_KRB5,              \
+                            SPTLRPC_SVC_NULL)
+#define SPTLRPC_FLVR_KRB5A                                      \
         SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_SUBPOLICY_GSS_KRB5,         \
+                            SPTLRPC_MECH_GSS_KRB5,              \
                             SPTLRPC_SVC_AUTH)
+#define SPTLRPC_FLVR_KRB5I                                      \
+        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
+                            SPTLRPC_MECH_GSS_KRB5,              \
+                            SPTLRPC_SVC_INTG)
 #define SPTLRPC_FLVR_KRB5P                                      \
         SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_SUBPOLICY_GSS_KRB5,         \
+                            SPTLRPC_MECH_GSS_KRB5,              \
                             SPTLRPC_SVC_PRIV)
 
 #define SPTLRPC_FLVR_INVALID            (-1)
@@ -259,15 +256,17 @@ struct ptlrpc_ctx_ops {
                                         PTLRPC_CTX_ERROR)
 
 struct ptlrpc_cli_ctx {
-        struct hlist_node       cc_hash;       /* linked into hash table */
+        struct hlist_node       cc_cache;      /* linked into ctx cache */
         atomic_t                cc_refcount;
         struct ptlrpc_sec      *cc_sec;
         struct ptlrpc_ctx_ops  *cc_ops;
         cfs_time_t              cc_expire;     /* in seconds */
+        unsigned int            cc_early_expire:1;
         unsigned long           cc_flags;
         struct vfs_cred         cc_vcred;
         spinlock_t              cc_lock;
         struct list_head        cc_req_list;   /* waiting reqs linked here */
+        struct list_head        cc_gc_chain;   /* linked to gc chain */
 };
 
 struct ptlrpc_sec_cops {
@@ -377,6 +376,17 @@ struct ptlrpc_sec {
         cfs_time_t                      ps_gc_next;     /* in seconds */
 };
 
+static inline int sec_is_reverse(struct ptlrpc_sec *sec)
+{
+        return (sec->ps_flags & PTLRPC_SEC_FL_REVERSE);
+}
+
+static inline int sec_is_rootonly(struct ptlrpc_sec *sec)
+{
+        return (sec->ps_flags & PTLRPC_SEC_FL_ROOTONLY);
+}
+
+
 struct ptlrpc_svc_ctx {
         atomic_t                        sc_refcount;
         struct ptlrpc_sec_policy       *sc_policy;
@@ -490,7 +500,7 @@ unsigned long cli_ctx_status(struct ptlrpc_cli_ctx *ctx)
 }
 
 static inline
-int cli_ctx_is_uptodate(struct ptlrpc_cli_ctx *ctx)
+int cli_ctx_is_ready(struct ptlrpc_cli_ctx *ctx)
 {
         return (cli_ctx_status(ctx) == PTLRPC_CTX_UPTODATE);
 }
@@ -501,6 +511,18 @@ int cli_ctx_is_refreshed(struct ptlrpc_cli_ctx *ctx)
         return (cli_ctx_status(ctx) != 0);
 }
 
+static inline
+int cli_ctx_is_uptodate(struct ptlrpc_cli_ctx *ctx)
+{
+        return ((ctx->cc_flags & PTLRPC_CTX_UPTODATE) != 0);
+}
+
+static inline
+int cli_ctx_is_error(struct ptlrpc_cli_ctx *ctx)
+{
+        return ((ctx->cc_flags & PTLRPC_CTX_ERROR) != 0);
+}
+
 static inline
 int cli_ctx_is_dead(struct ptlrpc_cli_ctx *ctx)
 {
@@ -551,7 +573,7 @@ void sptlrpc_import_flush_root_ctx(struct obd_import *imp);
 void sptlrpc_import_flush_my_ctx(struct obd_import *imp);
 void sptlrpc_import_flush_all_ctx(struct obd_import *imp);
 int  sptlrpc_req_get_ctx(struct ptlrpc_request *req);
-void sptlrpc_req_put_ctx(struct ptlrpc_request *req);
+void sptlrpc_req_put_ctx(struct ptlrpc_request *req, int sync);
 int  sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout);
 int  sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req);
 void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode);
@@ -559,6 +581,11 @@ void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode);
 int sptlrpc_parse_flavor(enum lustre_part from, enum lustre_part to,
                          char *str, struct sec_flavor_config *conf);
 
+/* gc */
+void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec);
+void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec);
+void sptlrpc_gc_add_ctx(struct ptlrpc_cli_ctx *ctx);
+
 /* misc */
 const char * sec2target_str(struct ptlrpc_sec *sec);
 int sptlrpc_lprocfs_rd(char *page, char **start, off_t off, int count,
@@ -573,6 +600,8 @@ enum secsvc_accept_res {
         SECSVC_DROP,
 };
 
+int sptlrpc_target_export_check(struct obd_export *exp,
+                                struct ptlrpc_request *req);
 int  sptlrpc_svc_unwrap_request(struct ptlrpc_request *req);
 int  sptlrpc_svc_alloc_rs(struct ptlrpc_request *req, int msglen);
 int  sptlrpc_svc_wrap_reply(struct ptlrpc_request *req);
@@ -627,8 +656,8 @@ int bulk_csum_cli_reply(struct ptlrpc_bulk_desc *desc, int read,
                         struct lustre_msg *rmsg, int roff,
                         struct lustre_msg *vmsg, int voff);
 int bulk_csum_svc(struct ptlrpc_bulk_desc *desc, int read,
-                  struct lustre_msg *vmsg, int voff,
-                  struct lustre_msg *rmsg, int roff);
+                  struct ptlrpc_bulk_sec_desc *bsdv, int vsize,
+                  struct ptlrpc_bulk_sec_desc *bsdr, int rsize);
 
 
 #endif /* _LUSTRE_SEC_H_ */
diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c
index a952e99a6b..446e9a520f 100644
--- a/lustre/ldlm/ldlm_lib.c
+++ b/lustre/ldlm/ldlm_lib.c
@@ -870,13 +870,6 @@ dont_check_exports:
                                                        req->rq_self,
                                                        &remote_uuid);
 
-        if (lustre_msg_get_op_flags(req->rq_repmsg) & MSG_CONNECT_RECONNECT) {
-                LASSERT(export->exp_imp_reverse);
-                sptlrpc_svc_install_rvs_ctx(export->exp_imp_reverse,
-                                            req->rq_svc_ctx);
-                GOTO(out, rc = 0);
-        }
-
         spin_lock_bh(&target->obd_processing_task_lock);
         if (target->obd_recovering && !export->exp_in_recovery) {
                 spin_lock(&export->exp_lock);
@@ -1817,6 +1810,9 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
         struct obd_export         *exp;
         struct ptlrpc_service     *svc;
 
+        if (req->rq_no_reply)
+                return;
+
         svc = req->rq_rqbd->rqbd_service;
         rs = req->rq_reply_state;
         if (rs == NULL || !rs->rs_difficult) {
diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c
index 56e4b734b2..4c502cd235 100644
--- a/lustre/ldlm/ldlm_lockd.c
+++ b/lustre/ldlm/ldlm_lockd.c
@@ -1500,6 +1500,9 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                 rc = llog_origin_handle_close(req);
                 ldlm_callback_reply(req, rc);
                 RETURN(0);
+        case SEC_CTX_FINI:
+                /* do nothing */
+                RETURN(0);
         default:
                 CERROR("unknown opcode %u\n",
                        lustre_msg_get_opc(req->rq_reqmsg));
diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c
index 6ca5e6f34f..11f0a2b848 100644
--- a/lustre/osc/osc_request.c
+++ b/lustre/osc/osc_request.c
@@ -1182,7 +1182,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
                                                   aa->aa_ppga)))
                         RETURN(-EAGAIN);
 
-                sptlrpc_cli_unwrap_bulk_write(req, req->rq_bulk);
+                if (sptlrpc_cli_unwrap_bulk_write(req, req->rq_bulk))
+                        RETURN(-EAGAIN);
 
                 rc = check_write_rcs(req, aa->aa_requested_nob,aa->aa_nio_count,
                                      aa->aa_page_count, aa->aa_ppga);
@@ -1205,7 +1206,9 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
         if (rc < aa->aa_requested_nob)
                 handle_short_read(rc, aa->aa_page_count, aa->aa_ppga);
 
-        sptlrpc_cli_unwrap_bulk_read(req, rc, aa->aa_page_count, aa->aa_ppga);
+        if (sptlrpc_cli_unwrap_bulk_read(req, rc, aa->aa_page_count,
+                                         aa->aa_ppga))
+                GOTO(out, rc = -EAGAIN);
 
         if (unlikely(body->oa.o_valid & OBD_MD_FLCKSUM)) {
                 static int cksum_counter;
diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c
index c18d9192bf..9b1526a0c9 100644
--- a/lustre/ost/ost_handler.c
+++ b/lustre/ost/ost_handler.c
@@ -1111,6 +1111,11 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
         }
         no_reply = rc != 0;
 
+        if (rc == 0) {
+                /* let client retry if unwrap failed */
+                rc = sptlrpc_svc_unwrap_bulk(req, desc);
+        }
+
         repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF,
                                  sizeof(*repbody));
         memcpy(&repbody->oa, &body->oa, sizeof(repbody->oa));
@@ -1132,19 +1137,6 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti)
                 }
         }
 
-        sptlrpc_svc_unwrap_bulk(req, desc);
-
-        /* Check if there is eviction in progress, and if so, wait for
-         * it to finish */
-        if (unlikely(atomic_read(&exp->exp_obd->obd_evict_inprogress))) {
-                lwi = LWI_INTR(NULL, NULL);
-                rc = l_wait_event(exp->exp_obd->obd_evict_inprogress_waitq,
-                        !atomic_read(&exp->exp_obd->obd_evict_inprogress),
-                        &lwi);
-        }
-        if (rc == 0 && exp->exp_failed)
-                rc = -ENOTCONN;
-
         /* Must commit after prep above in all cases */
         rc = obd_commitrw(OBD_BRW_WRITE, exp, &repbody->oa,
                            objcount, ioo, npages, local_nb, oti, rc);
diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c
index 8f79036ae5..4542504e8e 100644
--- a/lustre/ptlrpc/client.c
+++ b/lustre/ptlrpc/client.c
@@ -405,7 +405,7 @@ ptlrpc_prep_req_pool(struct obd_import *imp, __u32 version, int opcode,
 
         RETURN(request);
 out_ctx:
-        sptlrpc_req_put_ctx(request);
+        sptlrpc_req_put_ctx(request, 1);
 out_free:
         class_import_put(imp);
         if (request->rq_pool)
@@ -1294,7 +1294,7 @@ static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked)
         if (request->rq_reqbuf != NULL || request->rq_clrbuf != NULL)
                 sptlrpc_cli_free_reqbuf(request);
 
-        sptlrpc_req_put_ctx(request);
+        sptlrpc_req_put_ctx(request, !locked);
 
         if (request->rq_pool)
                 __ptlrpc_free_req_to_pool(request);
diff --git a/lustre/ptlrpc/gss/gss_bulk.c b/lustre/ptlrpc/gss/gss_bulk.c
index cede7916ba..7d4864c49d 100644
--- a/lustre/ptlrpc/gss/gss_bulk.c
+++ b/lustre/ptlrpc/gss/gss_bulk.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -141,7 +142,13 @@ int gss_cli_ctx_wrap_bulk(struct ptlrpc_cli_ctx *ctx,
         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
 
         switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
+        case SPTLRPC_SVC_NULL:
+                LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
+                msg = req->rq_reqbuf;
+                offset = msg->lm_bufcount - 1;
+                break;
         case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
                 LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
                 msg = req->rq_reqbuf;
                 offset = msg->lm_bufcount - 2;
@@ -208,7 +215,17 @@ int gss_cli_ctx_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
 
         switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
+        case SPTLRPC_SVC_NULL:
+                vmsg = req->rq_repbuf;
+                voff = vmsg->lm_bufcount - 1;
+                LASSERT(vmsg && vmsg->lm_bufcount >= 3);
+
+                rmsg = req->rq_reqbuf;
+                roff = rmsg->lm_bufcount - 1; /* last segment */
+                LASSERT(rmsg && rmsg->lm_bufcount >= 3);
+                break;
         case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
                 vmsg = req->rq_repbuf;
                 voff = vmsg->lm_bufcount - 2;
                 LASSERT(vmsg && vmsg->lm_bufcount >= 4);
@@ -264,43 +281,35 @@ verify_csum:
 int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
                         struct ptlrpc_bulk_desc *desc)
 {
-        struct ptlrpc_reply_state    *rs = req->rq_reply_state;
         struct gss_svc_reqctx        *grctx;
-        struct ptlrpc_bulk_sec_desc  *bsdv;
-        int                           voff, roff, rc;
+        int                           rc;
         ENTRY;
 
-        LASSERT(rs);
+        LASSERT(req->rq_svc_ctx);
         LASSERT(req->rq_bulk_write);
 
-        if (SEC_FLAVOR_SVC(req->rq_sec_flavor) == SPTLRPC_SVC_PRIV) {
-                LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
-                LASSERT(rs->rs_repbuf->lm_bufcount >= 2);
-                voff = req->rq_reqbuf->lm_bufcount - 1;
-                roff = rs->rs_repbuf->lm_bufcount - 1;
-        } else {
-                LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
-                LASSERT(rs->rs_repbuf->lm_bufcount >= 4);
-                voff = req->rq_reqbuf->lm_bufcount - 2;
-                roff = rs->rs_repbuf->lm_bufcount - 2;
-        }
+        grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
 
-        bsdv = lustre_msg_buf(req->rq_reqbuf, voff, sizeof(*bsdv));
-        if (bsdv->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
-                grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-                LASSERT(grctx->src_ctx);
-                LASSERT(grctx->src_ctx->gsc_mechctx);
+        LASSERT(grctx->src_reqbsd);
+        LASSERT(grctx->src_repbsd);
+        LASSERT(grctx->src_ctx);
+        LASSERT(grctx->src_ctx->gsc_mechctx);
 
+        /* decrypt bulk data if it's encrypted */
+        if (grctx->src_reqbsd->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
                 rc = do_bulk_privacy(grctx->src_ctx->gsc_mechctx, desc, 0,
-                                     bsdv->bsd_priv_alg, bsdv);
+                                     grctx->src_reqbsd->bsd_priv_alg,
+                                     grctx->src_reqbsd);
                 if (rc) {
                         CERROR("bulk write: server failed to decrypt data\n");
                         RETURN(rc);
                 }
         }
 
+        /* verify bulk data checksum */
         rc = bulk_csum_svc(desc, req->rq_bulk_read,
-                           req->rq_reqbuf, voff, rs->rs_repbuf, roff);
+                           grctx->src_reqbsd, grctx->src_reqbsd_size,
+                           grctx->src_repbsd, grctx->src_repbsd_size);
 
         RETURN(rc);
 }
@@ -308,40 +317,35 @@ int gss_svc_unwrap_bulk(struct ptlrpc_request *req,
 int gss_svc_wrap_bulk(struct ptlrpc_request *req,
                       struct ptlrpc_bulk_desc *desc)
 {
-        struct ptlrpc_reply_state    *rs = req->rq_reply_state;
         struct gss_svc_reqctx        *grctx;
-        struct ptlrpc_bulk_sec_desc  *bsdv, *bsdr;
-        int                           voff, roff, rc;
+        int                           rc;
         ENTRY;
 
-        LASSERT(rs);
+        LASSERT(req->rq_svc_ctx);
         LASSERT(req->rq_bulk_read);
 
-        if (SEC_FLAVOR_SVC(req->rq_sec_flavor) == SPTLRPC_SVC_PRIV) {
-                voff = req->rq_reqbuf->lm_bufcount - 1;
-                roff = rs->rs_repbuf->lm_bufcount - 1;
-        } else {
-                voff = req->rq_reqbuf->lm_bufcount - 2;
-                roff = rs->rs_repbuf->lm_bufcount - 2;
-        }
+        grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
+
+        LASSERT(grctx->src_reqbsd);
+        LASSERT(grctx->src_repbsd);
+        LASSERT(grctx->src_ctx);
+        LASSERT(grctx->src_ctx->gsc_mechctx);
 
+        /* generate bulk data checksum */
         rc = bulk_csum_svc(desc, req->rq_bulk_read,
-                           req->rq_reqbuf, voff, rs->rs_repbuf, roff);
+                           grctx->src_reqbsd, grctx->src_reqbsd_size,
+                           grctx->src_repbsd, grctx->src_repbsd_size);
         if (rc)
                 RETURN(rc);
 
-        bsdv = lustre_msg_buf(req->rq_reqbuf, voff, sizeof(*bsdv));
-        if (bsdv->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
-                grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-                LASSERT(grctx->src_ctx);
-                LASSERT(grctx->src_ctx->gsc_mechctx);
-
-                bsdr = lustre_msg_buf(rs->rs_repbuf, roff, sizeof(*bsdr));
-
+        /* encrypt bulk data if required */
+        if (grctx->src_reqbsd->bsd_priv_alg != BULK_PRIV_ALG_NULL) {
                 rc = do_bulk_privacy(grctx->src_ctx->gsc_mechctx, desc, 1,
-                                     bsdv->bsd_priv_alg, bsdr);
+                                     grctx->src_reqbsd->bsd_priv_alg,
+                                     grctx->src_repbsd);
                 if (rc)
-                        CERROR("bulk read: server failed to encrypt data\n");
+                        CERROR("bulk read: server failed to encrypt data: "
+                               "rc %d\n", rc);
         }
 
         RETURN(rc);
diff --git a/lustre/ptlrpc/gss/gss_cli_upcall.c b/lustre/ptlrpc/gss/gss_cli_upcall.c
index ac2a9036c1..e36a092530 100644
--- a/lustre/ptlrpc/gss/gss_cli_upcall.c
+++ b/lustre/ptlrpc/gss/gss_cli_upcall.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  *  Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of the Lustre file system, http://www.lustre.org
  *   Lustre is a trademark of Cluster File Systems, Inc.
@@ -78,7 +79,7 @@ int ctx_init_pack_request(struct obd_import *imp,
         ghdr->gh_flags = 0;
         ghdr->gh_proc = PTLRPC_GSS_PROC_INIT;
         ghdr->gh_seq = 0;
-        ghdr->gh_svc = PTLRPC_GSS_SVC_NONE;
+        ghdr->gh_svc = SPTLRPC_SVC_NULL;
         ghdr->gh_handle.len = 0;
 
         /* fix the user desc */
@@ -330,35 +331,19 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
         int                      rc;
         ENTRY;
 
-        if (ctx->cc_sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
-                CWARN("ctx %p(%u) is reverse, don't send destroy rpc\n",
-                      ctx, ctx->cc_vcred.vc_uid);
-                RETURN(0);
-        }
-
-        /* FIXME
-         * this could be called when import being tearing down, thus import's
-         * spinlock is held. A more clean solution might be: let gss worker
-         * thread handle the ctx destroying; don't wait reply for fini rpc.
-         */
-        if (imp->imp_invalid) {
-                CWARN("ctx %p(%u): skip because import is invalid\n",
-                      ctx, ctx->cc_vcred.vc_uid);
-                RETURN(0);
-        }
-        RETURN(0); // XXX remove after using gss worker thread
-
-        if (test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags) ||
-            !test_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags)) {
-                CWARN("ctx %p(%u->%s) already dead, don't send destroy rpc\n",
-                      ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+        if (cli_ctx_is_error(ctx) || !cli_ctx_is_uptodate(ctx)) {
+                CDEBUG(D_SEC, "ctx %p(%u->%s) not uptodate, "
+                       "don't send destroy rpc\n", ctx,
+                       ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
                 RETURN(0);
         }
 
         might_sleep();
 
-        CWARN("client destroy ctx %p(%u->%s)\n",
-              ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+        CDEBUG(D_SEC, "%s ctx %p(%u->%s)\n",
+               sec_is_reverse(ctx->cc_sec) ?
+               "server finishing reverse" : "client finishing forward",
+               ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
 
         /* context's refcount could be 0, steal one */
         atomic_inc(&ctx->cc_refcount);
@@ -386,12 +371,12 @@ int gss_do_ctx_fini_rpc(struct gss_cli_ctx *gctx)
                 pud->pud_ngroups = 0;
         }
 
-        req->rq_replen = lustre_msg_size_v2(1, &buflens);
-
-        rc = ptlrpc_queue_wait(req);
+        req->rq_phase = RQ_PHASE_RPC;
+        rc = ptl_send_rpc(req, 1);
         if (rc) {
-                CWARN("ctx %p(%u): rpc error %d, destroy locally\n",
-                      ctx, ctx->cc_vcred.vc_uid, rc);
+                CWARN("ctx %p(%u->%s): rpc error %d, destroy locally\n",
+                      ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
+                      rc);
         }
 
         ptlrpc_req_finished(req);
diff --git a/lustre/ptlrpc/gss/gss_internal.h b/lustre/ptlrpc/gss/gss_internal.h
index 0202d94a3e..67083c124f 100644
--- a/lustre/ptlrpc/gss/gss_internal.h
+++ b/lustre/ptlrpc/gss/gss_internal.h
@@ -82,27 +82,6 @@ unsigned long gss_round_ctx_expiry(unsigned long expiry,
         return expiry;
 }
 
-/* we try to force reconnect import 20m eariler than real expiry.
- * kerberos 5 usually allow 5m time skew, but which is adjustable,
- * so if we set krb5 to allow > 20m time skew, we have chance that
- * server's reverse ctx expired but client still hasn't start to
- * refresh it -- it's BAD. So here we actually put a limit on the
- * enviroment of krb5 (or other authentication mechanism)
- */
-#define GSS_MAX_TIME_SKEW       (20 * 60)
-
-static inline
-unsigned long gss_round_imp_reconnect(unsigned long expiry)
-{
-        unsigned long now = get_seconds();
-        unsigned long nice = GSS_MAX_TIME_SKEW + __TIMEOUT_DELTA;
-
-        while (nice && (now + nice >= expiry))
-                nice = nice / 2;
-
-        return (expiry - nice);
-}
-
 /*
  * Max encryption element in block cipher algorithms.
  */
@@ -124,15 +103,10 @@ enum ptlrpc_gss_proc {
         PTLRPC_GSS_PROC_ERR             = 4,
 };
 
-enum ptlrpc_gss_svc {
-        PTLRPC_GSS_SVC_NONE             = 1,
-        PTLRPC_GSS_SVC_INTEGRITY        = 2,
-        PTLRPC_GSS_SVC_PRIVACY          = 3,
-};
-
 enum ptlrpc_gss_tgt {
         LUSTRE_GSS_TGT_MDS              = 0,
         LUSTRE_GSS_TGT_OSS              = 1,
+        LUSTRE_GSS_TGT_MGS              = 2,
 };
 
 static inline
@@ -238,13 +212,26 @@ struct gss_svc_ctx {
 };
 
 struct gss_svc_reqctx {
-        struct ptlrpc_svc_ctx   src_base;
-        struct gss_wire_ctx     src_wirectx;
-        struct gss_svc_ctx     *src_ctx;
-        unsigned int            src_init:1,
-                                src_init_continue:1,
-                                src_err_notify:1;
-        int                     src_reserve_len;
+        struct ptlrpc_svc_ctx           src_base;
+        /*
+         * context
+         */
+        struct gss_wire_ctx             src_wirectx;
+        struct gss_svc_ctx             *src_ctx;
+        /*
+         * record place of bulk_sec_desc in request/reply buffer
+         */
+        struct ptlrpc_bulk_sec_desc    *src_reqbsd;
+        int                             src_reqbsd_size;
+        struct ptlrpc_bulk_sec_desc    *src_repbsd;
+        int                             src_repbsd_size;
+        /*
+         * flags
+         */
+        unsigned int                    src_init:1,
+                                        src_init_continue:1,
+                                        src_err_notify:1;
+        int                             src_reserve_len;
 };
 
 struct gss_cli_ctx {
@@ -405,6 +392,8 @@ int gss_cli_ctx_init_common(struct ptlrpc_sec *sec,
 int gss_cli_ctx_fini_common(struct ptlrpc_sec *sec,
                             struct ptlrpc_cli_ctx *ctx);
 
+void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize);
+
 /* gss_keyring.c */
 extern struct ptlrpc_sec_policy gss_policy_keyring;
 int  __init gss_init_keyring(void);
diff --git a/lustre/ptlrpc/gss/gss_keyring.c b/lustre/ptlrpc/gss/gss_keyring.c
index 305d4c5b52..5c6722c01a 100644
--- a/lustre/ptlrpc/gss/gss_keyring.c
+++ b/lustre/ptlrpc/gss/gss_keyring.c
@@ -144,7 +144,7 @@ void ctx_start_timer_kr(struct ptlrpc_cli_ctx *ctx, long timeout)
 
         LASSERT(timer);
 
-        CWARN("ctx %p: start timer %lds\n", ctx, timeout);
+        CDEBUG(D_SEC, "ctx %p: start timer %lds\n", ctx, timeout);
         timeout = timeout * HZ + cfs_time_current();
 
         init_timer(timer);
@@ -155,16 +155,20 @@ void ctx_start_timer_kr(struct ptlrpc_cli_ctx *ctx, long timeout)
         add_timer(timer);
 }
 
+/*
+ * caller should make sure no race with other threads
+ */
 static
 void ctx_clear_timer_kr(struct ptlrpc_cli_ctx *ctx)
 {
         struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
         struct timer_list          *timer = gctx_kr->gck_timer;
 
-        CWARN("ctx %p, key %p\n", ctx, gctx_kr->gck_key);
         if (timer == NULL)
                 return;
 
+        CDEBUG(D_SEC, "ctx %p, key %p\n", ctx, gctx_kr->gck_key);
+
         gctx_kr->gck_timer = NULL;
 
         del_singleshot_timer_sync(timer);
@@ -211,7 +215,7 @@ static void ctx_destroy_kr(struct ptlrpc_cli_ctx *ctx)
         struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
         int                         rc;
 
-        CWARN("destroying ctx %p\n", ctx);
+        CDEBUG(D_SEC, "destroying ctx %p\n", ctx);
 
         /* at this time the association with key has been broken. */
         LASSERT(sec);
@@ -279,7 +283,7 @@ void ctx_enlist_kr(struct ptlrpc_cli_ctx *ctx, int is_root, int locked)
 
         atomic_inc(&ctx->cc_refcount);
         set_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
-        hlist_add_head(&ctx->cc_hash, &gsec_kr->gsk_clist);
+        hlist_add_head(&ctx->cc_cache, &gsec_kr->gsk_clist);
         if (is_root)
                 gsec_kr->gsk_root_ctx = ctx;
 
@@ -305,8 +309,6 @@ int ctx_unlist_kr(struct ptlrpc_cli_ctx *ctx, int locked)
         if (test_and_clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0)
                 return 0;
 
-        CWARN("ctx %p(%d) unlist\n", ctx, atomic_read(&ctx->cc_refcount));
-
         /*
          * drop ref inside spin lock to prevent race with other operations
          */
@@ -314,7 +316,7 @@ int ctx_unlist_kr(struct ptlrpc_cli_ctx *ctx, int locked)
 
         if (gsec_kr->gsk_root_ctx == ctx)
                 gsec_kr->gsk_root_ctx = NULL;
-        hlist_del_init(&ctx->cc_hash);
+        hlist_del_init(&ctx->cc_cache);
         atomic_dec(&ctx->cc_refcount);
 
         spin_unlock_if(&sec->ps_lock, !locked);
@@ -419,17 +421,23 @@ static void kill_key_locked(struct key *key)
 }
 
 /*
- * since this called, nobody else could touch the ctx in @freelist
+ * caller should hold one ref on contexts in freelist.
  */
 static void dispose_ctx_list_kr(struct hlist_head *freelist)
 {
         struct hlist_node      *pos, *next;
         struct ptlrpc_cli_ctx  *ctx;
 
-        hlist_for_each_entry_safe(ctx, pos, next, freelist, cc_hash) {
-                hlist_del_init(&ctx->cc_hash);
+        hlist_for_each_entry_safe(ctx, pos, next, freelist, cc_cache) {
+                hlist_del_init(&ctx->cc_cache);
+
+                /*
+                 * we need to wakeup waiting reqs here. the context might
+                 * be forced released before upcall finished, then the
+                 * late-arrived downcall can't find the ctx even.
+                 */
+                sptlrpc_cli_ctx_wakeup(ctx);
 
-                atomic_inc(&ctx->cc_refcount);
                 unbind_ctx_kr(ctx);
                 ctx_put_kr(ctx);
         }
@@ -448,6 +456,25 @@ struct ptlrpc_cli_ctx * sec_lookup_root_ctx_kr(struct ptlrpc_sec *sec)
         spin_lock(&sec->ps_lock);
 
         ctx = gsec_kr->gsk_root_ctx;
+
+        if (ctx == NULL && unlikely(sec_is_reverse(sec))) {
+                struct hlist_node      *node;
+                struct ptlrpc_cli_ctx  *tmp;
+                /*
+                 * reverse ctx, search root ctx in list, choose the one
+                 * with shortest expire time, which is most possibly have
+                 * an established peer ctx at client side.
+                 */
+                hlist_for_each_entry(tmp, node, &gsec_kr->gsk_clist, cc_cache) {
+                        if (ctx == NULL || ctx->cc_expire == 0 ||
+                            ctx->cc_expire > tmp->cc_expire) {
+                                ctx = tmp;
+                                /* promote to be root_ctx */
+                                gsec_kr->gsk_root_ctx = ctx;
+                        }
+                }
+        }
+
         if (ctx) {
                 LASSERT(atomic_read(&ctx->cc_refcount) > 0);
                 LASSERT(!hlist_empty(&gsec_kr->gsk_clist));
@@ -459,40 +486,44 @@ struct ptlrpc_cli_ctx * sec_lookup_root_ctx_kr(struct ptlrpc_sec *sec)
         return ctx;
 }
 
-static void sec_replace_root_ctx_kr(struct ptlrpc_sec *sec,
-                                    struct ptlrpc_cli_ctx *new_ctx,
-                                    struct key *key)
+#define RVS_CTX_EXPIRE_NICE    (10)
+
+static
+void rvs_sec_install_root_ctx_kr(struct ptlrpc_sec *sec,
+                                 struct ptlrpc_cli_ctx *new_ctx,
+                                 struct key *key)
 {
         struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
-        struct ptlrpc_cli_ctx  *root_ctx;
-        struct hlist_head       freelist = HLIST_HEAD_INIT;
+        struct hlist_node      *hnode;
+        struct ptlrpc_cli_ctx  *ctx;
+        cfs_time_t              now;
         ENTRY;
 
-        spin_lock(&sec->ps_lock);
+        LASSERT(sec_is_reverse(sec));
 
-        if (gsec_kr->gsk_root_ctx) {
-                root_ctx = gsec_kr->gsk_root_ctx;
+        spin_lock(&sec->ps_lock);
 
-                set_bit(PTLRPC_CTX_DEAD_BIT, &root_ctx->cc_flags);
+        now = cfs_time_current_sec();
 
-                if (ctx_unlist_kr(root_ctx, 1))
-                        hlist_add_head(&root_ctx->cc_hash, &freelist);
+        /* set all existing ctxs short expiry */
+        hlist_for_each_entry(ctx, hnode, &gsec_kr->gsk_clist, cc_cache) {
+                if (ctx->cc_expire > now + RVS_CTX_EXPIRE_NICE) {
+                        ctx->cc_early_expire = 1;
+                        ctx->cc_expire = now + RVS_CTX_EXPIRE_NICE;
+                }
         }
 
-        /*
-         * at this time, we can't guarantee the gsk_root_ctx is NULL, because
-         * another thread might clear the HASHED flag of root ctx earlier,
-         * and waiting for spinlock which is held by us. But anyway we just
-         * install the new root ctx.
+        /* if there's root_ctx there, instead obsolete the current
+         * immediately, we leave it continue operating for a little while.
+         * hopefully when the first backward rpc with newest ctx send out,
+         * the client side already have the peer ctx well established.
          */
-        ctx_enlist_kr(new_ctx, 1, 1);
+        ctx_enlist_kr(new_ctx, gsec_kr->gsk_root_ctx ? 0 : 1, 1);
 
         if (key)
                 bind_key_ctx(key, new_ctx);
 
         spin_unlock(&sec->ps_lock);
-
-        dispose_ctx_list_kr(&freelist);
 }
 
 static void construct_key_desc(void *buf, int bufsize,
@@ -522,7 +553,7 @@ struct ptlrpc_sec * gss_sec_create_kr(struct obd_import *imp,
                 RETURN(NULL);
 
         gsec_kr->gsk_id = atomic_inc_return(&gss_sec_id_kr);
-        INIT_HLIST_HEAD(&gsec_kr->gsk_clist);
+        CFS_INIT_HLIST_HEAD(&gsec_kr->gsk_clist);
         gsec_kr->gsk_root_ctx = NULL;
         mutex_init(&gsec_kr->gsk_root_uc_lock);
 #ifdef HAVE_KEYRING_UPCALL_SERIALIZED
@@ -553,7 +584,7 @@ void gss_sec_destroy_kr(struct ptlrpc_sec *sec)
         struct gss_sec          *gsec = sec2gsec(sec);
         struct gss_sec_keyring  *gsec_kr = sec2gsec_keyring(sec);
 
-        CWARN("destroy %s@%p\n", sec->ps_policy->sp_name, sec);
+        CDEBUG(D_SEC, "destroy %s@%p\n", sec->ps_policy->sp_name, sec);
 
         LASSERT(hlist_empty(&gsec_kr->gsk_clist));
         LASSERT(gsec_kr->gsk_root_ctx == NULL);
@@ -648,7 +679,7 @@ struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_kr(struct ptlrpc_sec *sec,
                  * Only lookup directly for REVERSE sec, which should
                  * always succeed.
                  */
-                if (ctx || (sec->ps_flags & PTLRPC_SEC_FL_REVERSE))
+                if (ctx || sec_is_reverse(sec))
                         RETURN(ctx);
         }
 
@@ -727,8 +758,8 @@ struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_kr(struct ptlrpc_sec *sec,
 
                         ctx_start_timer_kr(ctx, KEYRING_UPCALL_TIMEOUT);
 
-                        CWARN("installed key %p <-> ctx %p (sec %p)\n",
-                              key, ctx, sec);
+                        CDEBUG(D_SEC, "installed key %p <-> ctx %p (sec %p)\n",
+                               key, ctx, sec);
                 } else {
                         /*
                          * we'd prefer to call key_revoke(), but we more like
@@ -757,8 +788,14 @@ void gss_sec_release_ctx_kr(struct ptlrpc_sec *sec,
                             struct ptlrpc_cli_ctx *ctx,
                             int sync)
 {
-        CWARN("ctx %p\n", ctx);
-        ctx_destroy_kr(ctx);
+        LASSERT(atomic_read(&ctx->cc_refcount) == 0);
+
+        if (sync)
+                ctx_destroy_kr(ctx);
+        else {
+                atomic_inc(&ctx->cc_refcount);
+                sptlrpc_gc_add_ctx(ctx);
+        }
 }
 
 /*
@@ -777,7 +814,7 @@ void flush_user_ctx_cache_kr(struct ptlrpc_sec *sec,
         char                     desc[24];
 
         /* nothing to do for reverse or rootonly sec */
-        if (sec->ps_flags & (PTLRPC_SEC_FL_REVERSE | PTLRPC_SEC_FL_ROOTONLY))
+        if (sec_is_reverse(sec) || sec_is_rootonly(sec))
                 return;
 
         construct_key_desc(desc, sizeof(desc), sec, uid);
@@ -794,7 +831,6 @@ void flush_user_ctx_cache_kr(struct ptlrpc_sec *sec,
 
                 down_write(&key->sem);
 
-                CWARN("invalidating key %p - ctx %p\n", key, key->payload.data);
                 kill_key_locked(key);
 
                 /* kill_key_locked() should usually revoke the key, but we
@@ -818,7 +854,7 @@ void flush_spec_ctx_cache_kr(struct ptlrpc_sec *sec,
                              int grace, int force)
 {
         struct gss_sec_keyring *gsec_kr;
-        struct hlist_head       freelist = HLIST_HEAD_INIT;
+        struct hlist_head       freelist = CFS_HLIST_HEAD_INIT;
         struct hlist_node      *pos, *next;
         struct ptlrpc_cli_ctx  *ctx;
         ENTRY;
@@ -827,7 +863,7 @@ void flush_spec_ctx_cache_kr(struct ptlrpc_sec *sec,
 
         spin_lock(&sec->ps_lock);
         hlist_for_each_entry_safe(ctx, pos, next,
-                                  &gsec_kr->gsk_clist, cc_hash) {
+                                  &gsec_kr->gsk_clist, cc_cache) {
                 LASSERT(atomic_read(&ctx->cc_refcount) > 0);
 
                 if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
@@ -849,11 +885,14 @@ void flush_spec_ctx_cache_kr(struct ptlrpc_sec *sec,
                 if (!grace)
                         clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
 
-                if (ctx_unlist_kr(ctx, 1)) {
-                        hlist_add_head(&ctx->cc_hash, &freelist);
-                        CWARN("unlisted ctx %p\n", ctx);
-                } else
-                        CWARN("ctx %p: unlist return 0, let it go\n", ctx);
+                atomic_inc(&ctx->cc_refcount);
+
+                if (ctx_unlist_kr(ctx, 1))
+                        hlist_add_head(&ctx->cc_cache, &freelist);
+                else {
+                        LASSERT(atomic_read(&ctx->cc_refcount) >= 2);
+                        atomic_dec(&ctx->cc_refcount);
+                }
 
         }
         spin_unlock(&sec->ps_lock);
@@ -869,9 +908,9 @@ int gss_sec_flush_ctx_cache_kr(struct ptlrpc_sec *sec,
 {
         ENTRY;
 
-        CWARN("sec %p(%d, busy %d), uid %d, grace %d, force %d\n",
-              sec, atomic_read(&sec->ps_refcount), atomic_read(&sec->ps_busy),
-              uid, grace, force);
+        CDEBUG(D_SEC, "sec %p(%d, busy %d), uid %d, grace %d, force %d\n",
+               sec, atomic_read(&sec->ps_refcount), atomic_read(&sec->ps_busy),
+               uid, grace, force);
 
         if (uid != -1 && uid != 0)
                 flush_user_ctx_cache_kr(sec, uid, grace, force);
@@ -885,7 +924,7 @@ static
 void gss_sec_gc_ctx_kr(struct ptlrpc_sec *sec)
 {
         struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
-        struct hlist_head       freelist = HLIST_HEAD_INIT;
+        struct hlist_head       freelist = CFS_HLIST_HEAD_INIT;
         struct hlist_node      *pos, *next;
         struct ptlrpc_cli_ctx  *ctx;
         ENTRY;
@@ -894,12 +933,17 @@ void gss_sec_gc_ctx_kr(struct ptlrpc_sec *sec)
 
         spin_lock(&sec->ps_lock);
         hlist_for_each_entry_safe(ctx, pos, next,
-                                  &gsec_kr->gsk_clist, cc_hash) {
+                                  &gsec_kr->gsk_clist, cc_cache) {
                 LASSERT(atomic_read(&ctx->cc_refcount) > 0);
 
+                atomic_inc(&ctx->cc_refcount);
+
                 if (cli_ctx_check_death(ctx) && ctx_unlist_kr(ctx, 1)) {
-                        hlist_add_head(&ctx->cc_hash, &freelist);
+                        hlist_add_head(&ctx->cc_cache, &freelist);
                         CWARN("unhashed ctx %p\n", ctx);
+                } else {
+                        LASSERT(atomic_read(&ctx->cc_refcount) >= 2);
+                        atomic_dec(&ctx->cc_refcount);
                 }
         }
         spin_unlock(&sec->ps_lock);
@@ -924,19 +968,27 @@ int gss_sec_display_kr(struct ptlrpc_sec *sec, char *buf, int bufsize)
 
         spin_lock(&sec->ps_lock);
         hlist_for_each_entry_safe(ctx, pos, next,
-                                  &gsec_kr->gsk_clist, cc_hash) {
-                struct key *key;
-                int         len;
+                                  &gsec_kr->gsk_clist, cc_cache) {
+                struct gss_cli_ctx     *gctx;
+                struct key             *key;
+                char                    flags_str[40];
+                int                     len;
 
+                gctx = ctx2gctx(ctx);
                 key = ctx2gctx_keyring(ctx)->gck_key;
 
-                len = snprintf(buf, bufsize, "%p(%d): expire %ld(%ld), "
-                               "uid %u, flags 0x%lx, key %08x(%d)\n",
+                gss_cli_ctx_flags2str(ctx->cc_flags,
+                                      flags_str, sizeof(flags_str));
+
+                len = snprintf(buf, bufsize, "%p(%d): uid %u, exp %ld(%ld)s, "
+                               "fl %s, seq %d, win %u, key %08x(%d), ",
                                ctx, atomic_read(&ctx->cc_refcount),
+                               ctx->cc_vcred.vc_uid,
                                ctx->cc_expire,
                                ctx->cc_expire - cfs_time_current_sec(),
-                               ctx->cc_vcred.vc_uid,
-                               ctx->cc_flags,
+                               flags_str,
+                               atomic_read(&gctx->gc_seq),
+                               gctx->gc_win,
                                key ? key->serial : 0,
                                key ? atomic_read(&key->usage) : 0);
 
@@ -944,7 +996,19 @@ int gss_sec_display_kr(struct ptlrpc_sec *sec, char *buf, int bufsize)
                 buf += len;
                 bufsize -= len;
 
-                if (bufsize < len)
+                if (bufsize <= 0)
+                        break;
+
+                if (gctx->gc_mechctx)
+                        len = lgss_display(gctx->gc_mechctx, buf, bufsize);
+                else
+                        len = snprintf(buf, bufsize, "mech N/A\n");
+
+                written += len;
+                buf += len;
+                bufsize -= len;
+
+                if (bufsize <= 0)
                         break;
         }
         spin_unlock(&sec->ps_lock);
@@ -974,7 +1038,7 @@ int gss_cli_ctx_validate_kr(struct ptlrpc_cli_ctx *ctx)
                 return 1;
         }
 
-        if (cli_ctx_is_uptodate(ctx))
+        if (cli_ctx_is_ready(ctx))
                 return 0;
         return 1;
 }
@@ -1025,7 +1089,7 @@ int sec_install_rctx_kr(struct ptlrpc_sec *sec,
                 return rc;
         }
 
-        sec_replace_root_ctx_kr(sec, cli_ctx, NULL);
+        rvs_sec_install_root_ctx_kr(sec, cli_ctx, NULL);
 
         ctx_put_kr(cli_ctx);
 
@@ -1079,7 +1143,7 @@ int sec_install_rctx_kr(struct ptlrpc_sec *sec,
                 goto err_put;
         }
 
-        sec_replace_root_ctx_kr(sec, cli_ctx, key);
+        rvs_sec_install_root_ctx_kr(sec, cli_ctx, key);
 
         ctx_put_kr(cli_ctx);
         up_write(&key->sem);
@@ -1141,7 +1205,7 @@ int gss_kt_instantiate(struct key *key, const void *data, size_t datalen)
 
         /* XXX */
         key->perm |= KEY_POS_ALL | KEY_USR_ALL;
-        CWARN("key %p instantiated, ctx %p\n", key, key->payload.data);
+        CDEBUG(D_SEC, "key %p instantiated, ctx %p\n", key, key->payload.data);
         RETURN(0);
 }
 
@@ -1203,7 +1267,6 @@ int gss_kt_update(struct key *key, const void *data, size_t datalen)
                 goto out;
         }
 
-        CWARN("secwin is %d\n", gctx->gc_win);
         if (gctx->gc_win == 0) {
                 __u32   nego_rpc_err, nego_gss_err;
 
@@ -1254,15 +1317,16 @@ out:
         if (rc == 0) {
                 gss_cli_ctx_uptodate(gctx);
         } else {
+                /*
+                 * this will also revoke the key. has to be done before
+                 * wakeup waiters otherwise they can find the stale key
+                 */
+                kill_key_locked(key);
+
                 cli_ctx_expire(ctx);
 
                 if (rc != -ERESTART)
                         set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
-
-                /* this will also revoke the key. has to be done before
-                 * wakeup waiters otherwise they can find the stale key
-                 */
-                kill_key_locked(key);
         }
 
         sptlrpc_cli_ctx_wakeup(ctx);
@@ -1283,7 +1347,7 @@ void gss_kt_destroy(struct key *key)
 {
         ENTRY;
         LASSERT(key->payload.data == NULL);
-        CWARN("destroy key %p\n", key);
+        CDEBUG(D_SEC, "destroy key %p\n", key);
         EXIT;
 }
 
@@ -1316,7 +1380,6 @@ static struct ptlrpc_ctx_ops gss_keyring_ctxops = {
         .refresh                = gss_cli_ctx_refresh_kr,
         .validate               = gss_cli_ctx_validate_kr,
         .die                    = gss_cli_ctx_die_kr,
-        .display                = gss_cli_ctx_display,
         .sign                   = gss_cli_ctx_sign,
         .verify                 = gss_cli_ctx_verify,
         .seal                   = gss_cli_ctx_seal,
diff --git a/lustre/ptlrpc/gss/gss_krb5_mech.c b/lustre/ptlrpc/gss/gss_krb5_mech.c
index 1b8d7a4f82..2e03843a1f 100644
--- a/lustre/ptlrpc/gss/gss_krb5_mech.c
+++ b/lustre/ptlrpc/gss/gss_krb5_mech.c
@@ -481,12 +481,8 @@ __u32 gss_copy_reverse_context_kerberos(struct gss_ctx *gctx,
         knew->kc_cfx = kctx->kc_cfx;
         knew->kc_seed_init = kctx->kc_seed_init;
         knew->kc_have_acceptor_subkey = kctx->kc_have_acceptor_subkey;
-#if 0
         knew->kc_endtime = kctx->kc_endtime;
-#else
-        /* FIXME reverse context don't expire for now */
-        knew->kc_endtime = INT_MAX;
-#endif
+
         memcpy(knew->kc_seed, kctx->kc_seed, sizeof(kctx->kc_seed));
         knew->kc_seq_send = kctx->kc_seq_recv;
         knew->kc_seq_recv = kctx->kc_seq_send;
@@ -1194,10 +1190,8 @@ int gss_display_kerberos(struct gss_ctx        *ctx,
         struct krb5_ctx    *kctx = ctx->internal_ctx_id;
         int                 written;
 
-        written = snprintf(buf, bufsize,
-                        "  mech:        krb5\n"
-                        "  enctype:     %s\n",
-                        enctype2str(kctx->kc_enctype));
+        written = snprintf(buf, bufsize, "mech: krb5 (%s)\n",
+                           enctype2str(kctx->kc_enctype));
         return written;
 }
 
@@ -1216,15 +1210,21 @@ static struct gss_api_ops gss_kerberos_ops = {
 
 static struct subflavor_desc gss_kerberos_sfs[] = {
         {
-                .sf_subflavor   = SPTLRPC_SUBFLVR_KRB5,
+                .sf_subflavor   = SPTLRPC_SUBFLVR_KRB5N,
                 .sf_qop         = 0,
-                .sf_service     = SPTLRPC_SVC_NONE,
-                .sf_name        = "krb5"
+                .sf_service     = SPTLRPC_SVC_NULL,
+                .sf_name        = "krb5n"
         },
         {
-                .sf_subflavor   = SPTLRPC_SUBFLVR_KRB5I,
+                .sf_subflavor   = SPTLRPC_SUBFLVR_KRB5A,
                 .sf_qop         = 0,
                 .sf_service     = SPTLRPC_SVC_AUTH,
+                .sf_name        = "krb5a"
+        },
+        {
+                .sf_subflavor   = SPTLRPC_SUBFLVR_KRB5I,
+                .sf_qop         = 0,
+                .sf_service     = SPTLRPC_SVC_INTG,
                 .sf_name        = "krb5i"
         },
         {
@@ -1244,7 +1244,7 @@ static struct gss_api_mech gss_kerberos_mech = {
         .gm_oid         = (rawobj_t)
                                 {9, "\052\206\110\206\367\022\001\002\002"},
         .gm_ops         = &gss_kerberos_ops,
-        .gm_sf_num      = 3,
+        .gm_sf_num      = 4,
         .gm_sfs         = gss_kerberos_sfs,
 };
 
diff --git a/lustre/ptlrpc/gss/gss_mech_switch.c b/lustre/ptlrpc/gss/gss_mech_switch.c
index 53e11e6fed..6e6386f03e 100644
--- a/lustre/ptlrpc/gss/gss_mech_switch.c
+++ b/lustre/ptlrpc/gss/gss_mech_switch.c
@@ -67,7 +67,7 @@
 #include "gss_internal.h"
 #include "gss_api.h"
 
-static LIST_HEAD(registered_mechs);
+static CFS_LIST_HEAD(registered_mechs);
 static spinlock_t registered_mechs_lock = SPIN_LOCK_UNLOCKED;
 
 int lgss_mech_register(struct gss_api_mech *gm)
diff --git a/lustre/ptlrpc/gss/gss_pipefs.c b/lustre/ptlrpc/gss/gss_pipefs.c
index 9cc2a07881..ecbe43f15d 100644
--- a/lustre/ptlrpc/gss/gss_pipefs.c
+++ b/lustre/ptlrpc/gss/gss_pipefs.c
@@ -135,7 +135,7 @@ void ctx_enhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *hash)
 {
         set_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
         atomic_inc(&ctx->cc_refcount);
-        hlist_add_head(&ctx->cc_hash, hash);
+        hlist_add_head(&ctx->cc_cache, hash);
 }
 
 /*
@@ -147,15 +147,15 @@ void ctx_unhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *freelist)
         LASSERT_SPIN_LOCKED(&ctx->cc_sec->ps_lock);
         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
-        LASSERT(!hlist_unhashed(&ctx->cc_hash));
+        LASSERT(!hlist_unhashed(&ctx->cc_cache));
 
         clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
 
         if (atomic_dec_and_test(&ctx->cc_refcount)) {
-                __hlist_del(&ctx->cc_hash);
-                hlist_add_head(&ctx->cc_hash, freelist);
+                __hlist_del(&ctx->cc_cache);
+                hlist_add_head(&ctx->cc_cache, freelist);
         } else
-                hlist_del_init(&ctx->cc_hash);
+                hlist_del_init(&ctx->cc_cache);
 }
 
 /*
@@ -200,12 +200,12 @@ void ctx_list_destroy_pf(struct hlist_head *head)
         struct ptlrpc_cli_ctx *ctx;
 
         while (!hlist_empty(head)) {
-                ctx = hlist_entry(head->first, struct ptlrpc_cli_ctx, cc_hash);
+                ctx = hlist_entry(head->first, struct ptlrpc_cli_ctx, cc_cache);
 
                 LASSERT(atomic_read(&ctx->cc_refcount) == 0);
                 LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
 
-                hlist_del_init(&ctx->cc_hash);
+                hlist_del_init(&ctx->cc_cache);
                 ctx_destroy_pf(ctx->cc_sec, ctx);
         }
 }
@@ -219,7 +219,7 @@ int gss_cli_ctx_validate_pf(struct ptlrpc_cli_ctx *ctx)
 {
         if (ctx_check_death_pf(ctx, NULL))
                 return 1;
-        if (cli_ctx_is_uptodate(ctx))
+        if (cli_ctx_is_ready(ctx))
                 return 0;
         return 1;
 }
@@ -235,10 +235,10 @@ void gss_cli_ctx_die_pf(struct ptlrpc_cli_ctx *ctx, int grace)
         spin_lock(&ctx->cc_sec->ps_lock);
 
         if (test_and_clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags)) {
-                LASSERT(!hlist_unhashed(&ctx->cc_hash));
+                LASSERT(!hlist_unhashed(&ctx->cc_cache));
                 LASSERT(atomic_read(&ctx->cc_refcount) > 1);
 
-                hlist_del_init(&ctx->cc_hash);
+                hlist_del_init(&ctx->cc_cache);
                 if (atomic_dec_and_test(&ctx->cc_refcount))
                         LBUG();
         }
@@ -263,7 +263,7 @@ void gss_sec_ctx_replace_pf(struct gss_sec *gsec,
         struct gss_sec_pipefs *gsec_pf;
         struct ptlrpc_cli_ctx *ctx;
         struct hlist_node *pos, *next;
-        HLIST_HEAD(freelist);
+        CFS_HLIST_HEAD(freelist);
         unsigned int hash;
         ENTRY;
 
@@ -276,7 +276,7 @@ void gss_sec_ctx_replace_pf(struct gss_sec *gsec,
         spin_lock(&gsec->gs_base.ps_lock);
 
         hlist_for_each_entry_safe(ctx, pos, next,
-                                  &gsec_pf->gsp_chash[hash], cc_hash) {
+                                  &gsec_pf->gsp_chash[hash], cc_cache) {
                 if (!ctx_match_pf(ctx, &new->cc_vcred))
                         continue;
 
@@ -336,7 +336,7 @@ void gss_ctx_cache_gc_pf(struct gss_sec_pipefs *gsec_pf,
 
         for (i = 0; i < gsec_pf->gsp_chash_size; i++) {
                 hlist_for_each_entry_safe(ctx, pos, next,
-                                          &gsec_pf->gsp_chash[i], cc_hash)
+                                          &gsec_pf->gsp_chash[i], cc_cache)
                         ctx_check_death_locked_pf(ctx, freelist);
         }
 
@@ -370,7 +370,7 @@ struct ptlrpc_sec* gss_sec_create_pf(struct obd_import *imp,
 
         gsec_pf->gsp_chash_size = hash_size;
         for (i = 0; i < hash_size; i++)
-                INIT_HLIST_HEAD(&gsec_pf->gsp_chash[i]);
+                CFS_INIT_HLIST_HEAD(&gsec_pf->gsp_chash[i]);
 
         if (gss_sec_create_common(&gsec_pf->gsp_base, &gss_policy_pipefs,
                                   imp, ctx, flavor, flags))
@@ -425,7 +425,7 @@ struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_pf(struct ptlrpc_sec *sec,
         struct ptlrpc_cli_ctx  *ctx = NULL, *new = NULL;
         struct hlist_head      *hash_head;
         struct hlist_node      *pos, *next;
-        HLIST_HEAD(freelist);
+        CFS_HLIST_HEAD(freelist);
         unsigned int            hash, gc = 0, found = 0;
         ENTRY;
 
@@ -449,7 +449,7 @@ retry:
                 gc = 1;
         }
 
-        hlist_for_each_entry_safe(ctx, pos, next, hash_head, cc_hash) {
+        hlist_for_each_entry_safe(ctx, pos, next, hash_head, cc_cache) {
                 if (gc == 0 &&
                     ctx_check_death_locked_pf(ctx,
                                               remove_dead ? &freelist : NULL))
@@ -464,18 +464,18 @@ retry:
         if (found) {
                 if (new && new != ctx) {
                         /* lost the race, just free it */
-                        hlist_add_head(&new->cc_hash, &freelist);
+                        hlist_add_head(&new->cc_cache, &freelist);
                         new = NULL;
                 }
 
                 /* hot node, move to head */
-                if (hash_head->first != &ctx->cc_hash) {
-                        __hlist_del(&ctx->cc_hash);
-                        hlist_add_head(&ctx->cc_hash, hash_head);
+                if (hash_head->first != &ctx->cc_cache) {
+                        __hlist_del(&ctx->cc_cache);
+                        hlist_add_head(&ctx->cc_cache, hash_head);
                 }
         } else {
                 /* don't allocate for reverse sec */
-                if (sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
+                if (sec_is_reverse(sec)) {
                         spin_unlock(&sec->ps_lock);
                         RETURN(NULL);
                 }
@@ -516,7 +516,7 @@ void gss_sec_release_ctx_pf(struct ptlrpc_sec *sec,
                             int sync)
 {
         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
-        LASSERT(hlist_unhashed(&ctx->cc_hash));
+        LASSERT(hlist_unhashed(&ctx->cc_cache));
 
         /* if required async, we must clear the UPTODATE bit to prevent extra
          * rpcs during destroy procedure.
@@ -547,7 +547,7 @@ int gss_sec_flush_ctx_cache_pf(struct ptlrpc_sec *sec,
         struct gss_sec_pipefs   *gsec_pf;
         struct ptlrpc_cli_ctx   *ctx;
         struct hlist_node *pos, *next;
-        HLIST_HEAD(freelist);
+        CFS_HLIST_HEAD(freelist);
         int i, busy = 0;
         ENTRY;
 
@@ -559,7 +559,7 @@ int gss_sec_flush_ctx_cache_pf(struct ptlrpc_sec *sec,
         spin_lock(&sec->ps_lock);
         for (i = 0; i < gsec_pf->gsp_chash_size; i++) {
                 hlist_for_each_entry_safe(ctx, pos, next,
-                                          &gsec_pf->gsp_chash[i], cc_hash) {
+                                          &gsec_pf->gsp_chash[i], cc_cache) {
                         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
 
                         if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
@@ -1064,7 +1064,7 @@ int gss_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx)
                 RETURN(-ENOMEM);
 
         /* initialize pipefs base msg */
-        INIT_LIST_HEAD(&gmsg->gum_base.list);
+        CFS_INIT_LIST_HEAD(&gmsg->gum_base.list);
         gmsg->gum_base.data = &gmsg->gum_data;
         gmsg->gum_base.len = sizeof(gmsg->gum_data);
         gmsg->gum_base.copied = 0;
@@ -1141,7 +1141,6 @@ static struct ptlrpc_ctx_ops gss_pipefs_ctxops = {
         .refresh                = gss_cli_ctx_refresh_pf,
         .validate               = gss_cli_ctx_validate_pf,
         .die                    = gss_cli_ctx_die_pf,
-        .display                = gss_cli_ctx_display,
         .sign                   = gss_cli_ctx_sign,
         .verify                 = gss_cli_ctx_verify,
         .seal                   = gss_cli_ctx_seal,
@@ -1212,7 +1211,7 @@ int __init gss_init_pipefs_upcall(void)
         }
 
         de_pipes[MECH_KRB5] = de;
-        INIT_LIST_HEAD(&upcall_lists[MECH_KRB5]);
+        CFS_INIT_LIST_HEAD(&upcall_lists[MECH_KRB5]);
         upcall_locks[MECH_KRB5] = SPIN_LOCK_UNLOCKED;
 
         return 0;
diff --git a/lustre/ptlrpc/gss/gss_rawobj.c b/lustre/ptlrpc/gss/gss_rawobj.c
index 99facc7ab5..75343c9692 100644
--- a/lustre/ptlrpc/gss/gss_rawobj.c
+++ b/lustre/ptlrpc/gss/gss_rawobj.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2004 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
diff --git a/lustre/ptlrpc/gss/gss_svc_upcall.c b/lustre/ptlrpc/gss/gss_svc_upcall.c
index 277fc235c9..ca32e4e798 100644
--- a/lustre/ptlrpc/gss/gss_svc_upcall.c
+++ b/lustre/ptlrpc/gss/gss_svc_upcall.c
@@ -316,7 +316,7 @@ out:
 static struct cache_detail rsi_cache = {
         .hash_size      = RSI_HASHMAX,
         .hash_table     = rsi_table,
-        .name           = "auth.ptlrpcs.init",
+        .name           = "auth.sptlrpc.init",
         .cache_put      = rsi_put,
         .cache_request  = rsi_request,
         .cache_parse    = rsi_parse,
@@ -597,7 +597,7 @@ EXPORT_SYMBOL(gss_secsvc_flush);
 static struct cache_detail rsc_cache = {
         .hash_size      = RSC_HASHMAX,
         .hash_table     = rsc_table,
-        .name           = "auth.ptlrpcs.context",
+        .name           = "auth.sptlrpc.context",
         .cache_put      = rsc_put,
         .cache_parse    = rsc_parse,
 };
@@ -662,74 +662,12 @@ int gss_svc_upcall_install_rvs_ctx(struct obd_import *imp,
         if (rscp)
                 rsc_put(&rscp->h, &rsc_cache);
 
-        CWARN("client installed reverse svc ctx to %s: idx "LPX64"\n",
-              imp->imp_obd->u.cli.cl_target_uuid.uuid,
-              gsec->gs_rvs_hdl);
-
-        imp->imp_next_reconnect = gss_round_imp_reconnect(ctx_expiry);
-        CWARN("import(%s) to %s: set force reconnect at %lu(%lds valid time)\n",
-              ptlrpc_import_state_name(imp->imp_state),
-              imp->imp_obd->u.cli.cl_target_uuid.uuid,
-              imp->imp_next_reconnect,
-              (long) (imp->imp_next_reconnect - get_seconds()));
+        CDEBUG(D_SEC, "client installed reverse svc ctx to %s: idx "LPX64"\n",
+               imp->imp_obd->u.cli.cl_target_uuid.uuid, gsec->gs_rvs_hdl);
 
         RETURN(0);
 }
 
-#if 0
-static int
-gss_svc_unseal_request(struct ptlrpc_request *req,
-                       struct rsc *rsci,
-                       struct gss_wire_cred *gc,
-                       __u32 *vp, __u32 vlen)
-{
-        struct ptlrpcs_wire_hdr *sec_hdr;
-        struct gss_ctx *ctx = rsci->mechctx;
-        rawobj_t cipher_text, plain_text;
-        __u32 major;
-        ENTRY;
-
-        sec_hdr = (struct ptlrpcs_wire_hdr *) req->rq_reqbuf;
-
-        if (vlen < 4) {
-                CERROR("vlen only %u\n", vlen);
-                RETURN(GSS_S_CALL_BAD_STRUCTURE);
-        }
-
-        cipher_text.len = le32_to_cpu(*vp++);
-        cipher_text.data = (__u8 *) vp;
-        vlen -= 4;
-        
-        if (cipher_text.len > vlen) {
-                CERROR("cipher claimed %u while buf only %u\n",
-                        cipher_text.len, vlen);
-                RETURN(GSS_S_CALL_BAD_STRUCTURE);
-        }
-
-        plain_text = cipher_text;
-
-        major = lgss_unwrap(ctx, GSS_C_QOP_DEFAULT, &cipher_text, &plain_text);
-        if (major) {
-                CERROR("unwrap error 0x%x\n", major);
-                RETURN(major);
-        }
-
-        if (gss_check_seq_num(&rsci->seqdata, gc->gc_seq)) {
-                CERROR("discard replayed request %p(o%u,x"LPU64",t"LPU64")\n",
-                        req, req->rq_reqmsg->opc, req->rq_xid,
-                        req->rq_reqmsg->transno);
-                RETURN(GSS_S_DUPLICATE_TOKEN);
-        }
-
-        req->rq_reqmsg = (struct lustre_msg *) (vp);
-        req->rq_reqlen = plain_text.len;
-
-        CDEBUG(D_SEC, "msg len %d\n", req->rq_reqlen);
-
-        RETURN(GSS_S_COMPLETE);
-}
-#endif
-
 static
 struct cache_deferred_req* cache_upcall_defer(struct cache_req *req)
 {
@@ -855,8 +793,8 @@ cache_check:
 
         rsci->target = target;
 
-        CWARN("server create rsc %p(%u->%s)\n",
-              rsci, rsci->ctx.gsc_uid, libcfs_nid2str(req->rq_peer.nid));
+        CDEBUG(D_SEC, "server create rsc %p(%u->%s)\n",
+               rsci, rsci->ctx.gsc_uid, libcfs_nid2str(req->rq_peer.nid));
 
         if (rsip->out_handle.len > PTLRPC_GSS_MAX_HANDLE_SIZE) {
                 CERROR("handle size %u too large\n", rsip->out_handle.len);
@@ -895,10 +833,6 @@ cache_check:
         rs->rs_repdata_len = lustre_shrink_msg(rs->rs_repbuf, 2,
                                                rsip->out_token.len, 0);
 
-        if (rsci->ctx.gsc_usr_mds)
-                CWARN("user from %s authenticated as mds\n",
-                      libcfs_nid2str(req->rq_peer.nid));
-
         rc = SECSVC_OK;
 
 out:
diff --git a/lustre/ptlrpc/gss/sec_gss.c b/lustre/ptlrpc/gss/sec_gss.c
index 382c966bd6..2982fd999d 100644
--- a/lustre/ptlrpc/gss/sec_gss.c
+++ b/lustre/ptlrpc/gss/sec_gss.c
@@ -76,6 +76,17 @@
 
 #include <linux/crypto.h>
 
+
+static inline int msg_last_segidx(struct lustre_msg *msg)
+{
+        LASSERT(msg->lm_bufcount > 0);
+        return msg->lm_bufcount - 1;
+}
+static inline int msg_last_seglen(struct lustre_msg *msg)
+{
+        return msg->lm_buflens[msg_last_segidx(msg)];
+}
+
 /********************************************
  * wire data swabber                        *
  ********************************************/
@@ -160,15 +171,15 @@ int gss_estimate_payload(struct gss_ctx *mechctx, int msgsize, int privacy)
 static
 int gss_sign_msg(struct lustre_msg *msg,
                  struct gss_ctx *mechctx,
-                 __u32 proc, __u32 seq,
+                 __u32 proc, __u32 seq, __u32 svc,
                  rawobj_t *handle)
 {
         struct gss_header      *ghdr;
         rawobj_t                text[3], mic;
-        int                     textcnt, mic_idx = msg->lm_bufcount - 1;
+        int                     textcnt, max_textcnt, mic_idx;
         __u32                   major;
 
-        LASSERT(msg->lm_bufcount >= 3);
+        LASSERT(msg->lm_bufcount >= 2);
 
         /* gss hdr */
         LASSERT(msg->lm_buflens[0] >=
@@ -179,7 +190,7 @@ int gss_sign_msg(struct lustre_msg *msg,
         ghdr->gh_flags = 0;
         ghdr->gh_proc = proc;
         ghdr->gh_seq = seq;
-        ghdr->gh_svc = PTLRPC_GSS_SVC_INTEGRITY;
+        ghdr->gh_svc = svc;
         if (!handle) {
                 /* fill in a fake one */
                 ghdr->gh_handle.len = 0;
@@ -188,8 +199,15 @@ int gss_sign_msg(struct lustre_msg *msg,
                 memcpy(ghdr->gh_handle.data, handle->data, handle->len);
         }
 
+        /* no actual signature for null mode */
+        if (svc == SPTLRPC_SVC_NULL)
+                return lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
+
         /* MIC */
-        for (textcnt = 0; textcnt < mic_idx; textcnt++) {
+        mic_idx = msg_last_segidx(msg);
+        max_textcnt = (svc == SPTLRPC_SVC_AUTH) ? 1 : mic_idx;
+
+        for (textcnt = 0; textcnt < max_textcnt; textcnt++) {
                 text[textcnt].len = msg->lm_buflens[textcnt];
                 text[textcnt].data = lustre_msg_buf(msg, textcnt, 0);
         }
@@ -212,14 +230,23 @@ int gss_sign_msg(struct lustre_msg *msg,
  */
 static
 __u32 gss_verify_msg(struct lustre_msg *msg,
-                   struct gss_ctx *mechctx)
+                     struct gss_ctx *mechctx,
+                     __u32 svc)
 {
-        rawobj_t         text[3];
-        rawobj_t         mic;
-        int              textcnt, mic_idx = msg->lm_bufcount - 1;
-        __u32            major;
+        rawobj_t        text[3], mic;
+        int             textcnt, max_textcnt;
+        int             mic_idx;
+        __u32           major;
+
+        LASSERT(msg->lm_bufcount >= 2);
+
+        if (svc == SPTLRPC_SVC_NULL)
+                return GSS_S_COMPLETE;
 
-        for (textcnt = 0; textcnt < mic_idx; textcnt++) {
+        mic_idx = msg_last_segidx(msg);
+        max_textcnt = (svc == SPTLRPC_SVC_AUTH) ? 1 : mic_idx;
+
+        for (textcnt = 0; textcnt < max_textcnt; textcnt++) {
                 text[textcnt].len = msg->lm_buflens[textcnt];
                 text[textcnt].data = lustre_msg_buf(msg, textcnt, 0);
         }
@@ -305,7 +332,8 @@ int cli_ctx_expire(struct ptlrpc_cli_ctx *ctx)
         if (!test_and_set_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags)) {
                 cfs_time_t now;
 
-                clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
+                if (!ctx->cc_early_expire)
+                        clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
 
                 now = cfs_time_current_sec();
                 if (ctx->cc_expire && cfs_time_aftereq(now, ctx->cc_expire))
@@ -349,8 +377,8 @@ int cli_ctx_check_death(struct ptlrpc_cli_ctx *ctx)
 
 void gss_cli_ctx_uptodate(struct gss_cli_ctx *gctx)
 {
-        struct ptlrpc_cli_ctx *ctx = &gctx->gc_base;
-        unsigned long ctx_expiry;
+        struct ptlrpc_cli_ctx  *ctx = &gctx->gc_base;
+        unsigned long           ctx_expiry;
 
         if (lgss_inquire_context(gctx->gc_mechctx, &ctx_expiry)) {
                 CERROR("ctx %p(%u): unable to inquire, expire it now\n",
@@ -368,11 +396,25 @@ void gss_cli_ctx_uptodate(struct gss_cli_ctx *gctx)
          */
         set_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
 
-        CWARN("%s ctx %p(%u->%s), will expire at %lu(%lds lifetime)\n",
-              (ctx->cc_sec->ps_flags & PTLRPC_SEC_FL_REVERSE ?
-               "server installed reverse" : "client refreshed"),
-              ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
-              ctx->cc_expire, (long) (ctx->cc_expire - get_seconds()));
+        if (sec_is_reverse(ctx->cc_sec))
+                CDEBUG(D_SEC, "server installed reverse ctx %p, "
+                       "will expire at %lu(%lds lifetime)\n",
+                       ctx, ctx->cc_expire,
+                       ctx->cc_expire - cfs_time_current_sec());
+        else
+                CWARN("client refreshed ctx %p(%u->%s), will expire at "
+                      "%lu(%lds lifetime)\n", ctx, ctx->cc_vcred.vc_uid,
+                      sec2target_str(ctx->cc_sec), ctx->cc_expire,
+                      ctx->cc_expire - cfs_time_current_sec());
+
+        /*
+         * install reverse svc ctx, but only for forward connection
+         * and root context
+         */
+        if (!sec_is_reverse(ctx->cc_sec) && ctx->cc_vcred.vc_uid == 0) {
+                gss_sec_install_rctx(ctx->cc_sec->ps_import,
+                                     ctx->cc_sec, ctx);
+        }
 }
 
 static
@@ -548,11 +590,12 @@ int gss_cli_ctx_match(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred)
         return (ctx->cc_vcred.vc_uid == vcred->vc_uid);
 }
 
-static
 void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize)
 {
         buf[0] = '\0';
 
+        if (flags & PTLRPC_CTX_NEW)
+                strncat(buf, "new,", bufsize);
         if (flags & PTLRPC_CTX_UPTODATE)
                 strncat(buf, "uptodate,", bufsize);
         if (flags & PTLRPC_CTX_DEAD)
@@ -569,44 +612,16 @@ void gss_cli_ctx_flags2str(unsigned long flags, char *buf, int bufsize)
         buf[strlen(buf) - 1] = '\0';
 }
 
-int gss_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize)
-{
-        struct gss_cli_ctx     *gctx;
-        char                    flags_str[40];
-        int                     written;
-
-        gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
-
-        gss_cli_ctx_flags2str(ctx->cc_flags, flags_str, sizeof(flags_str));
-
-        written = snprintf(buf, bufsize,
-                        "UID %d:\n" 
-                        "  flags:       %s\n"
-                        "  seqwin:      %d\n"
-                        "  sequence:    %d\n",
-                        ctx->cc_vcred.vc_uid,
-                        flags_str,
-                        gctx->gc_win,
-                        atomic_read(&gctx->gc_seq));
-
-        if (gctx->gc_mechctx) {
-                written += lgss_display(gctx->gc_mechctx,
-                                        buf + written, bufsize - written);
-        }
-
-        return written;
-}
-
 int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx,
                      struct ptlrpc_request *req)
 {
         struct gss_cli_ctx      *gctx;
-        __u32                    seq;
+        __u32                    seq, svc;
         int                      rc;
         ENTRY;
 
         LASSERT(req->rq_reqbuf);
-        LASSERT(req->rq_reqbuf->lm_bufcount >= 3);
+        LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
         LASSERT(req->rq_cli_ctx == ctx);
 
         /* nothing to do for context negotiation RPCs */
@@ -614,11 +629,13 @@ int gss_cli_ctx_sign(struct ptlrpc_cli_ctx *ctx,
                 RETURN(0);
 
         gctx = container_of(ctx, struct gss_cli_ctx, gc_base);
+        svc = SEC_FLAVOR_SVC(req->rq_sec_flavor);
 redo:
         seq = atomic_inc_return(&gctx->gc_seq);
 
         rc = gss_sign_msg(req->rq_reqbuf, gctx->gc_mechctx,
-                          gctx->gc_proc, seq, &gctx->gc_handle);
+                          gctx->gc_proc, seq, svc,
+                          &gctx->gc_handle);
         if (rc < 0)
                 RETURN(rc);
 
@@ -627,8 +644,11 @@ redo:
          * of them we should repack this rpc, because sent it too late might
          * lead to the sequence number fall behind the window on server and
          * be dropped. also applies to gss_cli_ctx_seal().
+         *
+         * Note: null mode dosen't check sequence number.
          */
-        if (atomic_read(&gctx->gc_seq) - seq > GSS_SEQ_REPACK_THRESHOLD) {
+        if (svc != SPTLRPC_SVC_NULL &&
+            atomic_read(&gctx->gc_seq) - seq > GSS_SEQ_REPACK_THRESHOLD) {
                 int behind = atomic_read(&gctx->gc_seq) - seq;
 
                 gss_stat_oos_record_cli(behind);
@@ -670,7 +690,7 @@ int gss_cli_ctx_handle_err_notify(struct ptlrpc_cli_ctx *ctx,
                 CWARN("server respond error (%08x/%08x) for ctx fini\n",
                       errhdr->gh_major, errhdr->gh_minor);
                 rc = -EINVAL;
-        } else if (ctx->cc_sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
+        } else if (sec_is_reverse(ctx->cc_sec)) {
                 CWARN("reverse server respond error (%08x/%08x)\n",
                       errhdr->gh_major, errhdr->gh_minor);
                 rc = -EINVAL;
@@ -727,7 +747,7 @@ int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx,
                 RETURN(0);
         }
 
-        if (msg->lm_bufcount < 3 || msg->lm_bufcount > 4) {
+        if (msg->lm_bufcount < 2 || msg->lm_bufcount > 4) {
                 CERROR("unexpected bufcount %u\n", msg->lm_bufcount);
                 RETURN(-EPROTO);
         }
@@ -756,15 +776,16 @@ int gss_cli_ctx_verify(struct ptlrpc_cli_ctx *ctx,
                         RETURN(-EPROTO);
                 }
 
-                if (ghdr->gh_svc != PTLRPC_GSS_SVC_INTEGRITY) {
-                        CERROR("unexpected svc %d\n", ghdr->gh_svc);
+                if (ghdr->gh_svc != reqhdr->gh_svc) {
+                        CERROR("svc %u mismatch, expect %u\n",
+                               ghdr->gh_svc, reqhdr->gh_svc);
                         RETURN(-EPROTO);
                 }
 
                 if (lustre_msg_swabbed(msg))
                         gss_header_swabber(ghdr);
 
-                major = gss_verify_msg(msg, gctx->gc_mechctx);
+                major = gss_verify_msg(msg, gctx->gc_mechctx, reqhdr->gh_svc);
                 if (major != GSS_S_COMPLETE)
                         RETURN(-EPERM);
 
@@ -841,7 +862,7 @@ int gss_cli_ctx_seal(struct ptlrpc_cli_ctx *ctx,
         ghdr->gh_flags = 0;
         ghdr->gh_proc = gctx->gc_proc;
         ghdr->gh_seq = atomic_inc_return(&gctx->gc_seq);
-        ghdr->gh_svc = PTLRPC_GSS_SVC_PRIVACY;
+        ghdr->gh_svc = SPTLRPC_SVC_PRIV;
         ghdr->gh_handle.len = gctx->gc_handle.len;
         memcpy(ghdr->gh_handle.data, gctx->gc_handle.data, gctx->gc_handle.len);
 
@@ -1028,13 +1049,13 @@ int gss_sec_create_common(struct gss_sec *gsec,
         sec->ps_import = class_import_get(imp);
         sec->ps_lock = SPIN_LOCK_UNLOCKED;
         atomic_set(&sec->ps_busy, 0);
-        INIT_LIST_HEAD(&sec->ps_gc_list);
+        CFS_INIT_LIST_HEAD(&sec->ps_gc_list);
 
         if (!ctx) {
                 sec->ps_gc_interval = GSS_GC_INTERVAL;
                 sec->ps_gc_next = cfs_time_current_sec() + sec->ps_gc_interval;
         } else {
-                LASSERT(sec->ps_flags & PTLRPC_SEC_FL_REVERSE);
+                LASSERT(sec_is_reverse(sec));
 
                 /* never do gc on reverse sec */
                 sec->ps_gc_interval = 0;
@@ -1045,8 +1066,8 @@ int gss_sec_create_common(struct gss_sec *gsec,
             flags & PTLRPC_SEC_FL_BULK)
                 sptlrpc_enc_pool_add_user();
 
-        CWARN("create %s%s@%p\n", (ctx ? "reverse " : ""),
-              policy->sp_name, gsec);
+        CDEBUG(D_SEC, "create %s%s@%p\n", (ctx ? "reverse " : ""),
+               policy->sp_name, gsec);
         return 0;
 }
 
@@ -1083,7 +1104,7 @@ int gss_cli_ctx_init_common(struct ptlrpc_sec *sec,
         gctx->gc_win = 0;
         atomic_set(&gctx->gc_seq, 0);
 
-        INIT_HLIST_NODE(&ctx->cc_hash);
+        CFS_INIT_HLIST_NODE(&ctx->cc_cache);
         atomic_set(&ctx->cc_refcount, 0);
         ctx->cc_sec = sec;
         ctx->cc_ops = ctxops;
@@ -1091,14 +1112,15 @@ int gss_cli_ctx_init_common(struct ptlrpc_sec *sec,
         ctx->cc_flags = PTLRPC_CTX_NEW;
         ctx->cc_vcred = *vcred;
         spin_lock_init(&ctx->cc_lock);
-        INIT_LIST_HEAD(&ctx->cc_req_list);
+        CFS_INIT_LIST_HEAD(&ctx->cc_req_list);
+        CFS_INIT_LIST_HEAD(&ctx->cc_gc_chain);
 
         /* take a ref on belonging sec */
         atomic_inc(&sec->ps_busy);
 
-        CWARN("%s@%p: create ctx %p(%u->%s)\n",
-              sec->ps_policy->sp_name, ctx->cc_sec,
-              ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+        CDEBUG(D_SEC, "%s@%p: create ctx %p(%u->%s)\n",
+               sec->ps_policy->sp_name, ctx->cc_sec,
+               ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
         return 0;
 }
 
@@ -1120,9 +1142,13 @@ int gss_cli_ctx_fini_common(struct ptlrpc_sec *sec,
                 gss_cli_ctx_finalize(gctx);
         }
 
-        CWARN("%s@%p: destroy ctx %p(%u->%s)\n",
-              sec->ps_policy->sp_name, ctx->cc_sec,
-              ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+        if (sec_is_reverse(sec))
+                CDEBUG(D_SEC, "reverse sec %p: destroy ctx %p\n",
+                       ctx->cc_sec, ctx);
+        else
+                CWARN("%s@%p: destroy ctx %p(%u->%s)\n",
+                      sec->ps_policy->sp_name, ctx->cc_sec,
+                      ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
 
         if (atomic_dec_and_test(&sec->ps_busy)) {
                 LASSERT(atomic_read(&sec->ps_refcount) == 0);
@@ -1133,29 +1159,41 @@ int gss_cli_ctx_fini_common(struct ptlrpc_sec *sec,
 }
 
 static
-int gss_alloc_reqbuf_auth(struct ptlrpc_sec *sec,
+int gss_alloc_reqbuf_intg(struct ptlrpc_sec *sec,
                           struct ptlrpc_request *req,
-                          int msgsize)
+                          int svc, int msgsize)
 {
         struct sec_flavor_config *conf;
-        int bufsize, txtsize;
-        int buflens[5], bufcnt = 2;
+        int                       bufsize, txtsize;
+        int                       buflens[5], bufcnt = 2;
         ENTRY;
 
         /*
+         * on-wire data layout:
          * - gss header
          * - lustre message
-         * - user descriptor
-         * - bulk sec descriptor
-         * - signature
+         * - user descriptor (optional)
+         * - bulk sec descriptor (optional)
+         * - signature (optional)
+         *   - svc == NULL: NULL
+         *   - svc == AUTH: signature of gss header
+         *   - svc == INTG: signature of all above
+         *
+         * if this is context negotiation, reserver fixed space
+         * at the last (signature) segment regardless of svc mode.
          */
+
         buflens[0] = PTLRPC_GSS_HEADER_SIZE;
+        txtsize = buflens[0];
+
         buflens[1] = msgsize;
-        txtsize = buflens[0] + buflens[1];
+        if (svc == SPTLRPC_SVC_INTG)
+                txtsize += buflens[1];
 
         if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
                 buflens[bufcnt] = sptlrpc_current_user_desc_size();
-                txtsize += buflens[bufcnt];
+                if (svc == SPTLRPC_SVC_INTG)
+                        txtsize += buflens[bufcnt];
                 bufcnt++;
         }
 
@@ -1163,12 +1201,15 @@ int gss_alloc_reqbuf_auth(struct ptlrpc_sec *sec,
                 conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
                 buflens[bufcnt] = bulk_sec_desc_size(conf->sfc_bulk_csum, 1,
                                                      req->rq_bulk_read);
-                txtsize += buflens[bufcnt];
+                if (svc == SPTLRPC_SVC_INTG)
+                        txtsize += buflens[bufcnt];
                 bufcnt++;
         }
 
-        buflens[bufcnt++] = req->rq_ctx_init ? GSS_CTX_INIT_MAX_LEN :
-                            gss_cli_payload(req->rq_cli_ctx, txtsize, 0);
+        if (req->rq_ctx_init)
+                buflens[bufcnt++] = GSS_CTX_INIT_MAX_LEN;
+        else if (svc != SPTLRPC_SVC_NULL)
+                buflens[bufcnt++] = gss_cli_payload(req->rq_cli_ctx, txtsize,0);
 
         bufsize = lustre_msg_size_v2(bufcnt, buflens);
 
@@ -1205,9 +1246,9 @@ int gss_alloc_reqbuf_priv(struct ptlrpc_sec *sec,
                           int msgsize)
 {
         struct sec_flavor_config *conf;
-        int ibuflens[3], ibufcnt;
-        int buflens[3];
-        int clearsize, wiresize;
+        int                       ibuflens[3], ibufcnt;
+        int                       buflens[3];
+        int                       clearsize, wiresize;
         ENTRY;
 
         LASSERT(req->rq_clrbuf == NULL);
@@ -1215,9 +1256,10 @@ int gss_alloc_reqbuf_priv(struct ptlrpc_sec *sec,
 
         /* Inner (clear) buffers
          *  - lustre message
-         *  - user descriptor
-         *  - bulk checksum
+         *  - user descriptor (optional)
+         *  - bulk checksum (optional)
          */
+
         ibufcnt = 1;
         ibuflens[0] = msgsize;
 
@@ -1237,6 +1279,7 @@ int gss_alloc_reqbuf_priv(struct ptlrpc_sec *sec,
          *  - signature of gss header
          *  - cipher text
          */
+
         buflens[0] = PTLRPC_GSS_HEADER_SIZE;
         buflens[1] = gss_cli_payload(req->rq_cli_ctx, buflens[0], 0);
         buflens[2] = gss_cli_payload(req->rq_cli_ctx, clearsize, 1);
@@ -1289,25 +1332,28 @@ int gss_alloc_reqbuf(struct ptlrpc_sec *sec,
                      struct ptlrpc_request *req,
                      int msgsize)
 {
+        int     svc = SEC_FLAVOR_SVC(req->rq_sec_flavor);
+
         LASSERT(!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor) ||
                 (req->rq_bulk_read || req->rq_bulk_write));
 
-        switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
-        case SPTLRPC_SVC_NONE:
+        switch (svc) {
+        case SPTLRPC_SVC_NULL:
         case SPTLRPC_SVC_AUTH:
-                return gss_alloc_reqbuf_auth(sec, req, msgsize);
+        case SPTLRPC_SVC_INTG:
+                return gss_alloc_reqbuf_intg(sec, req, svc, msgsize);
         case SPTLRPC_SVC_PRIV:
                 return gss_alloc_reqbuf_priv(sec, req, msgsize);
         default:
-                LBUG();
+                LASSERTF(0, "bad flavor %x\n", req->rq_sec_flavor);
+                return 0;
         }
-        return 0;
 }
 
 void gss_free_reqbuf(struct ptlrpc_sec *sec,
                      struct ptlrpc_request *req)
 {
-        int privacy;
+        int     privacy;
         ENTRY;
 
         LASSERT(!req->rq_pool || req->rq_reqbuf);
@@ -1340,62 +1386,126 @@ release_reqbuf:
         EXIT;
 }
 
-int gss_alloc_repbuf(struct ptlrpc_sec *sec,
-                     struct ptlrpc_request *req,
-                     int msgsize)
+static int do_alloc_repbuf(struct ptlrpc_request *req, int bufsize)
+{
+        bufsize = size_roundup_power2(bufsize);
+
+        OBD_ALLOC(req->rq_repbuf, bufsize);
+        if (!req->rq_repbuf)
+                return -ENOMEM;
+
+        req->rq_repbuf_len = bufsize;
+        return 0;
+}
+
+static
+int gss_alloc_repbuf_intg(struct ptlrpc_sec *sec,
+                          struct ptlrpc_request *req,
+                          int svc, int msgsize)
 {
         struct sec_flavor_config *conf;
-        int privacy = (SEC_FLAVOR_SVC(req->rq_sec_flavor) == SPTLRPC_SVC_PRIV);
-        int bufsize, txtsize;
-        int buflens[4], bufcnt;
-        ENTRY;
+        int                       txtsize;
+        int                       buflens[4], bufcnt = 2;
 
-        LASSERT(!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor) ||
-                (req->rq_bulk_read || req->rq_bulk_write));
+        /*
+         * on-wire data layout:
+         * - gss header
+         * - lustre message
+         * - bulk sec descriptor (optional)
+         * - signature (optional)
+         *   - svc == NULL: NULL
+         *   - svc == AUTH: signature of gss header
+         *   - svc == INTG: signature of all above
+         *
+         * if this is context negotiation, reserver fixed space
+         * at the last (signature) segment regardless of svc mode.
+         */
 
-        if (privacy) {
-                bufcnt = 1;
-                buflens[0] = msgsize;
-                if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
-                        conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
-                        buflens[bufcnt++] = bulk_sec_desc_size(
-                                                        conf->sfc_bulk_csum, 0,
-                                                        req->rq_bulk_read);
-                }
-                txtsize = lustre_msg_size_v2(bufcnt, buflens);
-                txtsize += GSS_MAX_CIPHER_BLOCK;
+        buflens[0] = PTLRPC_GSS_HEADER_SIZE;
+        txtsize = buflens[0];
 
-                bufcnt = 3;
-                buflens[0] = PTLRPC_GSS_HEADER_SIZE;
-                buflens[1] = gss_cli_payload(req->rq_cli_ctx, buflens[0], 0);
-                buflens[2] = gss_cli_payload(req->rq_cli_ctx, txtsize, 1);
-        } else {
-                bufcnt = 2;
-                buflens[0] = PTLRPC_GSS_HEADER_SIZE;
-                buflens[1] = msgsize;
-                txtsize = buflens[0] + buflens[1];
+        buflens[1] = msgsize;
+        if (svc == SPTLRPC_SVC_INTG)
+                txtsize += buflens[1];
 
-                if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
-                        conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
-                        buflens[bufcnt] = bulk_sec_desc_size(
-                                                        conf->sfc_bulk_csum, 0,
-                                                        req->rq_bulk_read);
+        if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
+                conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
+                buflens[bufcnt] = bulk_sec_desc_size(conf->sfc_bulk_csum, 0,
+                                                     req->rq_bulk_read);
+                if (svc == SPTLRPC_SVC_INTG)
                         txtsize += buflens[bufcnt];
-                        bufcnt++;
-                }
-                buflens[bufcnt++] = req->rq_ctx_init ? GSS_CTX_INIT_MAX_LEN :
-                                   gss_cli_payload(req->rq_cli_ctx, txtsize, 0);
+                bufcnt++;
         }
 
-        bufsize = lustre_msg_size_v2(bufcnt, buflens);
-        bufsize = size_roundup_power2(bufsize);
+        if (req->rq_ctx_init)
+                buflens[bufcnt++] = GSS_CTX_INIT_MAX_LEN;
+        else if (svc != SPTLRPC_SVC_NULL)
+                buflens[bufcnt++] = gss_cli_payload(req->rq_cli_ctx, txtsize,0);
 
-        OBD_ALLOC(req->rq_repbuf, bufsize);
-        if (!req->rq_repbuf)
-                return -ENOMEM;
+        return do_alloc_repbuf(req, lustre_msg_size_v2(bufcnt, buflens));
+}
 
-        req->rq_repbuf_len = bufsize;
-        return 0;
+static
+int gss_alloc_repbuf_priv(struct ptlrpc_sec *sec,
+                          struct ptlrpc_request *req,
+                          int msgsize)
+{
+        struct sec_flavor_config *conf;
+        int                       txtsize;
+        int                       buflens[3], bufcnt;
+
+        /* Inner (clear) buffers
+         *  - lustre message
+         *  - bulk checksum (optional)
+         */
+
+        bufcnt = 1;
+        buflens[0] = msgsize;
+
+        if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
+                conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
+                buflens[bufcnt++] = bulk_sec_desc_size(
+                                                conf->sfc_bulk_csum, 0,
+                                                req->rq_bulk_read);
+        }
+        txtsize = lustre_msg_size_v2(bufcnt, buflens);
+        txtsize += GSS_MAX_CIPHER_BLOCK;
+
+        /* Wrapper (wire) buffers
+         *  - gss header
+         *  - signature of gss header
+         *  - cipher text
+         */
+
+        bufcnt = 3;
+        buflens[0] = PTLRPC_GSS_HEADER_SIZE;
+        buflens[1] = gss_cli_payload(req->rq_cli_ctx, buflens[0], 0);
+        buflens[2] = gss_cli_payload(req->rq_cli_ctx, txtsize, 1);
+
+        return do_alloc_repbuf(req, lustre_msg_size_v2(bufcnt, buflens));
+}
+
+int gss_alloc_repbuf(struct ptlrpc_sec *sec,
+                     struct ptlrpc_request *req,
+                     int msgsize)
+{
+        int     svc = SEC_FLAVOR_SVC(req->rq_sec_flavor);
+        ENTRY;
+
+        LASSERT(!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor) ||
+                (req->rq_bulk_read || req->rq_bulk_write));
+
+        switch (svc) {
+        case SPTLRPC_SVC_NULL:
+        case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
+                return gss_alloc_repbuf_intg(sec, req, svc, msgsize);
+        case SPTLRPC_SVC_PRIV:
+                return gss_alloc_repbuf_priv(sec, req, msgsize);
+        default:
+                LASSERTF(0, "bad flavor %x\n", req->rq_sec_flavor);
+                return 0;
+        }
 }
 
 void gss_free_repbuf(struct ptlrpc_sec *sec,
@@ -1441,42 +1551,53 @@ static int get_enlarged_msgsize2(struct lustre_msg *msg,
         return newmsg_size;
 }
 
-static inline int msg_last_seglen(struct lustre_msg *msg)
-{
-        return msg->lm_buflens[msg->lm_bufcount - 1];
-}
-
 static
-int gss_enlarge_reqbuf_auth(struct ptlrpc_sec *sec,
+int gss_enlarge_reqbuf_intg(struct ptlrpc_sec *sec,
                             struct ptlrpc_request *req,
+                            int svc,
                             int segment, int newsize)
 {
         struct lustre_msg      *newbuf;
-        int                     txtsize, sigsize, i;
+        int                     txtsize, sigsize = 0, i;
         int                     newmsg_size, newbuf_size;
 
         /*
-         * embedded msg is at seg 1; signature is at the last seg
+         * gss header is at seg 0;
+         * embedded msg is at seg 1;
+         * signature (if any) is at the last seg
          */
         LASSERT(req->rq_reqbuf);
         LASSERT(req->rq_reqbuf_len > req->rq_reqlen);
         LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
         LASSERT(lustre_msg_buf(req->rq_reqbuf, 1, 0) == req->rq_reqmsg);
 
-        /* compute new embedded msg size */
+        /* 1. compute new embedded msg size */
         newmsg_size = get_enlarged_msgsize(req->rq_reqmsg, segment, newsize);
         LASSERT(newmsg_size >= req->rq_reqbuf->lm_buflens[1]);
 
-        /* compute new wrapper msg size */
-        for (txtsize = 0, i = 0; i < req->rq_reqbuf->lm_bufcount; i++)
-                txtsize += req->rq_reqbuf->lm_buflens[i];
-        txtsize += newmsg_size - req->rq_reqbuf->lm_buflens[1];
+        /* 2. compute new wrapper msg size */
+        if (svc == SPTLRPC_SVC_NULL) {
+                /* no signature, get size directly */
+                newbuf_size = get_enlarged_msgsize(req->rq_reqbuf,
+                                                   1, newmsg_size);
+        } else {
+                txtsize = req->rq_reqbuf->lm_buflens[0];
+
+                if (svc == SPTLRPC_SVC_INTG) {
+                        for (i = 1; i < req->rq_reqbuf->lm_bufcount; i++)
+                                txtsize += req->rq_reqbuf->lm_buflens[i];
+                        txtsize += newmsg_size - req->rq_reqbuf->lm_buflens[1];
+                }
+
+                sigsize = gss_cli_payload(req->rq_cli_ctx, txtsize, 0);
+                LASSERT(sigsize >= msg_last_seglen(req->rq_reqbuf));
 
-        sigsize = gss_cli_payload(req->rq_cli_ctx, txtsize, 0);
-        LASSERT(sigsize >= msg_last_seglen(req->rq_reqbuf));
-        newbuf_size = get_enlarged_msgsize2(req->rq_reqbuf, 1, newmsg_size,
-                                            req->rq_reqbuf->lm_bufcount - 1,
-                                            sigsize);
+                newbuf_size = get_enlarged_msgsize2(
+                                        req->rq_reqbuf,
+                                        1, newmsg_size,
+                                        msg_last_segidx(req->rq_reqbuf),
+                                        sigsize);
+        }
 
         /* request from pool should always have enough buffer */
         LASSERT(!req->rq_pool || req->rq_reqbuf_len >= newbuf_size);
@@ -1496,8 +1617,12 @@ int gss_enlarge_reqbuf_auth(struct ptlrpc_sec *sec,
                 req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf, 1, 0);
         }
 
-        _sptlrpc_enlarge_msg_inplace(req->rq_reqbuf,
-                                     req->rq_reqbuf->lm_bufcount - 1, sigsize);
+        /* do enlargement, from wrapper to embedded, from end to begin */
+        if (svc != SPTLRPC_SVC_NULL)
+                _sptlrpc_enlarge_msg_inplace(req->rq_reqbuf,
+                                             msg_last_segidx(req->rq_reqbuf),
+                                             sigsize);
+
         _sptlrpc_enlarge_msg_inplace(req->rq_reqbuf, 1, newmsg_size);
         _sptlrpc_enlarge_msg_inplace(req->rq_reqmsg, segment, newsize);
 
@@ -1604,11 +1729,15 @@ int gss_enlarge_reqbuf(struct ptlrpc_sec *sec,
                        struct ptlrpc_request *req,
                        int segment, int newsize)
 {
+        int     svc = SEC_FLAVOR_SVC(req->rq_sec_flavor);
+
         LASSERT(!req->rq_ctx_init && !req->rq_ctx_fini);
 
-        switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
+        switch (svc) {
+        case SPTLRPC_SVC_NULL:
         case SPTLRPC_SVC_AUTH:
-                return gss_enlarge_reqbuf_auth(sec, req, segment, newsize);
+        case SPTLRPC_SVC_INTG:
+                return gss_enlarge_reqbuf_intg(sec, req, svc, segment, newsize);
         case SPTLRPC_SVC_PRIV:
                 return gss_enlarge_reqbuf_priv(sec, req, segment, newsize);
         default:
@@ -1673,7 +1802,8 @@ void gss_svc_reqctx_decref(struct gss_svc_reqctx *grctx)
 static
 int gss_svc_sign(struct ptlrpc_request *req,
                  struct ptlrpc_reply_state *rs,
-                 struct gss_svc_reqctx *grctx)
+                 struct gss_svc_reqctx *grctx,
+                 int svc)
 {
         int     rc;
         ENTRY;
@@ -1686,7 +1816,7 @@ int gss_svc_sign(struct ptlrpc_request *req,
 
         rc = gss_sign_msg(rs->rs_repbuf, grctx->src_ctx->gsc_mechctx,
                           PTLRPC_GSS_PROC_DATA, grctx->src_wirectx.gw_seq,
-                          NULL);
+                          svc, NULL);
         if (rc < 0)
                 RETURN(rc);
 
@@ -1750,6 +1880,8 @@ int gss_svc_handle_init(struct ptlrpc_request *req,
         CDEBUG(D_SEC, "processing gss init(%d) request from %s\n", gw->gw_proc,
                libcfs_nid2str(req->rq_peer.nid));
 
+        req->rq_ctx_init = 1;
+
         if (gw->gw_proc == PTLRPC_GSS_PROC_INIT && gw->gw_handle.len != 0) {
                 CERROR("proc %u: invalid handle length %u\n",
                        gw->gw_proc, gw->gw_handle.len);
@@ -1809,6 +1941,14 @@ int gss_svc_handle_init(struct ptlrpc_request *req,
         if (rc != SECSVC_OK)
                 RETURN(rc);
 
+        if (grctx->src_ctx->gsc_usr_mds || grctx->src_ctx->gsc_usr_root)
+                CWARN("user from %s authenticated as %s\n",
+                      libcfs_nid2str(req->rq_peer.nid),
+                      grctx->src_ctx->gsc_usr_mds ? "mds" : "root");
+        else
+                CWARN("accept user %u from %s\n", grctx->src_ctx->gsc_uid,
+                      libcfs_nid2str(req->rq_peer.nid));
+
         if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
                 if (reqbuf->lm_bufcount < 4) {
                         CERROR("missing user descriptor\n");
@@ -1832,28 +1972,32 @@ int gss_svc_handle_init(struct ptlrpc_request *req,
  */
 static
 int gss_svc_verify_request(struct ptlrpc_request *req,
-                           struct gss_svc_ctx *gctx,
+                           struct gss_svc_reqctx *grctx,
                            struct gss_wire_ctx *gw,
                            __u32 *major)
 {
+        struct gss_svc_ctx *gctx = grctx->src_ctx;
         struct lustre_msg  *msg = req->rq_reqbuf;
         int                 offset = 2;
         ENTRY;
 
         *major = GSS_S_COMPLETE;
 
-        if (msg->lm_bufcount < 3) {
+        if (msg->lm_bufcount < 2) {
                 CERROR("Too few segments (%u) in request\n", msg->lm_bufcount);
                 RETURN(-EINVAL);
         }
 
+        if (gw->gw_svc == SPTLRPC_SVC_NULL)
+                goto verified;
+
         if (gss_check_seq_num(&gctx->gsc_seqdata, gw->gw_seq, 0)) {
                 CERROR("phase 0: discard replayed req: seq %u\n", gw->gw_seq);
                 *major = GSS_S_DUPLICATE_TOKEN;
                 RETURN(-EACCES);
         }
 
-        *major = gss_verify_msg(msg, gctx->gsc_mechctx);
+        *major = gss_verify_msg(msg, gctx->gsc_mechctx, gw->gw_svc);
         if (*major != GSS_S_COMPLETE)
                 RETURN(-EACCES);
 
@@ -1863,9 +2007,10 @@ int gss_svc_verify_request(struct ptlrpc_request *req,
                 RETURN(-EACCES);
         }
 
+verified:
         /* user descriptor */
         if (SEC_FLAVOR_HAS_USER(req->rq_sec_flavor)) {
-                if (msg->lm_bufcount < (offset + 1 + 1)) {
+                if (msg->lm_bufcount < (offset + 1)) {
                         CERROR("no user desc included\n");
                         RETURN(-EINVAL);
                 }
@@ -1881,13 +2026,16 @@ int gss_svc_verify_request(struct ptlrpc_request *req,
 
         /* check bulk cksum data */
         if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
-                if (msg->lm_bufcount < (offset + 1 + 1)) {
+                if (msg->lm_bufcount < (offset + 1)) {
                         CERROR("no bulk checksum included\n");
                         RETURN(-EINVAL);
                 }
 
                 if (bulk_sec_desc_unpack(msg, offset))
                         RETURN(-EINVAL);
+
+                grctx->src_reqbsd = lustre_msg_buf(msg, offset, 0);
+                grctx->src_reqbsd_size = lustre_msg_buflen(msg, offset);
         }
 
         req->rq_reqmsg = lustre_msg_buf(msg, 1, 0);
@@ -1897,10 +2045,11 @@ int gss_svc_verify_request(struct ptlrpc_request *req,
 
 static
 int gss_svc_unseal_request(struct ptlrpc_request *req,
-                           struct gss_svc_ctx *gctx,
+                           struct gss_svc_reqctx *grctx,
                            struct gss_wire_ctx *gw,
                            __u32 *major)
 {
+        struct gss_svc_ctx *gctx = grctx->src_ctx;
         struct lustre_msg  *msg = req->rq_reqbuf;
         int                 msglen, offset = 1;
         ENTRY;
@@ -1956,6 +2105,9 @@ int gss_svc_unseal_request(struct ptlrpc_request *req,
 
                 if (bulk_sec_desc_unpack(msg, offset))
                         RETURN(-EINVAL);
+
+                grctx->src_reqbsd = lustre_msg_buf(msg, offset, 0);
+                grctx->src_reqbsd_size = lustre_msg_buflen(msg, offset);
         }
 
         req->rq_reqmsg = lustre_msg_buf(req->rq_reqbuf, 0, 0);
@@ -1979,11 +2131,13 @@ int gss_svc_handle_data(struct ptlrpc_request *req,
         }
 
         switch (gw->gw_svc) {
-        case PTLRPC_GSS_SVC_INTEGRITY:
-                rc = gss_svc_verify_request(req, grctx->src_ctx, gw, &major);
+        case SPTLRPC_SVC_NULL:
+        case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
+                rc = gss_svc_verify_request(req, grctx, gw, &major);
                 break;
-        case PTLRPC_GSS_SVC_PRIVACY:
-                rc = gss_svc_unseal_request(req, grctx->src_ctx, gw, &major);
+        case SPTLRPC_SVC_PRIV:
+                rc = gss_svc_unseal_request(req, grctx, gw, &major);
                 break;
         default:
                 CERROR("unsupported gss service %d\n", gw->gw_svc);
@@ -2013,29 +2167,28 @@ int gss_svc_handle_destroy(struct ptlrpc_request *req,
                            struct gss_wire_ctx *gw)
 {
         struct gss_svc_reqctx  *grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
-        int                     replen = sizeof(struct ptlrpc_body);
         __u32                   major;
         ENTRY;
 
+        req->rq_ctx_fini = 1;
+        req->rq_no_reply = 1;
+
         grctx->src_ctx = gss_svc_upcall_get_ctx(req, gw);
         if (!grctx->src_ctx) {
                 CWARN("invalid gss context handle for destroy.\n");
                 RETURN(SECSVC_DROP);
         }
 
-        if (gw->gw_svc != PTLRPC_GSS_SVC_INTEGRITY) {
+        if (gw->gw_svc != SPTLRPC_SVC_INTG) {
                 CERROR("svc %u is not supported in destroy.\n", gw->gw_svc);
                 RETURN(SECSVC_DROP);
         }
 
-        if (gss_svc_verify_request(req, grctx->src_ctx, gw, &major))
-                RETURN(SECSVC_DROP);
-
-        if (lustre_pack_reply_v2(req, 1, &replen, NULL))
+        if (gss_svc_verify_request(req, grctx, gw, &major))
                 RETURN(SECSVC_DROP);
 
-        CWARN("gss svc destroy ctx %p(%u->%s)\n", grctx->src_ctx,
-              grctx->src_ctx->gsc_uid, libcfs_nid2str(req->rq_peer.nid));
+        CWARN("destroy svc ctx %p(%u->%s)\n", grctx->src_ctx,
+               grctx->src_ctx->gsc_uid, libcfs_nid2str(req->rq_peer.nid));
 
         gss_svc_upcall_destroy_ctx(grctx->src_ctx);
 
@@ -2175,8 +2328,7 @@ int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
 {
         struct gss_svc_reqctx       *grctx;
         struct ptlrpc_reply_state   *rs;
-        struct ptlrpc_bulk_sec_desc *bsd;
-        int                          privacy;
+        int                          privacy, svc, bsd_off = 0;
         int                          ibuflens[2], ibufcnt = 0;
         int                          buflens[4], bufcnt;
         int                          txtsize, wmsg_size, rs_size;
@@ -2190,12 +2342,13 @@ int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
                 RETURN(-EPROTO);
         }
 
+        svc = SEC_FLAVOR_SVC(req->rq_sec_flavor);
+
         grctx = gss_svc_ctx2reqctx(req->rq_svc_ctx);
         if (gss_svc_reqctx_is_special(grctx))
                 privacy = 0;
         else
-                privacy = (SEC_FLAVOR_SVC(req->rq_sec_flavor) ==
-                           SPTLRPC_SVC_PRIV);
+                privacy = (svc == SPTLRPC_SVC_PRIV);
 
         if (privacy) {
                 /* Inner buffer */
@@ -2203,14 +2356,12 @@ int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
                 ibuflens[0] = msglen;
 
                 if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
-                        LASSERT(req->rq_reqbuf->lm_bufcount >= 2);
-                        bsd = lustre_msg_buf(req->rq_reqbuf,
-                                             req->rq_reqbuf->lm_bufcount - 1,
-                                             sizeof(*bsd));
+                        LASSERT(grctx->src_reqbsd);
 
+                        bsd_off = ibufcnt;
                         ibuflens[ibufcnt++] = bulk_sec_desc_size(
-                                                        bsd->bsd_csum_alg, 0,
-                                                        req->rq_bulk_read);
+                                                grctx->src_reqbsd->bsd_csum_alg,
+                                                0, req->rq_bulk_read);
                 }
 
                 txtsize = lustre_msg_size_v2(ibufcnt, ibuflens);
@@ -2225,21 +2376,26 @@ int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
                 bufcnt = 2;
                 buflens[0] = PTLRPC_GSS_HEADER_SIZE;
                 buflens[1] = msglen;
-                txtsize = buflens[0] + buflens[1];
+
+                txtsize = buflens[0];
+                if (svc == SPTLRPC_SVC_INTG)
+                        txtsize += buflens[1];
 
                 if (SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor)) {
-                        LASSERT(req->rq_reqbuf->lm_bufcount >= 4);
-                        bsd = lustre_msg_buf(req->rq_reqbuf,
-                                             req->rq_reqbuf->lm_bufcount - 2,
-                                             sizeof(*bsd));
+                        LASSERT(grctx->src_reqbsd);
 
+                        bsd_off = bufcnt;
                         buflens[bufcnt] = bulk_sec_desc_size(
-                                                        bsd->bsd_csum_alg, 0,
-                                                        req->rq_bulk_read);
-                        txtsize += buflens[bufcnt];
+                                                grctx->src_reqbsd->bsd_csum_alg,
+                                                0, req->rq_bulk_read);
+                        if (svc == SPTLRPC_SVC_INTG)
+                                txtsize += buflens[bufcnt];
                         bufcnt++;
                 }
-                buflens[bufcnt++] = gss_svc_payload(grctx, txtsize, 0);
+
+                if (gss_svc_reqctx_is_special(grctx) ||
+                    svc != SPTLRPC_SVC_NULL)
+                        buflens[bufcnt++] = gss_svc_payload(grctx, txtsize, 0);
         }
 
         wmsg_size = lustre_msg_size_v2(bufcnt, buflens);
@@ -2261,6 +2417,7 @@ int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
         rs->rs_repbuf = (struct lustre_msg *) (rs + 1);
         rs->rs_repbuf_len = wmsg_size;
 
+        /* initialize the buffer */
         if (privacy) {
                 lustre_init_msg_v2(rs->rs_repbuf, ibufcnt, ibuflens, NULL);
                 rs->rs_msg = lustre_msg_buf(rs->rs_repbuf, 0, msglen);
@@ -2268,8 +2425,13 @@ int gss_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
                 lustre_init_msg_v2(rs->rs_repbuf, bufcnt, buflens, NULL);
                 rs->rs_repbuf->lm_secflvr = req->rq_sec_flavor;
 
-                rs->rs_msg = (struct lustre_msg *)
-                                lustre_msg_buf(rs->rs_repbuf, 1, 0);
+                rs->rs_msg = lustre_msg_buf(rs->rs_repbuf, 1, 0);
+        }
+
+        if (bsd_off) {
+                grctx->src_repbsd = lustre_msg_buf(rs->rs_repbuf, bsd_off, 0);
+                grctx->src_repbsd_size = lustre_msg_buflen(rs->rs_repbuf,
+                                                           bsd_off);
         }
 
         gss_svc_reqctx_addref(grctx);
@@ -2323,6 +2485,13 @@ int gss_svc_seal(struct ptlrpc_request *req,
         }
         LASSERT(cipher_obj.len <= cipher_buflen);
 
+        /*
+         * we are about to override data at rs->rs_repbuf, nullify pointers
+         * to which to catch further illegal usage.
+         */
+        grctx->src_repbsd = NULL;
+        grctx->src_repbsd_size = 0;
+
         /* now the real wire data */
         buflens[0] = PTLRPC_GSS_HEADER_SIZE;
         buflens[1] = gss_estimate_payload(gctx->gsc_mechctx, buflens[0], 0);
@@ -2338,7 +2507,7 @@ int gss_svc_seal(struct ptlrpc_request *req,
         ghdr->gh_flags = 0;
         ghdr->gh_proc = PTLRPC_GSS_PROC_DATA;
         ghdr->gh_seq = grctx->src_wirectx.gw_seq;
-        ghdr->gh_svc = PTLRPC_GSS_SVC_PRIVACY;
+        ghdr->gh_svc = SPTLRPC_SVC_PRIV;
         ghdr->gh_handle.len = 0;
 
         /* header signature */
@@ -2393,10 +2562,12 @@ int gss_svc_authorize(struct ptlrpc_request *req)
         LASSERT(grctx->src_ctx);
 
         switch (gw->gw_svc) {
-        case  PTLRPC_GSS_SVC_INTEGRITY:
-                rc = gss_svc_sign(req, rs, grctx);
+        case SPTLRPC_SVC_NULL:
+        case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
+                rc = gss_svc_sign(req, rs, grctx, gw->gw_svc);
                 break;
-        case  PTLRPC_GSS_SVC_PRIVACY:
+        case SPTLRPC_SVC_PRIV:
                 rc = gss_svc_seal(req, rs, grctx);
                 break;
         default:
@@ -2416,6 +2587,10 @@ void gss_svc_free_rs(struct ptlrpc_reply_state *rs)
         LASSERT(rs->rs_svc_ctx);
         grctx = container_of(rs->rs_svc_ctx, struct gss_svc_reqctx, src_base);
 
+        /* paranoid, maybe not necessary */
+        grctx->src_reqbsd = NULL;
+        grctx->src_repbsd = NULL;
+
         gss_svc_reqctx_decref(grctx);
         rs->rs_svc_ctx = NULL;
 
diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c
index 0c7eff2392..409bb67061 100644
--- a/lustre/ptlrpc/import.c
+++ b/lustre/ptlrpc/import.c
@@ -561,10 +561,6 @@ static int ptlrpc_connect_interpret(struct ptlrpc_request *request,
         }
         spin_unlock(&imp->imp_lock);
 
-        if (rc)
-                GOTO(out, rc);
-
-        rc = sptlrpc_cli_install_rvs_ctx(imp, request->rq_cli_ctx);
         if (rc)
                 GOTO(out, rc);
 
diff --git a/lustre/ptlrpc/ptlrpc_internal.h b/lustre/ptlrpc/ptlrpc_internal.h
index c2610aae9b..cc1bf806be 100644
--- a/lustre/ptlrpc/ptlrpc_internal.h
+++ b/lustre/ptlrpc/ptlrpc_internal.h
@@ -197,8 +197,6 @@ int  sptlrpc_lproc_init(void);
 void sptlrpc_lproc_fini(void);
 
 /* sec_gc.c */
-void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec);
-void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec);
 int sptlrpc_gc_start_thread(void);
 void sptlrpc_gc_stop_thread(void);
 
diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c
index 76b40c5948..7511b94c51 100644
--- a/lustre/ptlrpc/sec.c
+++ b/lustre/ptlrpc/sec.c
@@ -152,8 +152,8 @@ ptlrpc_sec_flavor_t sptlrpc_name2flavor(const char *name)
                 return SPTLRPC_FLVR_NULL;
         if (!strcmp(name, "plain"))
                 return SPTLRPC_FLVR_PLAIN;
-        if (!strcmp(name, "krb5"))
-                return SPTLRPC_FLVR_KRB5;
+        if (!strcmp(name, "krb5n"))
+                return SPTLRPC_FLVR_KRB5N;
         if (!strcmp(name, "krb5i"))
                 return SPTLRPC_FLVR_KRB5I;
         if (!strcmp(name, "krb5p"))
@@ -170,15 +170,17 @@ char *sptlrpc_flavor2name(ptlrpc_sec_flavor_t flavor)
                 return "null";
         case SPTLRPC_FLVR_PLAIN:
                 return "plain";
-        case SPTLRPC_FLVR_KRB5:
-                return "krb5";
+        case SPTLRPC_FLVR_KRB5N:
+                return "krb5n";
+        case SPTLRPC_FLVR_KRB5A:
+                return "krb5a";
         case SPTLRPC_FLVR_KRB5I:
                 return "krb5i";
         case SPTLRPC_FLVR_KRB5P:
                 return "krb5p";
         default:
                 CERROR("invalid flavor 0x%x(p%u,s%u,v%u)\n", flavor,
-                       SEC_FLAVOR_POLICY(flavor), SEC_FLAVOR_SUBPOLICY(flavor),
+                       SEC_FLAVOR_POLICY(flavor), SEC_FLAVOR_MECH(flavor),
                        SEC_FLAVOR_SVC(flavor));
         }
         return "UNKNOWN";
@@ -294,7 +296,11 @@ int sptlrpc_req_get_ctx(struct ptlrpc_request *req)
         RETURN(0);
 }
 
-void sptlrpc_req_put_ctx(struct ptlrpc_request *req)
+/*
+ * if @sync == 0, this function should return quickly without sleep;
+ * otherwise might trigger ctx destroying rpc to server.
+ */
+void sptlrpc_req_put_ctx(struct ptlrpc_request *req, int sync)
 {
         ENTRY;
 
@@ -310,8 +316,7 @@ void sptlrpc_req_put_ctx(struct ptlrpc_request *req)
                 spin_unlock(&req->rq_cli_ctx->cc_lock);
         }
 
-        /* this could be called with spinlock hold, use async mode */
-        sptlrpc_cli_ctx_put(req->rq_cli_ctx, 0);
+        sptlrpc_cli_ctx_put(req->rq_cli_ctx, sync);
         req->rq_cli_ctx = NULL;
         EXIT;
 }
@@ -335,7 +340,7 @@ int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req)
         spin_unlock(&ctx->cc_lock);
 
         sptlrpc_cli_ctx_get(ctx);
-        sptlrpc_req_put_ctx(req);
+        sptlrpc_req_put_ctx(req, 0);
         rc = sptlrpc_req_get_ctx(req);
         if (!rc) {
                 LASSERT(req->rq_cli_ctx);
@@ -380,7 +385,11 @@ int ctx_refresh_timeout(void *data)
 static
 void ctx_refresh_interrupt(void *data)
 {
-        /* do nothing */
+        struct ptlrpc_request *req = data;
+
+        spin_lock(&req->rq_lock);
+        req->rq_intr = 1;
+        spin_unlock(&req->rq_lock);
 }
 
 static
@@ -413,10 +422,6 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
 
         LASSERT(ctx);
 
-        /* skip reverse ctxs */
-        if (ctx->cc_sec->ps_flags & PTLRPC_SEC_FL_REVERSE)
-                RETURN(0);
-
         /* skip special ctxs */
         if (cli_ctx_is_eternal(ctx) || req->rq_ctx_init || req->rq_ctx_fini)
                 RETURN(0);
@@ -428,6 +433,12 @@ int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
         LASSERT(test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags) == 0);
 
 again:
+        LASSERT(ctx->cc_ops->validate);
+        if (ctx->cc_ops->validate(ctx) == 0) {
+                req_off_ctx_list(req, ctx);
+                RETURN(0);
+        }
+
         if (unlikely(test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags))) {
                 req->rq_err = 1;
                 req_off_ctx_list(req, ctx);
@@ -498,12 +509,6 @@ again:
                 goto again;
         }
 
-        LASSERT(ctx->cc_ops->validate);
-        if (ctx->cc_ops->validate(ctx) == 0) {
-                req_off_ctx_list(req, ctx);
-                RETURN(0);
-        }
-
         /* Now we're sure this context is during upcall, add myself into
          * waiting list
          */
@@ -525,8 +530,8 @@ again:
         req->rq_restart = 0;
         spin_unlock(&req->rq_lock);
 
-        lwi = LWI_TIMEOUT_INTR(timeout == 0 ? LONG_MAX : timeout * HZ,
-                               ctx_refresh_timeout, ctx_refresh_interrupt, req);
+        lwi = LWI_TIMEOUT_INTR(timeout * HZ, ctx_refresh_timeout,
+                               ctx_refresh_interrupt, req);
         rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
 
         /* five cases we are here:
@@ -575,19 +580,19 @@ void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode)
 
         req->rq_sec_flavor = req->rq_cli_ctx->cc_sec->ps_flavor;
 
-        /* force SVC_NONE for context initiation rpc, SVC_AUTH for context
+        /* force SVC_NULL for context initiation rpc, SVC_INTG for context
          * destruction rpc
          */
         if (unlikely(req->rq_ctx_init)) {
                 req->rq_sec_flavor = SEC_MAKE_RPC_FLAVOR(
                                 SEC_FLAVOR_POLICY(req->rq_sec_flavor),
-                                SEC_FLAVOR_SUBPOLICY(req->rq_sec_flavor),
-                                SEC_FLAVOR_SVC(SPTLRPC_SVC_NONE));
+                                SEC_FLAVOR_MECH(req->rq_sec_flavor),
+                                SPTLRPC_SVC_NULL);
         } else if (unlikely(req->rq_ctx_fini)) {
                 req->rq_sec_flavor = SEC_MAKE_RPC_FLAVOR(
                                 SEC_FLAVOR_POLICY(req->rq_sec_flavor),
-                                SEC_FLAVOR_SUBPOLICY(req->rq_sec_flavor),
-                                SEC_FLAVOR_SVC(SPTLRPC_SVC_AUTH));
+                                SEC_FLAVOR_MECH(req->rq_sec_flavor),
+                                SPTLRPC_SVC_INTG);
         }
 
         conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
@@ -650,7 +655,7 @@ int sptlrpc_import_check_ctx(struct obd_import *imp)
 
         spin_lock_init(&req->rq_lock);
         atomic_set(&req->rq_refcount, 10000);
-        INIT_LIST_HEAD(&req->rq_ctx_chain);
+        CFS_INIT_LIST_HEAD(&req->rq_ctx_chain);
         init_waitqueue_head(&req->rq_reply_waitq);
         req->rq_import = imp;
         req->rq_cli_ctx = ctx;
@@ -683,8 +688,9 @@ int sptlrpc_cli_wrap_request(struct ptlrpc_request *req)
         }
 
         switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
-        case SPTLRPC_SVC_NONE:
+        case SPTLRPC_SVC_NULL:
         case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
                 LASSERT(ctx->cc_ops->sign);
                 rc = ctx->cc_ops->sign(ctx, req);
                 break;
@@ -759,8 +765,9 @@ int sptlrpc_cli_unwrap_reply(struct ptlrpc_request *req)
         }
 
         switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
-        case SPTLRPC_SVC_NONE:
+        case SPTLRPC_SVC_NULL:
         case SPTLRPC_SVC_AUTH:
+        case SPTLRPC_SVC_INTG:
                 LASSERT(ctx->cc_ops->verify);
                 rc = ctx->cc_ops->verify(ctx, req);
                 break;
@@ -789,7 +796,7 @@ void sec_cop_destroy_sec(struct ptlrpc_sec *sec)
         LASSERT(atomic_read(&sec->ps_busy) == 0);
         LASSERT(policy->sp_cops->destroy_sec);
 
-        CWARN("%s@%p: being destroied\n", sec->ps_policy->sp_name, sec);
+        CDEBUG(D_SEC, "%s@%p: being destroied\n", sec->ps_policy->sp_name, sec);
 
         policy->sp_cops->destroy_sec(sec);
         sptlrpc_policy_put(policy);
@@ -902,22 +909,20 @@ void sptlrpc_import_put_sec(struct obd_import *imp)
         sec = imp->imp_sec;
         policy = sec->ps_policy;
 
-        if (!atomic_dec_and_test(&sec->ps_refcount)) {
-                sptlrpc_policy_put(policy);
-                goto out;
-        }
+        if (atomic_dec_and_test(&sec->ps_refcount)) {
+                sec_cop_flush_ctx_cache(sec, -1, 1, 1);
+                sptlrpc_gc_del_sec(sec);
 
-        sec_cop_flush_ctx_cache(sec, -1, 1, 1);
-        sptlrpc_gc_del_sec(sec);
-
-        if (atomic_dec_and_test(&sec->ps_busy))
-                sec_cop_destroy_sec(sec);
-        else {
-                CWARN("delay to destroy %s@%p: busy contexts\n",
-                      policy->sp_name, sec);
+                if (atomic_dec_and_test(&sec->ps_busy))
+                        sec_cop_destroy_sec(sec);
+                else {
+                        CWARN("delay destroying busy sec %s %p\n",
+                              policy->sp_name, sec);
+                }
+        } else {
+                sptlrpc_policy_put(policy);
         }
 
-out:
         imp->imp_sec = NULL;
 }
 
@@ -946,7 +951,7 @@ void sptlrpc_import_flush_all_ctx(struct obd_import *imp)
         if (imp == NULL || imp->imp_sec == NULL)
                 return;
 
-        sec_cop_flush_ctx_cache(imp->imp_sec, -1, 0, 1);
+        sec_cop_flush_ctx_cache(imp->imp_sec, -1, 1, 1);
 }
 EXPORT_SYMBOL(sptlrpc_import_flush_all_ctx);
 
@@ -1127,6 +1132,21 @@ int sptlrpc_svc_install_rvs_ctx(struct obd_import *imp,
  * server side security                 *
  ****************************************/
 
+int sptlrpc_target_export_check(struct obd_export *exp,
+                                struct ptlrpc_request *req)
+{
+        if (!req->rq_auth_gss ||
+            (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt))
+                return 0;
+
+        if (!req->rq_ctx_init)
+                return 0;
+
+        LASSERT(exp->exp_imp_reverse);
+        sptlrpc_svc_install_rvs_ctx(exp->exp_imp_reverse, req->rq_svc_ctx);
+        return 0;
+}
+
 int sptlrpc_svc_unwrap_request(struct ptlrpc_request *req)
 {
         struct ptlrpc_sec_policy *policy;
@@ -1555,6 +1575,8 @@ void get_flavor_by_rpc(__u32 rpc_flavor, struct sec_flavor_config *conf)
         switch (rpc_flavor) {
         case SPTLRPC_FLVR_NULL:
         case SPTLRPC_FLVR_PLAIN:
+        case SPTLRPC_FLVR_KRB5N:
+        case SPTLRPC_FLVR_KRB5A:
                 break;
         case SPTLRPC_FLVR_KRB5P:
                 conf->sfc_bulk_priv = BULK_PRIV_ALG_ARC4;
@@ -1580,6 +1602,8 @@ void get_flavor_by_rpc_bulk(__u32 rpc_flavor, int bulk_priv,
         case SPTLRPC_FLVR_PLAIN:
                 conf->sfc_bulk_csum = BULK_CSUM_ALG_MD5;
                 break;
+        case SPTLRPC_FLVR_KRB5N:
+        case SPTLRPC_FLVR_KRB5A:
         case SPTLRPC_FLVR_KRB5I:
         case SPTLRPC_FLVR_KRB5P:
                 conf->sfc_bulk_csum = BULK_CSUM_ALG_SHA1;
@@ -1592,6 +1616,8 @@ void get_flavor_by_rpc_bulk(__u32 rpc_flavor, int bulk_priv,
 static __u32 __flavors[] = {
         SPTLRPC_FLVR_NULL,
         SPTLRPC_FLVR_PLAIN,
+        SPTLRPC_FLVR_KRB5N,
+        SPTLRPC_FLVR_KRB5A,
         SPTLRPC_FLVR_KRB5I,
         SPTLRPC_FLVR_KRB5P,
 };
@@ -1740,7 +1766,7 @@ const char * sec2target_str(struct ptlrpc_sec *sec)
 {
         if (!sec || !sec->ps_import || !sec->ps_import->imp_obd)
                 return "*";
-        if (sec->ps_flags & PTLRPC_SEC_FL_REVERSE)
+        if (sec_is_reverse(sec))
                 return "c";
         return obd_uuid2str(&sec->ps_import->imp_obd->u.cli.cl_target_uuid);
 }
diff --git a/lustre/ptlrpc/sec_bulk.c b/lustre/ptlrpc/sec_bulk.c
index c13650a584..ac281c9831 100644
--- a/lustre/ptlrpc/sec_bulk.c
+++ b/lustre/ptlrpc/sec_bulk.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -959,16 +960,10 @@ int bulk_csum_cli_reply(struct ptlrpc_bulk_desc *desc, int read,
 EXPORT_SYMBOL(bulk_csum_cli_reply);
 
 int bulk_csum_svc(struct ptlrpc_bulk_desc *desc, int read,
-                  struct lustre_msg *vmsg, int voff,
-                  struct lustre_msg *rmsg, int roff)
+                  struct ptlrpc_bulk_sec_desc *bsdv, int vsize,
+                  struct ptlrpc_bulk_sec_desc *bsdr, int rsize)
 {
-        struct ptlrpc_bulk_sec_desc *bsdv, *bsdr;
-        int    vsize, rsize, rc;
-
-        vsize = vmsg->lm_buflens[voff];
-        rsize = rmsg->lm_buflens[roff];
-        bsdv = lustre_msg_buf(vmsg, voff, 0);
-        bsdr = lustre_msg_buf(rmsg, roff, 0);
+        int    rc;
 
         LASSERT(vsize >= sizeof(*bsdv));
         LASSERT(rsize >= sizeof(*bsdr));
diff --git a/lustre/ptlrpc/sec_gc.c b/lustre/ptlrpc/sec_gc.c
index f99c0a44bc..296b8ebefc 100644
--- a/lustre/ptlrpc/sec_gc.c
+++ b/lustre/ptlrpc/sec_gc.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2007 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -38,15 +39,18 @@
 #ifdef __KERNEL__
 
 static DECLARE_MUTEX(sec_gc_mutex);
-static LIST_HEAD(sec_gc_list);
+static CFS_LIST_HEAD(sec_gc_list);
 static spinlock_t sec_gc_list_lock = SPIN_LOCK_UNLOCKED;
 
+static CFS_LIST_HEAD(sec_gc_ctx_list);
+static spinlock_t sec_gc_ctx_list_lock = SPIN_LOCK_UNLOCKED;
+
 static struct ptlrpc_thread sec_gc_thread;
 static atomic_t sec_gc_wait_del = ATOMIC_INIT(0);
 
+
 void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec)
 {
-        CWARN("add sec %p(%s)\n", sec, sec->ps_policy->sp_name);
         if (!list_empty(&sec->ps_gc_list)) {
                 CERROR("sec %p(%s) already in gc list\n",
                        sec, sec->ps_policy->sp_name);
@@ -56,11 +60,13 @@ void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec)
         spin_lock(&sec_gc_list_lock);
         list_add_tail(&sec_gc_list, &sec->ps_gc_list);
         spin_unlock(&sec_gc_list_lock);
+
+        CDEBUG(D_SEC, "added sec %p(%s)\n", sec, sec->ps_policy->sp_name);
 }
+EXPORT_SYMBOL(sptlrpc_gc_add_sec);
 
 void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec)
 {
-        CWARN("del sec %p(%s)\n", sec, sec->ps_policy->sp_name);
         if (list_empty(&sec->ps_gc_list))
                 return;
 
@@ -75,6 +81,47 @@ void sptlrpc_gc_del_sec(struct ptlrpc_sec *sec)
         mutex_down(&sec_gc_mutex);
         mutex_up(&sec_gc_mutex);
         atomic_dec(&sec_gc_wait_del);
+
+        CDEBUG(D_SEC, "del sec %p(%s)\n", sec, sec->ps_policy->sp_name);
+}
+EXPORT_SYMBOL(sptlrpc_gc_del_sec);
+
+void sptlrpc_gc_add_ctx(struct ptlrpc_cli_ctx *ctx)
+{
+        LASSERT(list_empty(&ctx->cc_gc_chain));
+
+        CDEBUG(D_SEC, "hand over ctx %p(%u->%s)\n",
+               ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+        spin_lock(&sec_gc_ctx_list_lock);
+        list_add(&ctx->cc_gc_chain, &sec_gc_ctx_list);
+        spin_unlock(&sec_gc_ctx_list_lock);
+
+        sec_gc_thread.t_flags |= SVC_SIGNAL;
+        cfs_waitq_signal(&sec_gc_thread.t_ctl_waitq);
+}
+EXPORT_SYMBOL(sptlrpc_gc_add_ctx);
+
+static void sec_process_ctx_list(void)
+{
+        struct ptlrpc_cli_ctx *ctx;
+
+again:
+        spin_lock(&sec_gc_ctx_list_lock);
+        if (!list_empty(&sec_gc_ctx_list)) {
+                ctx = list_entry(sec_gc_ctx_list.next,
+                                 struct ptlrpc_cli_ctx, cc_gc_chain);
+                list_del_init(&ctx->cc_gc_chain);
+                spin_unlock(&sec_gc_ctx_list_lock);
+
+                LASSERT(ctx->cc_sec);
+                LASSERT(atomic_read(&ctx->cc_refcount) == 1);
+                CDEBUG(D_SEC, "gc pick up ctx %p(%u->%s)\n",
+                       ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec));
+                sptlrpc_cli_ctx_put(ctx, 1);
+
+                goto again;
+        }
+        spin_unlock(&sec_gc_ctx_list_lock);
 }
 
 static void sec_do_gc(struct ptlrpc_sec *sec)
@@ -93,7 +140,8 @@ static void sec_do_gc(struct ptlrpc_sec *sec)
                 return;
         }
 
-        CWARN("check on sec %p(%s)\n", sec, sec->ps_policy->sp_name);
+        CDEBUG(D_SEC, "check on sec %p(%s)\n", sec, sec->ps_policy->sp_name);
+
         if (time_after(sec->ps_gc_next, now))
                 return;
 
@@ -115,6 +163,8 @@ static int sec_gc_main(void *arg)
         while (1) {
                 struct ptlrpc_sec *sec, *next;
 
+                thread->t_flags &= ~SVC_SIGNAL;
+                sec_process_ctx_list();
 again:
                 mutex_down(&sec_gc_mutex);
                 list_for_each_entry_safe(sec, next, &sec_gc_list, ps_gc_list) {
@@ -134,7 +184,7 @@ again:
 
                 lwi = LWI_TIMEOUT(SEC_GC_INTERVAL * HZ, NULL, NULL);
                 l_wait_event(thread->t_ctl_waitq,
-                             thread->t_flags & SVC_STOPPING,
+                             thread->t_flags & (SVC_STOPPING | SVC_SIGNAL),
                              &lwi);
 
                 if (thread->t_flags & SVC_STOPPING) {
diff --git a/lustre/ptlrpc/sec_lproc.c b/lustre/ptlrpc/sec_lproc.c
index 0d1d57126c..df81d9c734 100644
--- a/lustre/ptlrpc/sec_lproc.c
+++ b/lustre/ptlrpc/sec_lproc.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -114,28 +115,6 @@ int sptlrpc_lprocfs_rd(char *page, char **start, off_t off, int count,
                 written += sec->ps_policy->sp_cops->display(
                                         sec, page + written, count - written);
         }
-#if 0
-        /*
-         * list contexts
-         */
-        if (sec->ps_policy->sp_policy != SPTLRPC_POLICY_GSS)
-                goto out;
-
-        written += snprintf(page + written, count - written,
-                            "GSS contexts ==>\n");
-
-        spin_lock(&sec->ps_lock);
-        for (i = 0; i < sec->ps_ccache_size; i++) {
-                hlist_for_each_entry_safe(ctx, pos, next,
-                                          &sec->ps_ccache[i], cc_hash) {
-                        if (written >= count)
-                                break;
-                        written += sptlrpc_cli_ctx_display(ctx, page + written,
-                                                           count - written);
-                }
-        }
-        spin_unlock(&sec->ps_lock);
-#endif
 
 out:
         return written;
diff --git a/lustre/ptlrpc/sec_null.c b/lustre/ptlrpc/sec_null.c
index 6d96c0141f..bee970bdfc 100644
--- a/lustre/ptlrpc/sec_null.c
+++ b/lustre/ptlrpc/sec_null.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2004-2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -335,7 +336,7 @@ void null_init_internal(void)
         null_sec.ps_gc_interval = 0;
         null_sec.ps_gc_next = 0;
 
-        hlist_add_head(&null_cli_ctx.cc_hash, &__list);
+        hlist_add_head(&null_cli_ctx.cc_cache, &__list);
         atomic_set(&null_cli_ctx.cc_refcount, 1);    /* for hash */
         null_cli_ctx.cc_sec = &null_sec;
         null_cli_ctx.cc_ops = &null_ctx_ops;
@@ -345,6 +346,7 @@ void null_init_internal(void)
         null_cli_ctx.cc_vcred.vc_uid = 0;
         spin_lock_init(&null_cli_ctx.cc_lock);
         INIT_LIST_HEAD(&null_cli_ctx.cc_req_list);
+        INIT_LIST_HEAD(&null_cli_ctx.cc_gc_chain);
 }
 
 int sptlrpc_null_init(void)
diff --git a/lustre/ptlrpc/sec_plain.c b/lustre/ptlrpc/sec_plain.c
index ee8746535e..e15a69eeb3 100644
--- a/lustre/ptlrpc/sec_plain.c
+++ b/lustre/ptlrpc/sec_plain.c
@@ -2,6 +2,7 @@
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
  * Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Eric Mei <ericm@clusterfs.com>
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -34,10 +35,15 @@
 #include <lustre_sec.h>
 
 static struct ptlrpc_sec_policy plain_policy;
+static struct ptlrpc_ctx_ops    plain_ctx_ops;
 static struct ptlrpc_sec        plain_sec;
 static struct ptlrpc_cli_ctx    plain_cli_ctx;
 static struct ptlrpc_svc_ctx    plain_svc_ctx;
 
+/****************************************
+ * cli_ctx apis                         *
+ ****************************************/
+
 static
 int plain_ctx_refresh(struct ptlrpc_cli_ctx *ctx)
 {
@@ -116,18 +122,9 @@ int plain_cli_unwrap_bulk(struct ptlrpc_cli_ctx *ctx,
                                    req->rq_repbuf->lm_bufcount - 1);
 }
 
-static struct ptlrpc_ctx_ops plain_ctx_ops = {
-        .refresh        = plain_ctx_refresh,
-        .sign           = plain_ctx_sign,
-        .verify         = plain_ctx_verify,
-        .wrap_bulk      = plain_cli_wrap_bulk,
-        .unwrap_bulk    = plain_cli_unwrap_bulk,
-};
-
-static struct ptlrpc_svc_ctx plain_svc_ctx = {
-        .sc_refcount    = ATOMIC_INIT(1),
-        .sc_policy      = &plain_policy,
-};
+/****************************************
+ * sec apis                             *
+ ****************************************/
 
 static
 struct ptlrpc_sec* plain_create_sec(struct obd_import *imp,
@@ -322,6 +319,15 @@ int plain_enlarge_reqbuf(struct ptlrpc_sec *sec,
         RETURN(0);
 }
 
+/****************************************
+ * service apis                         *
+ ****************************************/
+
+static struct ptlrpc_svc_ctx plain_svc_ctx = {
+        .sc_refcount    = ATOMIC_INIT(1),
+        .sc_policy      = &plain_policy,
+};
+
 static
 int plain_accept(struct ptlrpc_request *req)
 {
@@ -460,28 +466,48 @@ static
 int plain_svc_unwrap_bulk(struct ptlrpc_request *req,
                           struct ptlrpc_bulk_desc *desc)
 {
-        struct ptlrpc_reply_state *rs = req->rq_reply_state;
+        struct ptlrpc_reply_state      *rs = req->rq_reply_state;
+        int                             voff, roff;
 
         LASSERT(rs);
 
+        voff = req->rq_reqbuf->lm_bufcount - 1;
+        roff = rs->rs_repbuf->lm_bufcount - 1;
+
         return bulk_csum_svc(desc, req->rq_bulk_read,
-                             req->rq_reqbuf, req->rq_reqbuf->lm_bufcount - 1,
-                             rs->rs_repbuf, rs->rs_repbuf->lm_bufcount - 1);
+                             lustre_msg_buf(req->rq_reqbuf, voff, 0),
+                             lustre_msg_buflen(req->rq_reqbuf, voff),
+                             lustre_msg_buf(rs->rs_repbuf, roff, 0),
+                             lustre_msg_buflen(rs->rs_repbuf, roff));
 }
 
 static
 int plain_svc_wrap_bulk(struct ptlrpc_request *req,
                         struct ptlrpc_bulk_desc *desc)
 {
-        struct ptlrpc_reply_state *rs = req->rq_reply_state;
+        struct ptlrpc_reply_state      *rs = req->rq_reply_state;
+        int                             voff, roff;
 
         LASSERT(rs);
 
+        voff = req->rq_reqbuf->lm_bufcount - 1;
+        roff = rs->rs_repbuf->lm_bufcount - 1;
+
         return bulk_csum_svc(desc, req->rq_bulk_read,
-                             req->rq_reqbuf, req->rq_reqbuf->lm_bufcount - 1,
-                             rs->rs_repbuf, rs->rs_repbuf->lm_bufcount - 1);
+                             lustre_msg_buf(req->rq_reqbuf, voff, 0),
+                             lustre_msg_buflen(req->rq_reqbuf, voff),
+                             lustre_msg_buf(rs->rs_repbuf, roff, 0),
+                             lustre_msg_buflen(rs->rs_repbuf, roff));
 }
 
+static struct ptlrpc_ctx_ops plain_ctx_ops = {
+        .refresh                = plain_ctx_refresh,
+        .sign                   = plain_ctx_sign,
+        .verify                 = plain_ctx_verify,
+        .wrap_bulk              = plain_cli_wrap_bulk,
+        .unwrap_bulk            = plain_cli_unwrap_bulk,
+};
+
 static struct ptlrpc_sec_cops plain_sec_cops = {
         .create_sec             = plain_create_sec,
         .destroy_sec            = plain_destroy_sec,
@@ -523,11 +549,11 @@ void plain_init_internal(void)
         plain_sec.ps_flags = 0;
         spin_lock_init(&plain_sec.ps_lock);
         atomic_set(&plain_sec.ps_busy, 1);         /* for "plain_cli_ctx" */
-        INIT_LIST_HEAD(&plain_sec.ps_gc_list);
+        CFS_INIT_LIST_HEAD(&plain_sec.ps_gc_list);
         plain_sec.ps_gc_interval = 0;
         plain_sec.ps_gc_next = 0;
 
-        hlist_add_head(&plain_cli_ctx.cc_hash, &__list);
+        hlist_add_head(&plain_cli_ctx.cc_cache, &__list);
         atomic_set(&plain_cli_ctx.cc_refcount, 1);    /* for hash */
         plain_cli_ctx.cc_sec = &plain_sec;
         plain_cli_ctx.cc_ops = &plain_ctx_ops;
@@ -536,7 +562,8 @@ void plain_init_internal(void)
                                  PTLRPC_CTX_UPTODATE;
         plain_cli_ctx.cc_vcred.vc_uid = 0;
         spin_lock_init(&plain_cli_ctx.cc_lock);
-        INIT_LIST_HEAD(&plain_cli_ctx.cc_req_list);
+        CFS_INIT_LIST_HEAD(&plain_cli_ctx.cc_req_list);
+        CFS_INIT_LIST_HEAD(&plain_cli_ctx.cc_gc_chain);
 }
 
 int sptlrpc_plain_init(void)
diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c
index c81fbc45ea..feb542b8a8 100644
--- a/lustre/ptlrpc/service.c
+++ b/lustre/ptlrpc/service.c
@@ -671,6 +671,14 @@ ptlrpc_server_handle_request(struct ptlrpc_service *svc,
                         ptlrpc_error(request);
                         goto put_conn;
                 }
+
+                rc = sptlrpc_target_export_check(request->rq_export, request);
+                if (unlikely(rc)) {
+                        DEBUG_REQ(D_ERROR, request,
+                                  "DROPPING req with illeagle security flavor");
+                        goto put_conn;
+                }
+
                 ptlrpc_update_export_timer(request->rq_export, timediff/500000);
                 export = class_export_rpc_get(request->rq_export);
         }
diff --git a/lustre/tests/disk1_4.zip b/lustre/tests/disk1_4.zip
index 0970c8309df5ec7211f7afc0b23b5e40527c8622..c5773e703135e94827f06922b91c478531328206 100644
GIT binary patch
literal 170785
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
a%$_O?ey?KSAinwm^lu++_n#R+_x}ZOjtn>e

literal 216468
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

diff --git a/lustre/tests/insanity.sh b/lustre/tests/insanity.sh
index 6e37027961..54ae83a70e 100755
--- a/lustre/tests/insanity.sh
+++ b/lustre/tests/insanity.sh
@@ -265,6 +265,7 @@ test_3() {
     reintegrate_clients || return 1
 
     client_df || return 3
+    sleep 2 # give it a little time for fully recovered before next test
 }
 run_test 3  "Thirdb Failure Mode: MDS/CLIENT `date`"
 ###################################################
diff --git a/lustre/tests/recovery-small.sh b/lustre/tests/recovery-small.sh
index e26dcd28f2..fbcc420938 100755
--- a/lustre/tests/recovery-small.sh
+++ b/lustre/tests/recovery-small.sh
@@ -581,6 +581,7 @@ run_test 26 "evict dead exports"
 test_26b() {      # bug 10140 - evict dead exports by pinger
 	client_df
         zconf_mount `hostname` $MOUNT2 || error "Failed to mount $MOUNT2"
+        sleep 1 # wait connections being established
 	MDS_FILE=$LPROC/mdt/${mds1_svc}/num_exports
         MDS_NEXP1="`do_facet $SINGLEMDS cat $MDS_FILE | cut -d' ' -f2`"
 	OST_FILE=$LPROC/obdfilter/${ost1_svc}/num_exports
diff --git a/lustre/tests/sanity-gss.sh b/lustre/tests/sanity-gss.sh
index d52cc1ff9f..4e3111aca4 100644
--- a/lustre/tests/sanity-gss.sh
+++ b/lustre/tests/sanity-gss.sh
@@ -61,22 +61,23 @@ export NAME=${NAME:-local}
 
 SAVE_PWD=$PWD
 
-#
-# check pre-set $SEC
-#
-if [ ! -z $SEC ]; then
-    if [ "$SEC" != "krb5i" -a "$SEC" != "krb5p" ]; then
-        echo "SEC=$SEC is invalid, this script only run in gss mode (krb5i/krb5p)"
-        exit 1
-    fi
-fi
-
 export SEC=${SEC:-krb5p}
 export KRB5_CCACHE_DIR=/tmp
 export KRB5_CRED=$KRB5_CCACHE_DIR/krb5cc_$RUNAS_ID
 export KRB5_CRED_SAVE=$KRB5_CCACHE_DIR/krb5cc.sanity.save
 
-echo "Using security flavor $SEC"
+#
+# check pre-set $SEC
+#
+case "x$SEC" in
+    xkrb5*)
+        echo "Using ptlrpc security flavor $SEC"
+        ;;
+    *)
+        echo "SEC=$SEC is invalid, it has to be gss/krb5 flavor"
+        exit 1
+        ;;
+esac
 
 LUSTRE=${LUSTRE:-`dirname $0`/..}
 . $LUSTRE/tests/test-framework.sh
@@ -164,7 +165,7 @@ test_2() {
 
     # cleanup all cred/ctx and touch
     $RUNAS kdestroy
-    $RUNAS $LFS flushctx
+    $RUNAS $LFS flushctx || error "can't flush ctx"
     $RUNAS touch $MOUNT/f2_2 && error "unexpected success"
 
     # restore and touch
@@ -247,7 +248,7 @@ run_test 4 "lgssd dead, operations should wait timeout and fail"
 test_5() {
     local file1=$MOUNT/f5_1
     local file2=$MOUNT/f5_2
-    local wait_time=120
+    local wait_time=`expr $TIMEOUT + $TIMEOUT`
 
     # current access should be ok
     $RUNAS touch $file1 || error "can't touch $file1"
diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh
index b20c986435..b2f195051f 100644
--- a/lustre/tests/sanity-sec.sh
+++ b/lustre/tests/sanity-sec.sh
@@ -68,7 +68,7 @@ LUSTRE=${LUSTRE:-`dirname $0`/..}
 init_test_env $@
 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
 
-if [ ! -z "$USING_KRB5" ]; then
+if $GSS_KRB5; then
     $RUNAS -u $ID1 krb5_login.sh || exit 1
     $RUNAS -u $ID2 krb5_login.sh || exit 1
 fi
diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh
index f4afe9fe43..96a5ca8cd9 100644
--- a/lustre/tests/sanity.sh
+++ b/lustre/tests/sanity.sh
@@ -90,7 +90,7 @@ LUSTRE=${LUSTRE:-`dirname $0`/..}
 init_test_env $@
 . ${CONFIG:=$LUSTRE/tests/cfg/local.sh}
 
-if [ ! -z "$USING_KRB5" ]; then
+if $GSS_KRB5; then
     $RUNAS krb5_login.sh || exit 1
     $RUNAS -u $(($RUNAS_ID + 1)) krb5_login.sh || exit 1
 fi
@@ -2839,8 +2839,7 @@ run_test 68 "support swapping to Lustre ========================"
 test_69() {
 	[ $(grep -c obdfilter $LPROC/devices) -eq 0 ] && \
 		skip "skipping test for remote OST" && return
-	[ ! -z "$USING_KRB5" ] && \
-		skip "gss with bulk security will triger oops. re-enable this after b10091 get fixed" && return
+	$GSS && skip "gss with bulk security will triger oops. re-enable this after b10091 get fixed" && return
 
 	f="$DIR/$tfile"
 	touch $f
@@ -3716,7 +3715,7 @@ test_103 () {
     [ "$UID" != 0 ] && skip "must run as root" && return
     [ -z "$(grep acl $LPROC/mdc/*-mdc-*/connect_flags)" ] && skip "must have acl enabled" && return
     [ -z "$(which setfacl 2>/dev/null)" ] && skip "could not find setfacl" && return
-    [ ! -z "$USING_KRB5" ] && skip "could not run under gss" && return
+    $GSS && skip "could not run under gss" && return
 
     SAVE_UMASK=`umask`
     umask 0022
diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh
index beeeba3823..56982f3765 100644
--- a/lustre/tests/sanityN.sh
+++ b/lustre/tests/sanityN.sh
@@ -56,7 +56,7 @@ init_test_env $@
 SANITYLOG=${TESTSUITELOG:-$TMP/$(basename $0 .sh).log}
 FAIL_ON_ERROR=false
 
-if [ ! -z "$USING_KRB5" ]; then
+if $GSS_KRB5; then
     $RUNAS krb5_login.sh || exit 1
 fi
 
diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh
index 8141bb0ea1..a77b2317ba 100644
--- a/lustre/tests/test-framework.sh
+++ b/lustre/tests/test-framework.sh
@@ -10,6 +10,9 @@ export REFORMAT=${REFORMAT:-""}
 export VERBOSE=false
 export GMNALNID=${GMNALNID:-/usr/sbin/gmlndnid}
 export CATASTROPHE=${CATASTROPHE:-/proc/sys/lnet/catastrophe}
+export GSS=false
+export GSS_KRB5=false
+export GSS_PIPEFS=false
 #export PDSH="pdsh -S -Rssh -w"
 
 # eg, assert_env LUSTRE MDSNODES OSTNODES CLIENTS
@@ -66,7 +69,8 @@ init_test_env() {
     case "x$SEC" in
         xkrb5*)
             echo "Using GSS/krb5 ptlrpc security flavor"
-            export USING_KRB5="y"
+            GSS=true
+            GSS_KRB5=true
             ;;
     esac
 
@@ -105,7 +109,7 @@ load_module() {
         # must be testing a "make install" or "rpm" installation
         # note failed to load ptlrpc_gss is considered not fatal
         if [ "$BASE" == "ptlrpc_gss" ]; then
-            modprobe $BASE $@ || echo "gss/krb5 is not supported"
+            modprobe $BASE $@ 2>/dev/null || echo "gss/krb5 is not supported"
         else
             modprobe $BASE $@
         fi
@@ -250,7 +254,7 @@ start_gss_daemons() {
     # starting on MDT
     for num in `seq $MDSCOUNT`; do
         do_facet mds$num "$LSVCGSSD -v"
-        if [ "x$GSS_PIPEFS" == "xy" ]; then
+        if $GSS_PIPEFS; then
             do_facet mds$num "$LGSSD -v"
         fi
     done
@@ -260,7 +264,7 @@ start_gss_daemons() {
     done
     # starting on client
     # FIXME: is "client" the right facet name?
-    if [ "x$GSS_PIPEFS" == "xy" ]; then
+    if $GSS_PIPEFS; then
         do_facet client "$LGSSD -v"
     fi
 
@@ -272,14 +276,14 @@ start_gss_daemons() {
     #
     for num in `seq $MDSCOUNT`; do
         check_gss_daemon_facet mds$num lsvcgssd
-        if [ "x$GSS_PIPEFS" == "xy" ]; then
+        if $GSS_PIPEFS; then
             check_gss_daemon_facet mds$num lgssd
         fi
     done
     for num in `seq $OSTCOUNT`; do
         check_gss_daemon_facet ost$num lsvcgssd
     done
-    if [ "x$GSS_PIPEFS" == "xy" ]; then
+    if $GSS_PIPEFS; then
         check_gss_daemon_facet client lgssd
     fi
 }
@@ -300,13 +304,13 @@ init_krb5_env() {
         OST_MOUNT_OPTS=$OST_MOUNT_OPTS,sec=$SEC
     fi
 
-    if [ ! -z $USING_KRB5 ]; then
+    if $GSS; then
         start_gss_daemons
     fi
 }
 
 cleanup_krb5_env() {
-    if [ ! -z $USING_KRB5 ]; then
+    if $GSS; then
         stop_gss_daemons
         # maybe cleanup credential cache?
     fi
diff --git a/lustre/utils/gss/lgss_utils.c b/lustre/utils/gss/lgss_utils.c
index 1a3a941d9d..2f5f2738bc 100644
--- a/lustre/utils/gss/lgss_utils.c
+++ b/lustre/utils/gss/lgss_utils.c
@@ -221,7 +221,7 @@ gss_OID_desc spkm3oid =
  * log facilities                       *
  ****************************************/
 
-loglevel_t g_log_level = LL_INFO;
+loglevel_t g_log_level = LL_WARN;
 
 static const char *log_prefix[] = {
         [LL_ERR]        = "ERROR",
diff --git a/lustre/utils/gss/lsupport.c b/lustre/utils/gss/lsupport.c
index f20f208412..a5f01468ea 100644
--- a/lustre/utils/gss/lsupport.c
+++ b/lustre/utils/gss/lsupport.c
@@ -56,6 +56,12 @@
 #endif
 #include "lsupport.h"
 
+const char * lustre_svc_name[] = 
+{
+        [LUSTRE_GSS_SVC_MDS]    = "MDS",
+        [LUSTRE_GSS_SVC_OSS]    = "OSS",
+};
+
 /****************************************
  * exclusive startup                    *
  ****************************************/
diff --git a/lustre/utils/gss/lsupport.h b/lustre/utils/gss/lsupport.h
index 264021041c..673980411e 100644
--- a/lustre/utils/gss/lsupport.h
+++ b/lustre/utils/gss/lsupport.h
@@ -21,6 +21,8 @@ void gssd_exit_unique(int type);
 #define LUSTRE_GSS_SVC_MDS      0
 #define LUSTRE_GSS_SVC_OSS      1
 
+extern const char * lustre_svc_name[];
+
 struct lgssd_upcall_data {
         uint32_t        seq;
         uint32_t        uid;
diff --git a/lustre/utils/gss/nfs-utils-1.0.11-lustre.diff b/lustre/utils/gss/nfs-utils-1.0.11-lustre.diff
index 983de6b8fb..46efbcfa08 100644
--- a/lustre/utils/gss/nfs-utils-1.0.11-lustre.diff
+++ b/lustre/utils/gss/nfs-utils-1.0.11-lustre.diff
@@ -1,6 +1,6 @@
 diff -Nrup nfs-utils-1.0.11/configure.in nfs-utils-1.0.11.lustre/configure.in
 --- nfs-utils-1.0.11/configure.in	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/configure.in	2007-05-23 14:35:45.000000000 -0600
++++ nfs-utils-1.0.11.lustre/configure.in	2007-06-29 12:29:20.000000000 -0600
 @@ -18,61 +18,14 @@ AC_ARG_WITH(release,
  	RELEASE=$withval,
  	RELEASE=1)
@@ -193,7 +193,7 @@ diff -Nrup nfs-utils-1.0.11/configure.in nfs-utils-1.0.11.lustre/configure.in
  
 diff -Nrup nfs-utils-1.0.11/Makefile.am nfs-utils-1.0.11.lustre/Makefile.am
 --- nfs-utils-1.0.11/Makefile.am	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/Makefile.am	2007-05-23 14:35:45.000000000 -0600
++++ nfs-utils-1.0.11.lustre/Makefile.am	2007-06-29 12:29:20.000000000 -0600
 @@ -1,6 +1,6 @@
  ## Process this file with automake to produce Makefile.in
  
@@ -204,7 +204,7 @@ diff -Nrup nfs-utils-1.0.11/Makefile.am nfs-utils-1.0.11.lustre/Makefile.am
  
 diff -Nrup nfs-utils-1.0.11/utils/gssd/cacheio.c nfs-utils-1.0.11.lustre/utils/gssd/cacheio.c
 --- nfs-utils-1.0.11/utils/gssd/cacheio.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/cacheio.c	2007-05-23 14:36:28.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/cacheio.c	2007-06-29 12:32:27.000000000 -0600
 @@ -240,7 +240,8 @@ int qword_get(char **bpp, char *dest, in
  		return -1;
  	while (*bp == ' ') bp++;
@@ -217,7 +217,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/cacheio.c nfs-utils-1.0.11.lustre/utils/g
  
 diff -Nrup nfs-utils-1.0.11/utils/gssd/context.c nfs-utils-1.0.11.lustre/utils/gssd/context.c
 --- nfs-utils-1.0.11/utils/gssd/context.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/context.c	2007-05-23 14:36:29.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/context.c	2007-06-29 12:32:28.000000000 -0600
 @@ -33,11 +33,14 @@
  #include <syslog.h>
  #include <string.h>
@@ -239,8 +239,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/context.c nfs-utils-1.0.11.lustre/utils/g
  
  int
 diff -Nrup nfs-utils-1.0.11/utils/gssd/context.h nfs-utils-1.0.11.lustre/utils/gssd/context.h
---- nfs-utils-1.0.11/utils/gssd/context.h	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/context.h	2007-05-23 14:36:30.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/context.h	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/context.h	2007-06-29 12:32:29.000000000 -0600
 @@ -31,8 +31,6 @@
  #ifndef _CONTEXT_H_
  #define _CONTEXT_H_
@@ -252,7 +252,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/context.h nfs-utils-1.0.11.lustre/utils/g
  
 diff -Nrup nfs-utils-1.0.11/utils/gssd/context_heimdal.c nfs-utils-1.0.11.lustre/utils/gssd/context_heimdal.c
 --- nfs-utils-1.0.11/utils/gssd/context_heimdal.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/context_heimdal.c	2007-05-23 14:36:30.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/context_heimdal.c	2007-06-29 12:32:29.000000000 -0600
 @@ -43,8 +43,13 @@
  #ifdef HAVE_COM_ERR_H
  #include <com_err.h>
@@ -270,8 +270,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/context_heimdal.c nfs-utils-1.0.11.lustre
  
  int write_heimdal_keyblock(char **p, char *end, krb5_keyblock *key)
 diff -Nrup nfs-utils-1.0.11/utils/gssd/context_lucid.c nfs-utils-1.0.11.lustre/utils/gssd/context_lucid.c
---- nfs-utils-1.0.11/utils/gssd/context_lucid.c	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/context_lucid.c	2007-05-23 14:36:31.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/context_lucid.c	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/context_lucid.c	2007-06-29 12:32:30.000000000 -0600
 @@ -41,11 +41,7 @@
  #include <syslog.h>
  #include <string.h>
@@ -411,8 +411,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/context_lucid.c nfs-utils-1.0.11.lustre/u
  						1, &return_ctx);
  	if (maj_stat != GSS_S_COMPLETE) {
 diff -Nrup nfs-utils-1.0.11/utils/gssd/context_mit.c nfs-utils-1.0.11.lustre/utils/gssd/context_mit.c
---- nfs-utils-1.0.11/utils/gssd/context_mit.c	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/context_mit.c	2007-05-23 14:36:32.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/context_mit.c	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/context_mit.c	2007-06-29 12:32:30.000000000 -0600
 @@ -39,10 +39,14 @@
  #include <errno.h>
  #include <gssapi/gssapi.h>
@@ -448,7 +448,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/context_mit.c nfs-utils-1.0.11.lustre/uti
  		/* Only applicable flag for this is initiator */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/context_spkm3.c nfs-utils-1.0.11.lustre/utils/gssd/context_spkm3.c
 --- nfs-utils-1.0.11/utils/gssd/context_spkm3.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/context_spkm3.c	2007-05-23 14:36:32.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/context_spkm3.c	2007-06-29 12:32:31.000000000 -0600
 @@ -33,8 +33,6 @@
  #include <syslog.h>
  #include <string.h>
@@ -460,7 +460,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/context_spkm3.c nfs-utils-1.0.11.lustre/u
  #include "err_util.h"
 diff -Nrup nfs-utils-1.0.11/utils/gssd/err_util.c nfs-utils-1.0.11.lustre/utils/gssd/err_util.c
 --- nfs-utils-1.0.11/utils/gssd/err_util.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/err_util.c	2007-05-23 14:36:33.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/err_util.c	2007-06-29 12:32:31.000000000 -0600
 @@ -32,6 +32,8 @@
  #include <stdarg.h>
  #include <syslog.h>
@@ -513,7 +513,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/err_util.c nfs-utils-1.0.11.lustre/utils/
 +
 diff -Nrup nfs-utils-1.0.11/utils/gssd/err_util.h nfs-utils-1.0.11.lustre/utils/gssd/err_util.h
 --- nfs-utils-1.0.11/utils/gssd/err_util.h	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/err_util.h	2007-05-23 14:36:33.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/err_util.h	2007-06-29 12:32:32.000000000 -0600
 @@ -33,5 +33,6 @@
  
  void initerr(char *progname, int verbosity, int fg);
@@ -523,7 +523,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/err_util.h nfs-utils-1.0.11.lustre/utils/
  #endif /* _ERR_UTIL_H_ */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gss_clnt_send_err.c nfs-utils-1.0.11.lustre/utils/gssd/gss_clnt_send_err.c
 --- nfs-utils-1.0.11/utils/gssd/gss_clnt_send_err.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gss_clnt_send_err.c	2007-05-23 14:35:45.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gss_clnt_send_err.c	2007-06-29 12:29:20.000000000 -0600
 @@ -47,6 +47,7 @@
  #include "gssd.h"
  #include "write_bytes.h"
@@ -538,8 +538,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gss_clnt_send_err.c nfs-utils-1.0.11.lust
  }
 +#endif
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd.c nfs-utils-1.0.11.lustre/utils/gssd/gssd.c
---- nfs-utils-1.0.11/utils/gssd/gssd.c	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gssd.c	2007-05-23 14:36:34.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/gssd.c	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gssd.c	2007-06-29 12:32:36.000000000 -0600
 @@ -38,9 +38,12 @@
  
  #include "config.h"
@@ -767,8 +767,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd.c nfs-utils-1.0.11.lustre/utils/gssd
 +	return 0;
  }
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd.h nfs-utils-1.0.11.lustre/utils/gssd/gssd.h
---- nfs-utils-1.0.11/utils/gssd/gssd.h	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gssd.h	2007-05-23 14:36:34.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/gssd.h	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gssd.h	2007-06-29 12:32:37.000000000 -0600
 @@ -48,8 +48,13 @@
  #define GSSD_DEFAULT_CRED_PREFIX		"krb5cc_"
  #define GSSD_DEFAULT_MACHINE_CRED_SUFFIX	"machine"
@@ -825,8 +825,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd.h nfs-utils-1.0.11.lustre/utils/gssd
  
  #endif /* _RPC_GSSD_H_ */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd_main_loop.c nfs-utils-1.0.11.lustre/utils/gssd/gssd_main_loop.c
---- nfs-utils-1.0.11/utils/gssd/gssd_main_loop.c	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gssd_main_loop.c	2007-05-23 14:36:35.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/gssd_main_loop.c	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gssd_main_loop.c	2007-06-29 12:32:38.000000000 -0600
 @@ -94,11 +94,13 @@ scan_poll_results(int ret)
  };
  
@@ -897,8 +897,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd_main_loop.c nfs-utils-1.0.11.lustre/
  	return;
  }
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd_proc.c nfs-utils-1.0.11.lustre/utils/gssd/gssd_proc.c
---- nfs-utils-1.0.11/utils/gssd/gssd_proc.c	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gssd_proc.c	2007-05-23 14:36:35.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/gssd_proc.c	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gssd_proc.c	2007-06-29 12:32:38.000000000 -0600
 @@ -43,7 +43,6 @@
  #endif
  #include "config.h"
@@ -1702,7 +1702,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gssd_proc.c nfs-utils-1.0.11.lustre/utils
  }
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gss_util.c nfs-utils-1.0.11.lustre/utils/gssd/gss_util.c
 --- nfs-utils-1.0.11/utils/gssd/gss_util.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gss_util.c	2007-05-23 14:36:37.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gss_util.c	2007-06-29 12:32:40.000000000 -0600
 @@ -87,9 +87,16 @@
  #ifdef HAVE_COM_ERR_H
  #include <com_err.h>
@@ -1918,7 +1918,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gss_util.c nfs-utils-1.0.11.lustre/utils/
 +
 diff -Nrup nfs-utils-1.0.11/utils/gssd/gss_util.h nfs-utils-1.0.11.lustre/utils/gssd/gss_util.h
 --- nfs-utils-1.0.11/utils/gssd/gss_util.h	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/gss_util.h	2007-05-23 14:36:37.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/gss_util.h	2007-06-29 12:32:41.000000000 -0600
 @@ -32,14 +32,14 @@
  #define _GSS_UTIL_H_
  
@@ -1937,8 +1937,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/gss_util.h nfs-utils-1.0.11.lustre/utils/
  
  #endif /* _GSS_UTIL_H_ */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/krb5_util.c nfs-utils-1.0.11.lustre/utils/gssd/krb5_util.c
---- nfs-utils-1.0.11/utils/gssd/krb5_util.c	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/krb5_util.c	2007-05-23 14:36:38.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/krb5_util.c	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/krb5_util.c	2007-06-29 12:32:42.000000000 -0600
 @@ -99,12 +99,15 @@
  #include <rpc/rpc.h>
  #include <sys/types.h>
@@ -2405,8 +2405,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/krb5_util.c nfs-utils-1.0.11.lustre/utils
  }
 +#endif
 diff -Nrup nfs-utils-1.0.11/utils/gssd/krb5_util.h nfs-utils-1.0.11.lustre/utils/gssd/krb5_util.h
---- nfs-utils-1.0.11/utils/gssd/krb5_util.h	2007-05-23 14:35:21.000000000 -0600
-+++ nfs-utils-1.0.11.lustre/utils/gssd/krb5_util.h	2007-05-23 14:36:39.000000000 -0600
+--- nfs-utils-1.0.11/utils/gssd/krb5_util.h	2007-06-29 12:28:01.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/krb5_util.h	2007-06-29 12:32:42.000000000 -0600
 @@ -10,6 +10,8 @@
  struct gssd_k5_kt_princ {
  	struct gssd_k5_kt_princ *next;
@@ -2427,7 +2427,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/krb5_util.h nfs-utils-1.0.11.lustre/utils
  #endif /* KRB5_UTIL_H */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/lsupport.c nfs-utils-1.0.11.lustre/utils/gssd/lsupport.c
 --- nfs-utils-1.0.11/utils/gssd/lsupport.c	1969-12-31 17:00:00.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/lsupport.c	2007-05-23 14:36:40.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/lsupport.c	2007-06-29 12:32:43.000000000 -0600
 @@ -0,0 +1,787 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -3218,7 +3218,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/lsupport.c nfs-utils-1.0.11.lustre/utils/
 +}
 diff -Nrup nfs-utils-1.0.11/utils/gssd/lsupport.h nfs-utils-1.0.11.lustre/utils/gssd/lsupport.h
 --- nfs-utils-1.0.11/utils/gssd/lsupport.h	1969-12-31 17:00:00.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/lsupport.h	2007-05-23 14:36:41.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/lsupport.h	2007-06-29 12:32:43.000000000 -0600
 @@ -0,0 +1,89 @@
 +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
 + * vim:expandtab:shiftwidth=8:tabstop=8:
@@ -3311,7 +3311,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/lsupport.h nfs-utils-1.0.11.lustre/utils/
 +#endif /* __LIBCFS_H__ */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/Makefile.am nfs-utils-1.0.11.lustre/utils/gssd/Makefile.am
 --- nfs-utils-1.0.11/utils/gssd/Makefile.am	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/Makefile.am	2007-05-23 14:35:45.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/Makefile.am	2007-06-29 12:29:20.000000000 -0600
 @@ -1,17 +1,11 @@
  ## Process this file with automake to produce Makefile.in
  
@@ -3419,7 +3419,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/Makefile.am nfs-utils-1.0.11.lustre/utils
 -
 diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd.c nfs-utils-1.0.11.lustre/utils/gssd/svcgssd.c
 --- nfs-utils-1.0.11/utils/gssd/svcgssd.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd.c	2007-05-23 14:36:41.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd.c	2007-06-29 12:32:44.000000000 -0600
 @@ -43,7 +43,6 @@
  #include <sys/types.h>
  #include <sys/stat.h>
@@ -3472,6 +3472,15 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd.c nfs-utils-1.0.11.lustre/utils/g
  	printerr(1, "exiting on signal %d\n", signal);
  	exit(1);
  }
+@@ -155,7 +177,7 @@ sig_hup(int signal)
+ static void
+ usage(char *progname)
+ {
+-	fprintf(stderr, "usage: %s [-n] [-f] [-v] [-r] [-i]\n",
++	fprintf(stderr, "usage: %s [-n] [-f] [-v] [-r] [-m] [-o]\n",
+ 		progname);
+ 	exit(1);
+ }
 @@ -166,9 +188,8 @@ main(int argc, char *argv[])
  	int get_creds = 1;
  	int fg = 0;
@@ -3576,7 +3585,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd.c nfs-utils-1.0.11.lustre/utils/g
  }
 diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd.h nfs-utils-1.0.11.lustre/utils/gssd/svcgssd.h
 --- nfs-utils-1.0.11/utils/gssd/svcgssd.h	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd.h	2007-05-23 14:36:42.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd.h	2007-06-29 12:32:45.000000000 -0600
 @@ -35,9 +35,20 @@
  #include <sys/queue.h>
  #include <gssapi/gssapi.h>
@@ -3603,7 +3612,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd.h nfs-utils-1.0.11.lustre/utils/g
  #endif /* _RPC_SVCGSSD_H_ */
 diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd_main_loop.c nfs-utils-1.0.11.lustre/utils/gssd/svcgssd_main_loop.c
 --- nfs-utils-1.0.11/utils/gssd/svcgssd_main_loop.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd_main_loop.c	2007-05-23 14:36:42.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd_main_loop.c	2007-06-29 12:32:45.000000000 -0600
 @@ -46,46 +46,66 @@
  #include "svcgssd.h"
  #include "err_util.h"
@@ -3628,7 +3637,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd_main_loop.c nfs-utils-1.0.11.lust
 +	struct timespec		halfsec = { .tv_sec = 0, .tv_nsec = 500000000 };
  
 -#define NULLRPC_FILE "/proc/net/rpc/auth.rpcsec.init/channel"
-+#define NULLRPC_FILE "/proc/net/rpc/auth.ptlrpcs.init/channel"
++#define NULLRPC_FILE "/proc/net/rpc/auth.sptlrpc.init/channel"
  
 -	f = fopen(NULLRPC_FILE, "rw");
 -
@@ -3694,7 +3703,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd_main_loop.c nfs-utils-1.0.11.lust
  }
 diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd_proc.c nfs-utils-1.0.11.lustre/utils/gssd/svcgssd_proc.c
 --- nfs-utils-1.0.11/utils/gssd/svcgssd_proc.c	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd_proc.c	2007-05-23 14:36:44.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/gssd/svcgssd_proc.c	2007-06-29 12:32:46.000000000 -0600
 @@ -35,7 +35,6 @@
  
  #include <sys/param.h>
@@ -3720,8 +3729,8 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd_proc.c nfs-utils-1.0.11.lustre/ut
  extern char * mech2file(gss_OID mech);
 -#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.rpcsec.context/channel"
 -#define SVCGSSD_INIT_CHANNEL    "/proc/net/rpc/auth.rpcsec.init/channel"
-+#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.ptlrpcs.context/channel"
-+#define SVCGSSD_INIT_CHANNEL    "/proc/net/rpc/auth.ptlrpcs.init/channel"
++#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.sptlrpc.context/channel"
++#define SVCGSSD_INIT_CHANNEL    "/proc/net/rpc/auth.sptlrpc.init/channel"
  
  #define TOKEN_BUF_SIZE		8192
  
@@ -4031,7 +4040,7 @@ diff -Nrup nfs-utils-1.0.11/utils/gssd/svcgssd_proc.c nfs-utils-1.0.11.lustre/ut
  	if (ctx != GSS_C_NO_CONTEXT)
 diff -Nrup nfs-utils-1.0.11/utils/Makefile.am nfs-utils-1.0.11.lustre/utils/Makefile.am
 --- nfs-utils-1.0.11/utils/Makefile.am	2007-02-21 21:50:03.000000000 -0700
-+++ nfs-utils-1.0.11.lustre/utils/Makefile.am	2007-05-23 14:35:45.000000000 -0600
++++ nfs-utils-1.0.11.lustre/utils/Makefile.am	2007-06-29 12:29:20.000000000 -0600
 @@ -2,30 +2,6 @@
  
  OPTDIRS =
diff --git a/lustre/utils/gss/svcgssd_main_loop.c b/lustre/utils/gss/svcgssd_main_loop.c
index 5300647010..bd5fea7558 100644
--- a/lustre/utils/gss/svcgssd_main_loop.c
+++ b/lustre/utils/gss/svcgssd_main_loop.c
@@ -65,7 +65,7 @@ svcgssd_run()
 	struct pollfd		pollfd;
 	struct timespec		halfsec = { .tv_sec = 0, .tv_nsec = 500000000 };
 
-#define NULLRPC_FILE "/proc/net/rpc/auth.ptlrpcs.init/channel"
+#define NULLRPC_FILE "/proc/net/rpc/auth.sptlrpc.init/channel"
 
 	while (1) {
 		int save_err;
diff --git a/lustre/utils/gss/svcgssd_proc.c b/lustre/utils/gss/svcgssd_proc.c
index f9a543c9ab..745268a2f7 100644
--- a/lustre/utils/gss/svcgssd_proc.c
+++ b/lustre/utils/gss/svcgssd_proc.c
@@ -53,8 +53,8 @@
 #include "lsupport.h"
 
 extern char * mech2file(gss_OID mech);
-#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.ptlrpcs.context/channel"
-#define SVCGSSD_INIT_CHANNEL    "/proc/net/rpc/auth.ptlrpcs.init/channel"
+#define SVCGSSD_CONTEXT_CHANNEL "/proc/net/rpc/auth.sptlrpc.context/channel"
+#define SVCGSSD_INIT_CHANNEL    "/proc/net/rpc/auth.sptlrpc.init/channel"
 
 #define TOKEN_BUF_SIZE		8192
 
@@ -323,7 +323,8 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
 		return -1;
 	}
 	memcpy(sname, name.value, name.length);
-	printerr(1, "authenticated %s from %016llx\n", sname, nid);
+	printerr(1, "%s: authenticated %s from %016llx\n",
+		 lustre_svc_name[lustre_svc], sname, nid);
 	gss_release_buffer(&min_stat, &name);
 
 	if (lustre_svc == LUSTRE_GSS_SVC_MDS)
@@ -446,7 +447,7 @@ handle_nullreq(FILE *f) {
 	qword_get(&cp, (char *) &lustre_svc, sizeof(lustre_svc));
 	qword_get(&cp, (char *) &nid, sizeof(nid));
 	qword_get(&cp, (char *) &handle_seq, sizeof(handle_seq));
-	printerr(1, "handling req: svc %u, nid %016llx, idx %llx\n",
+	printerr(2, "handling req: svc %u, nid %016llx, idx %llx\n",
 		 lustre_svc, nid, handle_seq);
 
 	in_handle.length = (size_t) qword_get(&cp, in_handle.value,
-- 
GitLab