/* cred's refcount is 0, steal one */
atomic_inc(&cred->pc_refcount);
- gcred = container_of(cred, struct gss_cred, gc_base);
- gcred->gc_ctx->gc_proc = PTLRPC_GSS_PROC_DESTROY;
- imp = cred->pc_sec->ps_import;
- LASSERT(imp);
-
if (!(cred->pc_flags & PTLRPC_CRED_UPTODATE)) {
- CDEBUG(D_SEC, "Destroy a dead gss cred %p(%u@%s)\n",
- gcred, cred->pc_uid, imp->imp_target_uuid.uuid);
+ CDEBUG(D_SEC, "Destroy dead cred %p(%u@%s)\n",
+ cred, cred->pc_uid, imp->imp_target_uuid.uuid);
atomic_dec(&cred->pc_refcount);
EXIT;
return;
}
+ gcred = container_of(cred, struct gss_cred, gc_base);
+ gcred->gc_ctx->gc_proc = PTLRPC_GSS_PROC_DESTROY;
+ imp = cred->pc_sec->ps_import;
+ LASSERT(imp);
+
CDEBUG(D_SEC, "client destroy gss cred %p(%u@%s)\n",
gcred, cred->pc_uid, imp->imp_target_uuid.uuid);
EXIT;
}
+/*
+ * grace: mark cred DEAD, allow graceful destroy like notify
+ * server side, etc.
+ * force: flush all entries, otherwise only free ones be flushed.
+ */
static
-int ptlrpcs_flush_credcache(struct ptlrpc_sec *sec, int force)
+int ptlrpcs_flush_credcache(struct ptlrpc_sec *sec, int grace, int force)
{
struct ptlrpc_cred *cred, *n;
LIST_HEAD(freelist);
} else
list_move(&cred->pc_hash, &freelist);
- /* don't remove CRED_UPTODATE flag here */
cred->pc_flags |= PTLRPC_CRED_DEAD;
+ if (!grace)
+ cred->pc_flags &= ~PTLRPC_CRED_UPTODATE;
}
}
spin_unlock(&sec->ps_lock);
void ptlrpcs_sec_put(struct ptlrpc_sec *sec)
{
if (atomic_dec_and_test(&sec->ps_refcount)) {
- ptlrpcs_flush_credcache(sec, 1);
+ ptlrpcs_flush_credcache(sec, 1, 1);
if (atomic_read(&sec->ps_credcount) == 0) {
ptlrpcs_sec_destroy(sec);
void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec)
{
- ptlrpcs_flush_credcache(sec, 1);
+ ptlrpcs_flush_credcache(sec, 0, 1);
}
int sec_alloc_reqbuf(struct ptlrpc_sec *sec,