Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124761
b: refs/heads/master
c: 79a3f20
h: refs/heads/master
i:
  124759: 3264ca7
v: v3
  • Loading branch information
\"J. Bruce Fields\ authored and Trond Myklebust committed Dec 23, 2008
1 parent 369f316 commit 03676ea
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cf81939d6fcdf381fcb069d780c29eceb516bccd
refs/heads/master: 79a3f20b641f9f93787ada49d1d7cfa98ee5a11e
64 changes: 61 additions & 3 deletions trunk/net/sunrpc/auth_gss/auth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ struct gss_auth {
struct dentry *dentry;
};

/* pipe_version >= 0 if and only if someone has a pipe open. */
static int pipe_version = -1;
static atomic_t pipe_users = ATOMIC_INIT(0);
static DEFINE_SPINLOCK(pipe_version_lock);
static struct rpc_wait_queue pipe_version_rpc_waitqueue;
static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);

static void gss_free_ctx(struct gss_cl_ctx *);
static struct rpc_pipe_ops gss_upcall_ops;
Expand Down Expand Up @@ -234,12 +239,34 @@ struct gss_upcall_msg {
struct gss_cl_ctx *ctx;
};

static int get_pipe_version(void)
{
int ret;

spin_lock(&pipe_version_lock);
if (pipe_version >= 0) {
atomic_inc(&pipe_users);
ret = 0;
} else
ret = -EAGAIN;
spin_unlock(&pipe_version_lock);
return ret;
}

static void put_pipe_version(void)
{
if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) {
pipe_version = -1;
spin_unlock(&pipe_version_lock);
}
}

static void
gss_release_msg(struct gss_upcall_msg *gss_msg)
{
if (!atomic_dec_and_test(&gss_msg->count))
return;
atomic_dec(&pipe_users);
put_pipe_version();
BUG_ON(!list_empty(&gss_msg->list));
if (gss_msg->ctx != NULL)
gss_put_ctx(gss_msg->ctx);
Expand Down Expand Up @@ -330,11 +357,16 @@ static inline struct gss_upcall_msg *
gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid)
{
struct gss_upcall_msg *gss_msg;
int vers;

gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
if (gss_msg == NULL)
return ERR_PTR(-ENOMEM);
atomic_inc(&pipe_users);
vers = get_pipe_version();
if (vers < 0) {
kfree(gss_msg);
return ERR_PTR(vers);
}
INIT_LIST_HEAD(&gss_msg->list);
rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
init_waitqueue_head(&gss_msg->waitqueue);
Expand Down Expand Up @@ -400,6 +432,14 @@ gss_refresh_upcall(struct rpc_task *task)
dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
cred->cr_uid);
gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
if (IS_ERR(gss_msg) == -EAGAIN) {
/* XXX: warning on the first, under the assumption we
* shouldn't normally hit this case on a refresh. */
warn_gssd();
task->tk_timeout = 15*HZ;
rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
return 0;
}
if (IS_ERR(gss_msg)) {
err = PTR_ERR(gss_msg);
goto out;
Expand Down Expand Up @@ -437,7 +477,17 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
int err = 0;

dprintk("RPC: gss_upcall for uid %u\n", cred->cr_uid);
retry:
gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
if (PTR_ERR(gss_msg) == -EAGAIN) {
err = wait_event_interruptible_timeout(pipe_version_waitqueue,
pipe_version >= 0, 15*HZ);
if (err)
goto out;
if (pipe_version < 0)
warn_gssd();
goto retry;
}
if (IS_ERR(gss_msg)) {
err = PTR_ERR(gss_msg);
goto out;
Expand Down Expand Up @@ -562,7 +612,14 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
static int
gss_pipe_open(struct inode *inode)
{
spin_lock(&pipe_version_lock);
if (pipe_version < 0) {
pipe_version = 0;
rpc_wake_up(&pipe_version_rpc_waitqueue);
wake_up(&pipe_version_waitqueue);
}
atomic_inc(&pipe_users);
spin_unlock(&pipe_version_lock);
return 0;
}

Expand All @@ -586,7 +643,7 @@ gss_pipe_release(struct inode *inode)
}
spin_unlock(&inode->i_lock);

atomic_dec(&pipe_users);
put_pipe_version();
}

static void
Expand Down Expand Up @@ -1379,6 +1436,7 @@ static int __init init_rpcsec_gss(void)
err = gss_svc_init();
if (err)
goto out_unregister;
rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
return 0;
out_unregister:
rpcauth_unregister(&authgss_ops);
Expand Down

0 comments on commit 03676ea

Please sign in to comment.