Add a key to struct gss_msg. While the uid will still be used to search the upcall message list in __gss_find_upcall() to determine if a request is already posted, the new gss_msg->rq_mkey will be used by gss_pipe_downcall to match a received downcall with the appropriate upcall message in the struct rpc_upcall_info upcall queue. Signed-off-by: Andy Adamson --- diff -puN net/sunrpc/auth_gss/auth_gss.c~gss-common-pipe net/sunrpc/auth_gss/auth_gss.c --- linux-2.6.18-rc5/net/sunrpc/auth_gss/auth_gss.c~gss-common-pipe 2006-10-17 15:38:54.000000000 -0400 +++ linux-2.6.18-rc5-andros/net/sunrpc/auth_gss/auth_gss.c 2006-10-17 15:42:29.000000000 -0400 @@ -114,6 +114,7 @@ struct gss_auth { struct rpc_auth rpc_auth; struct rpc_upcall_info *info; struct gss_api_mech *mech; + u32 mkey; enum rpc_gss_svc service; struct rpc_clnt *client; struct dentry *dentry; @@ -322,6 +323,7 @@ err: struct gss_upcall_msg { atomic_t count; uid_t uid; + u32 rq_mkey; struct rpc_pipe_msg msg; struct list_head list; struct gss_auth *auth; @@ -343,6 +345,21 @@ gss_release_msg(struct gss_upcall_msg *g } static struct gss_upcall_msg * +__gss_find_upcall_msg(struct gss_auth *gss_auth, u32 mkey) +{ + struct gss_upcall_msg *pos; + list_for_each_entry(pos, &gss_auth->info->upcalls, list) { + if (pos->rq_mkey != mkey) + continue; + atomic_inc(&pos->count); + dprintk("RPC: gss_find_upcall_msg found msg %p\n", pos); + return pos; + } + dprintk("RPC: gss_find_upcall_msg found nothing\n"); + return NULL; +} + +static struct gss_upcall_msg * __gss_find_upcall(struct gss_auth *gss_auth, uid_t uid) { struct gss_upcall_msg *pos; @@ -462,9 +479,10 @@ gss_init_msg_upcall_info(struct gss_upca get_current_keyrings(&skey, &pkey, &tkey); len = snprintf(gss_msg->upcall_info, sizeof(gss_msg->upcall_info), - "%s %d %d %d %d %d %d %d", - krinfo->op, tsk->fsuid, tsk->fsgid, krinfo->key->serial, - krinfo->authkey->serial, tkey, pkey, skey); + "%s %d %d %d %d %d %d %d %d", + krinfo->op, tsk->fsuid, gss_msg->rq_mkey, tsk->fsgid, + krinfo->key->serial, krinfo->authkey->serial, + tkey, pkey, skey); if (len >= sizeof(gss_msg->upcall_info)) { dprintk("%s: returning error (len %d)\n", __FUNCTION__, len); return -1; @@ -486,6 +504,9 @@ gss_alloc_msg(struct gss_auth *gss_auth, INIT_LIST_HEAD(&gss_msg->list); rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); atomic_set(&gss_msg->count, 1); + spin_lock(&gss_auth->info->lock); + gss_msg->rq_mkey = gss_auth->info->mkey++; + spin_unlock(&gss_auth->info->lock); #ifdef CONFIG_RPCSEC_GSS_KEYRING if (gss_init_msg_upcall_info(gss_msg, krinfo)) { gss_release_msg(gss_msg); @@ -499,6 +520,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, #else gss_msg->msg.data = &gss_msg->uid; gss_msg->msg.len = sizeof(gss_msg->uid); + gss_msg->msg.len = sizeof(gss_msg->uid) + sizeof(gss_msg->rq_mkey); #endif gss_msg->uid = uid; gss_msg->auth = gss_auth; @@ -666,6 +688,7 @@ gss_pipe_downcall(struct file *filp, con struct gss_upcall_msg *gss_msg; struct gss_cl_ctx *ctx; char principal[32]; + u32 mkey; uid_t uid; #ifdef CONFIG_RPCSEC_GSS_KEYRING key_serial_t skey, pkey, tkey; @@ -691,6 +714,12 @@ gss_pipe_downcall(struct file *filp, con err = PTR_ERR(p); goto err; } + p = simple_get_bytes(p, end, &mkey, sizeof(mkey)); + if (IS_ERR(p)) { + err = PTR_ERR(p); + goto err; + } + #ifdef CONFIG_RPCSEC_GSS_KEYRING p = simple_get_bytes(p, end, &skey, sizeof(skey)); if (IS_ERR(p)) { @@ -723,7 +752,7 @@ gss_pipe_downcall(struct file *filp, con goto err_put_ctx; } spin_lock(&gss_auth->info->lock); - gss_msg = __gss_find_upcall(gss_auth, uid); + gss_msg = __gss_find_upcall_msg(gss_auth, mkey); if (gss_msg) { if (err == 0 && gss_msg->ctx == NULL) gss_msg->ctx = gss_get_ctx(ctx); _