On Jun 4, 2015, at 12:44 PM, Jeff Layton <jlayton@xxxxxxxxxxxxxxx> wrote: > Change the uniform client string generator to use the same scheme as > the nonuniform one. This is a scary sentence. What do you mean by “same scheme” ? Is your new code following the same requirements for uniform client strings? Are you changing the client to use only uniform strings? That will break some servers that cleave to the recommendations in RFC 7530. > This one is a little simpler since we don't need to > deal with RCU, but we do have two different cases, depending on whether > there is a uniquifier or not. > > Signed-off-by: Jeff Layton <jeff.layton@xxxxxxxxxxxxxxx> > --- > fs/nfs/nfs4proc.c | 105 ++++++++++++++++++++++++++++++++---------------- > include/linux/nfs_xdr.h | 6 --- > 2 files changed, 70 insertions(+), 41 deletions(-) > > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 49e3b3e55887..479b0f583f33 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -5000,28 +5000,71 @@ retry: > return 0; > } > > -static unsigned int > -nfs4_init_uniform_client_string(struct nfs_client *clp, > - char *buf, size_t len) > +static int > +nfs4_init_uniquifier_client_string(struct nfs_client *clp) > { > - const char *nodename = clp->cl_rpcclient->cl_nodename; > - unsigned int result; > + int result; > + size_t len; > + char *str; > > if (clp->cl_owner_id != NULL) > - return strlcpy(buf, clp->cl_owner_id, len); > + return 0; > + > + len = 10 + 10 + 1 + 10 + 1 + > + strlen(nfs4_client_id_uniquifier) + 1 + > + strlen(clp->cl_rpcclient->cl_nodename) + 1; > + > + if (len > NFS4_OPAQUE_LIMIT + 1) > + return -EINVAL; > + > + str = kmalloc(len, GFP_NOFS); > + if (!str) > + return -ENOMEM; > + > + result = scnprintf(str, len, "Linux NFSv%u.%u %s/%s", > + clp->rpc_ops->version, clp->cl_minorversion, > + nfs4_client_id_uniquifier, > + clp->cl_rpcclient->cl_nodename); > + if (result >= len) { > + kfree(str); > + return -EINVAL; > + } > + clp->cl_owner_id = str; > + return 0; > +} > + > +static int > +nfs4_init_uniform_client_string(struct nfs_client *clp) > +{ > + int result; > + size_t len; > + char *str; > + > + if (clp->cl_owner_id != NULL) > + return 0; > > if (nfs4_client_id_uniquifier[0] != '\0') > - result = scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", > - clp->rpc_ops->version, > - clp->cl_minorversion, > - nfs4_client_id_uniquifier, > - nodename); > - else > - result = scnprintf(buf, len, "Linux NFSv%u.%u %s", > - clp->rpc_ops->version, clp->cl_minorversion, > - nodename); > - clp->cl_owner_id = kstrdup(buf, GFP_NOFS); > - return result; > + return nfs4_init_uniquifier_client_string(clp); > + > + len = 10 + 10 + 1 + 10 + 1 + > + strlen(clp->cl_rpcclient->cl_nodename) + 1; > + > + str = kmalloc(len, GFP_NOFS); > + if (!str) > + return -ENOMEM; > + > + if (len > NFS4_OPAQUE_LIMIT + 1) > + return -EINVAL; > + > + result = scnprintf(str, len, "Linux NFSv%u.%u %s", > + clp->rpc_ops->version, clp->cl_minorversion, > + clp->cl_rpcclient->cl_nodename); > + if (result >= len) { > + kfree(str); > + return -EINVAL; > + } > + clp->cl_owner_id = str; > + return 0; > } > > /* > @@ -5088,20 +5131,14 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, > > /* nfs_client_id4 */ > nfs4_init_boot_verifier(clp, &sc_verifier); > - if (test_bit(NFS_CS_MIGRATION, &clp->cl_flags)) { > - setclientid.sc_name_len = > - nfs4_init_uniform_client_string(clp, > - setclientid.sc_name, > - sizeof(setclientid.sc_name)); > - if (!clp->cl_owner_id) { > - status = -ENOMEM; > - goto out; > - } > - } else { > + > + if (test_bit(NFS_CS_MIGRATION, &clp->cl_flags)) > + status = nfs4_init_uniform_client_string(clp); > + else > status = nfs4_init_nonuniform_client_string(clp); > - if (status) > - goto out; > - } > + > + if (status) > + goto out; > > /* cb_client4 */ > setclientid.sc_netid_len = > @@ -6875,12 +6912,10 @@ 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)); > - if (!clp->cl_owner_id) { > - status = -ENOMEM; > + > + status = nfs4_init_uniform_client_string(clp); > + if (status) > goto out; > - } > > dprintk("NFS call exchange_id auth=%s, '%s'\n", > clp->cl_rpcclient->cl_auth->au_ops->au_name, > diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h > index 16991f5e274e..c959e7eb5bd4 100644 > --- a/include/linux/nfs_xdr.h > +++ b/include/linux/nfs_xdr.h > @@ -984,11 +984,8 @@ struct nfs4_readlink_res { > struct nfs4_sequence_res seq_res; > }; > > -#define NFS4_SETCLIENTID_NAMELEN (127) > struct nfs4_setclientid { > const nfs4_verifier * sc_verifier; > - unsigned int sc_name_len; > - char sc_name[NFS4_SETCLIENTID_NAMELEN + 1]; > u32 sc_prog; > unsigned int sc_netid_len; > char sc_netid[RPCBIND_MAXNETIDLEN + 1]; > @@ -1142,12 +1139,9 @@ struct nfs41_state_protection { > struct nfs4_op_map allow; > }; > > -#define NFS4_EXCHANGE_ID_LEN (48) > struct nfs41_exchange_id_args { > struct nfs_client *client; > nfs4_verifier *verifier; > - unsigned int id_len; > - char id[NFS4_EXCHANGE_ID_LEN]; > u32 flags; > struct nfs41_state_protection state_protect; > }; > -- > 2.4.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Chuck Lever chuck[dot]lever[at]oracle[dot]com -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html