diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2005-06-22 13:16:23 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-06-22 16:07:16 -0400 |
commit | 6a19275ada9137435da58990c8f8d3f58e170bf1 (patch) | |
tree | 927f8aa96c9b558a0bed5355dde66df9c0ec8554 | |
parent | 438b6fdebf2a2e8573e7290bc176feb4d4475f43 (diff) |
[PATCH] RPC: [PATCH] improve rpcauthauth_create error returns
Currently we return -ENOMEM for every single failure to create a new auth.
This is actually accurate for auth_null and auth_unix, but for auth_gss it's a
bit confusing.
Allow rpcauth_create (and the ->create methods) to return errors. With this
patch, the user may sometimes see an EINVAL instead. Whee.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/inode.c | 27 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 3 | ||||
-rw-r--r-- | net/sunrpc/auth.c | 6 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 13 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 6 |
5 files changed, 35 insertions, 20 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 350c48c12639..97b3fe7ece63 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -160,11 +160,10 @@ nfs_clear_inode(struct inode *inode) | |||
160 | void | 160 | void |
161 | nfs_umount_begin(struct super_block *sb) | 161 | nfs_umount_begin(struct super_block *sb) |
162 | { | 162 | { |
163 | struct nfs_server *server = NFS_SB(sb); | 163 | struct rpc_clnt *rpc = NFS_SB(sb)->client; |
164 | struct rpc_clnt *rpc; | ||
165 | 164 | ||
166 | /* -EIO all pending I/O */ | 165 | /* -EIO all pending I/O */ |
167 | if ((rpc = server->client) != NULL) | 166 | if (!IS_ERR(rpc)) |
168 | rpc_killall_tasks(rpc); | 167 | rpc_killall_tasks(rpc); |
169 | } | 168 | } |
170 | 169 | ||
@@ -450,11 +449,14 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent) | |||
450 | return PTR_ERR(server->client); | 449 | return PTR_ERR(server->client); |
451 | /* RFC 2623, sec 2.3.2 */ | 450 | /* RFC 2623, sec 2.3.2 */ |
452 | if (authflavor != RPC_AUTH_UNIX) { | 451 | if (authflavor != RPC_AUTH_UNIX) { |
452 | struct rpc_auth *auth; | ||
453 | |||
453 | server->client_sys = rpc_clone_client(server->client); | 454 | server->client_sys = rpc_clone_client(server->client); |
454 | if (IS_ERR(server->client_sys)) | 455 | if (IS_ERR(server->client_sys)) |
455 | return PTR_ERR(server->client_sys); | 456 | return PTR_ERR(server->client_sys); |
456 | if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys)) | 457 | auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys); |
457 | return -ENOMEM; | 458 | if (IS_ERR(auth)) |
459 | return PTR_ERR(auth); | ||
458 | } else { | 460 | } else { |
459 | atomic_inc(&server->client->cl_count); | 461 | atomic_inc(&server->client->cl_count); |
460 | server->client_sys = server->client; | 462 | server->client_sys = server->client; |
@@ -1450,6 +1452,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type, | |||
1450 | memset(server, 0, sizeof(struct nfs_server)); | 1452 | memset(server, 0, sizeof(struct nfs_server)); |
1451 | /* Zero out the NFS state stuff */ | 1453 | /* Zero out the NFS state stuff */ |
1452 | init_nfsv4_state(server); | 1454 | init_nfsv4_state(server); |
1455 | server->client = server->client_sys = ERR_PTR(-EINVAL); | ||
1453 | 1456 | ||
1454 | root = &server->fh; | 1457 | root = &server->fh; |
1455 | if (data->flags & NFS_MOUNT_VER3) | 1458 | if (data->flags & NFS_MOUNT_VER3) |
@@ -1506,9 +1509,9 @@ static void nfs_kill_super(struct super_block *s) | |||
1506 | 1509 | ||
1507 | kill_anon_super(s); | 1510 | kill_anon_super(s); |
1508 | 1511 | ||
1509 | if (server->client != NULL && !IS_ERR(server->client)) | 1512 | if (!IS_ERR(server->client)) |
1510 | rpc_shutdown_client(server->client); | 1513 | rpc_shutdown_client(server->client); |
1511 | if (server->client_sys != NULL && !IS_ERR(server->client_sys)) | 1514 | if (!IS_ERR(server->client_sys)) |
1512 | rpc_shutdown_client(server->client_sys); | 1515 | rpc_shutdown_client(server->client_sys); |
1513 | 1516 | ||
1514 | if (!(server->flags & NFS_MOUNT_NONLM)) | 1517 | if (!(server->flags & NFS_MOUNT_NONLM)) |
@@ -1650,7 +1653,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1650 | } | 1653 | } |
1651 | 1654 | ||
1652 | down_write(&clp->cl_sem); | 1655 | down_write(&clp->cl_sem); |
1653 | if (clp->cl_rpcclient == NULL) { | 1656 | if (IS_ERR(clp->cl_rpcclient)) { |
1654 | xprt = xprt_create_proto(proto, &server->addr, &timeparms); | 1657 | xprt = xprt_create_proto(proto, &server->addr, &timeparms); |
1655 | if (IS_ERR(xprt)) { | 1658 | if (IS_ERR(xprt)) { |
1656 | up_write(&clp->cl_sem); | 1659 | up_write(&clp->cl_sem); |
@@ -1711,9 +1714,12 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, | |||
1711 | } | 1714 | } |
1712 | 1715 | ||
1713 | if (clnt->cl_auth->au_flavor != authflavour) { | 1716 | if (clnt->cl_auth->au_flavor != authflavour) { |
1714 | if (rpcauth_create(authflavour, clnt) == NULL) { | 1717 | struct rpc_auth *auth; |
1718 | |||
1719 | auth = rpcauth_create(authflavour, clnt); | ||
1720 | if (IS_ERR(auth)) { | ||
1715 | dprintk("%s: couldn't create credcache!\n", __FUNCTION__); | 1721 | dprintk("%s: couldn't create credcache!\n", __FUNCTION__); |
1716 | return -ENOMEM; | 1722 | return PTR_ERR(auth); |
1717 | } | 1723 | } |
1718 | } | 1724 | } |
1719 | 1725 | ||
@@ -1788,6 +1794,7 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type, | |||
1788 | memset(server, 0, sizeof(struct nfs_server)); | 1794 | memset(server, 0, sizeof(struct nfs_server)); |
1789 | /* Zero out the NFS state stuff */ | 1795 | /* Zero out the NFS state stuff */ |
1790 | init_nfsv4_state(server); | 1796 | init_nfsv4_state(server); |
1797 | server->client = server->client_sys = ERR_PTR(-EINVAL); | ||
1791 | 1798 | ||
1792 | p = nfs_copy_user_string(NULL, &data->hostname, 256); | 1799 | p = nfs_copy_user_string(NULL, &data->hostname, 256); |
1793 | if (IS_ERR(p)) | 1800 | if (IS_ERR(p)) |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 17b187f2d776..591ad1d51880 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -110,6 +110,7 @@ nfs4_alloc_client(struct in_addr *addr) | |||
110 | INIT_LIST_HEAD(&clp->cl_superblocks); | 110 | INIT_LIST_HEAD(&clp->cl_superblocks); |
111 | init_waitqueue_head(&clp->cl_waitq); | 111 | init_waitqueue_head(&clp->cl_waitq); |
112 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); | 112 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); |
113 | clp->cl_rpcclient = ERR_PTR(-EINVAL); | ||
113 | clp->cl_boot_time = CURRENT_TIME; | 114 | clp->cl_boot_time = CURRENT_TIME; |
114 | clp->cl_state = 1 << NFS4CLNT_OK; | 115 | clp->cl_state = 1 << NFS4CLNT_OK; |
115 | return clp; | 116 | return clp; |
@@ -131,7 +132,7 @@ nfs4_free_client(struct nfs4_client *clp) | |||
131 | if (clp->cl_cred) | 132 | if (clp->cl_cred) |
132 | put_rpccred(clp->cl_cred); | 133 | put_rpccred(clp->cl_cred); |
133 | nfs_idmap_delete(clp); | 134 | nfs_idmap_delete(clp); |
134 | if (clp->cl_rpcclient) | 135 | if (!IS_ERR(clp->cl_rpcclient)) |
135 | rpc_shutdown_client(clp->cl_rpcclient); | 136 | rpc_shutdown_client(clp->cl_rpcclient); |
136 | kfree(clp); | 137 | kfree(clp); |
137 | nfs_callback_down(); | 138 | nfs_callback_down(); |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 9bcec9b927b9..505e2d4b3d62 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -66,10 +66,10 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt) | |||
66 | u32 flavor = pseudoflavor_to_flavor(pseudoflavor); | 66 | u32 flavor = pseudoflavor_to_flavor(pseudoflavor); |
67 | 67 | ||
68 | if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor])) | 68 | if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor])) |
69 | return NULL; | 69 | return ERR_PTR(-EINVAL); |
70 | auth = ops->create(clnt, pseudoflavor); | 70 | auth = ops->create(clnt, pseudoflavor); |
71 | if (!auth) | 71 | if (IS_ERR(auth)) |
72 | return NULL; | 72 | return auth; |
73 | if (clnt->cl_auth) | 73 | if (clnt->cl_auth) |
74 | rpcauth_destroy(clnt->cl_auth); | 74 | rpcauth_destroy(clnt->cl_auth); |
75 | clnt->cl_auth = auth; | 75 | clnt->cl_auth = auth; |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 7d88db83ab12..2f7b867161d2 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -660,14 +660,16 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | |||
660 | { | 660 | { |
661 | struct gss_auth *gss_auth; | 661 | struct gss_auth *gss_auth; |
662 | struct rpc_auth * auth; | 662 | struct rpc_auth * auth; |
663 | int err = -ENOMEM; /* XXX? */ | ||
663 | 664 | ||
664 | dprintk("RPC: creating GSS authenticator for client %p\n",clnt); | 665 | dprintk("RPC: creating GSS authenticator for client %p\n",clnt); |
665 | 666 | ||
666 | if (!try_module_get(THIS_MODULE)) | 667 | if (!try_module_get(THIS_MODULE)) |
667 | return NULL; | 668 | return ERR_PTR(err); |
668 | if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) | 669 | if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) |
669 | goto out_dec; | 670 | goto out_dec; |
670 | gss_auth->client = clnt; | 671 | gss_auth->client = clnt; |
672 | err = -EINVAL; | ||
671 | gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); | 673 | gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); |
672 | if (!gss_auth->mech) { | 674 | if (!gss_auth->mech) { |
673 | printk(KERN_WARNING "%s: Pseudoflavor %d not found!", | 675 | printk(KERN_WARNING "%s: Pseudoflavor %d not found!", |
@@ -686,15 +688,18 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor) | |||
686 | auth->au_flavor = flavor; | 688 | auth->au_flavor = flavor; |
687 | atomic_set(&auth->au_count, 1); | 689 | atomic_set(&auth->au_count, 1); |
688 | 690 | ||
689 | if (rpcauth_init_credcache(auth, GSS_CRED_EXPIRE) < 0) | 691 | err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE); |
692 | if (err) | ||
690 | goto err_put_mech; | 693 | goto err_put_mech; |
691 | 694 | ||
692 | snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s", | 695 | snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s", |
693 | clnt->cl_pathname, | 696 | clnt->cl_pathname, |
694 | gss_auth->mech->gm_name); | 697 | gss_auth->mech->gm_name); |
695 | gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); | 698 | gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); |
696 | if (IS_ERR(gss_auth->dentry)) | 699 | if (IS_ERR(gss_auth->dentry)) { |
700 | err = PTR_ERR(gss_auth->dentry); | ||
697 | goto err_put_mech; | 701 | goto err_put_mech; |
702 | } | ||
698 | 703 | ||
699 | return auth; | 704 | return auth; |
700 | err_put_mech: | 705 | err_put_mech: |
@@ -703,7 +708,7 @@ err_free: | |||
703 | kfree(gss_auth); | 708 | kfree(gss_auth); |
704 | out_dec: | 709 | out_dec: |
705 | module_put(THIS_MODULE); | 710 | module_put(THIS_MODULE); |
706 | return NULL; | 711 | return ERR_PTR(err); |
707 | } | 712 | } |
708 | 713 | ||
709 | static void | 714 | static void |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index b36797ad8083..9da1deb482e2 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -103,6 +103,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, | |||
103 | { | 103 | { |
104 | struct rpc_version *version; | 104 | struct rpc_version *version; |
105 | struct rpc_clnt *clnt = NULL; | 105 | struct rpc_clnt *clnt = NULL; |
106 | struct rpc_auth *auth; | ||
106 | int err; | 107 | int err; |
107 | int len; | 108 | int len; |
108 | 109 | ||
@@ -157,10 +158,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, | |||
157 | if (err < 0) | 158 | if (err < 0) |
158 | goto out_no_path; | 159 | goto out_no_path; |
159 | 160 | ||
160 | err = -ENOMEM; | 161 | auth = rpcauth_create(flavor, clnt); |
161 | if (!rpcauth_create(flavor, clnt)) { | 162 | if (IS_ERR(auth)) { |
162 | printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", | 163 | printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", |
163 | flavor); | 164 | flavor); |
165 | err = PTR_ERR(auth); | ||
164 | goto out_no_auth; | 166 | goto out_no_auth; |
165 | } | 167 | } |
166 | 168 | ||