diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/sunrpc/auth.c | 6 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 295 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_generic_token.c | 6 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_mech_switch.c | 18 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 28 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 16 | ||||
| -rw-r--r-- | net/sunrpc/rpc_pipe.c | 42 | ||||
| -rw-r--r-- | net/sunrpc/xdr.c | 50 |
8 files changed, 350 insertions, 111 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 0443f8349458..0c431c277af5 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -234,7 +234,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan) | |||
| 234 | list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { | 234 | list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { |
| 235 | 235 | ||
| 236 | /* Enforce a 60 second garbage collection moratorium */ | 236 | /* Enforce a 60 second garbage collection moratorium */ |
| 237 | if (time_in_range(cred->cr_expire, expired, jiffies) && | 237 | if (time_in_range_open(cred->cr_expire, expired, jiffies) && |
| 238 | test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) | 238 | test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) |
| 239 | continue; | 239 | continue; |
| 240 | 240 | ||
| @@ -515,7 +515,7 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, | |||
| 515 | if (cred->cr_ops->crwrap_req) | 515 | if (cred->cr_ops->crwrap_req) |
| 516 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); | 516 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); |
| 517 | /* By default, we encode the arguments normally. */ | 517 | /* By default, we encode the arguments normally. */ |
| 518 | return rpc_call_xdrproc(encode, rqstp, data, obj); | 518 | return encode(rqstp, data, obj); |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | int | 521 | int |
| @@ -530,7 +530,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
| 530 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, | 530 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, |
| 531 | data, obj); | 531 | data, obj); |
| 532 | /* By default, we decode the arguments normally. */ | 532 | /* By default, we decode the arguments normally. */ |
| 533 | return rpc_call_xdrproc(decode, rqstp, data, obj); | 533 | return decode(rqstp, data, obj); |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | int | 536 | int |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 853a4142cea1..e630b38a6047 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -72,11 +72,25 @@ struct gss_auth { | |||
| 72 | struct gss_api_mech *mech; | 72 | struct gss_api_mech *mech; |
| 73 | enum rpc_gss_svc service; | 73 | enum rpc_gss_svc service; |
| 74 | struct rpc_clnt *client; | 74 | struct rpc_clnt *client; |
| 75 | struct dentry *dentry; | 75 | /* |
| 76 | * There are two upcall pipes; dentry[1], named "gssd", is used | ||
| 77 | * for the new text-based upcall; dentry[0] is named after the | ||
| 78 | * mechanism (for example, "krb5") and exists for | ||
| 79 | * backwards-compatibility with older gssd's. | ||
| 80 | */ | ||
| 81 | struct dentry *dentry[2]; | ||
| 76 | }; | 82 | }; |
| 77 | 83 | ||
| 84 | /* pipe_version >= 0 if and only if someone has a pipe open. */ | ||
| 85 | static int pipe_version = -1; | ||
| 86 | static atomic_t pipe_users = ATOMIC_INIT(0); | ||
| 87 | static DEFINE_SPINLOCK(pipe_version_lock); | ||
| 88 | static struct rpc_wait_queue pipe_version_rpc_waitqueue; | ||
| 89 | static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); | ||
| 90 | |||
| 78 | static void gss_free_ctx(struct gss_cl_ctx *); | 91 | static void gss_free_ctx(struct gss_cl_ctx *); |
| 79 | static struct rpc_pipe_ops gss_upcall_ops; | 92 | static struct rpc_pipe_ops gss_upcall_ops_v0; |
| 93 | static struct rpc_pipe_ops gss_upcall_ops_v1; | ||
| 80 | 94 | ||
| 81 | static inline struct gss_cl_ctx * | 95 | static inline struct gss_cl_ctx * |
| 82 | gss_get_ctx(struct gss_cl_ctx *ctx) | 96 | gss_get_ctx(struct gss_cl_ctx *ctx) |
| @@ -220,6 +234,7 @@ err: | |||
| 220 | return p; | 234 | return p; |
| 221 | } | 235 | } |
| 222 | 236 | ||
| 237 | #define UPCALL_BUF_LEN 128 | ||
| 223 | 238 | ||
| 224 | struct gss_upcall_msg { | 239 | struct gss_upcall_msg { |
| 225 | atomic_t count; | 240 | atomic_t count; |
| @@ -227,16 +242,41 @@ struct gss_upcall_msg { | |||
| 227 | struct rpc_pipe_msg msg; | 242 | struct rpc_pipe_msg msg; |
| 228 | struct list_head list; | 243 | struct list_head list; |
| 229 | struct gss_auth *auth; | 244 | struct gss_auth *auth; |
| 245 | struct rpc_inode *inode; | ||
| 230 | struct rpc_wait_queue rpc_waitqueue; | 246 | struct rpc_wait_queue rpc_waitqueue; |
| 231 | wait_queue_head_t waitqueue; | 247 | wait_queue_head_t waitqueue; |
| 232 | struct gss_cl_ctx *ctx; | 248 | struct gss_cl_ctx *ctx; |
| 249 | char databuf[UPCALL_BUF_LEN]; | ||
| 233 | }; | 250 | }; |
| 234 | 251 | ||
| 252 | static int get_pipe_version(void) | ||
| 253 | { | ||
| 254 | int ret; | ||
| 255 | |||
| 256 | spin_lock(&pipe_version_lock); | ||
| 257 | if (pipe_version >= 0) { | ||
| 258 | atomic_inc(&pipe_users); | ||
| 259 | ret = pipe_version; | ||
| 260 | } else | ||
| 261 | ret = -EAGAIN; | ||
| 262 | spin_unlock(&pipe_version_lock); | ||
| 263 | return ret; | ||
| 264 | } | ||
| 265 | |||
| 266 | static void put_pipe_version(void) | ||
| 267 | { | ||
| 268 | if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) { | ||
| 269 | pipe_version = -1; | ||
| 270 | spin_unlock(&pipe_version_lock); | ||
| 271 | } | ||
| 272 | } | ||
| 273 | |||
| 235 | static void | 274 | static void |
| 236 | gss_release_msg(struct gss_upcall_msg *gss_msg) | 275 | gss_release_msg(struct gss_upcall_msg *gss_msg) |
| 237 | { | 276 | { |
| 238 | if (!atomic_dec_and_test(&gss_msg->count)) | 277 | if (!atomic_dec_and_test(&gss_msg->count)) |
| 239 | return; | 278 | return; |
| 279 | put_pipe_version(); | ||
| 240 | BUG_ON(!list_empty(&gss_msg->list)); | 280 | BUG_ON(!list_empty(&gss_msg->list)); |
| 241 | if (gss_msg->ctx != NULL) | 281 | if (gss_msg->ctx != NULL) |
| 242 | gss_put_ctx(gss_msg->ctx); | 282 | gss_put_ctx(gss_msg->ctx); |
| @@ -266,8 +306,8 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | |||
| 266 | static inline struct gss_upcall_msg * | 306 | static inline struct gss_upcall_msg * |
| 267 | gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) | 307 | gss_add_msg(struct gss_auth *gss_auth, struct gss_upcall_msg *gss_msg) |
| 268 | { | 308 | { |
| 269 | struct inode *inode = gss_auth->dentry->d_inode; | 309 | struct rpc_inode *rpci = gss_msg->inode; |
| 270 | struct rpc_inode *rpci = RPC_I(inode); | 310 | struct inode *inode = &rpci->vfs_inode; |
| 271 | struct gss_upcall_msg *old; | 311 | struct gss_upcall_msg *old; |
| 272 | 312 | ||
| 273 | spin_lock(&inode->i_lock); | 313 | spin_lock(&inode->i_lock); |
| @@ -293,8 +333,7 @@ __gss_unhash_msg(struct gss_upcall_msg *gss_msg) | |||
| 293 | static void | 333 | static void |
| 294 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) | 334 | gss_unhash_msg(struct gss_upcall_msg *gss_msg) |
| 295 | { | 335 | { |
| 296 | struct gss_auth *gss_auth = gss_msg->auth; | 336 | struct inode *inode = &gss_msg->inode->vfs_inode; |
| 297 | struct inode *inode = gss_auth->dentry->d_inode; | ||
| 298 | 337 | ||
| 299 | if (list_empty(&gss_msg->list)) | 338 | if (list_empty(&gss_msg->list)) |
| 300 | return; | 339 | return; |
| @@ -310,7 +349,7 @@ gss_upcall_callback(struct rpc_task *task) | |||
| 310 | struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, | 349 | struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, |
| 311 | struct gss_cred, gc_base); | 350 | struct gss_cred, gc_base); |
| 312 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; | 351 | struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; |
| 313 | struct inode *inode = gss_msg->auth->dentry->d_inode; | 352 | struct inode *inode = &gss_msg->inode->vfs_inode; |
| 314 | 353 | ||
| 315 | spin_lock(&inode->i_lock); | 354 | spin_lock(&inode->i_lock); |
| 316 | if (gss_msg->ctx) | 355 | if (gss_msg->ctx) |
| @@ -323,22 +362,75 @@ gss_upcall_callback(struct rpc_task *task) | |||
| 323 | gss_release_msg(gss_msg); | 362 | gss_release_msg(gss_msg); |
| 324 | } | 363 | } |
| 325 | 364 | ||
| 365 | static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) | ||
| 366 | { | ||
| 367 | gss_msg->msg.data = &gss_msg->uid; | ||
| 368 | gss_msg->msg.len = sizeof(gss_msg->uid); | ||
| 369 | } | ||
| 370 | |||
| 371 | static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, | ||
| 372 | struct rpc_clnt *clnt, int machine_cred) | ||
| 373 | { | ||
| 374 | char *p = gss_msg->databuf; | ||
| 375 | int len = 0; | ||
| 376 | |||
| 377 | gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", | ||
| 378 | gss_msg->auth->mech->gm_name, | ||
| 379 | gss_msg->uid); | ||
| 380 | p += gss_msg->msg.len; | ||
| 381 | if (clnt->cl_principal) { | ||
| 382 | len = sprintf(p, "target=%s ", clnt->cl_principal); | ||
| 383 | p += len; | ||
| 384 | gss_msg->msg.len += len; | ||
| 385 | } | ||
| 386 | if (machine_cred) { | ||
| 387 | len = sprintf(p, "service=* "); | ||
| 388 | p += len; | ||
| 389 | gss_msg->msg.len += len; | ||
| 390 | } else if (!strcmp(clnt->cl_program->name, "nfs4_cb")) { | ||
| 391 | len = sprintf(p, "service=nfs "); | ||
| 392 | p += len; | ||
| 393 | gss_msg->msg.len += len; | ||
| 394 | } | ||
| 395 | len = sprintf(p, "\n"); | ||
| 396 | gss_msg->msg.len += len; | ||
| 397 | |||
| 398 | gss_msg->msg.data = gss_msg->databuf; | ||
| 399 | BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN); | ||
| 400 | } | ||
| 401 | |||
| 402 | static void gss_encode_msg(struct gss_upcall_msg *gss_msg, | ||
| 403 | struct rpc_clnt *clnt, int machine_cred) | ||
| 404 | { | ||
| 405 | if (pipe_version == 0) | ||
| 406 | gss_encode_v0_msg(gss_msg); | ||
| 407 | else /* pipe_version == 1 */ | ||
| 408 | gss_encode_v1_msg(gss_msg, clnt, machine_cred); | ||
| 409 | } | ||
| 410 | |||
| 326 | static inline struct gss_upcall_msg * | 411 | static inline struct gss_upcall_msg * |
| 327 | gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) | 412 | gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid, struct rpc_clnt *clnt, |
| 413 | int machine_cred) | ||
| 328 | { | 414 | { |
| 329 | struct gss_upcall_msg *gss_msg; | 415 | struct gss_upcall_msg *gss_msg; |
| 416 | int vers; | ||
| 330 | 417 | ||
| 331 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); | 418 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); |
| 332 | if (gss_msg != NULL) { | 419 | if (gss_msg == NULL) |
| 333 | INIT_LIST_HEAD(&gss_msg->list); | 420 | return ERR_PTR(-ENOMEM); |
| 334 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | 421 | vers = get_pipe_version(); |
| 335 | init_waitqueue_head(&gss_msg->waitqueue); | 422 | if (vers < 0) { |
| 336 | atomic_set(&gss_msg->count, 1); | 423 | kfree(gss_msg); |
| 337 | gss_msg->msg.data = &gss_msg->uid; | 424 | return ERR_PTR(vers); |
| 338 | gss_msg->msg.len = sizeof(gss_msg->uid); | ||
| 339 | gss_msg->uid = uid; | ||
| 340 | gss_msg->auth = gss_auth; | ||
| 341 | } | 425 | } |
| 426 | gss_msg->inode = RPC_I(gss_auth->dentry[vers]->d_inode); | ||
| 427 | INIT_LIST_HEAD(&gss_msg->list); | ||
| 428 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | ||
| 429 | init_waitqueue_head(&gss_msg->waitqueue); | ||
| 430 | atomic_set(&gss_msg->count, 1); | ||
| 431 | gss_msg->uid = uid; | ||
| 432 | gss_msg->auth = gss_auth; | ||
| 433 | gss_encode_msg(gss_msg, clnt, machine_cred); | ||
| 342 | return gss_msg; | 434 | return gss_msg; |
| 343 | } | 435 | } |
| 344 | 436 | ||
| @@ -350,16 +442,13 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
| 350 | struct gss_upcall_msg *gss_new, *gss_msg; | 442 | struct gss_upcall_msg *gss_new, *gss_msg; |
| 351 | uid_t uid = cred->cr_uid; | 443 | uid_t uid = cred->cr_uid; |
| 352 | 444 | ||
| 353 | /* Special case: rpc.gssd assumes that uid == 0 implies machine creds */ | 445 | gss_new = gss_alloc_msg(gss_auth, uid, clnt, gss_cred->gc_machine_cred); |
| 354 | if (gss_cred->gc_machine_cred != 0) | 446 | if (IS_ERR(gss_new)) |
| 355 | uid = 0; | 447 | return gss_new; |
| 356 | |||
| 357 | gss_new = gss_alloc_msg(gss_auth, uid); | ||
| 358 | if (gss_new == NULL) | ||
| 359 | return ERR_PTR(-ENOMEM); | ||
| 360 | gss_msg = gss_add_msg(gss_auth, gss_new); | 448 | gss_msg = gss_add_msg(gss_auth, gss_new); |
| 361 | if (gss_msg == gss_new) { | 449 | if (gss_msg == gss_new) { |
| 362 | int res = rpc_queue_upcall(gss_auth->dentry->d_inode, &gss_new->msg); | 450 | struct inode *inode = &gss_new->inode->vfs_inode; |
| 451 | int res = rpc_queue_upcall(inode, &gss_new->msg); | ||
| 363 | if (res) { | 452 | if (res) { |
| 364 | gss_unhash_msg(gss_new); | 453 | gss_unhash_msg(gss_new); |
| 365 | gss_msg = ERR_PTR(res); | 454 | gss_msg = ERR_PTR(res); |
| @@ -369,6 +458,18 @@ gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cr | |||
| 369 | return gss_msg; | 458 | return gss_msg; |
| 370 | } | 459 | } |
| 371 | 460 | ||
| 461 | static void warn_gssd(void) | ||
| 462 | { | ||
| 463 | static unsigned long ratelimit; | ||
| 464 | unsigned long now = jiffies; | ||
| 465 | |||
| 466 | if (time_after(now, ratelimit)) { | ||
| 467 | printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n" | ||
| 468 | "Please check user daemon is running.\n"); | ||
| 469 | ratelimit = now + 15*HZ; | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 372 | static inline int | 473 | static inline int |
| 373 | gss_refresh_upcall(struct rpc_task *task) | 474 | gss_refresh_upcall(struct rpc_task *task) |
| 374 | { | 475 | { |
| @@ -378,16 +479,25 @@ gss_refresh_upcall(struct rpc_task *task) | |||
| 378 | struct gss_cred *gss_cred = container_of(cred, | 479 | struct gss_cred *gss_cred = container_of(cred, |
| 379 | struct gss_cred, gc_base); | 480 | struct gss_cred, gc_base); |
| 380 | struct gss_upcall_msg *gss_msg; | 481 | struct gss_upcall_msg *gss_msg; |
| 381 | struct inode *inode = gss_auth->dentry->d_inode; | 482 | struct inode *inode; |
| 382 | int err = 0; | 483 | int err = 0; |
| 383 | 484 | ||
| 384 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, | 485 | dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid, |
| 385 | cred->cr_uid); | 486 | cred->cr_uid); |
| 386 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); | 487 | gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred); |
| 488 | if (IS_ERR(gss_msg) == -EAGAIN) { | ||
| 489 | /* XXX: warning on the first, under the assumption we | ||
| 490 | * shouldn't normally hit this case on a refresh. */ | ||
| 491 | warn_gssd(); | ||
| 492 | task->tk_timeout = 15*HZ; | ||
| 493 | rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL); | ||
| 494 | return 0; | ||
| 495 | } | ||
| 387 | if (IS_ERR(gss_msg)) { | 496 | if (IS_ERR(gss_msg)) { |
| 388 | err = PTR_ERR(gss_msg); | 497 | err = PTR_ERR(gss_msg); |
| 389 | goto out; | 498 | goto out; |
| 390 | } | 499 | } |
| 500 | inode = &gss_msg->inode->vfs_inode; | ||
| 391 | spin_lock(&inode->i_lock); | 501 | spin_lock(&inode->i_lock); |
| 392 | if (gss_cred->gc_upcall != NULL) | 502 | if (gss_cred->gc_upcall != NULL) |
| 393 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); | 503 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); |
| @@ -414,18 +524,29 @@ out: | |||
| 414 | static inline int | 524 | static inline int |
| 415 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) | 525 | gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) |
| 416 | { | 526 | { |
| 417 | struct inode *inode = gss_auth->dentry->d_inode; | 527 | struct inode *inode; |
| 418 | struct rpc_cred *cred = &gss_cred->gc_base; | 528 | struct rpc_cred *cred = &gss_cred->gc_base; |
| 419 | struct gss_upcall_msg *gss_msg; | 529 | struct gss_upcall_msg *gss_msg; |
| 420 | DEFINE_WAIT(wait); | 530 | DEFINE_WAIT(wait); |
| 421 | int err = 0; | 531 | int err = 0; |
| 422 | 532 | ||
| 423 | dprintk("RPC: gss_upcall for uid %u\n", cred->cr_uid); | 533 | dprintk("RPC: gss_upcall for uid %u\n", cred->cr_uid); |
| 534 | retry: | ||
| 424 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); | 535 | gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred); |
| 536 | if (PTR_ERR(gss_msg) == -EAGAIN) { | ||
| 537 | err = wait_event_interruptible_timeout(pipe_version_waitqueue, | ||
| 538 | pipe_version >= 0, 15*HZ); | ||
| 539 | if (err) | ||
| 540 | goto out; | ||
| 541 | if (pipe_version < 0) | ||
| 542 | warn_gssd(); | ||
| 543 | goto retry; | ||
| 544 | } | ||
| 425 | if (IS_ERR(gss_msg)) { | 545 | if (IS_ERR(gss_msg)) { |
| 426 | err = PTR_ERR(gss_msg); | 546 | err = PTR_ERR(gss_msg); |
| 427 | goto out; | 547 | goto out; |
| 428 | } | 548 | } |
| 549 | inode = &gss_msg->inode->vfs_inode; | ||
| 429 | for (;;) { | 550 | for (;;) { |
| 430 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); | 551 | prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_INTERRUPTIBLE); |
| 431 | spin_lock(&inode->i_lock); | 552 | spin_lock(&inode->i_lock); |
| @@ -543,6 +664,38 @@ out: | |||
| 543 | return err; | 664 | return err; |
| 544 | } | 665 | } |
| 545 | 666 | ||
| 667 | static int gss_pipe_open(struct inode *inode, int new_version) | ||
| 668 | { | ||
| 669 | int ret = 0; | ||
| 670 | |||
| 671 | spin_lock(&pipe_version_lock); | ||
| 672 | if (pipe_version < 0) { | ||
| 673 | /* First open of any gss pipe determines the version: */ | ||
| 674 | pipe_version = new_version; | ||
| 675 | rpc_wake_up(&pipe_version_rpc_waitqueue); | ||
| 676 | wake_up(&pipe_version_waitqueue); | ||
| 677 | } else if (pipe_version != new_version) { | ||
| 678 | /* Trying to open a pipe of a different version */ | ||
| 679 | ret = -EBUSY; | ||
| 680 | goto out; | ||
| 681 | } | ||
| 682 | atomic_inc(&pipe_users); | ||
| 683 | out: | ||
| 684 | spin_unlock(&pipe_version_lock); | ||
| 685 | return ret; | ||
| 686 | |||
| 687 | } | ||
| 688 | |||
| 689 | static int gss_pipe_open_v0(struct inode *inode) | ||
| 690 | { | ||
| 691 | return gss_pipe_open(inode, 0); | ||
| 692 | } | ||
| 693 | |||
| 694 | static int gss_pipe_open_v1(struct inode *inode) | ||
| 695 | { | ||
| 696 | return gss_pipe_open(inode, 1); | ||
| 697 | } | ||
| 698 | |||
| 546 | static void | 699 | static void |
| 547 | gss_pipe_release(struct inode *inode) | 700 | gss_pipe_release(struct inode *inode) |
| 548 | { | 701 | { |
| @@ -562,27 +715,22 @@ gss_pipe_release(struct inode *inode) | |||
| 562 | spin_lock(&inode->i_lock); | 715 | spin_lock(&inode->i_lock); |
| 563 | } | 716 | } |
| 564 | spin_unlock(&inode->i_lock); | 717 | spin_unlock(&inode->i_lock); |
| 718 | |||
| 719 | put_pipe_version(); | ||
| 565 | } | 720 | } |
| 566 | 721 | ||
| 567 | static void | 722 | static void |
| 568 | gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) | 723 | gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) |
| 569 | { | 724 | { |
| 570 | struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg); | 725 | struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg); |
| 571 | static unsigned long ratelimit; | ||
| 572 | 726 | ||
| 573 | if (msg->errno < 0) { | 727 | if (msg->errno < 0) { |
| 574 | dprintk("RPC: gss_pipe_destroy_msg releasing msg %p\n", | 728 | dprintk("RPC: gss_pipe_destroy_msg releasing msg %p\n", |
| 575 | gss_msg); | 729 | gss_msg); |
| 576 | atomic_inc(&gss_msg->count); | 730 | atomic_inc(&gss_msg->count); |
| 577 | gss_unhash_msg(gss_msg); | 731 | gss_unhash_msg(gss_msg); |
| 578 | if (msg->errno == -ETIMEDOUT) { | 732 | if (msg->errno == -ETIMEDOUT) |
| 579 | unsigned long now = jiffies; | 733 | warn_gssd(); |
| 580 | if (time_after(now, ratelimit)) { | ||
| 581 | printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n" | ||
| 582 | "Please check user daemon is running!\n"); | ||
| 583 | ratelimit = now + 15*HZ; | ||
| 584 | } | ||
| 585 | } | ||
| 586 | gss_release_msg(gss_msg); | 734 | gss_release_msg(gss_msg); |
| 587 | } | 735 | } |
| 588 | } | 736 | } |
| @@ -623,20 +771,38 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | |||
| 623 | atomic_set(&auth->au_count, 1); | 771 | atomic_set(&auth->au_count, 1); |
| 624 | kref_init(&gss_auth->kref); | 772 | kref_init(&gss_auth->kref); |
| 625 | 773 | ||
| 626 | gss_auth->dentry = rpc_mkpipe(clnt->cl_dentry, gss_auth->mech->gm_name, | 774 | /* |
| 627 | clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); | 775 | * Note: if we created the old pipe first, then someone who |
| 628 | if (IS_ERR(gss_auth->dentry)) { | 776 | * examined the directory at the right moment might conclude |
| 629 | err = PTR_ERR(gss_auth->dentry); | 777 | * that we supported only the old pipe. So we instead create |
| 778 | * the new pipe first. | ||
| 779 | */ | ||
| 780 | gss_auth->dentry[1] = rpc_mkpipe(clnt->cl_dentry, | ||
| 781 | "gssd", | ||
| 782 | clnt, &gss_upcall_ops_v1, | ||
| 783 | RPC_PIPE_WAIT_FOR_OPEN); | ||
| 784 | if (IS_ERR(gss_auth->dentry[1])) { | ||
| 785 | err = PTR_ERR(gss_auth->dentry[1]); | ||
| 630 | goto err_put_mech; | 786 | goto err_put_mech; |
| 631 | } | 787 | } |
| 632 | 788 | ||
| 789 | gss_auth->dentry[0] = rpc_mkpipe(clnt->cl_dentry, | ||
| 790 | gss_auth->mech->gm_name, | ||
| 791 | clnt, &gss_upcall_ops_v0, | ||
| 792 | RPC_PIPE_WAIT_FOR_OPEN); | ||
| 793 | if (IS_ERR(gss_auth->dentry[0])) { | ||
| 794 | err = PTR_ERR(gss_auth->dentry[0]); | ||
| 795 | goto err_unlink_pipe_1; | ||
| 796 | } | ||
| 633 | err = rpcauth_init_credcache(auth); | 797 | err = rpcauth_init_credcache(auth); |
| 634 | if (err) | 798 | if (err) |
| 635 | goto err_unlink_pipe; | 799 | goto err_unlink_pipe_0; |
| 636 | 800 | ||
| 637 | return auth; | 801 | return auth; |
| 638 | err_unlink_pipe: | 802 | err_unlink_pipe_0: |
| 639 | rpc_unlink(gss_auth->dentry); | 803 | rpc_unlink(gss_auth->dentry[0]); |
| 804 | err_unlink_pipe_1: | ||
| 805 | rpc_unlink(gss_auth->dentry[1]); | ||
| 640 | err_put_mech: | 806 | err_put_mech: |
| 641 | gss_mech_put(gss_auth->mech); | 807 | gss_mech_put(gss_auth->mech); |
| 642 | err_free: | 808 | err_free: |
| @@ -649,8 +815,8 @@ out_dec: | |||
| 649 | static void | 815 | static void |
| 650 | gss_free(struct gss_auth *gss_auth) | 816 | gss_free(struct gss_auth *gss_auth) |
| 651 | { | 817 | { |
| 652 | rpc_unlink(gss_auth->dentry); | 818 | rpc_unlink(gss_auth->dentry[1]); |
| 653 | gss_auth->dentry = NULL; | 819 | rpc_unlink(gss_auth->dentry[0]); |
| 654 | gss_mech_put(gss_auth->mech); | 820 | gss_mech_put(gss_auth->mech); |
| 655 | 821 | ||
| 656 | kfree(gss_auth); | 822 | kfree(gss_auth); |
| @@ -693,7 +859,7 @@ gss_destroying_context(struct rpc_cred *cred) | |||
| 693 | struct rpc_task *task; | 859 | struct rpc_task *task; |
| 694 | 860 | ||
| 695 | if (gss_cred->gc_ctx == NULL || | 861 | if (gss_cred->gc_ctx == NULL || |
| 696 | test_and_clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) | 862 | test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) |
| 697 | return 0; | 863 | return 0; |
| 698 | 864 | ||
| 699 | gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY; | 865 | gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY; |
| @@ -757,14 +923,12 @@ gss_free_cred_callback(struct rcu_head *head) | |||
| 757 | } | 923 | } |
| 758 | 924 | ||
| 759 | static void | 925 | static void |
| 760 | gss_destroy_cred(struct rpc_cred *cred) | 926 | gss_destroy_nullcred(struct rpc_cred *cred) |
| 761 | { | 927 | { |
| 762 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); | 928 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); |
| 763 | struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); | 929 | struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); |
| 764 | struct gss_cl_ctx *ctx = gss_cred->gc_ctx; | 930 | struct gss_cl_ctx *ctx = gss_cred->gc_ctx; |
| 765 | 931 | ||
| 766 | if (gss_destroying_context(cred)) | ||
| 767 | return; | ||
| 768 | rcu_assign_pointer(gss_cred->gc_ctx, NULL); | 932 | rcu_assign_pointer(gss_cred->gc_ctx, NULL); |
| 769 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); | 933 | call_rcu(&cred->cr_rcu, gss_free_cred_callback); |
| 770 | if (ctx) | 934 | if (ctx) |
| @@ -772,6 +936,15 @@ gss_destroy_cred(struct rpc_cred *cred) | |||
| 772 | kref_put(&gss_auth->kref, gss_free_callback); | 936 | kref_put(&gss_auth->kref, gss_free_callback); |
| 773 | } | 937 | } |
| 774 | 938 | ||
| 939 | static void | ||
| 940 | gss_destroy_cred(struct rpc_cred *cred) | ||
| 941 | { | ||
| 942 | |||
| 943 | if (gss_destroying_context(cred)) | ||
| 944 | return; | ||
| 945 | gss_destroy_nullcred(cred); | ||
| 946 | } | ||
| 947 | |||
| 775 | /* | 948 | /* |
| 776 | * Lookup RPCSEC_GSS cred for the current process | 949 | * Lookup RPCSEC_GSS cred for the current process |
| 777 | */ | 950 | */ |
| @@ -1017,7 +1190,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
| 1017 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1190 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
| 1018 | *p++ = htonl(rqstp->rq_seqno); | 1191 | *p++ = htonl(rqstp->rq_seqno); |
| 1019 | 1192 | ||
| 1020 | status = rpc_call_xdrproc(encode, rqstp, p, obj); | 1193 | status = encode(rqstp, p, obj); |
| 1021 | if (status) | 1194 | if (status) |
| 1022 | return status; | 1195 | return status; |
| 1023 | 1196 | ||
| @@ -1111,7 +1284,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
| 1111 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1284 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
| 1112 | *p++ = htonl(rqstp->rq_seqno); | 1285 | *p++ = htonl(rqstp->rq_seqno); |
| 1113 | 1286 | ||
| 1114 | status = rpc_call_xdrproc(encode, rqstp, p, obj); | 1287 | status = encode(rqstp, p, obj); |
| 1115 | if (status) | 1288 | if (status) |
| 1116 | return status; | 1289 | return status; |
| 1117 | 1290 | ||
| @@ -1170,12 +1343,12 @@ gss_wrap_req(struct rpc_task *task, | |||
| 1170 | /* The spec seems a little ambiguous here, but I think that not | 1343 | /* The spec seems a little ambiguous here, but I think that not |
| 1171 | * wrapping context destruction requests makes the most sense. | 1344 | * wrapping context destruction requests makes the most sense. |
| 1172 | */ | 1345 | */ |
| 1173 | status = rpc_call_xdrproc(encode, rqstp, p, obj); | 1346 | status = encode(rqstp, p, obj); |
| 1174 | goto out; | 1347 | goto out; |
| 1175 | } | 1348 | } |
| 1176 | switch (gss_cred->gc_service) { | 1349 | switch (gss_cred->gc_service) { |
| 1177 | case RPC_GSS_SVC_NONE: | 1350 | case RPC_GSS_SVC_NONE: |
| 1178 | status = rpc_call_xdrproc(encode, rqstp, p, obj); | 1351 | status = encode(rqstp, p, obj); |
| 1179 | break; | 1352 | break; |
| 1180 | case RPC_GSS_SVC_INTEGRITY: | 1353 | case RPC_GSS_SVC_INTEGRITY: |
| 1181 | status = gss_wrap_req_integ(cred, ctx, encode, | 1354 | status = gss_wrap_req_integ(cred, ctx, encode, |
| @@ -1291,7 +1464,7 @@ gss_unwrap_resp(struct rpc_task *task, | |||
| 1291 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) | 1464 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) |
| 1292 | + (savedlen - head->iov_len); | 1465 | + (savedlen - head->iov_len); |
| 1293 | out_decode: | 1466 | out_decode: |
| 1294 | status = rpc_call_xdrproc(decode, rqstp, p, obj); | 1467 | status = decode(rqstp, p, obj); |
| 1295 | out: | 1468 | out: |
| 1296 | gss_put_ctx(ctx); | 1469 | gss_put_ctx(ctx); |
| 1297 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, | 1470 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, |
| @@ -1324,7 +1497,7 @@ static const struct rpc_credops gss_credops = { | |||
| 1324 | 1497 | ||
| 1325 | static const struct rpc_credops gss_nullops = { | 1498 | static const struct rpc_credops gss_nullops = { |
| 1326 | .cr_name = "AUTH_GSS", | 1499 | .cr_name = "AUTH_GSS", |
| 1327 | .crdestroy = gss_destroy_cred, | 1500 | .crdestroy = gss_destroy_nullcred, |
| 1328 | .crbind = rpcauth_generic_bind_cred, | 1501 | .crbind = rpcauth_generic_bind_cred, |
| 1329 | .crmatch = gss_match, | 1502 | .crmatch = gss_match, |
| 1330 | .crmarshal = gss_marshal, | 1503 | .crmarshal = gss_marshal, |
| @@ -1334,10 +1507,19 @@ static const struct rpc_credops gss_nullops = { | |||
| 1334 | .crunwrap_resp = gss_unwrap_resp, | 1507 | .crunwrap_resp = gss_unwrap_resp, |
| 1335 | }; | 1508 | }; |
| 1336 | 1509 | ||
| 1337 | static struct rpc_pipe_ops gss_upcall_ops = { | 1510 | static struct rpc_pipe_ops gss_upcall_ops_v0 = { |
| 1511 | .upcall = gss_pipe_upcall, | ||
| 1512 | .downcall = gss_pipe_downcall, | ||
| 1513 | .destroy_msg = gss_pipe_destroy_msg, | ||
| 1514 | .open_pipe = gss_pipe_open_v0, | ||
| 1515 | .release_pipe = gss_pipe_release, | ||
| 1516 | }; | ||
| 1517 | |||
| 1518 | static struct rpc_pipe_ops gss_upcall_ops_v1 = { | ||
| 1338 | .upcall = gss_pipe_upcall, | 1519 | .upcall = gss_pipe_upcall, |
| 1339 | .downcall = gss_pipe_downcall, | 1520 | .downcall = gss_pipe_downcall, |
| 1340 | .destroy_msg = gss_pipe_destroy_msg, | 1521 | .destroy_msg = gss_pipe_destroy_msg, |
| 1522 | .open_pipe = gss_pipe_open_v1, | ||
| 1341 | .release_pipe = gss_pipe_release, | 1523 | .release_pipe = gss_pipe_release, |
| 1342 | }; | 1524 | }; |
| 1343 | 1525 | ||
| @@ -1354,6 +1536,7 @@ static int __init init_rpcsec_gss(void) | |||
| 1354 | err = gss_svc_init(); | 1536 | err = gss_svc_init(); |
| 1355 | if (err) | 1537 | if (err) |
| 1356 | goto out_unregister; | 1538 | goto out_unregister; |
| 1539 | rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); | ||
| 1357 | return 0; | 1540 | return 0; |
| 1358 | out_unregister: | 1541 | out_unregister: |
| 1359 | rpcauth_unregister(&authgss_ops); | 1542 | rpcauth_unregister(&authgss_ops); |
diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c index d83b881685fe..c0ba39c4f5f2 100644 --- a/net/sunrpc/auth_gss/gss_generic_token.c +++ b/net/sunrpc/auth_gss/gss_generic_token.c | |||
| @@ -152,7 +152,7 @@ g_token_size(struct xdr_netobj *mech, unsigned int body_size) | |||
| 152 | return(1 + der_length_size(body_size) + body_size); | 152 | return(1 + der_length_size(body_size) + body_size); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | EXPORT_SYMBOL(g_token_size); | 155 | EXPORT_SYMBOL_GPL(g_token_size); |
| 156 | 156 | ||
| 157 | /* fills in a buffer with the token header. The buffer is assumed to | 157 | /* fills in a buffer with the token header. The buffer is assumed to |
| 158 | be the right size. buf is advanced past the token header */ | 158 | be the right size. buf is advanced past the token header */ |
| @@ -167,7 +167,7 @@ g_make_token_header(struct xdr_netobj *mech, int body_size, unsigned char **buf) | |||
| 167 | TWRITE_STR(*buf, mech->data, ((int) mech->len)); | 167 | TWRITE_STR(*buf, mech->data, ((int) mech->len)); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | EXPORT_SYMBOL(g_make_token_header); | 170 | EXPORT_SYMBOL_GPL(g_make_token_header); |
| 171 | 171 | ||
| 172 | /* | 172 | /* |
| 173 | * Given a buffer containing a token, reads and verifies the token, | 173 | * Given a buffer containing a token, reads and verifies the token, |
| @@ -231,5 +231,5 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size, | |||
| 231 | return(ret); | 231 | return(ret); |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | EXPORT_SYMBOL(g_verify_token_header); | 234 | EXPORT_SYMBOL_GPL(g_verify_token_header); |
| 235 | 235 | ||
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index bce9d527af08..6efbb0cd3c7c 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c | |||
| @@ -117,7 +117,7 @@ gss_mech_register(struct gss_api_mech *gm) | |||
| 117 | return 0; | 117 | return 0; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | EXPORT_SYMBOL(gss_mech_register); | 120 | EXPORT_SYMBOL_GPL(gss_mech_register); |
| 121 | 121 | ||
| 122 | void | 122 | void |
| 123 | gss_mech_unregister(struct gss_api_mech *gm) | 123 | gss_mech_unregister(struct gss_api_mech *gm) |
| @@ -129,7 +129,7 @@ gss_mech_unregister(struct gss_api_mech *gm) | |||
| 129 | gss_mech_free(gm); | 129 | gss_mech_free(gm); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | EXPORT_SYMBOL(gss_mech_unregister); | 132 | EXPORT_SYMBOL_GPL(gss_mech_unregister); |
| 133 | 133 | ||
| 134 | struct gss_api_mech * | 134 | struct gss_api_mech * |
| 135 | gss_mech_get(struct gss_api_mech *gm) | 135 | gss_mech_get(struct gss_api_mech *gm) |
| @@ -138,7 +138,7 @@ gss_mech_get(struct gss_api_mech *gm) | |||
| 138 | return gm; | 138 | return gm; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | EXPORT_SYMBOL(gss_mech_get); | 141 | EXPORT_SYMBOL_GPL(gss_mech_get); |
| 142 | 142 | ||
| 143 | struct gss_api_mech * | 143 | struct gss_api_mech * |
| 144 | gss_mech_get_by_name(const char *name) | 144 | gss_mech_get_by_name(const char *name) |
| @@ -158,7 +158,7 @@ gss_mech_get_by_name(const char *name) | |||
| 158 | 158 | ||
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | EXPORT_SYMBOL(gss_mech_get_by_name); | 161 | EXPORT_SYMBOL_GPL(gss_mech_get_by_name); |
| 162 | 162 | ||
| 163 | static inline int | 163 | static inline int |
| 164 | mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor) | 164 | mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor) |
| @@ -191,7 +191,7 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | |||
| 191 | return gm; | 191 | return gm; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | EXPORT_SYMBOL(gss_mech_get_by_pseudoflavor); | 194 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); |
| 195 | 195 | ||
| 196 | u32 | 196 | u32 |
| 197 | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) | 197 | gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) |
| @@ -205,7 +205,7 @@ gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) | |||
| 205 | } | 205 | } |
| 206 | return RPC_AUTH_MAXFLAVOR; /* illegal value */ | 206 | return RPC_AUTH_MAXFLAVOR; /* illegal value */ |
| 207 | } | 207 | } |
| 208 | EXPORT_SYMBOL(gss_svc_to_pseudoflavor); | 208 | EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor); |
| 209 | 209 | ||
| 210 | u32 | 210 | u32 |
| 211 | gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) | 211 | gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) |
| @@ -219,7 +219,7 @@ gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) | |||
| 219 | return 0; | 219 | return 0; |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | EXPORT_SYMBOL(gss_pseudoflavor_to_service); | 222 | EXPORT_SYMBOL_GPL(gss_pseudoflavor_to_service); |
| 223 | 223 | ||
| 224 | char * | 224 | char * |
| 225 | gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) | 225 | gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) |
| @@ -233,7 +233,7 @@ gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service) | |||
| 233 | return NULL; | 233 | return NULL; |
| 234 | } | 234 | } |
| 235 | 235 | ||
| 236 | EXPORT_SYMBOL(gss_service_to_auth_domain_name); | 236 | EXPORT_SYMBOL_GPL(gss_service_to_auth_domain_name); |
| 237 | 237 | ||
| 238 | void | 238 | void |
| 239 | gss_mech_put(struct gss_api_mech * gm) | 239 | gss_mech_put(struct gss_api_mech * gm) |
| @@ -242,7 +242,7 @@ gss_mech_put(struct gss_api_mech * gm) | |||
| 242 | module_put(gm->gm_owner); | 242 | module_put(gm->gm_owner); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | EXPORT_SYMBOL(gss_mech_put); | 245 | EXPORT_SYMBOL_GPL(gss_mech_put); |
| 246 | 246 | ||
| 247 | /* The mech could probably be determined from the token instead, but it's just | 247 | /* The mech could probably be determined from the token instead, but it's just |
| 248 | * as easy for now to pass it in. */ | 248 | * as easy for now to pass it in. */ |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 81ae3d62a0cc..2278a50c6444 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -332,6 +332,7 @@ struct rsc { | |||
| 332 | struct svc_cred cred; | 332 | struct svc_cred cred; |
| 333 | struct gss_svc_seq_data seqdata; | 333 | struct gss_svc_seq_data seqdata; |
| 334 | struct gss_ctx *mechctx; | 334 | struct gss_ctx *mechctx; |
| 335 | char *client_name; | ||
| 335 | }; | 336 | }; |
| 336 | 337 | ||
| 337 | static struct cache_head *rsc_table[RSC_HASHMAX]; | 338 | static struct cache_head *rsc_table[RSC_HASHMAX]; |
| @@ -346,6 +347,7 @@ static void rsc_free(struct rsc *rsci) | |||
| 346 | gss_delete_sec_context(&rsci->mechctx); | 347 | gss_delete_sec_context(&rsci->mechctx); |
| 347 | if (rsci->cred.cr_group_info) | 348 | if (rsci->cred.cr_group_info) |
| 348 | put_group_info(rsci->cred.cr_group_info); | 349 | put_group_info(rsci->cred.cr_group_info); |
| 350 | kfree(rsci->client_name); | ||
| 349 | } | 351 | } |
| 350 | 352 | ||
| 351 | static void rsc_put(struct kref *ref) | 353 | static void rsc_put(struct kref *ref) |
| @@ -383,6 +385,7 @@ rsc_init(struct cache_head *cnew, struct cache_head *ctmp) | |||
| 383 | tmp->handle.data = NULL; | 385 | tmp->handle.data = NULL; |
| 384 | new->mechctx = NULL; | 386 | new->mechctx = NULL; |
| 385 | new->cred.cr_group_info = NULL; | 387 | new->cred.cr_group_info = NULL; |
| 388 | new->client_name = NULL; | ||
| 386 | } | 389 | } |
| 387 | 390 | ||
| 388 | static void | 391 | static void |
| @@ -397,6 +400,8 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp) | |||
| 397 | spin_lock_init(&new->seqdata.sd_lock); | 400 | spin_lock_init(&new->seqdata.sd_lock); |
| 398 | new->cred = tmp->cred; | 401 | new->cred = tmp->cred; |
| 399 | tmp->cred.cr_group_info = NULL; | 402 | tmp->cred.cr_group_info = NULL; |
| 403 | new->client_name = tmp->client_name; | ||
| 404 | tmp->client_name = NULL; | ||
| 400 | } | 405 | } |
| 401 | 406 | ||
| 402 | static struct cache_head * | 407 | static struct cache_head * |
| @@ -486,6 +491,15 @@ static int rsc_parse(struct cache_detail *cd, | |||
| 486 | status = gss_import_sec_context(buf, len, gm, &rsci.mechctx); | 491 | status = gss_import_sec_context(buf, len, gm, &rsci.mechctx); |
| 487 | if (status) | 492 | if (status) |
| 488 | goto out; | 493 | goto out; |
| 494 | |||
| 495 | /* get client name */ | ||
| 496 | len = qword_get(&mesg, buf, mlen); | ||
| 497 | if (len > 0) { | ||
| 498 | rsci.client_name = kstrdup(buf, GFP_KERNEL); | ||
| 499 | if (!rsci.client_name) | ||
| 500 | goto out; | ||
| 501 | } | ||
| 502 | |||
| 489 | } | 503 | } |
| 490 | rsci.h.expiry_time = expiry; | 504 | rsci.h.expiry_time = expiry; |
| 491 | rscp = rsc_update(&rsci, rscp); | 505 | rscp = rsc_update(&rsci, rscp); |
| @@ -746,7 +760,7 @@ u32 svcauth_gss_flavor(struct auth_domain *dom) | |||
| 746 | return gd->pseudoflavor; | 760 | return gd->pseudoflavor; |
| 747 | } | 761 | } |
| 748 | 762 | ||
| 749 | EXPORT_SYMBOL(svcauth_gss_flavor); | 763 | EXPORT_SYMBOL_GPL(svcauth_gss_flavor); |
| 750 | 764 | ||
| 751 | int | 765 | int |
| 752 | svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) | 766 | svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) |
| @@ -780,7 +794,7 @@ out: | |||
| 780 | return stat; | 794 | return stat; |
| 781 | } | 795 | } |
| 782 | 796 | ||
| 783 | EXPORT_SYMBOL(svcauth_gss_register_pseudoflavor); | 797 | EXPORT_SYMBOL_GPL(svcauth_gss_register_pseudoflavor); |
| 784 | 798 | ||
| 785 | static inline int | 799 | static inline int |
| 786 | read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj) | 800 | read_u32_from_xdr_buf(struct xdr_buf *buf, int base, u32 *obj) |
| @@ -913,6 +927,16 @@ struct gss_svc_data { | |||
| 913 | struct rsc *rsci; | 927 | struct rsc *rsci; |
| 914 | }; | 928 | }; |
| 915 | 929 | ||
| 930 | char *svc_gss_principal(struct svc_rqst *rqstp) | ||
| 931 | { | ||
| 932 | struct gss_svc_data *gd = (struct gss_svc_data *)rqstp->rq_auth_data; | ||
| 933 | |||
| 934 | if (gd && gd->rsci) | ||
| 935 | return gd->rsci->client_name; | ||
| 936 | return NULL; | ||
| 937 | } | ||
| 938 | EXPORT_SYMBOL_GPL(svc_gss_principal); | ||
| 939 | |||
| 916 | static int | 940 | static int |
| 917 | svcauth_gss_set_client(struct svc_rqst *rqstp) | 941 | svcauth_gss_set_client(struct svc_rqst *rqstp) |
| 918 | { | 942 | { |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 3ca518386d15..836f15c0c4a3 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -197,6 +197,12 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
| 197 | 197 | ||
| 198 | clnt->cl_rtt = &clnt->cl_rtt_default; | 198 | clnt->cl_rtt = &clnt->cl_rtt_default; |
| 199 | rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); | 199 | rpc_init_rtt(&clnt->cl_rtt_default, clnt->cl_timeout->to_initval); |
| 200 | clnt->cl_principal = NULL; | ||
| 201 | if (args->client_name) { | ||
| 202 | clnt->cl_principal = kstrdup(args->client_name, GFP_KERNEL); | ||
| 203 | if (!clnt->cl_principal) | ||
| 204 | goto out_no_principal; | ||
| 205 | } | ||
| 200 | 206 | ||
| 201 | kref_init(&clnt->cl_kref); | 207 | kref_init(&clnt->cl_kref); |
| 202 | 208 | ||
| @@ -226,6 +232,8 @@ out_no_auth: | |||
| 226 | rpc_put_mount(); | 232 | rpc_put_mount(); |
| 227 | } | 233 | } |
| 228 | out_no_path: | 234 | out_no_path: |
| 235 | kfree(clnt->cl_principal); | ||
| 236 | out_no_principal: | ||
| 229 | rpc_free_iostats(clnt->cl_metrics); | 237 | rpc_free_iostats(clnt->cl_metrics); |
| 230 | out_no_stats: | 238 | out_no_stats: |
| 231 | if (clnt->cl_server != clnt->cl_inline_name) | 239 | if (clnt->cl_server != clnt->cl_inline_name) |
| @@ -354,6 +362,11 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
| 354 | new->cl_metrics = rpc_alloc_iostats(clnt); | 362 | new->cl_metrics = rpc_alloc_iostats(clnt); |
| 355 | if (new->cl_metrics == NULL) | 363 | if (new->cl_metrics == NULL) |
| 356 | goto out_no_stats; | 364 | goto out_no_stats; |
| 365 | if (clnt->cl_principal) { | ||
| 366 | new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL); | ||
| 367 | if (new->cl_principal == NULL) | ||
| 368 | goto out_no_principal; | ||
| 369 | } | ||
| 357 | kref_init(&new->cl_kref); | 370 | kref_init(&new->cl_kref); |
| 358 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); | 371 | err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); |
| 359 | if (err != 0) | 372 | if (err != 0) |
| @@ -366,6 +379,8 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
| 366 | rpciod_up(); | 379 | rpciod_up(); |
| 367 | return new; | 380 | return new; |
| 368 | out_no_path: | 381 | out_no_path: |
| 382 | kfree(new->cl_principal); | ||
| 383 | out_no_principal: | ||
| 369 | rpc_free_iostats(new->cl_metrics); | 384 | rpc_free_iostats(new->cl_metrics); |
| 370 | out_no_stats: | 385 | out_no_stats: |
| 371 | kfree(new); | 386 | kfree(new); |
| @@ -417,6 +432,7 @@ rpc_free_client(struct kref *kref) | |||
| 417 | out_free: | 432 | out_free: |
| 418 | rpc_unregister_client(clnt); | 433 | rpc_unregister_client(clnt); |
| 419 | rpc_free_iostats(clnt->cl_metrics); | 434 | rpc_free_iostats(clnt->cl_metrics); |
| 435 | kfree(clnt->cl_principal); | ||
| 420 | clnt->cl_metrics = NULL; | 436 | clnt->cl_metrics = NULL; |
| 421 | xprt_put(clnt->cl_xprt); | 437 | xprt_put(clnt->cl_xprt); |
| 422 | rpciod_down(); | 438 | rpciod_down(); |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 23a2b8f6dc49..192453248870 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -113,7 +113,7 @@ out: | |||
| 113 | wake_up(&rpci->waitq); | 113 | wake_up(&rpci->waitq); |
| 114 | return res; | 114 | return res; |
| 115 | } | 115 | } |
| 116 | EXPORT_SYMBOL(rpc_queue_upcall); | 116 | EXPORT_SYMBOL_GPL(rpc_queue_upcall); |
| 117 | 117 | ||
| 118 | static inline void | 118 | static inline void |
| 119 | rpc_inode_setowner(struct inode *inode, void *private) | 119 | rpc_inode_setowner(struct inode *inode, void *private) |
| @@ -126,13 +126,14 @@ rpc_close_pipes(struct inode *inode) | |||
| 126 | { | 126 | { |
| 127 | struct rpc_inode *rpci = RPC_I(inode); | 127 | struct rpc_inode *rpci = RPC_I(inode); |
| 128 | struct rpc_pipe_ops *ops; | 128 | struct rpc_pipe_ops *ops; |
| 129 | int need_release; | ||
| 129 | 130 | ||
| 130 | mutex_lock(&inode->i_mutex); | 131 | mutex_lock(&inode->i_mutex); |
| 131 | ops = rpci->ops; | 132 | ops = rpci->ops; |
| 132 | if (ops != NULL) { | 133 | if (ops != NULL) { |
| 133 | LIST_HEAD(free_list); | 134 | LIST_HEAD(free_list); |
| 134 | |||
| 135 | spin_lock(&inode->i_lock); | 135 | spin_lock(&inode->i_lock); |
| 136 | need_release = rpci->nreaders != 0 || rpci->nwriters != 0; | ||
| 136 | rpci->nreaders = 0; | 137 | rpci->nreaders = 0; |
| 137 | list_splice_init(&rpci->in_upcall, &free_list); | 138 | list_splice_init(&rpci->in_upcall, &free_list); |
| 138 | list_splice_init(&rpci->pipe, &free_list); | 139 | list_splice_init(&rpci->pipe, &free_list); |
| @@ -141,7 +142,7 @@ rpc_close_pipes(struct inode *inode) | |||
| 141 | spin_unlock(&inode->i_lock); | 142 | spin_unlock(&inode->i_lock); |
| 142 | rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); | 143 | rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); |
| 143 | rpci->nwriters = 0; | 144 | rpci->nwriters = 0; |
| 144 | if (ops->release_pipe) | 145 | if (need_release && ops->release_pipe) |
| 145 | ops->release_pipe(inode); | 146 | ops->release_pipe(inode); |
| 146 | cancel_delayed_work_sync(&rpci->queue_timeout); | 147 | cancel_delayed_work_sync(&rpci->queue_timeout); |
| 147 | } | 148 | } |
| @@ -169,16 +170,24 @@ static int | |||
| 169 | rpc_pipe_open(struct inode *inode, struct file *filp) | 170 | rpc_pipe_open(struct inode *inode, struct file *filp) |
| 170 | { | 171 | { |
| 171 | struct rpc_inode *rpci = RPC_I(inode); | 172 | struct rpc_inode *rpci = RPC_I(inode); |
| 173 | int first_open; | ||
| 172 | int res = -ENXIO; | 174 | int res = -ENXIO; |
| 173 | 175 | ||
| 174 | mutex_lock(&inode->i_mutex); | 176 | mutex_lock(&inode->i_mutex); |
| 175 | if (rpci->ops != NULL) { | 177 | if (rpci->ops == NULL) |
| 176 | if (filp->f_mode & FMODE_READ) | 178 | goto out; |
| 177 | rpci->nreaders ++; | 179 | first_open = rpci->nreaders == 0 && rpci->nwriters == 0; |
| 178 | if (filp->f_mode & FMODE_WRITE) | 180 | if (first_open && rpci->ops->open_pipe) { |
| 179 | rpci->nwriters ++; | 181 | res = rpci->ops->open_pipe(inode); |
| 180 | res = 0; | 182 | if (res) |
| 183 | goto out; | ||
| 181 | } | 184 | } |
| 185 | if (filp->f_mode & FMODE_READ) | ||
| 186 | rpci->nreaders++; | ||
| 187 | if (filp->f_mode & FMODE_WRITE) | ||
| 188 | rpci->nwriters++; | ||
| 189 | res = 0; | ||
| 190 | out: | ||
| 182 | mutex_unlock(&inode->i_mutex); | 191 | mutex_unlock(&inode->i_mutex); |
| 183 | return res; | 192 | return res; |
| 184 | } | 193 | } |
| @@ -188,6 +197,7 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 188 | { | 197 | { |
| 189 | struct rpc_inode *rpci = RPC_I(inode); | 198 | struct rpc_inode *rpci = RPC_I(inode); |
| 190 | struct rpc_pipe_msg *msg; | 199 | struct rpc_pipe_msg *msg; |
| 200 | int last_close; | ||
| 191 | 201 | ||
| 192 | mutex_lock(&inode->i_mutex); | 202 | mutex_lock(&inode->i_mutex); |
| 193 | if (rpci->ops == NULL) | 203 | if (rpci->ops == NULL) |
| @@ -214,7 +224,8 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 214 | rpci->ops->destroy_msg, -EAGAIN); | 224 | rpci->ops->destroy_msg, -EAGAIN); |
| 215 | } | 225 | } |
| 216 | } | 226 | } |
| 217 | if (rpci->ops->release_pipe) | 227 | last_close = rpci->nwriters == 0 && rpci->nreaders == 0; |
| 228 | if (last_close && rpci->ops->release_pipe) | ||
| 218 | rpci->ops->release_pipe(inode); | 229 | rpci->ops->release_pipe(inode); |
| 219 | out: | 230 | out: |
| 220 | mutex_unlock(&inode->i_mutex); | 231 | mutex_unlock(&inode->i_mutex); |
| @@ -396,6 +407,7 @@ enum { | |||
| 396 | RPCAUTH_nfs, | 407 | RPCAUTH_nfs, |
| 397 | RPCAUTH_portmap, | 408 | RPCAUTH_portmap, |
| 398 | RPCAUTH_statd, | 409 | RPCAUTH_statd, |
| 410 | RPCAUTH_nfsd4_cb, | ||
| 399 | RPCAUTH_RootEOF | 411 | RPCAUTH_RootEOF |
| 400 | }; | 412 | }; |
| 401 | 413 | ||
| @@ -429,6 +441,10 @@ static struct rpc_filelist files[] = { | |||
| 429 | .name = "statd", | 441 | .name = "statd", |
| 430 | .mode = S_IFDIR | S_IRUGO | S_IXUGO, | 442 | .mode = S_IFDIR | S_IRUGO | S_IXUGO, |
| 431 | }, | 443 | }, |
| 444 | [RPCAUTH_nfsd4_cb] = { | ||
| 445 | .name = "nfsd4_cb", | ||
| 446 | .mode = S_IFDIR | S_IRUGO | S_IXUGO, | ||
| 447 | }, | ||
| 432 | }; | 448 | }; |
| 433 | 449 | ||
| 434 | enum { | 450 | enum { |
| @@ -748,7 +764,7 @@ rpc_rmdir(struct dentry *dentry) | |||
| 748 | * @name: name of pipe | 764 | * @name: name of pipe |
| 749 | * @private: private data to associate with the pipe, for the caller's use | 765 | * @private: private data to associate with the pipe, for the caller's use |
| 750 | * @ops: operations defining the behavior of the pipe: upcall, downcall, | 766 | * @ops: operations defining the behavior of the pipe: upcall, downcall, |
| 751 | * release_pipe, and destroy_msg. | 767 | * release_pipe, open_pipe, and destroy_msg. |
| 752 | * @flags: rpc_inode flags | 768 | * @flags: rpc_inode flags |
| 753 | * | 769 | * |
| 754 | * Data is made available for userspace to read by calls to | 770 | * Data is made available for userspace to read by calls to |
| @@ -808,7 +824,7 @@ err_dput: | |||
| 808 | -ENOMEM); | 824 | -ENOMEM); |
| 809 | goto out; | 825 | goto out; |
| 810 | } | 826 | } |
| 811 | EXPORT_SYMBOL(rpc_mkpipe); | 827 | EXPORT_SYMBOL_GPL(rpc_mkpipe); |
| 812 | 828 | ||
| 813 | /** | 829 | /** |
| 814 | * rpc_unlink - remove a pipe | 830 | * rpc_unlink - remove a pipe |
| @@ -839,7 +855,7 @@ rpc_unlink(struct dentry *dentry) | |||
| 839 | dput(parent); | 855 | dput(parent); |
| 840 | return error; | 856 | return error; |
| 841 | } | 857 | } |
| 842 | EXPORT_SYMBOL(rpc_unlink); | 858 | EXPORT_SYMBOL_GPL(rpc_unlink); |
| 843 | 859 | ||
| 844 | /* | 860 | /* |
| 845 | * populate the filesystem | 861 | * populate the filesystem |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 79a55d56cc98..406e26de584e 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
| @@ -28,7 +28,7 @@ xdr_encode_netobj(__be32 *p, const struct xdr_netobj *obj) | |||
| 28 | memcpy(p, obj->data, obj->len); | 28 | memcpy(p, obj->data, obj->len); |
| 29 | return p + XDR_QUADLEN(obj->len); | 29 | return p + XDR_QUADLEN(obj->len); |
| 30 | } | 30 | } |
| 31 | EXPORT_SYMBOL(xdr_encode_netobj); | 31 | EXPORT_SYMBOL_GPL(xdr_encode_netobj); |
| 32 | 32 | ||
| 33 | __be32 * | 33 | __be32 * |
| 34 | xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj) | 34 | xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj) |
| @@ -41,7 +41,7 @@ xdr_decode_netobj(__be32 *p, struct xdr_netobj *obj) | |||
| 41 | obj->data = (u8 *) p; | 41 | obj->data = (u8 *) p; |
| 42 | return p + XDR_QUADLEN(len); | 42 | return p + XDR_QUADLEN(len); |
| 43 | } | 43 | } |
| 44 | EXPORT_SYMBOL(xdr_decode_netobj); | 44 | EXPORT_SYMBOL_GPL(xdr_decode_netobj); |
| 45 | 45 | ||
| 46 | /** | 46 | /** |
| 47 | * xdr_encode_opaque_fixed - Encode fixed length opaque data | 47 | * xdr_encode_opaque_fixed - Encode fixed length opaque data |
| @@ -71,7 +71,7 @@ __be32 *xdr_encode_opaque_fixed(__be32 *p, const void *ptr, unsigned int nbytes) | |||
| 71 | } | 71 | } |
| 72 | return p; | 72 | return p; |
| 73 | } | 73 | } |
| 74 | EXPORT_SYMBOL(xdr_encode_opaque_fixed); | 74 | EXPORT_SYMBOL_GPL(xdr_encode_opaque_fixed); |
| 75 | 75 | ||
| 76 | /** | 76 | /** |
| 77 | * xdr_encode_opaque - Encode variable length opaque data | 77 | * xdr_encode_opaque - Encode variable length opaque data |
| @@ -86,14 +86,14 @@ __be32 *xdr_encode_opaque(__be32 *p, const void *ptr, unsigned int nbytes) | |||
| 86 | *p++ = htonl(nbytes); | 86 | *p++ = htonl(nbytes); |
| 87 | return xdr_encode_opaque_fixed(p, ptr, nbytes); | 87 | return xdr_encode_opaque_fixed(p, ptr, nbytes); |
| 88 | } | 88 | } |
| 89 | EXPORT_SYMBOL(xdr_encode_opaque); | 89 | EXPORT_SYMBOL_GPL(xdr_encode_opaque); |
| 90 | 90 | ||
| 91 | __be32 * | 91 | __be32 * |
| 92 | xdr_encode_string(__be32 *p, const char *string) | 92 | xdr_encode_string(__be32 *p, const char *string) |
| 93 | { | 93 | { |
| 94 | return xdr_encode_array(p, string, strlen(string)); | 94 | return xdr_encode_array(p, string, strlen(string)); |
| 95 | } | 95 | } |
| 96 | EXPORT_SYMBOL(xdr_encode_string); | 96 | EXPORT_SYMBOL_GPL(xdr_encode_string); |
| 97 | 97 | ||
| 98 | __be32 * | 98 | __be32 * |
| 99 | xdr_decode_string_inplace(__be32 *p, char **sp, | 99 | xdr_decode_string_inplace(__be32 *p, char **sp, |
| @@ -108,7 +108,7 @@ xdr_decode_string_inplace(__be32 *p, char **sp, | |||
| 108 | *sp = (char *) p; | 108 | *sp = (char *) p; |
| 109 | return p + XDR_QUADLEN(len); | 109 | return p + XDR_QUADLEN(len); |
| 110 | } | 110 | } |
| 111 | EXPORT_SYMBOL(xdr_decode_string_inplace); | 111 | EXPORT_SYMBOL_GPL(xdr_decode_string_inplace); |
| 112 | 112 | ||
| 113 | void | 113 | void |
| 114 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | 114 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, |
| @@ -136,7 +136,7 @@ xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | |||
| 136 | xdr->buflen += len; | 136 | xdr->buflen += len; |
| 137 | xdr->len += len; | 137 | xdr->len += len; |
| 138 | } | 138 | } |
| 139 | EXPORT_SYMBOL(xdr_encode_pages); | 139 | EXPORT_SYMBOL_GPL(xdr_encode_pages); |
| 140 | 140 | ||
| 141 | void | 141 | void |
| 142 | xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, | 142 | xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, |
| @@ -158,7 +158,7 @@ xdr_inline_pages(struct xdr_buf *xdr, unsigned int offset, | |||
| 158 | 158 | ||
| 159 | xdr->buflen += len; | 159 | xdr->buflen += len; |
| 160 | } | 160 | } |
| 161 | EXPORT_SYMBOL(xdr_inline_pages); | 161 | EXPORT_SYMBOL_GPL(xdr_inline_pages); |
| 162 | 162 | ||
| 163 | /* | 163 | /* |
| 164 | * Helper routines for doing 'memmove' like operations on a struct xdr_buf | 164 | * Helper routines for doing 'memmove' like operations on a struct xdr_buf |
| @@ -428,7 +428,7 @@ xdr_shift_buf(struct xdr_buf *buf, size_t len) | |||
| 428 | { | 428 | { |
| 429 | xdr_shrink_bufhead(buf, len); | 429 | xdr_shrink_bufhead(buf, len); |
| 430 | } | 430 | } |
| 431 | EXPORT_SYMBOL(xdr_shift_buf); | 431 | EXPORT_SYMBOL_GPL(xdr_shift_buf); |
| 432 | 432 | ||
| 433 | /** | 433 | /** |
| 434 | * xdr_init_encode - Initialize a struct xdr_stream for sending data. | 434 | * xdr_init_encode - Initialize a struct xdr_stream for sending data. |
| @@ -465,7 +465,7 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | |||
| 465 | iov->iov_len += len; | 465 | iov->iov_len += len; |
| 466 | } | 466 | } |
| 467 | } | 467 | } |
| 468 | EXPORT_SYMBOL(xdr_init_encode); | 468 | EXPORT_SYMBOL_GPL(xdr_init_encode); |
| 469 | 469 | ||
| 470 | /** | 470 | /** |
| 471 | * xdr_reserve_space - Reserve buffer space for sending | 471 | * xdr_reserve_space - Reserve buffer space for sending |
| @@ -492,7 +492,7 @@ __be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes) | |||
| 492 | xdr->buf->len += nbytes; | 492 | xdr->buf->len += nbytes; |
| 493 | return p; | 493 | return p; |
| 494 | } | 494 | } |
| 495 | EXPORT_SYMBOL(xdr_reserve_space); | 495 | EXPORT_SYMBOL_GPL(xdr_reserve_space); |
| 496 | 496 | ||
| 497 | /** | 497 | /** |
| 498 | * xdr_write_pages - Insert a list of pages into an XDR buffer for sending | 498 | * xdr_write_pages - Insert a list of pages into an XDR buffer for sending |
| @@ -527,7 +527,7 @@ void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int b | |||
| 527 | buf->buflen += len; | 527 | buf->buflen += len; |
| 528 | buf->len += len; | 528 | buf->len += len; |
| 529 | } | 529 | } |
| 530 | EXPORT_SYMBOL(xdr_write_pages); | 530 | EXPORT_SYMBOL_GPL(xdr_write_pages); |
| 531 | 531 | ||
| 532 | /** | 532 | /** |
| 533 | * xdr_init_decode - Initialize an xdr_stream for decoding data. | 533 | * xdr_init_decode - Initialize an xdr_stream for decoding data. |
| @@ -547,7 +547,7 @@ void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | |||
| 547 | xdr->p = p; | 547 | xdr->p = p; |
| 548 | xdr->end = (__be32 *)((char *)iov->iov_base + len); | 548 | xdr->end = (__be32 *)((char *)iov->iov_base + len); |
| 549 | } | 549 | } |
| 550 | EXPORT_SYMBOL(xdr_init_decode); | 550 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
| 551 | 551 | ||
| 552 | /** | 552 | /** |
| 553 | * xdr_inline_decode - Retrieve non-page XDR data to decode | 553 | * xdr_inline_decode - Retrieve non-page XDR data to decode |
| @@ -569,7 +569,7 @@ __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) | |||
| 569 | xdr->p = q; | 569 | xdr->p = q; |
| 570 | return p; | 570 | return p; |
| 571 | } | 571 | } |
| 572 | EXPORT_SYMBOL(xdr_inline_decode); | 572 | EXPORT_SYMBOL_GPL(xdr_inline_decode); |
| 573 | 573 | ||
| 574 | /** | 574 | /** |
| 575 | * xdr_read_pages - Ensure page-based XDR data to decode is aligned at current pointer position | 575 | * xdr_read_pages - Ensure page-based XDR data to decode is aligned at current pointer position |
| @@ -613,7 +613,7 @@ void xdr_read_pages(struct xdr_stream *xdr, unsigned int len) | |||
| 613 | xdr->p = (__be32 *)((char *)iov->iov_base + padding); | 613 | xdr->p = (__be32 *)((char *)iov->iov_base + padding); |
| 614 | xdr->end = (__be32 *)((char *)iov->iov_base + end); | 614 | xdr->end = (__be32 *)((char *)iov->iov_base + end); |
| 615 | } | 615 | } |
| 616 | EXPORT_SYMBOL(xdr_read_pages); | 616 | EXPORT_SYMBOL_GPL(xdr_read_pages); |
| 617 | 617 | ||
| 618 | /** | 618 | /** |
| 619 | * xdr_enter_page - decode data from the XDR page | 619 | * xdr_enter_page - decode data from the XDR page |
| @@ -638,7 +638,7 @@ void xdr_enter_page(struct xdr_stream *xdr, unsigned int len) | |||
| 638 | xdr->p = (__be32 *)(kaddr + xdr->buf->page_base); | 638 | xdr->p = (__be32 *)(kaddr + xdr->buf->page_base); |
| 639 | xdr->end = (__be32 *)((char *)xdr->p + len); | 639 | xdr->end = (__be32 *)((char *)xdr->p + len); |
| 640 | } | 640 | } |
| 641 | EXPORT_SYMBOL(xdr_enter_page); | 641 | EXPORT_SYMBOL_GPL(xdr_enter_page); |
| 642 | 642 | ||
| 643 | static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; | 643 | static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0}; |
| 644 | 644 | ||
| @@ -650,7 +650,7 @@ xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf) | |||
| 650 | buf->page_len = 0; | 650 | buf->page_len = 0; |
| 651 | buf->buflen = buf->len = iov->iov_len; | 651 | buf->buflen = buf->len = iov->iov_len; |
| 652 | } | 652 | } |
| 653 | EXPORT_SYMBOL(xdr_buf_from_iov); | 653 | EXPORT_SYMBOL_GPL(xdr_buf_from_iov); |
| 654 | 654 | ||
| 655 | /* Sets subbuf to the portion of buf of length len beginning base bytes | 655 | /* Sets subbuf to the portion of buf of length len beginning base bytes |
| 656 | * from the start of buf. Returns -1 if base of length are out of bounds. */ | 656 | * from the start of buf. Returns -1 if base of length are out of bounds. */ |
| @@ -699,7 +699,7 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | |||
| 699 | return -1; | 699 | return -1; |
| 700 | return 0; | 700 | return 0; |
| 701 | } | 701 | } |
| 702 | EXPORT_SYMBOL(xdr_buf_subsegment); | 702 | EXPORT_SYMBOL_GPL(xdr_buf_subsegment); |
| 703 | 703 | ||
| 704 | static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) | 704 | static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) |
| 705 | { | 705 | { |
| @@ -730,7 +730,7 @@ int read_bytes_from_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, u | |||
| 730 | __read_bytes_from_xdr_buf(&subbuf, obj, len); | 730 | __read_bytes_from_xdr_buf(&subbuf, obj, len); |
| 731 | return 0; | 731 | return 0; |
| 732 | } | 732 | } |
| 733 | EXPORT_SYMBOL(read_bytes_from_xdr_buf); | 733 | EXPORT_SYMBOL_GPL(read_bytes_from_xdr_buf); |
| 734 | 734 | ||
| 735 | static void __write_bytes_to_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) | 735 | static void __write_bytes_to_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len) |
| 736 | { | 736 | { |
| @@ -774,7 +774,7 @@ xdr_decode_word(struct xdr_buf *buf, unsigned int base, u32 *obj) | |||
| 774 | *obj = ntohl(raw); | 774 | *obj = ntohl(raw); |
| 775 | return 0; | 775 | return 0; |
| 776 | } | 776 | } |
| 777 | EXPORT_SYMBOL(xdr_decode_word); | 777 | EXPORT_SYMBOL_GPL(xdr_decode_word); |
| 778 | 778 | ||
| 779 | int | 779 | int |
| 780 | xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) | 780 | xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) |
| @@ -783,7 +783,7 @@ xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj) | |||
| 783 | 783 | ||
| 784 | return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj)); | 784 | return write_bytes_to_xdr_buf(buf, base, &raw, sizeof(obj)); |
| 785 | } | 785 | } |
| 786 | EXPORT_SYMBOL(xdr_encode_word); | 786 | EXPORT_SYMBOL_GPL(xdr_encode_word); |
| 787 | 787 | ||
| 788 | /* If the netobj starting offset bytes from the start of xdr_buf is contained | 788 | /* If the netobj starting offset bytes from the start of xdr_buf is contained |
| 789 | * entirely in the head or the tail, set object to point to it; otherwise | 789 | * entirely in the head or the tail, set object to point to it; otherwise |
| @@ -821,7 +821,7 @@ int xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, unsigned in | |||
| 821 | __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len); | 821 | __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len); |
| 822 | return 0; | 822 | return 0; |
| 823 | } | 823 | } |
| 824 | EXPORT_SYMBOL(xdr_buf_read_netobj); | 824 | EXPORT_SYMBOL_GPL(xdr_buf_read_netobj); |
| 825 | 825 | ||
| 826 | /* Returns 0 on success, or else a negative error code. */ | 826 | /* Returns 0 on success, or else a negative error code. */ |
| 827 | static int | 827 | static int |
| @@ -1027,7 +1027,7 @@ xdr_decode_array2(struct xdr_buf *buf, unsigned int base, | |||
| 1027 | 1027 | ||
| 1028 | return xdr_xcode_array2(buf, base, desc, 0); | 1028 | return xdr_xcode_array2(buf, base, desc, 0); |
| 1029 | } | 1029 | } |
| 1030 | EXPORT_SYMBOL(xdr_decode_array2); | 1030 | EXPORT_SYMBOL_GPL(xdr_decode_array2); |
| 1031 | 1031 | ||
| 1032 | int | 1032 | int |
| 1033 | xdr_encode_array2(struct xdr_buf *buf, unsigned int base, | 1033 | xdr_encode_array2(struct xdr_buf *buf, unsigned int base, |
| @@ -1039,7 +1039,7 @@ xdr_encode_array2(struct xdr_buf *buf, unsigned int base, | |||
| 1039 | 1039 | ||
| 1040 | return xdr_xcode_array2(buf, base, desc, 1); | 1040 | return xdr_xcode_array2(buf, base, desc, 1); |
| 1041 | } | 1041 | } |
| 1042 | EXPORT_SYMBOL(xdr_encode_array2); | 1042 | EXPORT_SYMBOL_GPL(xdr_encode_array2); |
| 1043 | 1043 | ||
| 1044 | int | 1044 | int |
| 1045 | xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | 1045 | xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, |
| @@ -1106,5 +1106,5 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | |||
| 1106 | out: | 1106 | out: |
| 1107 | return ret; | 1107 | return ret; |
| 1108 | } | 1108 | } |
| 1109 | EXPORT_SYMBOL(xdr_process_buf); | 1109 | EXPORT_SYMBOL_GPL(xdr_process_buf); |
| 1110 | 1110 | ||
