diff options
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index e894e2fc360d..653d712a1ffb 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -88,7 +88,6 @@ struct gss_auth { | |||
| 88 | struct list_head upcalls; | 88 | struct list_head upcalls; |
| 89 | struct rpc_clnt *client; | 89 | struct rpc_clnt *client; |
| 90 | struct dentry *dentry; | 90 | struct dentry *dentry; |
| 91 | spinlock_t lock; | ||
| 92 | }; | 91 | }; |
| 93 | 92 | ||
| 94 | static void gss_destroy_ctx(struct gss_cl_ctx *); | 93 | static void gss_destroy_ctx(struct gss_cl_ctx *); |
| @@ -290,16 +289,17 @@ __gss_find_upcall(struct gss_auth *gss_auth, uid_t uid) | |||
| 290 | static inline struct gss_upcall_msg * | 289 | static inline struct gss_upcall_msg * |
| 291 | gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) | 290 | gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) |
| 292 | { | 291 | { |
| 292 | struct inode *inode = gss_auth->dentry->d_inode; | ||
| 293 | struct gss_upcall_msg *old; | 293 | struct gss_upcall_msg *old; |
| 294 | 294 | ||
| 295 | spin_lock(&gss_auth->lock); | 295 | spin_lock(&inode->i_lock); |
| 296 | old = __gss_find_upcall(gss_auth, gss_msg->uid); | 296 | old = __gss_find_upcall(gss_auth, gss_msg->uid); |
| 297 | if (old == NULL) { | 297 | if (old == NULL) { |
| 298 | atomic_inc(&gss_msg->count); | 298 | atomic_inc(&gss_msg->count); |
| 299 | list_add(&gss_msg->list, &gss_auth->upcalls); | 299 | list_add(&gss_msg->list, &gss_auth->upcalls); |
| 300 | } else | 300 | } else |
| 301 | gss_msg = old; | 301 | gss_msg = old; |
| 302 | spin_unlock(&gss_auth->lock); | 302 | spin_unlock(&inode->i_lock); |
| 303 | return gss_msg; | 303 | return gss_msg; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| @@ -318,10 +318,11 @@ static void | |||
| 318 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) | 318 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) |
| 319 | { | 319 | { |
| 320 | struct gss_auth *gss_auth = gss_msg->auth; | 320 | struct gss_auth *gss_auth = gss_msg->auth; |
| 321 | struct inode *inode = gss_auth->dentry->d_inode; | ||
| 321 | 322 | ||
| 322 | spin_lock(&gss_auth->lock); | 323 | spin_lock(&inode->i_lock); |
| 323 | __gss_unhash_msg(gss_msg); | 324 | __gss_unhash_msg(gss_msg); |
| 324 | spin_unlock(&gss_auth->lock); | 325 | spin_unlock(&inode->i_lock); |
| 325 | } | 326 | } |
| 326 | 327 | ||
| 327 | static void | 328 | static void |
| @@ -330,16 +331,16 @@ gss_upcall_callback(struct rpc_task *task) | |||
| 330 | struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, | 331 | struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, |
| 331 | struct gss_cred, gc_base); | 332 | struct gss_cred, gc_base); |
| 332 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; | 333 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; |
| 334 | struct inode *inode = gss_msg->auth->dentry->d_inode; | ||
| 333 | 335 | ||
| 334 | BUG_ON(gss_msg == NULL); | ||
| 335 | if (gss_msg->ctx) | 336 | if (gss_msg->ctx) |
| 336 | gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx)); | 337 | gss_cred_set_ctx(task->tk_msg.rpc_cred, gss_get_ctx(gss_msg->ctx)); |
| 337 | else | 338 | else |
| 338 | task->tk_status = gss_msg->msg.errno; | 339 | task->tk_status = gss_msg->msg.errno; |
| 339 | spin_lock(&gss_msg->auth->lock); | 340 | spin_lock(&inode->i_lock); |
| 340 | gss_cred->gc_upcall = NULL; | 341 | gss_cred->gc_upcall = NULL; |
| 341 | rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); | 342 | rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); |
| 342 | spin_unlock(&gss_msg->auth->lock); | 343 | spin_unlock(&inode->i_lock); |
| 343 | gss_release_msg(gss_msg); | 344 | gss_release_msg(gss_msg); |
| 344 | } | 345 | } |
| 345 | 346 | ||
| @@ -391,6 +392,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
| 391 | struct gss_cred *gss_cred = container_of(cred, | 392 | struct gss_cred *gss_cred = container_of(cred, |
| 392 | struct gss_cred, gc_base); | 393 | struct gss_cred, gc_base); |
| 393 | struct gss_upcall_msg *gss_msg; | 394 | struct gss_upcall_msg *gss_msg; |
| 395 | struct inode *inode = gss_auth->dentry->d_inode; | ||
| 394 | int err = 0; | 396 | int err = 0; |
| 395 | 397 | ||
| 396 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, | 398 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, |
| @@ -400,7 +402,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
| 400 | err = PTR_ERR(gss_msg); | 402 | err = PTR_ERR(gss_msg); |
| 401 | goto out; | 403 | goto out; |
| 402 | } | 404 | } |
| 403 | spin_lock(&gss_auth->lock); | 405 | spin_lock(&inode->i_lock); |
| 404 | if (gss_cred->gc_upcall != NULL) | 406 | if (gss_cred->gc_upcall != NULL) |
| 405 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL); | 407 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL); |
| 406 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { | 408 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { |
| @@ -411,7 +413,7 @@ gss_refresh_upcall(struct rpc_task *task) | |||
| 411 | rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL); | 413 | rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL); |
| 412 | } else | 414 | } else |
| 413 | err = gss_msg->msg.errno; | 415 | err = gss_msg->msg.errno; |
| 414 | spin_unlock(&gss_auth->lock); | 416 | spin_unlock(&inode->i_lock); |
| 415 | gss_release_msg(gss_msg); | 417 | gss_release_msg(gss_msg); |
| 416 | out: | 418 | out: |
| 417 | dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", | 419 | dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n", |
| @@ -422,6 +424,7 @@ out: | |||
| 422 | static inline int | 424 | static inline int |
| 423 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | 425 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) |
| 424 | { | 426 | { |
| 427 | struct inode *inode = gss_auth->dentry->d_inode; | ||
| 425 | struct rpc_cred *cred = &gss_cred->gc_base; | 428 | struct rpc_cred *cred = &gss_cred->gc_base; |
| 426 | struct gss_upcall_msg *gss_msg; | 429 | struct gss_upcall_msg *gss_msg; |
| 427 | DEFINE_WAIT(wait); | 430 | DEFINE_WAIT(wait); |
| @@ -435,12 +438,12 @@ gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | |||
| 435 | } | 438 | } |
| 436 | for (;;) { | 439 | for (;;) { |
| 437 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); | 440 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); |
| 438 | spin_lock(&gss_auth->lock); | 441 | spin_lock(&inode->i_lock); |
| 439 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { | 442 | if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { |
| 440 | spin_unlock(&gss_auth->lock); | 443 | spin_unlock(&inode->i_lock); |
| 441 | break; | 444 | break; |
| 442 | } | 445 | } |
| 443 | spin_unlock(&gss_auth->lock); | 446 | spin_unlock(&inode->i_lock); |
| 444 | if (signalled()) { | 447 | if (signalled()) { |
| 445 | err = -ERESTARTSYS; | 448 | err = -ERESTARTSYS; |
| 446 | goto out_intr; | 449 | goto out_intr; |
| @@ -492,6 +495,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 492 | struct gss_auth *gss_auth; | 495 | struct gss_auth *gss_auth; |
| 493 | struct rpc_cred *cred; | 496 | struct rpc_cred *cred; |
| 494 | struct gss_upcall_msg *gss_msg; | 497 | struct gss_upcall_msg *gss_msg; |
| 498 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
| 495 | struct gss_cl_ctx *ctx; | 499 | struct gss_cl_ctx *ctx; |
| 496 | uid_t uid; | 500 | uid_t uid; |
| 497 | int err = -EFBIG; | 501 | int err = -EFBIG; |
| @@ -503,7 +507,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 503 | if (!buf) | 507 | if (!buf) |
| 504 | goto out; | 508 | goto out; |
| 505 | 509 | ||
| 506 | clnt = RPC_I(filp->f_path.dentry->d_inode)->private; | 510 | clnt = RPC_I(inode)->private; |
| 507 | err = -EFAULT; | 511 | err = -EFAULT; |
| 508 | if (copy_from_user(buf, src, mlen)) | 512 | if (copy_from_user(buf, src, mlen)) |
| 509 | goto err; | 513 | goto err; |
| @@ -527,18 +531,18 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 527 | if (err != -EACCES) | 531 | if (err != -EACCES) |
| 528 | goto err_put_ctx; | 532 | goto err_put_ctx; |
| 529 | } | 533 | } |
| 530 | spin_lock(&gss_auth->lock); | 534 | spin_lock(&inode->i_lock); |
| 531 | gss_msg = __gss_find_upcall(gss_auth, uid); | 535 | gss_msg = __gss_find_upcall(gss_auth, uid); |
| 532 | if (gss_msg) { | 536 | if (gss_msg) { |
| 533 | if (err == 0 && gss_msg->ctx == NULL) | 537 | if (err == 0 && gss_msg->ctx == NULL) |
| 534 | gss_msg->ctx = gss_get_ctx(ctx); | 538 | gss_msg->ctx = gss_get_ctx(ctx); |
| 535 | gss_msg->msg.errno = err; | 539 | gss_msg->msg.errno = err; |
| 536 | __gss_unhash_msg(gss_msg); | 540 | __gss_unhash_msg(gss_msg); |
| 537 | spin_unlock(&gss_auth->lock); | 541 | spin_unlock(&inode->i_lock); |
| 538 | gss_release_msg(gss_msg); | 542 | gss_release_msg(gss_msg); |
| 539 | } else { | 543 | } else { |
| 540 | struct auth_cred acred = { .uid = uid }; | 544 | struct auth_cred acred = { .uid = uid }; |
| 541 | spin_unlock(&gss_auth->lock); | 545 | spin_unlock(&inode->i_lock); |
| 542 | cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW); | 546 | cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW); |
| 543 | if (IS_ERR(cred)) { | 547 | if (IS_ERR(cred)) { |
| 544 | err = PTR_ERR(cred); | 548 | err = PTR_ERR(cred); |
| @@ -570,7 +574,7 @@ gss_pipe_release(struct inode *inode) | |||
| 570 | clnt = rpci->private; | 574 | clnt = rpci->private; |
| 571 | auth = clnt->cl_auth; | 575 | auth = clnt->cl_auth; |
| 572 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 576 | gss_auth = container_of(auth, struct gss_auth, rpc_auth); |
| 573 | spin_lock(&gss_auth->lock); | 577 | spin_lock(&inode->i_lock); |
| 574 | while (!list_empty(&gss_auth->upcalls)) { | 578 | while (!list_empty(&gss_auth->upcalls)) { |
| 575 | struct gss_upcall_msg *gss_msg; | 579 | struct gss_upcall_msg *gss_msg; |
| 576 | 580 | ||
| @@ -579,11 +583,11 @@ gss_pipe_release(struct inode *inode) | |||
| 579 | gss_msg->msg.errno = -EPIPE; | 583 | gss_msg->msg.errno = -EPIPE; |
| 580 | atomic_inc(&gss_msg->count); | 584 | atomic_inc(&gss_msg->count); |
| 581 | __gss_unhash_msg(gss_msg); | 585 | __gss_unhash_msg(gss_msg); |
| 582 | spin_unlock(&gss_auth->lock); | 586 | spin_unlock(&inode->i_lock); |
| 583 | gss_release_msg(gss_msg); | 587 | gss_release_msg(gss_msg); |
| 584 | spin_lock(&gss_auth->lock); | 588 | spin_lock(&inode->i_lock); |
| 585 | } | 589 | } |
| 586 | spin_unlock(&gss_auth->lock); | 590 | spin_unlock(&inode->i_lock); |
| 587 | } | 591 | } |
| 588 | 592 | ||
| 589 | static void | 593 | static void |
| @@ -638,7 +642,6 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | |||
| 638 | if (gss_auth->service == 0) | 642 | if (gss_auth->service == 0) |
| 639 | goto err_put_mech; | 643 | goto err_put_mech; |
| 640 | INIT_LIST_HEAD(&gss_auth->upcalls); | 644 | INIT_LIST_HEAD(&gss_auth->upcalls); |
| 641 | spin_lock_init(&gss_auth->lock); | ||
| 642 | auth = &gss_auth->rpc_auth; | 645 | auth = &gss_auth->rpc_auth; |
| 643 | auth->au_cslack = GSS_CRED_SLACK >> 2; | 646 | auth->au_cslack = GSS_CRED_SLACK >> 2; |
| 644 | auth->au_rslack = GSS_VERF_SLACK >> 2; | 647 | auth->au_rslack = GSS_VERF_SLACK >> 2; |
