Commit 6d1616b2 authored by Trond Myklebust's avatar Trond Myklebust Committed by J. Bruce Fields
Browse files

SUNRPC: Lockless server RPCSEC_GSS context lookup



Use RCU protection for looking up the RPCSEC_GSS context.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 9ceddd9d
Loading
Loading
Loading
Loading
+26 −6
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ struct rsi {
	struct xdr_netobj	in_handle, in_token;
	struct xdr_netobj	out_handle, out_token;
	int			major_status, minor_status;
	struct rcu_head		rcu_head;
};

static struct rsi *rsi_update(struct cache_detail *cd, struct rsi *new, struct rsi *old);
@@ -89,13 +90,21 @@ static void rsi_free(struct rsi *rsii)
	kfree(rsii->out_token.data);
}

static void rsi_put(struct kref *ref)
static void rsi_free_rcu(struct rcu_head *head)
{
	struct rsi *rsii = container_of(ref, struct rsi, h.ref);
	struct rsi *rsii = container_of(head, struct rsi, rcu_head);

	rsi_free(rsii);
	kfree(rsii);
}

static void rsi_put(struct kref *ref)
{
	struct rsi *rsii = container_of(ref, struct rsi, h.ref);

	call_rcu(&rsii->rcu_head, rsi_free_rcu);
}

static inline int rsi_hash(struct rsi *item)
{
	return hash_mem(item->in_handle.data, item->in_handle.len, RSI_HASHBITS)
@@ -282,7 +291,7 @@ static struct rsi *rsi_lookup(struct cache_detail *cd, struct rsi *item)
	struct cache_head *ch;
	int hash = rsi_hash(item);

	ch = sunrpc_cache_lookup(cd, &item->h, hash);
	ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
	if (ch)
		return container_of(ch, struct rsi, h);
	else
@@ -330,6 +339,7 @@ struct rsc {
	struct svc_cred		cred;
	struct gss_svc_seq_data	seqdata;
	struct gss_ctx		*mechctx;
	struct rcu_head		rcu_head;
};

static struct rsc *rsc_update(struct cache_detail *cd, struct rsc *new, struct rsc *old);
@@ -343,12 +353,22 @@ static void rsc_free(struct rsc *rsci)
	free_svc_cred(&rsci->cred);
}

static void rsc_free_rcu(struct rcu_head *head)
{
	struct rsc *rsci = container_of(head, struct rsc, rcu_head);

	kfree(rsci->handle.data);
	kfree(rsci);
}

static void rsc_put(struct kref *ref)
{
	struct rsc *rsci = container_of(ref, struct rsc, h.ref);

	rsc_free(rsci);
	kfree(rsci);
	if (rsci->mechctx)
		gss_delete_sec_context(&rsci->mechctx);
	free_svc_cred(&rsci->cred);
	call_rcu(&rsci->rcu_head, rsc_free_rcu);
}

static inline int
@@ -542,7 +562,7 @@ static struct rsc *rsc_lookup(struct cache_detail *cd, struct rsc *item)
	struct cache_head *ch;
	int hash = rsc_hash(item);

	ch = sunrpc_cache_lookup(cd, &item->h, hash);
	ch = sunrpc_cache_lookup_rcu(cd, &item->h, hash);
	if (ch)
		return container_of(ch, struct rsc, h);
	else