fs/nfs: Support both IPv6 and TCP

And correctly handle the retransmission
This commit is contained in:
Xiang Xiao
2020-03-01 17:24:29 +08:00
committed by Gregory Nutt
parent 6c77829940
commit 7794214a7d
8 changed files with 278 additions and 269 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
config NFS config NFS
bool "NFS client file system" bool "NFS client file system"
default n default n
depends on NET_UDP && NET_IPv4 && !DISABLE_MOUNTPOINT depends on !DISABLE_MOUNTPOINT
select FS_READABLE select FS_READABLE
select FS_WRITABLE select FS_WRITABLE
---help--- ---help---
+1 -1
View File
@@ -61,7 +61,7 @@
#define NFS_RETRANS 10 /* Num of retrans for soft mounts */ #define NFS_RETRANS 10 /* Num of retrans for soft mounts */
#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */ #define NFS_WSIZE 8192 /* Def. write data size <= 8192 */
#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */ #define NFS_RSIZE 8192 /* Def. read data size <= 8192 */
#define NFS_READDIRSIZE 8192 /* Def. readdir size */ #define NFS_READDIRSIZE 1024 /* Def. readdir size */
/* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with /* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with
* broken NFS/ethernet drivers that won't work with anything bigger (Linux..) * broken NFS/ethernet drivers that won't work with anything bigger (Linux..)
+1 -3
View File
@@ -73,7 +73,7 @@ struct nfsmount
char nm_path[90]; /* server's path of the directory being mounted */ char nm_path[90]; /* server's path of the directory being mounted */
struct nfs_fattr nm_fattr; /* nfs file attribute cache */ struct nfs_fattr nm_fattr; /* nfs file attribute cache */
FAR struct rpcclnt *nm_rpcclnt; /* RPC state */ FAR struct rpcclnt *nm_rpcclnt; /* RPC state */
struct sockaddr nm_nam; /* Addr of server */ struct sockaddr_storage nm_nam; /* Addr of server */
uint8_t nm_fhsize; /* Size of root file handle (host order) */ uint8_t nm_fhsize; /* Size of root file handle (host order) */
uint16_t nm_rsize; /* Max size of read RPC */ uint16_t nm_rsize; /* Max size of read RPC */
uint16_t nm_wsize; /* Max size of write RPC */ uint16_t nm_wsize; /* Max size of write RPC */
@@ -87,8 +87,6 @@ struct nfsmount
union union
{ {
struct rpc_call_pmap pmap;
struct rpc_call_mount mountd;
struct rpc_call_create create; struct rpc_call_create create;
struct rpc_call_lookup lookup; struct rpc_call_lookup lookup;
struct rpc_call_read read; struct rpc_call_read read;
+2 -11
View File
@@ -149,18 +149,9 @@ int nfs_request(FAR struct nfsmount *nmp, int procnum,
if (replyh.nfs_status != 0) if (replyh.nfs_status != 0)
{ {
if (fxdr_unsigned(uint32_t, replyh.nfs_status) > 32) /* NFS_ERRORS are the same as NuttX errno values */
{
error = -EOPNOTSUPP;
}
else
{
/* NFS_ERRORS are the same as NuttX errno values */
error = -fxdr_unsigned(uint32_t, replyh.nfs_status); return -fxdr_unsigned(uint32_t, replyh.nfs_status);
}
return error;
} }
if (replyh.rh.rpc_verfi.authtype != 0) if (replyh.rh.rpc_verfi.authtype != 0)
+53 -71
View File
@@ -66,8 +66,6 @@
#include <nuttx/fs/dirent.h> #include <nuttx/fs/dirent.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/fs/nfs.h> #include <nuttx/fs/nfs.h>
#include <nuttx/net/udp.h>
#include <nuttx/net/arp.h>
#include <nuttx/net/netconfig.h> #include <nuttx/net/netconfig.h>
#include <net/if.h> #include <net/if.h>
@@ -1634,16 +1632,20 @@ static void nfs_decode_args(FAR struct nfs_mount_parameters *nprmt,
/* Get the maximum amount of data that can be transferred in one packet */ /* Get the maximum amount of data that can be transferred in one packet */
if ((argp->sotype == SOCK_DGRAM) != 0) if (argp->sotype == SOCK_DGRAM)
{ {
maxio = NFS_MAXDGRAMDATA; maxio = NFS_MAXDGRAMDATA;
} }
else else
{ {
ferr("ERROR: Only SOCK_DRAM is supported\n");
maxio = NFS_MAXDATA; maxio = NFS_MAXDATA;
} }
if (maxio > MAXBSIZE)
{
maxio = MAXBSIZE;
}
/* Get the maximum amount of data that can be transferred in one write transfer */ /* Get the maximum amount of data that can be transferred in one write transfer */
if ((argp->flags & NFSMNT_WSIZE) != 0 && argp->wsize > 0) if ((argp->flags & NFSMNT_WSIZE) != 0 && argp->wsize > 0)
@@ -1664,11 +1666,6 @@ static void nfs_decode_args(FAR struct nfs_mount_parameters *nprmt,
nprmt->wsize = maxio; nprmt->wsize = maxio;
} }
if (nprmt->wsize > MAXBSIZE)
{
nprmt->wsize = MAXBSIZE;
}
/* Get the maximum amount of data that can be transferred in one read transfer */ /* Get the maximum amount of data that can be transferred in one read transfer */
if ((argp->flags & NFSMNT_RSIZE) != 0 && argp->rsize > 0) if ((argp->flags & NFSMNT_RSIZE) != 0 && argp->rsize > 0)
@@ -1689,11 +1686,6 @@ static void nfs_decode_args(FAR struct nfs_mount_parameters *nprmt,
nprmt->rsize = maxio; nprmt->rsize = maxio;
} }
if (nprmt->rsize > MAXBSIZE)
{
nprmt->rsize = MAXBSIZE;
}
/* Get the maximum amount of data that can be transferred in directory transfer */ /* Get the maximum amount of data that can be transferred in directory transfer */
if ((argp->flags & NFSMNT_READDIRSIZE) != 0 && argp->readdirsize > 0) if ((argp->flags & NFSMNT_READDIRSIZE) != 0 && argp->readdirsize > 0)
@@ -1767,6 +1759,14 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data,
/* The buffer size will be the maximum of those two sizes */ /* The buffer size will be the maximum of those two sizes */
if (tmp > buflen)
{
buflen = tmp;
}
/* And consider the maximum size of a read dir transfer too */
tmp = SIZEOF_rpc_reply_readdir(nprmt.readdirsize);
if (tmp > buflen) if (tmp > buflen)
{ {
buflen = tmp; buflen = tmp;
@@ -1780,9 +1780,9 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data,
* that case. * that case.
*/ */
if (buflen > MIN_IPv4_UDP_MSS) if (argp->sotype == SOCK_DGRAM && buflen > MIN_UDP_MSS)
{ {
buflen = MIN_IPv4_UDP_MSS; buflen = MIN_UDP_MSS;
} }
/* Create an instance of the mountpt state structure */ /* Create an instance of the mountpt state structure */
@@ -1824,43 +1824,36 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data,
strncpy(nmp->nm_path, argp->path, 90); strncpy(nmp->nm_path, argp->path, 90);
memcpy(&nmp->nm_nam, &argp->addr, argp->addrlen); memcpy(&nmp->nm_nam, &argp->addr, argp->addrlen);
/* Set up the sockets and per-host congestion */ /* Create an instance of the rpc state structure */
if (argp->sotype == SOCK_DGRAM) rpc = (FAR struct rpcclnt *)kmm_zalloc(sizeof(struct rpcclnt));
if (!rpc)
{ {
/* Connection-less... connect now */ ferr("ERROR: Failed to allocate rpc structure\n");
return -ENOMEM;
/* Create an instance of the rpc state structure */
rpc = (FAR struct rpcclnt *)kmm_zalloc(sizeof(struct rpcclnt));
if (!rpc)
{
ferr("ERROR: Failed to allocate rpc structure\n");
return -ENOMEM;
}
finfo("Connecting\n");
/* Translate nfsmnt flags -> rpcclnt flags */
rpc->rc_path = nmp->nm_path;
rpc->rc_name = &nmp->nm_nam;
rpc->rc_sotype = argp->sotype;
rpc->rc_timeo = nprmt.timeo;
rpc->rc_retry = nprmt.retry;
nmp->nm_rpcclnt = rpc;
error = rpcclnt_connect(nmp->nm_rpcclnt);
if (error != OK)
{
ferr("ERROR: nfs_connect failed: %d\n", error);
goto bad;
}
} }
nmp->nm_fhsize = nmp->nm_rpcclnt->rc_fhsize; finfo("Connecting\n");
nmp->nm_fh = &nmp->nm_rpcclnt->rc_fh;
/* Translate nfsmnt flags -> rpcclnt flags */
rpc->rc_path = nmp->nm_path;
rpc->rc_name = &nmp->nm_nam;
rpc->rc_sotype = argp->sotype;
rpc->rc_timeo = nprmt.timeo;
rpc->rc_retry = nprmt.retry;
nmp->nm_rpcclnt = rpc;
error = rpcclnt_connect(nmp->nm_rpcclnt);
if (error != OK)
{
ferr("ERROR: nfs_connect failed: %d\n", error);
goto bad;
}
nmp->nm_fhsize = nmp->nm_rpcclnt->rc_fhsize;
nmp->nm_fh = &nmp->nm_rpcclnt->rc_fh;
/* Get the file sytem info */ /* Get the file sytem info */
@@ -1880,22 +1873,19 @@ static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data,
return OK; return OK;
bad: bad:
if (nmp) /* Disconnect from the server */
if (nmp->nm_rpcclnt)
{ {
/* Disconnect from the server */ rpcclnt_disconnect(nmp->nm_rpcclnt);
kmm_free(nmp->nm_rpcclnt);
if (nmp->nm_rpcclnt)
{
rpcclnt_disconnect(nmp->nm_rpcclnt);
kmm_free(nmp->nm_rpcclnt);
}
/* Free connection-related resources */
nxsem_destroy(&nmp->nm_sem);
kmm_free(nmp);
} }
/* Free connection-related resources */
nxsem_destroy(&nmp->nm_sem);
kmm_free(nmp);
return error; return error;
} }
@@ -1941,14 +1931,6 @@ static int nfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
goto errout_with_semaphore; goto errout_with_semaphore;
} }
/* No open file... Umount the file system. */
error = rpcclnt_umount(nmp->nm_rpcclnt);
if (error)
{
ferr("ERROR: rpcclnt_umount failed: %d\n", error);
}
/* Disconnect from the server */ /* Disconnect from the server */
rpcclnt_disconnect(nmp->nm_rpcclnt); rpcclnt_disconnect(nmp->nm_rpcclnt);
@@ -1959,7 +1941,7 @@ static int nfs_unbind(FAR void *handle, FAR struct inode **blkdriver,
kmm_free(nmp->nm_rpcclnt); kmm_free(nmp->nm_rpcclnt);
kmm_free(nmp); kmm_free(nmp);
return error; return OK;
errout_with_semaphore: errout_with_semaphore:
nfs_semgive(nmp); nfs_semgive(nmp);
+2 -3
View File
@@ -146,7 +146,6 @@
/* RPC definitions for the portmapper. */ /* RPC definitions for the portmapper. */
#define PMAPPORT 111
#define PMAPPROG 100000 #define PMAPPROG 100000
#define PMAPVERS 2 #define PMAPVERS 2
@@ -450,12 +449,13 @@ struct rpcclnt
uint8_t rc_fhsize; /* File size of the root directory */ uint8_t rc_fhsize; /* File size of the root directory */
FAR char *rc_path; /* Server's path of the mounted directory */ FAR char *rc_path; /* Server's path of the mounted directory */
FAR struct sockaddr *rc_name; FAR struct sockaddr_storage *rc_name;
struct socket rc_so; /* RPC socket */ struct socket rc_so; /* RPC socket */
uint8_t rc_sotype; /* Type of socket */ uint8_t rc_sotype; /* Type of socket */
uint8_t rc_timeo; /* Timeout value (in deciseconds) */ uint8_t rc_timeo; /* Timeout value (in deciseconds) */
uint8_t rc_retry; /* Max retries */ uint8_t rc_retry; /* Max retries */
uint32_t rc_xid; /* Transaction id */
}; };
/**************************************************************************** /****************************************************************************
@@ -465,7 +465,6 @@ struct rpcclnt
void rpcclnt_init(void); void rpcclnt_init(void);
int rpcclnt_connect(FAR struct rpcclnt *rpc); int rpcclnt_connect(FAR struct rpcclnt *rpc);
void rpcclnt_disconnect(FAR struct rpcclnt *rpc); void rpcclnt_disconnect(FAR struct rpcclnt *rpc);
int rpcclnt_umount(FAR struct rpcclnt *rpc);
int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog, int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
int version, FAR void *request, size_t reqlen, int version, FAR void *request, size_t reqlen,
FAR void *response, size_t resplen); FAR void *response, size_t resplen);
+217 -179
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -54,6 +54,7 @@
#include <stdint.h> #include <stdint.h>
#include <nuttx/config.h> #include <nuttx/config.h>
#include <nuttx/net/ethernet.h>
/**************************************************************************** /****************************************************************************
* Public Definitions * Public Definitions