nfs: convert setclientid and exchange_id encoders to use clp->cl_owner_id
authorJeff Layton <jlayton@poochiereds.net>
Tue, 9 Jun 2015 23:43:57 +0000 (19:43 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 16 Jun 2015 15:15:31 +0000 (11:15 -0400)
...instead of buffers that are part of their arg structs. We already
hold a reference to the client, so we might as well use the allocated
buffer. In the event that we can't allocate the clp->cl_owner_id, then
just return -ENOMEM.

Note too that we switch from a GFP_KERNEL allocation here to GFP_NOFS.
It's possible we could end up trying to do a SETCLIENTID or EXCHANGE_ID
in order to reclaim some memory, and the GFP_KERNEL allocations in the
existing code could cause recursion back into NFS reclaim.

Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs_xdr.h

index d689ea37be8484b5d38b10078528656b6352aa6e..b2afe95561471744a008e26644430259b909a713 100644 (file)
@@ -5046,7 +5046,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
        struct nfs4_setclientid setclientid = {
                .sc_verifier = &sc_verifier,
                .sc_prog = program,
-               .sc_cb_ident = clp->cl_cb_ident,
+               .sc_clnt = clp,
        };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
@@ -5076,6 +5076,12 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                                nfs4_init_nonuniform_client_string(clp,
                                                setclientid.sc_name,
                                                sizeof(setclientid.sc_name));
+
+       if (!clp->cl_owner_id) {
+               status = -ENOMEM;
+               goto out;
+       }
+
        /* cb_client4 */
        setclientid.sc_netid_len =
                                nfs4_init_callback_netid(clp,
@@ -5085,9 +5091,9 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                                sizeof(setclientid.sc_uaddr), "%s.%u.%u",
                                clp->cl_ipaddr, port >> 8, port & 255);
 
-       dprintk("NFS call  setclientid auth=%s, '%.*s'\n",
+       dprintk("NFS call  setclientid auth=%s, '%s'\n",
                clp->cl_rpcclient->cl_auth->au_ops->au_name,
-               setclientid.sc_name_len, setclientid.sc_name);
+               clp->cl_owner_id);
        task = rpc_run_task(&task_setup_data);
        if (IS_ERR(task)) {
                status = PTR_ERR(task);
@@ -6850,9 +6856,14 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
        nfs4_init_boot_verifier(clp, &verifier);
        args.id_len = nfs4_init_uniform_client_string(clp, args.id,
                                                        sizeof(args.id));
-       dprintk("NFS call  exchange_id auth=%s, '%.*s'\n",
+       if (!clp->cl_owner_id) {
+               status = -ENOMEM;
+               goto out;
+       }
+
+       dprintk("NFS call  exchange_id auth=%s, '%s'\n",
                clp->cl_rpcclient->cl_auth->au_ops->au_name,
-               args.id_len, args.id);
+               clp->cl_owner_id);
 
        res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
                                        GFP_NOFS);
index 0aea97841d3038b56056d0d7fcd0dcddb11f584e..f58e8a9793971d73637c66ddcdf1e58197506a36 100644 (file)
@@ -1667,13 +1667,14 @@ static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclie
        encode_op_hdr(xdr, OP_SETCLIENTID, decode_setclientid_maxsz, hdr);
        encode_nfs4_verifier(xdr, setclientid->sc_verifier);
 
-       encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name);
+       encode_string(xdr, strlen(setclientid->sc_clnt->cl_owner_id),
+                       setclientid->sc_clnt->cl_owner_id);
        p = reserve_space(xdr, 4);
        *p = cpu_to_be32(setclientid->sc_prog);
        encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
        encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
        p = reserve_space(xdr, 4);
-       *p = cpu_to_be32(setclientid->sc_cb_ident);
+       *p = cpu_to_be32(setclientid->sc_clnt->cl_cb_ident);
 }
 
 static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
@@ -1747,7 +1748,8 @@ static void encode_exchange_id(struct xdr_stream *xdr,
        encode_op_hdr(xdr, OP_EXCHANGE_ID, decode_exchange_id_maxsz, hdr);
        encode_nfs4_verifier(xdr, args->verifier);
 
-       encode_string(xdr, args->id_len, args->id);
+       encode_string(xdr, strlen(args->client->cl_owner_id),
+                       args->client->cl_owner_id);
 
        encode_uint32(xdr, args->flags);
        encode_uint32(xdr, args->state_protect.how);
index e9e9a8dcfb477ab1d64ea6d1c736819d6bb803f7..6c0b423d781b526a0646cb644a71aae5e46ce4b2 100644 (file)
@@ -994,7 +994,7 @@ struct nfs4_setclientid {
        char                            sc_netid[RPCBIND_MAXNETIDLEN + 1];
        unsigned int                    sc_uaddr_len;
        char                            sc_uaddr[RPCBIND_MAXUADDRLEN + 1];
-       u32                             sc_cb_ident;
+       struct nfs_client               *sc_clnt;
        struct rpc_cred                 *sc_cred;
 };