diff options
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r-- | fs/nfs/idmap.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index ba3019f5934c..b5b86a05059c 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -415,7 +415,7 @@ static int __nfs_idmap_register(struct dentry *dir, | |||
415 | static void nfs_idmap_unregister(struct nfs_client *clp, | 415 | static void nfs_idmap_unregister(struct nfs_client *clp, |
416 | struct rpc_pipe *pipe) | 416 | struct rpc_pipe *pipe) |
417 | { | 417 | { |
418 | struct net *net = clp->net; | 418 | struct net *net = clp->cl_net; |
419 | struct super_block *pipefs_sb; | 419 | struct super_block *pipefs_sb; |
420 | 420 | ||
421 | pipefs_sb = rpc_get_sb_net(net); | 421 | pipefs_sb = rpc_get_sb_net(net); |
@@ -429,7 +429,7 @@ static int nfs_idmap_register(struct nfs_client *clp, | |||
429 | struct idmap *idmap, | 429 | struct idmap *idmap, |
430 | struct rpc_pipe *pipe) | 430 | struct rpc_pipe *pipe) |
431 | { | 431 | { |
432 | struct net *net = clp->net; | 432 | struct net *net = clp->cl_net; |
433 | struct super_block *pipefs_sb; | 433 | struct super_block *pipefs_sb; |
434 | int err = 0; | 434 | int err = 0; |
435 | 435 | ||
@@ -530,9 +530,25 @@ static struct nfs_client *nfs_get_client_for_event(struct net *net, int event) | |||
530 | struct nfs_net *nn = net_generic(net, nfs_net_id); | 530 | struct nfs_net *nn = net_generic(net, nfs_net_id); |
531 | struct dentry *cl_dentry; | 531 | struct dentry *cl_dentry; |
532 | struct nfs_client *clp; | 532 | struct nfs_client *clp; |
533 | int err; | ||
533 | 534 | ||
535 | restart: | ||
534 | spin_lock(&nn->nfs_client_lock); | 536 | spin_lock(&nn->nfs_client_lock); |
535 | list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { | 537 | list_for_each_entry(clp, &nn->nfs_client_list, cl_share_link) { |
538 | /* Wait for initialisation to finish */ | ||
539 | if (clp->cl_cons_state == NFS_CS_INITING) { | ||
540 | atomic_inc(&clp->cl_count); | ||
541 | spin_unlock(&nn->nfs_client_lock); | ||
542 | err = nfs_wait_client_init_complete(clp); | ||
543 | nfs_put_client(clp); | ||
544 | if (err) | ||
545 | return NULL; | ||
546 | goto restart; | ||
547 | } | ||
548 | /* Skip nfs_clients that failed to initialise */ | ||
549 | if (clp->cl_cons_state < 0) | ||
550 | continue; | ||
551 | smp_rmb(); | ||
536 | if (clp->rpc_ops != &nfs_v4_clientops) | 552 | if (clp->rpc_ops != &nfs_v4_clientops) |
537 | continue; | 553 | continue; |
538 | cl_dentry = clp->cl_idmap->idmap_pipe->dentry; | 554 | cl_dentry = clp->cl_idmap->idmap_pipe->dentry; |
@@ -640,20 +656,16 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
640 | struct idmap_msg *im; | 656 | struct idmap_msg *im; |
641 | struct idmap *idmap = (struct idmap *)aux; | 657 | struct idmap *idmap = (struct idmap *)aux; |
642 | struct key *key = cons->key; | 658 | struct key *key = cons->key; |
643 | int ret; | 659 | int ret = -ENOMEM; |
644 | 660 | ||
645 | /* msg and im are freed in idmap_pipe_destroy_msg */ | 661 | /* msg and im are freed in idmap_pipe_destroy_msg */ |
646 | msg = kmalloc(sizeof(*msg), GFP_KERNEL); | 662 | msg = kmalloc(sizeof(*msg), GFP_KERNEL); |
647 | if (IS_ERR(msg)) { | 663 | if (!msg) |
648 | ret = PTR_ERR(msg); | ||
649 | goto out0; | 664 | goto out0; |
650 | } | ||
651 | 665 | ||
652 | im = kmalloc(sizeof(*im), GFP_KERNEL); | 666 | im = kmalloc(sizeof(*im), GFP_KERNEL); |
653 | if (IS_ERR(im)) { | 667 | if (!im) |
654 | ret = PTR_ERR(im); | ||
655 | goto out1; | 668 | goto out1; |
656 | } | ||
657 | 669 | ||
658 | ret = nfs_idmap_prepare_message(key->description, im, msg); | 670 | ret = nfs_idmap_prepare_message(key->description, im, msg); |
659 | if (ret < 0) | 671 | if (ret < 0) |