NFS just finished a major weight reduction program

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4838 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-06-14 00:47:42 +00:00
parent 241c3f86d3
commit a27028feab
17 changed files with 480 additions and 1077 deletions

View File

@ -1266,7 +1266,6 @@ int cmd_mv(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct nfs_args data;
FAR char *protocol;
FAR char *address;
FAR char *lpath;
FAR char *rpath;
@ -1278,54 +1277,8 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
FAR struct sockaddr_in *sin;
struct in_addr inaddr;
#endif
bool tcp = false;
int ret;
/* Get the NFS mount options */
int option;
while ((option = getopt(argc, argv, ":p:")) != ERROR)
{
switch (option)
{
/* Protocol may be UDP or TCP */
case 'p':
protocol = optarg;
break;
/* Handle missing required arguments */
case ':':
nsh_output(vtbl, g_fmtargrequired, argv[0]);
badarg = true;
break;
/* Handle unrecognized arguments */
case '?':
default:
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
break;
}
}
/* Decode the protocol string */
if (protocol)
{
if (strncmp(protocol, "tcp", 3) == 0)
{
tcp = true;
}
else if (!strncmp(protocol, "udp", 3) != 0)
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
}
}
/* If a bad argument was encountered, then return without processing the
* command.
*/
@ -1335,26 +1288,11 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
return ERROR;
}
/* There are three required arguments after the options: (1) The NFS server IP
* address and then (1) the path to the mount point.
*/
if (optind + 3 < argc)
{
nsh_output(vtbl, g_fmttoomanyargs, argv[0]);
return ERROR;
}
else if (optind + 3 > argc)
{
nsh_output(vtbl, g_fmtargrequired, argv[0]);
return ERROR;
}
/* The next argument on the command line should be the NFS server IP address
/* The fist argument on the command line should be the NFS server IP address
* in standard IPv4 (or IPv6) dot format.
*/
address = argv[optind];
address = argv[1];
if (!address)
{
return ERROR;
@ -1364,7 +1302,7 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
* directory.
*/
lpath = nsh_getfullpath(vtbl, argv[optind+1]);
lpath = nsh_getfullpath(vtbl, argv[2]);
if (!lpath)
{
return ERROR;
@ -1372,7 +1310,7 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
/* Get the remote mount point path */
rpath = argv[optind+2];
rpath = argv[3];
/* Convert the IP address string into its binary form */
@ -1406,16 +1344,11 @@ int cmd_nfsmount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
#endif
data.version = NFS_ARGSVERSION;
data.sotype = (tcp) ? SOCK_STREAM : SOCK_DGRAM;
data.proto = (tcp) ? IPPROTO_TCP : IPPROTO_UDP;
data.sotype = SOCK_DGRAM;
data.flags = NFSMNT_NFSV3;
data.retrans = 3;
data.path = rpath;
data.acregmin = 3;
data.acregmax = 60;
data.acdirmin = 30;
data.acdirmax = 60;
data.timeo = (tcp) ? 70 : 7;
data.timeo = 7;
/* Perform the mount */

View File

@ -276,7 +276,7 @@ static const struct cmdmap_s g_cmdmap[] =
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0 && \
defined(CONFIG_FS_READABLE) && defined(CONFIG_NET) && defined(CONFIG_NFS)
# ifndef CONFIG_NSH_DISABLE_NFSMOUNT
{ "nfsmount", cmd_nfsmount, 4, 6, "[-p <protocol>] <server-address> <mount-point> <remote-path>" },
{ "nfsmount", cmd_nfsmount, 4, 4, "<server-address> <mount-point> <remote-path>" },
# endif
#endif

View File

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4">
<td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: June 6, 2012</p>
<p>Last Updated: June 13, 2012</p>
</td>
</tr>
</table>
@ -424,6 +424,15 @@
</li>
</p>
</tr>
<tr>
<td><br></td>
<td>
<p>
<li>
NFS Client. Client side support for a Network File System (NFS, version 3, UDP).
</li>
</p>
</tr>
<tr>
<td><br></td>
<td>
@ -561,6 +570,15 @@
<li>Networking utilities (DHCP server and client, SMTP client, TELNET client, FTP server and client, TFTP client, HTTP server and client). Inheritable TELNET sessions (as &quot;controlling terminal&quot;)</li>
</p>
</tr>
<tr>
<td><br></td>
<td>
<p>
<li>
NFS Client. Client side support for a Network File System (NFS, version 3, UDP).
</li>
</p>
</tr>
<tr>
<td><br></td>
<td>

View File

@ -12,7 +12,7 @@
<h1><big><font color="#3c34ec">
<i>NuttX RTOS Porting Guide</i>
</font></big></h1>
<p>Last Updated: May 6, 2011</p>
<p>Last Updated: June 13, 2012</p>
</td>
</tr>
</table>
@ -634,6 +634,7 @@
</p>
<ul><pre>
<i>&lt;board-name&gt;</i>
|-- Kconfig
|-- include/
| |-- board.h
| `-- <i>(board-specific header files)</i>
@ -1005,41 +1006,58 @@
</p>
<ul><pre>
drivers/
|-- Kconfig
|-- Makefile
|-- analog/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common ADC and DAC driver source files)</i>
|-- bch/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(bch driver source files)</i>
|-- input/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common touchscreen and keypad driver source files)</i>
|-- lcd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common LCD driver source files)</i>
|-- mmcsd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common MMC/SD card driver source files)</i>
|-- mtd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common memory technology device driver source files)</i>
|-- net/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common network driver source files)</i>
|-- sensors/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common sensor driver source files)</i>
|-- serial/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Files for the Calypso SERCOMM driver)</i>
|-- serial/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common front-end character drivers for chip-specific UARTs)</i>
|-- usbdev/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common USB device driver source files)</i>
|-- usbhost/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common USB host driver source files)</i>
|-- wirelss/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(Common wireless driver source files)</i>
`-- <i>(Various common driver source files)</i>
@ -1053,17 +1071,26 @@ drivers/
</p>
<ul><pre>
fs/
|-- Kconfig
|-- Makefile
|-- fat/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(FAT file system source files)</i>
|-- mmap/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(RAM-based file mapping source files)</i>
|-- nfs/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(NFS client file system source files)</i>
|-- nxffs/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(NuttX Flash File System (NXFFS) source files)</i>
|-- romfs/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(ROMFS file system source files)</i>
`-- <i>(common file system source files)</i>
@ -1076,6 +1103,7 @@ fs/
</p>
<ul><pre>
graphics/
|-- Kconfig
|-- Makefile
|-- nxbe/
| |-- Make.defs
@ -1255,37 +1283,60 @@ tools/
</p>
<ul><pre>
netutils/
|-- Kconfig
|-- Makefile
|-- dhcp/
|-- dhcdp/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(dhcp source files)</i>
| `-- <i>(DHCP client source files)</i>
|-- dhcpd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(dhcpd source files)</i>
| `-- <i>(DHCP server source files)</i>
|-- ftpc/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(FTP client source files)</i>
|-- ftpd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(FTP server source files)</i>
|-- resolv/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(resolv source files)</i>
|-- resolv/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(resolv source files)</i>
|-- smtp/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(smtp source files)</i>
|-- telnetd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(telnetd source files)</i>
| `-- <i>(Telnet client source files)</i>
|-- tftpc/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(tftpc source files)</i>
| `-- <i>(TFTP client source files)</i>
|-- thttpd/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(thttpd source files)</i>
| `-- <i>(thttpd HTTP server source files)</i>
|-- uiplib/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(uiplib source files)</i>
|-- weblclient/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(webclient source files)</i>
|-- webserver/
| |-- Kconfig
| |-- Make.defs
| `-- <i>(webserver source files)</i>
| `-- <i>(uIP webserver source files)</i>
`-- <i>(netutils common files)</i>
</pre></ul>
@ -2262,8 +2313,9 @@ extern void up_ledoff(int led);
NuttX supports the standard <code>mount()</code> command that allows
a block driver to be bound to a mountpoint within the pseudo file system
and to a file system.
At present, NuttX supports the standard VFAT and ROMFS file systems and
well as a special, wear-leveling NuttX FLASH File System (NXFFS).
At present, NuttX supports the standard VFAT and ROMFS file systems,
a special, wear-leveling NuttX FLASH File System (NXFFS),
as well as a Network File System client (NFS version 3, UDP).
</p>
<p><b>Comparison to Linux</b>
@ -4437,6 +4489,13 @@ build
<li>
<code>CONFIG_FS_ROMFS</code>: Enable ROMFS file system support
</li>
<li>
<code>CONFIG_NFS</code>: Enable Network File System (NFS) client file system support.
Provided support is version 3 using UDP.
In addition to common prerequisites for mount-able file systems in general,
this option requires UDP networking support;
this would include <code>CONFIG_NET</code> and <code>CONFIG_NET_UDP</code> at a minimum.
</li>
<li>
<code>CONFIG_FS_RAMMAP</code>: For file systems that do not support
XIP, this option will enable a limited form of memory mapping that is

View File

@ -647,6 +647,11 @@ defconfig -- This is a configuration file similar to the Linux
and making it available for re-use (and possible over-wear).
Default: 8192.
CONFIG_FS_ROMFS - Enable ROMFS filesystem support
CONFIG_NFS - Enable Network File System (NFS) client file system support.
Provided support is version 3 using UDP. In addition to common
prerequisites for mount-able file systems in general, this option
requires UDP networking support; this would include CONFIG_NETand
CONFIG_NET_UDP at a minimum.
CONFIG_FS_RAMMAP - For file systems that do not support XIP, this
option will enable a limited form of memory mapping that is
implemented by copying whole files into memory.

View File

@ -12,19 +12,13 @@ config NFS
#if NFS
config NFS_TCPIP
bool "TCP/IP RPC support"
config NFS_STATISTICS
bool "NFS Stastics"
default n
depends on NFS
---help---
By default, NFS uses a UDP RPC protocol. Enable this option to
build in support for a TCP/IP-based RPC.
Collect support for NFS statistics. There is no user interface to
obtain these statistics, however. So they would only be of value
if you add debug instrumentation or use a debugger.
config NFS_UNIX_AUTH
bool "NFS Unix authentication"
default n
depends on NFS
---help---
Build in support for Unix-style authentication.
#endif
#endif

View File

@ -54,19 +54,25 @@
* Pre-processor Definitions
****************************************************************************/
#define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */
#define NFS_HZ (CLOCKS_PER_SEC / nfs_ticks) /* Ticks/sec */
#if MSEC_PER_TICK <= 5
# define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */
# define NFS_TICKS (CLOCKS_PER_SEC * NFS_TICKINTVL + 500) / 1000
# define NFS_HZ (CLOCKS_PER_SEC / NFS_TICKS) /* Ticks/sec */
#else
# define NFS_TICKINTVL MSEC_PER_TICK /* Smallest that we can get */
# define NFS_TICKS 1 /* Number of system ticks */
# define NFS_HZ CLOCKS_PER_SEC /* Ticks/sec */
#endif
#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */
#define NFS_MINTIMEO (1 * NFS_HZ) /* Min timeout to use */
#define NFS_MAXTIMEO (60 * NFS_HZ) /* Max timeout to backoff to */
#define NFS_MINIDEMTIMEO (5 * NFS_HZ) /* Min timeout for non-idempotent ops */
#define NFS_TIMEOUTMUL 2 /* Timeout/Delay multiplier */
#define NFS_MAXREXMIT 100 /* Stop counting after this many */
#define NFS_RETRANS 10 /* Num of retrans for soft mounts */
#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */
#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */
#define NFS_READDIRSIZE 8192 /* Def. readdir size */
#define NFS_MAXASYNCDAEMON 20 /* Max. number async_daemons runable */
#define NFS_NPROCS 23
/* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with
@ -74,85 +80,6 @@
*/
#define NFS_DIRBLKSIZ 1024 /* Must be a multiple of DIRBLKSIZ */
#define NFS_READDIRBLKSIZ 512 /* Size of read dir blocks. XXX */
/* Oddballs */
#define NFS_CMPFH(n, f, s) \
((n)->n_fhsize == (s) && !bcmp((void *)(n)->n_fhp, (void *)(f), (s)))
#define NFS_ISV3(i) (VFSTONFS((i)->f_inode)->nm_flag & NFSMNT_NFSV3)
#define NFS_SRVMAXDATA(n) \
(((n)->nd_flag & ND_NFSV3) ? (((n)->nd_nam2) ? \
NFS_MAXDGRAMDATA : NFS_MAXDATA) : NFS_V2MAXDATA)
/* sys/malloc.h needs M_NFSDIROFF, M_NFSRVDESC and M_NFSBIGFH added. */
#ifndef M_NFSRVDESC
# define M_NFSRVDESC M_TEMP
#endif
#ifndef M_NFSDIROFF
# define M_NFSDIROFF M_TEMP
#endif
#ifndef M_NFSBIGFH
# define M_NFSBIGFH M_TEMP
#endif
/*The B_INVAFTERWRITE flag should be set to whatever is required by the
* buffer cache code to say "Invalidate the block after it is written back".
*/
#define B_INVAFTERWRITE B_INVAL
/* Flags for nfssvc() system call. */
#define NFSSVC_BIOD 0x002
#define NFSSVC_NFSD 0x004
#define NFSSVC_ADDSOCK 0x008
#define NFSSVC_AUTHIN 0x010
#define NFSSVC_GOTAUTH 0x040
#define NFSSVC_AUTHINFAIL 0x080
#define NFSSVC_MNTD 0x100
/* On fast networks, the estimator will try to reduce the timeout lower than
* the latency of the server's disks, which results in too many timeouts, so
* cap the lower bound.
*/
#define NFS_MINRTO (NFS_HZ >> 2)
/* Keep the RTO from increasing to unreasonably large values when a server is
* not responding.
*/
#define NFS_MAXRTO (20 * NFS_HZ)
#define NFS_MAX_TIMER (NFS_WRITE_TIMER)
#define NFS_INITRTT (NFS_HZ << 3)
/* Bits for "ns_flag" */
#define SLP_VALID 0x01 /* connection is usable */
#define SLP_DOREC 0x02 /* receive operation required */
#define SLP_NEEDQ 0x04 /* connection has data to queue from socket */
#define SLP_DISCONN 0x08 /* connection is closed */
#define SLP_GETSTREAM 0x10 /* extracting RPC from TCP connection */
#define SLP_LASTFRAG 0x20 /* last fragment received on TCP connection */
#define SLP_ALLFLAGS 0xff /* convenience */
#define SLP_INIT 0x01 /* NFS data undergoing initialization */
#define SLP_WANTINIT 0x02 /* thread waiting on NFS initialization */
/* Bits for "nfsd_flag" */
#define NFSD_WAITING 0x01
#define NFSD_REQINPROG 0x02
#define NFSD_NEEDAUTH 0x04
#define NFSD_AUTHFAIL 0x08
/* Bits for "nd_flag" */
#define ND_NFSV3 0x08
#define NFSD_CHECKSLP 0x01
/* Increment NFS statistics */
@ -172,111 +99,12 @@ extern uint32_t nfs_xdrneg1;
#ifdef CONFIG_NFS_STATISTICS
extern struct nfsstats nfsstats;
#endif
extern int nfs_ticks;
/****************************************************************************
* Public Types
****************************************************************************/
#undef COMP
#ifdef COMP
/* Structures for the nfssvc(2) syscall.
* Not that anyone besides nfsd(8) should ever use it.
*/
struct nfsd_args
{
int sock; /* Socket to serve */
void *name; /* Client addr for connection based sockets */
int namelen; /* Length of name */
};
struct nfsd_srvargs
{
struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */
uid_t nsd_uid; /* Effective uid mapped to cred */
uint32_t nsd_haddr; /* IP address of client */
int nsd_authlen; /* Length of auth string (ret) */
uint8_t *nsd_authstr; /* Auth string (ret) */
int nsd_verflen; /* and the verifier */
uint8_t *nsd_verfstr;
struct timeval nsd_timestamp; /* timestamp from verifier */
uint32_t nsd_ttl; /* credential ttl (sec) */
};
/* The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts.
* What should be in this set is open to debate, but I believe that since
* I/O system calls on ufs are never interrupted by signals the set should
* be minimal. My reasoning is that many current programs that use signals
* such as SIGALRM will not expect file I/O system calls to be interrupted
* by them and break.
*/
/* Nfs outstanding request list element */
struct nfsreq
{
dq_entry_t r_chain;
struct nfsmount *r_nmp;
uint32_t r_xid;
int r_flags; /* flags on request, see below */
int r_rexmit; /* current retrans count */
int r_timer; /* tick counter on reply */
int r_procnum; /* NFS procedure number */
int r_rtt; /* RTT for rpc */
};
enum nfs_rto_timers
{
NFS_DEFAULT_TIMER,
NFS_GETATTR_TIMER,
NFS_LOOKUP_TIMER,
NFS_READ_TIMER,
NFS_WRITE_TIMER,
};
/* Network address hash list element */
union nethostaddr
{
uint32_t had_inetaddr;
struct mbuf *had_nam;
};
struct nfssvc_sock
{
// TAILQ_ENTRY(nfssvc_sock) ns_chain; /* List of all nfssvc_sock's */
struct file *ns_fp; /* fp from the... */
struct socket *ns_so; /* ...socket this struct wraps */
int ns_flag; /* socket status flags */
int ns_solock; /* lock for connected socket */
int ns_cc; /* actual chars queued */
int ns_reclen; /* length of first queued record */
uint32_t ns_sref; /* # of refs to this struct */
};
/* One of these structures is allocated for each nfsd. */
struct nfsd
{
//TAILQ_ENTRY(nfsd) nfsd_chain; /* List of all nfsd's */
int nfsd_flag; /* NFSD_ flags */
struct nfssvc_sock *nfsd_slp; /* Current socket */
struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */
};
/* This structure is used by the server for describing each request. */
struct nfsrv_descript
{
unsigned int nd_procnum; /* RPC # */
int nd_flag; /* nd_flag */
int nd_repstat; /* Reply status */
uint32_t nd_retxid; /* Reply xid */
};
#endif
/* Stats structure */
/* NFS statistics structure */
struct nfsstats
{

View File

@ -51,7 +51,7 @@
#include <sys/socket.h>
#include "rpc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -78,17 +78,17 @@ struct nfsmount
uint8_t nm_flag; /* Flags for soft/hard... */
uint8_t nm_fhsize; /* Size of root file handle (host order) */
uint8_t nm_sotype; /* Type of socket */
uint8_t nm_soproto; /* and protocol */
uint8_t nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */
uint8_t nm_retry; /* Max retries */
uint16_t nm_rsize; /* Max size of read RPC */
uint16_t nm_wsize; /* Max size of write RPC */
uint16_t nm_readdirsize; /* Size of a readdir RPC */
uint8_t nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */
uint16_t nm_buflen; /* Size of I/O buffer */
/* Set aside memory on the stack to hold the largest call message. NOTE
* that for the case of the write call message, the reply message is in
* this union.
* that for the case of the write call message, it is the reply message that
* is in this union.
*/
union
@ -105,7 +105,38 @@ struct nfsmount
struct rpc_call_readdir readdir;
struct rpc_call_fs fs;
struct rpc_reply_write write;
} nm_smallbuffer;
} nm_msgbuffer;
/* I/O buffer (must be a aligned to 32-bit boundaries). This buffer used for all
* reply messages EXCEPT for the WRITE RPC. In that case it is used for the WRITE
* call message that contains the data to be written. This buffer must be
* dynamically sized based on the characteristics of the server and upon the
* configuration of the NuttX network. It must be sized to hold the largest
* possible WRITE call message or READ response message.
*/
uint32_t nm_iobuffer[1]; /* Actual size is given by nm_buflen */
};
/* The size of the nfsmount structure will debug on the size of the allocated I/O
* buffer.
*/
#define SIZEOF_nfsmount(n) (sizeof(struct nfsmount) + ((n + 3) & ~3) - sizeof(uint32_t))
/* Mount parameters structure. This structure is use in nfs_decode_args funtion before one
* mount structure is allocated in each NFS mount.
*/
struct nfs_mount_parameters
{
uint8_t flag; /* Flags for soft/hard... */
uint8_t timeo; /* Init timer for NFSMNT_DUMBTIMR */
uint8_t retry; /* Max retries */
uint16_t rsize; /* Max size of read RPC */
uint16_t wsize; /* Max size of write RPC */
uint16_t readdirsize; /* Size of a readdir RPC */
};
#endif

View File

@ -73,16 +73,10 @@ struct nfsnode
uint8_t n_type; /* File type */
uint8_t n_fhsize; /* Size in bytes of the file handle */
uint8_t n_flags; /* Node flags */
uint16_t n_buflen; /* Size of I/O buffer */
struct timespec n_mtime; /* File modification time (see NOTE) */
time_t n_ctime; /* File creation time (see NOTE) */
nfsfh_t n_fhandle; /* NFS File Handle */
uint64_t n_size; /* Current size of file (see NOTE) */
/* I/O buffer (must be a aligned to 32-bit boundaries) */
uint8_t n_iobuffer[1]; /* Actual size is given by n_buflen */
};
#define SIZEOF_nfsnode(n) (sizeof(struct nfsnode) + ((n)-1))
#endif /* __FS_NFS_NFS_NODE_H */

View File

@ -296,34 +296,6 @@ typedef enum
NFFIFO = 7 /* Named FIFO */
} nfstype;
#if 0
typedef struct
{
int32_t val[2];
} fsid_t; /* file system id type */
/* File identifier.
* These are unique per filesystem on a single machine.
*/
struct fid
{
unsigned short fid_len; /* length of data in bytes */
unsigned short fid_reserved; /* force longword alignment */
char fid_data[MAXFIDSZ]; /* data (variable length) */
};
/* Generic file handle */
struct fhandle
{
fsid_t fh_fsid; /* File system id of mount point */
struct fid fh_fid; /* File sys specific id */
};
typedef struct fhandle fhandle_t;
#endif
/* File Handle variable is up to 64 bytes for version 3. This structures a
* ariable sized and are provided only for setting aside maximum memory
* allocations for a file handle.

View File

@ -80,7 +80,6 @@
uint32_t nfs_true;
uint32_t nfs_false;
uint32_t nfs_xdrneg1;
int nfs_ticks;
struct nfsstats nfsstats;
/****************************************************************************
@ -97,12 +96,6 @@ void nfs_init(void)
nfs_false = txdr_unsigned(FALSE);
nfs_xdrneg1 = txdr_unsigned(-1);
nfs_ticks = (CLOCKS_PER_SEC * NFS_TICKINTVL + 500) / 1000;
if (nfs_ticks < 1)
{
nfs_ticks = 1;
}
rpcclnt_init();
}
@ -131,7 +124,6 @@ int nfs_connect(struct nfsmount *nmp)
rpc->rc_path = nmp->nm_path;
rpc->rc_name = &nmp->nm_nam;
rpc->rc_sotype = nmp->nm_sotype;
rpc->rc_soproto = nmp->nm_soproto;
nmp->nm_rpcclnt = rpc;

View File

@ -196,102 +196,6 @@ int nfs_checkmount(struct nfsmount *nmp)
return 0;
}
/****************************************************************************
* Name: nfs_fsinfo
*
* Description:
* Return information about root directory.
*
* Returned Value:
* 0 on success; positive errno value on failure
*
* Assumptions:
* The caller has exclusive access to the NFS mount structure
*
****************************************************************************/
int nfs_fsinfo(FAR struct nfsmount *nmp)
{
struct rpc_call_fs fsinfo;
struct rpc_reply_fsinfo fsp;
uint32_t pref;
uint32_t max;
int error = 0;
memset(&fsinfo, 0, sizeof(struct rpc_call_fs));
memset(&fsp, 0, sizeof(struct rpc_reply_fsinfo));
fsinfo.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
fsinfo.fs.fsroot.handle = nmp->nm_fh;
/* Request FSINFO from the server */
nfs_statistics(NFSPROC_FSINFO);
error = nfs_request(nmp, NFSPROC_FSINFO,
(FAR const void *)&fsinfo, sizeof(struct FS3args),
(FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo));
if (error)
{
return error;
}
/* Save the root file system attributes */
#if 0
memcpy(&nmp->nm_fattr. &fsp.obj_attributes, sizeof(struct nfs_fattr));
#endif
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtpref);
if (pref < nmp->nm_wsize)
{
nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
}
max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtmax);
if (max < nmp->nm_wsize)
{
nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize == 0)
{
nmp->nm_wsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtpref);
if (pref < nmp->nm_rsize)
{
nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
}
max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtmax);
if (max < nmp->nm_rsize)
{
nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize == 0)
{
nmp->nm_rsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_dtpref);
if (pref < nmp->nm_readdirsize)
{
nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & ~(NFS_DIRBLKSIZ - 1);
}
if (max < nmp->nm_readdirsize)
{
nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize == 0)
{
nmp->nm_readdirsize = max;
}
}
nmp->nm_flag |= NFSMNT_GOTFSINFO;
return 0;
}
/****************************************************************************
* Name: nfs_lookup
*
@ -321,11 +225,6 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
DEBUGASSERT(nmp && filename && fhandle);
/* Set all of the buffers to a known state */
memset(&request, 0, sizeof(struct rpc_call_lookup));
memset(&response, 0, sizeof(struct rpc_reply_lookup));
/* Get the length of the string to be sent */
namelen = strlen(filename);
@ -361,7 +260,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
nfs_statistics(NFSPROC_LOOKUP);
error = nfs_request(nmp, NFSPROC_LOOKUP,
(FAR const void *)&request, reqlen,
(FAR void *)&request, reqlen,
(FAR void *)&response, sizeof(struct rpc_reply_lookup));
if (error)
{

File diff suppressed because it is too large Load Diff

View File

@ -277,9 +277,6 @@ struct rpc_call_header
uint32_t rp_vers; /* version */
uint32_t rp_proc; /* procedure */
struct rpc_auth_info rpc_auth;
#ifdef CONFIG_NFS_UNIX_AUTH
struct auth_unix rpc_unix;
#endif
struct rpc_auth_info rpc_verf;
};
@ -485,21 +482,10 @@ struct rpcclnt
uint8_t rc_clntflags; /* For RPCCLNT_* flags */
uint8_t rc_sotype; /* Type of socket */
uint8_t rc_soproto; /* and protocol */
/* These describe the current RPC call */
uint8_t rc_callflags; /* For RPCCALL_* flags */
/* Authentication: Can be RPCAUTH_NULL, RPCAUTH_KERBV4, RPCAUTH_UNIX
* Should be kept in XDR form
*/
/* RPCAUTH_UNIX */
#ifdef CONFIG_NFS_UNIX_AUTH
struct rpc_auth_info rc_oldauth; /* authentication */
void *rc_auth;
#endif
};
/****************************************************************************

View File

@ -98,23 +98,6 @@
* Pre-processor Definitions
****************************************************************************/
/* There is a congestion window for outstanding RPCs maintained per mount
* point. The cwnd size is adjusted in roughly the way that: Van Jacobson,
* Congestion avoidance and Control, In "Proceedings of SIGCOMM '88". ACM,
* August 1988. describes for TCP. The cwnd size is chopped in half on a
* retransmit timeout and incremented by 1/cwnd when each RPC reply is
* received and a full cwnd of RPCs is in progress. (The sent count and cwnd
* are scaled for integer arith.) Variants of "slow start" were tried and
* were found to be too much of a performance hit (ave. rtt 3 times larger),
* I suspect due to the large rtt that nfs RPCs have.
*/
#define RPC_CWNDSCALE 256
#define RPC_MAXCWND (RPC_CWNDSCALE * 32)
#define RPC_ERRSTR_ACCEPTED_SIZE 6
#define RPC_ERRSTR_AUTH_SIZE 6
/* Increment RPC statistics */
#ifdef CONFIG_NFS_STATISTICS
@ -159,9 +142,6 @@ static int rpcclnt_receive(FAR struct rpcclnt *rpc, struct sockaddr *aname,
int proc, int program, void *reply, size_t resplen);
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
void *reply, size_t resplen);
#ifdef CONFIG_NFS_TCPIP
static int rpcclnt_reconnect(FAR struct rpcclnt *rpc);
#endif
static uint32_t rpcclnt_newxid(void);
static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
uint32_t xid, int procid, int prog, int vers);
@ -221,208 +201,19 @@ static int rpcclnt_receive(FAR struct rpcclnt *rpc, struct sockaddr *aname,
int proc, int program, void *reply, size_t resplen)
{
ssize_t nbytes;
#ifdef CONFIG_NFS_TCPIP
uint32_t resplen;
int sotype;
#endif
int error = 0;
int errval;
#ifdef CONFIG_NFS_TCPIP
/* Set up arguments for psock_recvfrom() */
sotype = rpc->rc_sotype;
if (sotype != SOCK_DGRAM)
if (rpc->rc_so == NULL)
{
tryagain:
/* Check for fatal errors and resending request. */
if (rpc->rc_so == NULL)
{
error = rpcclnt_reconnect(rpc);
if (error)
{
return error;
}
goto tryagain;
}
while (rpc->rc_callflags & RPCCALL_MUSTRESEND)
{
rpc_statistics(rpcretries);
error = rpcclnt_send(rpc, proc, program, call, reqlen);
if (error)
{
if (error == EINTR || error == ERESTART)
{
return error;
}
error = rpcclnt_reconnect(rpc);
if (error != OK)
{
return error;
}
goto tryagain;
}
}
if (sotype == SOCK_STREAM)
{
errval = 0;
do
{
socklen_t fromlen = sizeof(*rpc->rc_name)
nbytes = psock_recvfrom(rpc->rc_so, reply, resplen,
MSG_WAITALL, rpc->rc_name,
&fromlen);
if (nbytes < 0)
{
errval = errno;
fdbg("ERROR: psock_recvfrom returned %d\n", errval);
}
}
while (errval == EWOULDBLOCK);
if (nbytes < 0)
{
error = errval;
}
else if (nbytes < resplen)
{
fdbg("ERROR: Short receive from RPC server\n");
fvdbg(" Expected %d bytes, received %d bytes\n",
resplen, nbytes);
error = EPIPE;
}
else
{
error = 0;
}
#warning "What is resplen? This logic is not right!"
resplen = ntohl(resplen) & ~0x80000000;
/* This is SERIOUS! We are out of sync with the
* sender and forcing a disconnect/reconnect is all I
* can do.
*/
else if (resplen > RPC_MAXPACKET)
{
fdbg("ERROR: Impossible length rom RPC server: %d\n", resplen);
error = EFBIG;
goto errout;
}
errval = 0
do
{
socklen_t fromlen = sizeof(*rpc->rc_name);
nbytes = psock_recvfrom(so, reply, sizeof(*reply),
MSG_WAITALL, rpc->rc_name,
&fromlen);
if (nbytes < 0)
{
errval = errno;
fdbg("ERROR: psock_recvfrom failed: %d\n", errval);
}
}
while (errval == EWOULDBLOCK || errval == EINTR || errval == ERESTART);
if (nbytes < 0)
{
error = errval;
goto errout;
}
else if (nbytes < resplen)
{
fdbg("ERROR: Short receive from RPC server\n");
fvdbg(" Expected %d bytes, received %d bytes\n",
resplen, nbytes);
error = EPIPE;
}
else
{
error = 0;
}
}
else
{
/* NB: Since uio_resid is big, MSG_WAITALL is ignored
* and psock_recvfrom() will return when it has either a
* control msg or a data msg. We have no use for
* control msg., but must grab them and then throw
* them away so we know what is going on.
*/
errval = 0;
do
{
socklen_t fromlen = sizeof(*rpc->rc_name);
nbytes = psock_recvfrom(so, reply, sizeof(*reply), 0,
rpc->rc_name, &fromlen);
if (nbytes < 0)
{
errval = errno;
fdbg("ERROR: psock_recvfrom failed: %d\n", errval);
}
}
while (errval == EWOULDBLOCK || nbytes == 0);
if (nbytes < 0)
{
error = errval;
goto errout;
}
else if (nbytes < resplen)
{
fdbg("ERROR: Short receive from RPC server\n");
fvdbg(" Expected %d bytes, received %d bytes\n",
resplen, nbytes);
error = EPIPE;
}
else
{
error = 0;
}
}
errout:
if (error != 0 && error != EINTR && error != ERESTART)
{
if (error != EPIPE)
{
fdbg("ERROR: Receive error %d from RPC server\n", error);
}
error = rpcclnt_reconnect(rpc);
if (error == 0)
{
goto tryagain;
}
}
return EACCES;
}
else
#endif
{
if (rpc->rc_so == NULL)
{
return EACCES;
}
socklen_t fromlen = sizeof(struct sockaddr);
nbytes = psock_recvfrom(rpc->rc_so, reply, resplen, 0, aname, &fromlen);
if (nbytes < 0)
{
errval = errno;
fdbg("ERROR: psock_recvfrom failed: %d\n", errval);
error = errval;
}
socklen_t fromlen = sizeof(struct sockaddr);
nbytes = psock_recvfrom(rpc->rc_so, reply, resplen, 0, aname, &fromlen);
if (nbytes < 0)
{
error = errno;
fdbg("ERROR: psock_recvfrom failed: %d\n", error);
}
return error;
@ -467,7 +258,7 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
replyheader = (FAR struct rpc_reply_header *)reply;
rxid = replyheader->rp_xid;
if (replyheader->rp_direction != rpc_reply)
{
rpc_statistics(rpcinvalid);
@ -522,7 +313,7 @@ static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
uint32_t xid, int prog, int vers, int procid)
{
/* Format the call header */
ch->rp_xid = txdr_unsigned(xid);
ch->rp_direction = rpc_call;
ch->rp_rpcvers = rpc_vers;
@ -535,14 +326,6 @@ static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
ch->rpc_auth.authtype = rpc_auth_null;
ch->rpc_auth.authlen = 0;
#ifdef CONFIG_NFS_UNIX_AUTH
ch->rpc_unix.stamp = txdr_unsigned(1);
ch->rpc_unix.hostname = 0;
ch->rpc_unix.uid = setuid;
ch->rpc_unix.gid = setgid;
ch->rpc_unix.gidlist = 0;
#endif
/* rpc_verf part (auth_null) */
ch->rpc_verf.authtype = rpc_auth_null;
@ -594,7 +377,6 @@ int rpcclnt_connect(struct rpcclnt *rpc)
/* Create the socket */
saddr = rpc->rc_name;
memset(&sin, 0, sizeof(sin));
/* Create an instance of the socket state structure */
@ -605,7 +387,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
return ENOMEM;
}
error = psock_socket(saddr->sa_family, rpc->rc_sotype, rpc->rc_soproto, so);
error = psock_socket(saddr->sa_family, rpc->rc_sotype, IPPROTO_UDP, so);
if (error < 0)
{
errval = errno;
@ -678,8 +460,6 @@ int rpcclnt_connect(struct rpcclnt *rpc)
* Get port number for MOUNTD.
*/
memset(&sdata, 0, sizeof(struct rpc_call_pmap));
memset(&rdata, 0, sizeof(struct rpc_reply_pmap));
sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT);
sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1);
sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
@ -707,8 +487,6 @@ int rpcclnt_connect(struct rpcclnt *rpc)
/* Do RPC to mountd. */
memset(&mountd, 0, sizeof(struct rpc_call_mount));
memset(&mdata, 0, sizeof(struct rpc_reply_mount));
strncpy(mountd.mount.rpath, rpc->rc_path, 90);
mountd.mount.len = txdr_unsigned(sizeof(mountd.mount.rpath));
@ -734,8 +512,6 @@ int rpcclnt_connect(struct rpcclnt *rpc)
* NFS port in the socket.
*/
memset(&sdata, 0, sizeof(struct rpc_call_pmap));
memset(&rdata, 0, sizeof(struct rpc_reply_pmap));
sa->sin_port = htons(PMAPPORT);
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
@ -776,35 +552,6 @@ bad:
return error;
}
/* Reconnect routine: Called when a connection is broken on a reliable
* protocol. - clean up the old socket - nfs_connect() again - set
* RPCCALL_MUSTRESEND for all outstanding requests on mount point If this
* fails the mount point is DEAD!
*/
#ifdef CONFIG_NFS_TCPIP
int rpcclnt_reconnect(FAR struct rpcclnt *rpc)
{
int error;
rpcclnt_disconnect(rpc);
do
{
error = rpcclnt_connect(rpc);
if (error != OK)
{
fdbg("ERROR: rpcclnt_connect failed: %d\n", error);
if (error == EINTR || error == ERESTART)
{
return EINTR;
}
}
}
while (error != OK)
return OK;
}
#endif
void rpcclnt_disconnect(struct rpcclnt *rpc)
{
struct socket *so;
@ -833,8 +580,6 @@ int rpcclnt_umount(struct rpcclnt *rpc)
* Get port number for MOUNTD.
*/
memset(&sdata, 0, sizeof(struct rpc_call_pmap));
memset(&rdata, 0, sizeof(struct rpc_reply_pmap));
sa->sin_port = htons(PMAPPORT);
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
@ -869,9 +614,6 @@ int rpcclnt_umount(struct rpcclnt *rpc)
/* Do RPC to umountd. */
memset(&mountd, 0, sizeof(struct rpc_call_mount));
memset(&mdata, 0, sizeof(struct rpc_reply_mount));
strncpy(mountd.mount.rpath, rpc->rc_path, 92);
mountd.mount.len = txdr_unsigned(sizeof(mountd.mount.rpath));

View File

@ -66,22 +66,13 @@ struct nfs_args
uint8_t version; /* Args structure version number */
uint8_t addrlen; /* Length of address */
uint8_t sotype; /* Socket type */
uint8_t proto; /* and Protocol */
int flags; /* Flags */
int wsize; /* Write size in bytes */
int rsize; /* Read size in bytes */
int readdirsize; /* readdir size in bytes */
int timeo; /* Initial timeout in .1 secs */
int retrans; /* Times to retry send */
//int maxgrouplist; /* Max. size of group list */
//int readahead; /* # of blocks to readahead */
//int leaseterm; /* Term (sec) of lease */
//int deadthresh; /* Retrans threshold */
char *path; /* Server's path of the directory being mount */
int acregmin; /* Cache attrs for reg files min time */
int acregmax; /* Cache attrs for reg files max time */
int acdirmin; /* Cache attrs for dirs min time */
int acdirmax; /* Cache attrs for dirs max time */
struct sockaddr_storage addr; /* File server address (requires 32-bit alignment) */
};

View File

@ -206,15 +206,19 @@ int main(int argc, char **argv, char **envp)
printf("#ifdef CONFIG_DISABLE_MOUNTPOINT\n");
printf("# undef CONFIG_FS_FAT\n");
printf("# undef CONFIG_FS_ROMFS\n");
printf("# undef CONFIG_FS_NXFFS\n");
printf("# undef CONFIG_APPS_BINDIR\n");
printf("# undef CONFIG_NFS\n");
printf("#endif\n\n");
printf("/* Check if any readable and writable filesystem (OR USB storage) is supported */\n\n");
printf("#undef CONFIG_FS_READABLE\n");
printf("#undef CONFIG_FS_WRITABLE\n");
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_FS_ROMFS) || defined(CONFIG_USBMSC) || \\\n");
printf(" defined(CONFIG_FS_NXFFS) || defined(CONFIG_APPS_BINDIR)\n");
printf(" defined(CONFIG_FS_NXFFS) || defined(CONFIG_APPS_BINDIR) || defined(CONFIG_NFS)\n");
printf("# define CONFIG_FS_READABLE 1\n");
printf("#endif\n\n");
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_USBMSC) || defined(CONFIG_FS_NXFFS)\n");
printf("#if defined(CONFIG_FS_FAT) || defined(CONFIG_USBMSC) || defined(CONFIG_FS_NXFFS) || \\\n");
printf(" defined(CONFIG_NFS)\n");
printf("# define CONFIG_FS_WRITABLE 1\n");
printf("#endif\n\n");
printf("/* There can be no network support with no socket descriptors */\n\n");
@ -234,6 +238,10 @@ int main(int argc, char **argv, char **envp)
printf("# undef CONFIG_NET_UDP\n");
printf("# undef CONFIG_NET_ICMP\n");
printf("#endif\n\n");
printf("/* NFS client can only be provided on top of UDP network support */\n\n");
printf("#if !defined(CONFIG_NET) || !defined(CONFIG_NET_UDP)\n");
printf("# undef CONFIG_NFS\n");
printf("#endif\n\n");
printf("/* Verbose debug and sub-system debug only make sense if debug is enabled */\n\n");
printf("#ifndef CONFIG_DEBUG\n");
printf("# undef CONFIG_DEBUG_VERBOSE\n");