NFSv4/pNFS: Store the transport type in struct nfs4_pnfs_ds_addr
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Fri, 6 Nov 2020 21:10:52 +0000 (16:10 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 2 Dec 2020 19:05:53 +0000 (14:05 -0500)
We want to enable RDMA and UDP as valid transport methods if a
GETDEVICEINFO call specifies it. Do so by adding a parser for the
netid that translates it to an appropriate argument for the RPC
transport layer.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/pnfs.h
fs/nfs/pnfs_nfs.c

index 2661c44c62db402fbbd4c1832ba533f2f187f433..f618c49697bbaadb9ccf9c2faeaaff002bba5614 100644 (file)
@@ -51,6 +51,8 @@ struct nfs4_pnfs_ds_addr {
        size_t                  da_addrlen;
        struct list_head        da_node;  /* nfs4_pnfs_dev_hlist dev_dslist */
        char                    *da_remotestr;  /* human readable addr+port */
+       const char              *da_netid;
+       int                     da_transport;
 };
 
 struct nfs4_pnfs_ds {
index c3c04a7639850a2001050a4f83f8ee9f61a45666..7a97643acf3fe2eb6bcaedd464df8ad20acb2259 100644 (file)
@@ -672,6 +672,7 @@ static struct nfs4_pnfs_ds_addr *nfs4_pnfs_ds_addr_alloc(gfp_t gfp_flags)
 static void nfs4_pnfs_ds_addr_free(struct nfs4_pnfs_ds_addr *da)
 {
        kfree(da->da_remotestr);
+       kfree(da->da_netid);
        kfree(da);
 }
 
@@ -867,13 +868,15 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
 
                if (!IS_ERR(clp)) {
                        struct xprt_create xprt_args = {
-                               .ident = XPRT_TRANSPORT_TCP,
+                               .ident = da->da_transport,
                                .net = clp->cl_net,
                                .dstaddr = (struct sockaddr *)&da->da_addr,
                                .addrlen = da->da_addrlen,
                                .servername = clp->cl_hostname,
                        };
 
+                       if (da->da_transport != clp->cl_proto)
+                               continue;
                        if (da->da_addr.ss_family != clp->cl_addr.ss_family)
                                continue;
                        /* Add this address as an alias */
@@ -883,7 +886,7 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
                }
                clp = get_v3_ds_connect(mds_srv,
                                (struct sockaddr *)&da->da_addr,
-                               da->da_addrlen, IPPROTO_TCP,
+                               da->da_addrlen, da->da_transport,
                                timeo, retrans);
                if (IS_ERR(clp))
                        continue;
@@ -921,7 +924,7 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
 
                if (!IS_ERR(clp) && clp->cl_mvops->session_trunk) {
                        struct xprt_create xprt_args = {
-                               .ident = XPRT_TRANSPORT_TCP,
+                               .ident = da->da_transport,
                                .net = clp->cl_net,
                                .dstaddr = (struct sockaddr *)&da->da_addr,
                                .addrlen = da->da_addrlen,
@@ -935,6 +938,8 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
                                .data = &xprtdata,
                        };
 
+                       if (da->da_transport != clp->cl_proto)
+                               continue;
                        if (da->da_addr.ss_family != clp->cl_addr.ss_family)
                                continue;
                        /**
@@ -950,8 +955,9 @@ static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
                } else {
                        clp = nfs4_set_ds_client(mds_srv,
                                                (struct sockaddr *)&da->da_addr,
-                                               da->da_addrlen, IPPROTO_TCP,
-                                               timeo, retrans, minor_version);
+                                               da->da_addrlen,
+                                               da->da_transport, timeo,
+                                               retrans, minor_version);
                        if (IS_ERR(clp))
                                continue;
 
@@ -1042,8 +1048,8 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
        int nlen, rlen;
        int tmp[2];
        __be32 *p;
-       char *netid, *match_netid;
-       size_t len, match_netid_len;
+       char *netid;
+       size_t len;
        char *startsep = "";
        char *endsep = "";
 
@@ -1125,15 +1131,11 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
        case AF_INET:
                ((struct sockaddr_in *)&da->da_addr)->sin_port = port;
                da->da_addrlen = sizeof(struct sockaddr_in);
-               match_netid = "tcp";
-               match_netid_len = 3;
                break;
 
        case AF_INET6:
                ((struct sockaddr_in6 *)&da->da_addr)->sin6_port = port;
                da->da_addrlen = sizeof(struct sockaddr_in6);
-               match_netid = "tcp6";
-               match_netid_len = 4;
                startsep = "[";
                endsep = "]";
                break;
@@ -1144,12 +1146,15 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
                goto out_free_da;
        }
 
-       if (nlen != match_netid_len || strncmp(netid, match_netid, nlen)) {
-               dprintk("%s: ERROR: r_netid \"%s\" != \"%s\"\n",
-                       __func__, netid, match_netid);
+       da->da_transport = xprt_find_transport_ident(netid);
+       if (da->da_transport < 0) {
+               dprintk("%s: ERROR: unknown r_netid \"%s\"\n",
+                       __func__, netid);
                goto out_free_da;
        }
 
+       da->da_netid = netid;
+
        /* save human readable address */
        len = strlen(startsep) + strlen(buf) + strlen(endsep) + 7;
        da->da_remotestr = kzalloc(len, gfp_flags);
@@ -1161,7 +1166,6 @@ nfs4_decode_mp_ds_addr(struct net *net, struct xdr_stream *xdr, gfp_t gfp_flags)
 
        dprintk("%s: Parsed DS addr %s\n", __func__, da->da_remotestr);
        kfree(buf);
-       kfree(netid);
        return da;
 
 out_free_da: