mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-04 09:59:32 +00:00
SUNRPC: Replace krb5_seq_lock with a lockless scheme
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
0c1c19f46e
commit
571ed1fd23
3 changed files with 30 additions and 18 deletions
|
@ -118,7 +118,8 @@ struct krb5_ctx {
|
|||
u8 acceptor_integ[GSS_KRB5_MAX_KEYLEN];
|
||||
};
|
||||
|
||||
extern spinlock_t krb5_seq_lock;
|
||||
extern u32 gss_seq_send_fetch_and_inc(struct krb5_ctx *ctx);
|
||||
extern u64 gss_seq_send64_fetch_and_inc(struct krb5_ctx *ctx);
|
||||
|
||||
/* The length of the Kerberos GSS token header */
|
||||
#define GSS_KRB5_TOK_HDR_LEN (16)
|
||||
|
|
|
@ -68,8 +68,6 @@
|
|||
# define RPCDBG_FACILITY RPCDBG_AUTH
|
||||
#endif
|
||||
|
||||
DEFINE_SPINLOCK(krb5_seq_lock);
|
||||
|
||||
static void *
|
||||
setup_token(struct krb5_ctx *ctx, struct xdr_netobj *token)
|
||||
{
|
||||
|
@ -124,6 +122,30 @@ setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token)
|
|||
return krb5_hdr;
|
||||
}
|
||||
|
||||
u32
|
||||
gss_seq_send_fetch_and_inc(struct krb5_ctx *ctx)
|
||||
{
|
||||
u32 old, seq_send = READ_ONCE(ctx->seq_send);
|
||||
|
||||
do {
|
||||
old = seq_send;
|
||||
seq_send = cmpxchg(&ctx->seq_send, old, old + 1);
|
||||
} while (old != seq_send);
|
||||
return seq_send;
|
||||
}
|
||||
|
||||
u64
|
||||
gss_seq_send64_fetch_and_inc(struct krb5_ctx *ctx)
|
||||
{
|
||||
u64 old, seq_send = READ_ONCE(ctx->seq_send);
|
||||
|
||||
do {
|
||||
old = seq_send;
|
||||
seq_send = cmpxchg(&ctx->seq_send64, old, old + 1);
|
||||
} while (old != seq_send);
|
||||
return seq_send;
|
||||
}
|
||||
|
||||
static u32
|
||||
gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
|
||||
struct xdr_netobj *token)
|
||||
|
@ -154,9 +176,7 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
|
|||
|
||||
memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
|
||||
|
||||
spin_lock(&krb5_seq_lock);
|
||||
seq_send = ctx->seq_send++;
|
||||
spin_unlock(&krb5_seq_lock);
|
||||
seq_send = gss_seq_send_fetch_and_inc(ctx);
|
||||
|
||||
if (krb5_make_seq_num(ctx, ctx->seq, ctx->initiate ? 0 : 0xff,
|
||||
seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8))
|
||||
|
@ -174,7 +194,6 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
|
|||
.data = cksumdata};
|
||||
void *krb5_hdr;
|
||||
s32 now;
|
||||
u64 seq_send;
|
||||
u8 *cksumkey;
|
||||
unsigned int cksum_usage;
|
||||
__be64 seq_send_be64;
|
||||
|
@ -185,11 +204,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
|
|||
|
||||
/* Set up the sequence number. Now 64-bits in clear
|
||||
* text and w/o direction indicator */
|
||||
spin_lock(&krb5_seq_lock);
|
||||
seq_send = ctx->seq_send64++;
|
||||
spin_unlock(&krb5_seq_lock);
|
||||
|
||||
seq_send_be64 = cpu_to_be64(seq_send);
|
||||
seq_send_be64 = cpu_to_be64(gss_seq_send64_fetch_and_inc(ctx));
|
||||
memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8);
|
||||
|
||||
if (ctx->initiate) {
|
||||
|
|
|
@ -228,9 +228,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,
|
|||
|
||||
memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
|
||||
|
||||
spin_lock(&krb5_seq_lock);
|
||||
seq_send = kctx->seq_send++;
|
||||
spin_unlock(&krb5_seq_lock);
|
||||
seq_send = gss_seq_send_fetch_and_inc(kctx);
|
||||
|
||||
/* XXX would probably be more efficient to compute checksum
|
||||
* and encrypt at the same time: */
|
||||
|
@ -477,9 +475,7 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
|
|||
*be16ptr++ = 0;
|
||||
|
||||
be64ptr = (__be64 *)be16ptr;
|
||||
spin_lock(&krb5_seq_lock);
|
||||
*be64ptr = cpu_to_be64(kctx->seq_send64++);
|
||||
spin_unlock(&krb5_seq_lock);
|
||||
*be64ptr = cpu_to_be64(gss_seq_send64_fetch_and_inc(kctx));
|
||||
|
||||
err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, pages);
|
||||
if (err)
|
||||
|
|
Loading…
Reference in a new issue