[PATCH] RPC: [PATCH] improve rpcauthauth_create error returns
authorJ. Bruce Fields <bfields@citi.umich.edu>
Wed, 22 Jun 2005 17:16:23 +0000 (17:16 +0000)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 22 Jun 2005 20:07:16 +0000 (16:07 -0400)
 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>
fs/nfs/inode.c
fs/nfs/nfs4state.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/clnt.c

index 350c48c1263976a46575718817326d7768d8d4c9..97b3fe7ece630509191409a8823e4ca717c51a4b 100644 (file)
@@ -160,11 +160,10 @@ nfs_clear_inode(struct inode *inode)
 void
 nfs_umount_begin(struct super_block *sb)
 {
 void
 nfs_umount_begin(struct super_block *sb)
 {
-       struct nfs_server *server = NFS_SB(sb);
-       struct rpc_clnt *rpc;
+       struct rpc_clnt *rpc = NFS_SB(sb)->client;
 
        /* -EIO all pending I/O */
 
        /* -EIO all pending I/O */
-       if ((rpc = server->client) != NULL)
+       if (!IS_ERR(rpc))
                rpc_killall_tasks(rpc);
 }
 
                rpc_killall_tasks(rpc);
 }
 
@@ -450,11 +449,14 @@ nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
                return PTR_ERR(server->client);
        /* RFC 2623, sec 2.3.2 */
        if (authflavor != RPC_AUTH_UNIX) {
                return PTR_ERR(server->client);
        /* RFC 2623, sec 2.3.2 */
        if (authflavor != RPC_AUTH_UNIX) {
+               struct rpc_auth *auth;
+
                server->client_sys = rpc_clone_client(server->client);
                if (IS_ERR(server->client_sys))
                        return PTR_ERR(server->client_sys);
                server->client_sys = rpc_clone_client(server->client);
                if (IS_ERR(server->client_sys))
                        return PTR_ERR(server->client_sys);
-               if (!rpcauth_create(RPC_AUTH_UNIX, server->client_sys))
-                       return -ENOMEM;
+               auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
+               if (IS_ERR(auth))
+                       return PTR_ERR(auth);
        } else {
                atomic_inc(&server->client->cl_count);
                server->client_sys = server->client;
        } else {
                atomic_inc(&server->client->cl_count);
                server->client_sys = server->client;
@@ -1450,6 +1452,7 @@ static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
        memset(server, 0, sizeof(struct nfs_server));
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
        memset(server, 0, sizeof(struct nfs_server));
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
+       server->client = server->client_sys = ERR_PTR(-EINVAL);
 
        root = &server->fh;
        if (data->flags & NFS_MOUNT_VER3)
 
        root = &server->fh;
        if (data->flags & NFS_MOUNT_VER3)
@@ -1506,9 +1509,9 @@ static void nfs_kill_super(struct super_block *s)
 
        kill_anon_super(s);
 
 
        kill_anon_super(s);
 
-       if (server->client != NULL && !IS_ERR(server->client))
+       if (!IS_ERR(server->client))
                rpc_shutdown_client(server->client);
                rpc_shutdown_client(server->client);
-       if (server->client_sys != NULL && !IS_ERR(server->client_sys))
+       if (!IS_ERR(server->client_sys))
                rpc_shutdown_client(server->client_sys);
 
        if (!(server->flags & NFS_MOUNT_NONLM))
                rpc_shutdown_client(server->client_sys);
 
        if (!(server->flags & NFS_MOUNT_NONLM))
@@ -1650,7 +1653,7 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
        }
 
        down_write(&clp->cl_sem);
        }
 
        down_write(&clp->cl_sem);
-       if (clp->cl_rpcclient == NULL) {
+       if (IS_ERR(clp->cl_rpcclient)) {
                xprt = xprt_create_proto(proto, &server->addr, &timeparms);
                if (IS_ERR(xprt)) {
                        up_write(&clp->cl_sem);
                xprt = xprt_create_proto(proto, &server->addr, &timeparms);
                if (IS_ERR(xprt)) {
                        up_write(&clp->cl_sem);
@@ -1711,9 +1714,12 @@ static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data,
        }
 
        if (clnt->cl_auth->au_flavor != authflavour) {
        }
 
        if (clnt->cl_auth->au_flavor != authflavour) {
-               if (rpcauth_create(authflavour, clnt) == NULL) {
+               struct rpc_auth *auth;
+
+               auth = rpcauth_create(authflavour, clnt);
+               if (IS_ERR(auth)) {
                        dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
                        dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
-                       return -ENOMEM;
+                       return PTR_ERR(auth);
                }
        }
 
                }
        }
 
@@ -1788,6 +1794,7 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
        memset(server, 0, sizeof(struct nfs_server));
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
        memset(server, 0, sizeof(struct nfs_server));
        /* Zero out the NFS state stuff */
        init_nfsv4_state(server);
+       server->client = server->client_sys = ERR_PTR(-EINVAL);
 
        p = nfs_copy_user_string(NULL, &data->hostname, 256);
        if (IS_ERR(p))
 
        p = nfs_copy_user_string(NULL, &data->hostname, 256);
        if (IS_ERR(p))
index 17b187f2d77691ba9c6325e56526d57e6d027e3b..591ad1d51880aa08f71ee5cc203d9546347125ee 100644 (file)
@@ -110,6 +110,7 @@ nfs4_alloc_client(struct in_addr *addr)
        INIT_LIST_HEAD(&clp->cl_superblocks);
        init_waitqueue_head(&clp->cl_waitq);
        rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
        INIT_LIST_HEAD(&clp->cl_superblocks);
        init_waitqueue_head(&clp->cl_waitq);
        rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
+       clp->cl_rpcclient = ERR_PTR(-EINVAL);
        clp->cl_boot_time = CURRENT_TIME;
        clp->cl_state = 1 << NFS4CLNT_OK;
        return clp;
        clp->cl_boot_time = CURRENT_TIME;
        clp->cl_state = 1 << NFS4CLNT_OK;
        return clp;
@@ -131,7 +132,7 @@ nfs4_free_client(struct nfs4_client *clp)
        if (clp->cl_cred)
                put_rpccred(clp->cl_cred);
        nfs_idmap_delete(clp);
        if (clp->cl_cred)
                put_rpccred(clp->cl_cred);
        nfs_idmap_delete(clp);
-       if (clp->cl_rpcclient)
+       if (!IS_ERR(clp->cl_rpcclient))
                rpc_shutdown_client(clp->cl_rpcclient);
        kfree(clp);
        nfs_callback_down();
                rpc_shutdown_client(clp->cl_rpcclient);
        kfree(clp);
        nfs_callback_down();
index 9bcec9b927b9bc9e1cc1b6088f228ab92da59b02..505e2d4b3d6259e3363c8a1c428da3535533132a 100644 (file)
@@ -66,10 +66,10 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
        u32                     flavor = pseudoflavor_to_flavor(pseudoflavor);
 
        if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor]))
        u32                     flavor = pseudoflavor_to_flavor(pseudoflavor);
 
        if (flavor >= RPC_AUTH_MAXFLAVOR || !(ops = auth_flavors[flavor]))
-               return NULL;
+               return ERR_PTR(-EINVAL);
        auth = ops->create(clnt, pseudoflavor);
        auth = ops->create(clnt, pseudoflavor);
-       if (!auth)
-               return NULL;
+       if (IS_ERR(auth))
+               return auth;
        if (clnt->cl_auth)
                rpcauth_destroy(clnt->cl_auth);
        clnt->cl_auth = auth;
        if (clnt->cl_auth)
                rpcauth_destroy(clnt->cl_auth);
        clnt->cl_auth = auth;
index 7d88db83ab12904e313f10b88b69e33ec47e54a2..2f7b867161d254cc6251dbe994fa90017a02e7a8 100644 (file)
@@ -660,14 +660,16 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
 {
        struct gss_auth *gss_auth;
        struct rpc_auth * auth;
 {
        struct gss_auth *gss_auth;
        struct rpc_auth * auth;
+       int err = -ENOMEM; /* XXX? */
 
        dprintk("RPC:      creating GSS authenticator for client %p\n",clnt);
 
        if (!try_module_get(THIS_MODULE))
 
        dprintk("RPC:      creating GSS authenticator for client %p\n",clnt);
 
        if (!try_module_get(THIS_MODULE))
-               return NULL;
+               return ERR_PTR(err);
        if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
                goto out_dec;
        gss_auth->client = clnt;
        if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
                goto out_dec;
        gss_auth->client = clnt;
+       err = -EINVAL;
        gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
        if (!gss_auth->mech) {
                printk(KERN_WARNING "%s: Pseudoflavor %d not found!",
        gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
        if (!gss_auth->mech) {
                printk(KERN_WARNING "%s: Pseudoflavor %d not found!",
@@ -686,15 +688,18 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
        auth->au_flavor = flavor;
        atomic_set(&auth->au_count, 1);
 
        auth->au_flavor = flavor;
        atomic_set(&auth->au_count, 1);
 
-       if (rpcauth_init_credcache(auth, GSS_CRED_EXPIRE) < 0)
+       err = rpcauth_init_credcache(auth, GSS_CRED_EXPIRE);
+       if (err)
                goto err_put_mech;
 
        snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s",
                        clnt->cl_pathname,
                        gss_auth->mech->gm_name);
        gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
                goto err_put_mech;
 
        snprintf(gss_auth->path, sizeof(gss_auth->path), "%s/%s",
                        clnt->cl_pathname,
                        gss_auth->mech->gm_name);
        gss_auth->dentry = rpc_mkpipe(gss_auth->path, clnt, &gss_upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
-       if (IS_ERR(gss_auth->dentry))
+       if (IS_ERR(gss_auth->dentry)) {
+               err = PTR_ERR(gss_auth->dentry);
                goto err_put_mech;
                goto err_put_mech;
+       }
 
        return auth;
 err_put_mech:
 
        return auth;
 err_put_mech:
@@ -703,7 +708,7 @@ err_free:
        kfree(gss_auth);
 out_dec:
        module_put(THIS_MODULE);
        kfree(gss_auth);
 out_dec:
        module_put(THIS_MODULE);
-       return NULL;
+       return ERR_PTR(err);
 }
 
 static void
 }
 
 static void
index b36797ad8083166c2c0f966ed38f506468794f8d..9da1deb482e2c6396813f7f45233e6e434ec543c 100644 (file)
@@ -103,6 +103,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
 {
        struct rpc_version      *version;
        struct rpc_clnt         *clnt = NULL;
 {
        struct rpc_version      *version;
        struct rpc_clnt         *clnt = NULL;
+       struct rpc_auth         *auth;
        int err;
        int len;
 
        int err;
        int len;
 
@@ -157,10 +158,11 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname,
        if (err < 0)
                goto out_no_path;
 
        if (err < 0)
                goto out_no_path;
 
-       err = -ENOMEM;
-       if (!rpcauth_create(flavor, clnt)) {
+       auth = rpcauth_create(flavor, clnt);
+       if (IS_ERR(auth)) {
                printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
                                flavor);
                printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
                                flavor);
+               err = PTR_ERR(auth);
                goto out_no_auth;
        }
 
                goto out_no_auth;
        }