|
|
@@ -5007,28 +5007,78 @@ 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;
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Since this string is allocated at mount time, and held until the
|
|
|
+ * nfs_client is destroyed, we can use GFP_KERNEL here w/o worrying
|
|
|
+ * about a memory-reclaim deadlock.
|
|
|
+ */
|
|
|
+ str = kmalloc(len, GFP_KERNEL);
|
|
|
+ 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 strlcpy(buf, clp->cl_owner_id, len);
|
|
|
+ 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_KERNEL);
|
|
|
- return result;
|
|
|
+ return nfs4_init_uniquifier_client_string(clp);
|
|
|
+
|
|
|
+ len = 10 + 10 + 1 + 10 + 1 +
|
|
|
+ strlen(clp->cl_rpcclient->cl_nodename) + 1;
|
|
|
+
|
|
|
+ if (len > NFS4_OPAQUE_LIMIT + 1)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Since this string is allocated at mount time, and held until the
|
|
|
+ * nfs_client is destroyed, we can use GFP_KERNEL here w/o worrying
|
|
|
+ * about a memory-reclaim deadlock.
|
|
|
+ */
|
|
|
+ str = kmalloc(len, GFP_KERNEL);
|
|
|
+ if (!str)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
@@ -5095,20 +5145,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 =
|
|
|
@@ -6882,12 +6926,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,
|