diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 11:32:58 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-06-01 11:32:58 -0400 |
| commit | 419f4319495043a9507ac3e616be9ca60af09744 (patch) | |
| tree | 0f747d80d11a6d4cd726ad6556839d5cd40b23ac /fs/lockd | |
| parent | fb21affa49204acd409328415b49bfe90136653c (diff) | |
| parent | 6eccece90b6addf80ef9e6db79b0bc873301034b (diff) | |
Merge branch 'for-3.5' of git://linux-nfs.org/~bfields/linux
Pull the rest of the nfsd commits from Bruce Fields:
"... and then I cherry-picked the remainder of the patches from the
head of my previous branch"
This is the rest of the original nfsd branch, rebased without the
delegation stuff that I thought really needed to be redone.
I don't like rebasing things like this in general, but in this situation
this was the lesser of two evils.
* 'for-3.5' of git://linux-nfs.org/~bfields/linux: (50 commits)
nfsd4: fix, consolidate client_has_state
nfsd4: don't remove rebooted client record until confirmation
nfsd4: remove some dprintk's and a comment
nfsd4: return "real" sequence id in confirmed case
nfsd4: fix exchange_id to return confirm flag
nfsd4: clarify that renewing expired client is a bug
nfsd4: simpler ordering of setclientid_confirm checks
nfsd4: setclientid: remove pointless assignment
nfsd4: fix error return in non-matching-creds case
nfsd4: fix setclientid_confirm same_cred check
nfsd4: merge 3 setclientid cases to 2
nfsd4: pull out common code from setclientid cases
nfsd4: merge last two setclientid cases
nfsd4: setclientid/confirm comment cleanup
nfsd4: setclientid remove unnecessary terms from a logical expression
nfsd4: move rq_flavor into svc_cred
nfsd4: stricter cred comparison for setclientid/exchange_id
nfsd4: move principal name into svc_cred
nfsd4: allow removing clients not holding state
nfsd4: rearrange exchange_id logic to simplify
...
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/svc.c | 145 |
1 files changed, 90 insertions, 55 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 1ead0750cdbb..80938fda67e0 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -251,39 +251,40 @@ out_err: | |||
| 251 | return err; | 251 | return err; |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | static int lockd_up_net(struct net *net) | 254 | static int lockd_up_net(struct svc_serv *serv, struct net *net) |
| 255 | { | 255 | { |
| 256 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 256 | struct lockd_net *ln = net_generic(net, lockd_net_id); |
| 257 | struct svc_serv *serv = nlmsvc_rqst->rq_server; | ||
| 258 | int error; | 257 | int error; |
| 259 | 258 | ||
| 260 | if (ln->nlmsvc_users) | 259 | if (ln->nlmsvc_users++) |
| 261 | return 0; | 260 | return 0; |
| 262 | 261 | ||
| 263 | error = svc_rpcb_setup(serv, net); | 262 | error = svc_bind(serv, net); |
| 264 | if (error) | 263 | if (error) |
| 265 | goto err_rpcb; | 264 | goto err_bind; |
| 266 | 265 | ||
| 267 | error = make_socks(serv, net); | 266 | error = make_socks(serv, net); |
| 268 | if (error < 0) | 267 | if (error < 0) |
| 269 | goto err_socks; | 268 | goto err_socks; |
| 269 | dprintk("lockd_up_net: per-net data created; net=%p\n", net); | ||
| 270 | return 0; | 270 | return 0; |
| 271 | 271 | ||
| 272 | err_socks: | 272 | err_socks: |
| 273 | svc_rpcb_cleanup(serv, net); | 273 | svc_rpcb_cleanup(serv, net); |
| 274 | err_rpcb: | 274 | err_bind: |
| 275 | ln->nlmsvc_users--; | ||
| 275 | return error; | 276 | return error; |
| 276 | } | 277 | } |
| 277 | 278 | ||
| 278 | static void lockd_down_net(struct net *net) | 279 | static void lockd_down_net(struct svc_serv *serv, struct net *net) |
| 279 | { | 280 | { |
| 280 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 281 | struct lockd_net *ln = net_generic(net, lockd_net_id); |
| 281 | struct svc_serv *serv = nlmsvc_rqst->rq_server; | ||
| 282 | 282 | ||
| 283 | if (ln->nlmsvc_users) { | 283 | if (ln->nlmsvc_users) { |
| 284 | if (--ln->nlmsvc_users == 0) { | 284 | if (--ln->nlmsvc_users == 0) { |
| 285 | nlm_shutdown_hosts_net(net); | 285 | nlm_shutdown_hosts_net(net); |
| 286 | svc_shutdown_net(serv, net); | 286 | svc_shutdown_net(serv, net); |
| 287 | dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net); | ||
| 287 | } | 288 | } |
| 288 | } else { | 289 | } else { |
| 289 | printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", | 290 | printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", |
| @@ -292,21 +293,60 @@ static void lockd_down_net(struct net *net) | |||
| 292 | } | 293 | } |
| 293 | } | 294 | } |
| 294 | 295 | ||
| 295 | /* | 296 | static int lockd_start_svc(struct svc_serv *serv) |
| 296 | * Bring up the lockd process if it's not already up. | 297 | { |
| 297 | */ | 298 | int error; |
| 298 | int lockd_up(struct net *net) | 299 | |
| 300 | if (nlmsvc_rqst) | ||
| 301 | return 0; | ||
| 302 | |||
| 303 | /* | ||
| 304 | * Create the kernel thread and wait for it to start. | ||
| 305 | */ | ||
| 306 | nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); | ||
| 307 | if (IS_ERR(nlmsvc_rqst)) { | ||
| 308 | error = PTR_ERR(nlmsvc_rqst); | ||
| 309 | printk(KERN_WARNING | ||
| 310 | "lockd_up: svc_rqst allocation failed, error=%d\n", | ||
| 311 | error); | ||
| 312 | goto out_rqst; | ||
| 313 | } | ||
| 314 | |||
| 315 | svc_sock_update_bufs(serv); | ||
| 316 | serv->sv_maxconn = nlm_max_connections; | ||
| 317 | |||
| 318 | nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); | ||
| 319 | if (IS_ERR(nlmsvc_task)) { | ||
| 320 | error = PTR_ERR(nlmsvc_task); | ||
| 321 | printk(KERN_WARNING | ||
| 322 | "lockd_up: kthread_run failed, error=%d\n", error); | ||
| 323 | goto out_task; | ||
| 324 | } | ||
| 325 | dprintk("lockd_up: service started\n"); | ||
| 326 | return 0; | ||
| 327 | |||
| 328 | out_task: | ||
| 329 | svc_exit_thread(nlmsvc_rqst); | ||
| 330 | nlmsvc_task = NULL; | ||
| 331 | out_rqst: | ||
| 332 | nlmsvc_rqst = NULL; | ||
| 333 | return error; | ||
| 334 | } | ||
| 335 | |||
| 336 | static struct svc_serv *lockd_create_svc(void) | ||
| 299 | { | 337 | { |
| 300 | struct svc_serv *serv; | 338 | struct svc_serv *serv; |
| 301 | int error = 0; | ||
| 302 | 339 | ||
| 303 | mutex_lock(&nlmsvc_mutex); | ||
| 304 | /* | 340 | /* |
| 305 | * Check whether we're already up and running. | 341 | * Check whether we're already up and running. |
| 306 | */ | 342 | */ |
| 307 | if (nlmsvc_rqst) { | 343 | if (nlmsvc_rqst) { |
| 308 | error = lockd_up_net(net); | 344 | /* |
| 309 | goto out; | 345 | * Note: increase service usage, because later in case of error |
| 346 | * svc_destroy() will be called. | ||
| 347 | */ | ||
| 348 | svc_get(nlmsvc_rqst->rq_server); | ||
| 349 | return nlmsvc_rqst->rq_server; | ||
| 310 | } | 350 | } |
| 311 | 351 | ||
| 312 | /* | 352 | /* |
| @@ -317,59 +357,53 @@ int lockd_up(struct net *net) | |||
| 317 | printk(KERN_WARNING | 357 | printk(KERN_WARNING |
| 318 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 358 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
| 319 | 359 | ||
| 320 | error = -ENOMEM; | ||
| 321 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); | 360 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); |
| 322 | if (!serv) { | 361 | if (!serv) { |
| 323 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 362 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
| 324 | goto out; | 363 | return ERR_PTR(-ENOMEM); |
| 325 | } | 364 | } |
| 365 | dprintk("lockd_up: service created\n"); | ||
| 366 | return serv; | ||
| 367 | } | ||
| 326 | 368 | ||
| 327 | error = make_socks(serv, net); | 369 | /* |
| 328 | if (error < 0) | 370 | * Bring up the lockd process if it's not already up. |
| 329 | goto destroy_and_out; | 371 | */ |
| 372 | int lockd_up(struct net *net) | ||
| 373 | { | ||
| 374 | struct svc_serv *serv; | ||
| 375 | int error; | ||
| 330 | 376 | ||
| 331 | /* | 377 | mutex_lock(&nlmsvc_mutex); |
| 332 | * Create the kernel thread and wait for it to start. | 378 | |
| 333 | */ | 379 | serv = lockd_create_svc(); |
| 334 | nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); | 380 | if (IS_ERR(serv)) { |
| 335 | if (IS_ERR(nlmsvc_rqst)) { | 381 | error = PTR_ERR(serv); |
| 336 | error = PTR_ERR(nlmsvc_rqst); | 382 | goto err_create; |
| 337 | nlmsvc_rqst = NULL; | ||
| 338 | printk(KERN_WARNING | ||
| 339 | "lockd_up: svc_rqst allocation failed, error=%d\n", | ||
| 340 | error); | ||
| 341 | goto destroy_and_out; | ||
| 342 | } | 383 | } |
| 343 | 384 | ||
| 344 | svc_sock_update_bufs(serv); | 385 | error = lockd_up_net(serv, net); |
| 345 | serv->sv_maxconn = nlm_max_connections; | 386 | if (error < 0) |
| 387 | goto err_net; | ||
| 346 | 388 | ||
| 347 | nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); | 389 | error = lockd_start_svc(serv); |
| 348 | if (IS_ERR(nlmsvc_task)) { | 390 | if (error < 0) |
| 349 | error = PTR_ERR(nlmsvc_task); | 391 | goto err_start; |
| 350 | svc_exit_thread(nlmsvc_rqst); | ||
| 351 | nlmsvc_task = NULL; | ||
| 352 | nlmsvc_rqst = NULL; | ||
| 353 | printk(KERN_WARNING | ||
| 354 | "lockd_up: kthread_run failed, error=%d\n", error); | ||
| 355 | goto destroy_and_out; | ||
| 356 | } | ||
| 357 | 392 | ||
| 393 | nlmsvc_users++; | ||
| 358 | /* | 394 | /* |
| 359 | * Note: svc_serv structures have an initial use count of 1, | 395 | * Note: svc_serv structures have an initial use count of 1, |
| 360 | * so we exit through here on both success and failure. | 396 | * so we exit through here on both success and failure. |
| 361 | */ | 397 | */ |
| 362 | destroy_and_out: | 398 | err_net: |
| 363 | svc_destroy(serv); | 399 | svc_destroy(serv); |
| 364 | out: | 400 | err_create: |
| 365 | if (!error) { | ||
| 366 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
| 367 | |||
| 368 | ln->nlmsvc_users++; | ||
| 369 | nlmsvc_users++; | ||
| 370 | } | ||
| 371 | mutex_unlock(&nlmsvc_mutex); | 401 | mutex_unlock(&nlmsvc_mutex); |
| 372 | return error; | 402 | return error; |
| 403 | |||
| 404 | err_start: | ||
| 405 | lockd_down_net(serv, net); | ||
| 406 | goto err_net; | ||
| 373 | } | 407 | } |
| 374 | EXPORT_SYMBOL_GPL(lockd_up); | 408 | EXPORT_SYMBOL_GPL(lockd_up); |
| 375 | 409 | ||
| @@ -380,11 +414,10 @@ void | |||
| 380 | lockd_down(struct net *net) | 414 | lockd_down(struct net *net) |
| 381 | { | 415 | { |
| 382 | mutex_lock(&nlmsvc_mutex); | 416 | mutex_lock(&nlmsvc_mutex); |
| 417 | lockd_down_net(nlmsvc_rqst->rq_server, net); | ||
| 383 | if (nlmsvc_users) { | 418 | if (nlmsvc_users) { |
| 384 | if (--nlmsvc_users) { | 419 | if (--nlmsvc_users) |
| 385 | lockd_down_net(net); | ||
| 386 | goto out; | 420 | goto out; |
| 387 | } | ||
| 388 | } else { | 421 | } else { |
| 389 | printk(KERN_ERR "lockd_down: no users! task=%p\n", | 422 | printk(KERN_ERR "lockd_down: no users! task=%p\n", |
| 390 | nlmsvc_task); | 423 | nlmsvc_task); |
| @@ -396,7 +429,9 @@ lockd_down(struct net *net) | |||
| 396 | BUG(); | 429 | BUG(); |
| 397 | } | 430 | } |
| 398 | kthread_stop(nlmsvc_task); | 431 | kthread_stop(nlmsvc_task); |
| 432 | dprintk("lockd_down: service stopped\n"); | ||
| 399 | svc_exit_thread(nlmsvc_rqst); | 433 | svc_exit_thread(nlmsvc_rqst); |
| 434 | dprintk("lockd_down: service destroyed\n"); | ||
| 400 | nlmsvc_task = NULL; | 435 | nlmsvc_task = NULL; |
| 401 | nlmsvc_rqst = NULL; | 436 | nlmsvc_rqst = NULL; |
| 402 | out: | 437 | out: |
