summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-06-14 00:47:42 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-06-14 00:47:42 +0000
commit68cef09eeafdbceef358b47ca3a6817600bdfc08 (patch)
tree8884f40bd84695b9de63c6eb5a85d2ce074552d7
parentcdbc82c04c609695764e116c593c390c46f37dd8 (diff)
downloadpx4-nuttx-68cef09eeafdbceef358b47ca3a6817600bdfc08.tar.gz
px4-nuttx-68cef09eeafdbceef358b47ca3a6817600bdfc08.tar.bz2
px4-nuttx-68cef09eeafdbceef358b47ca3a6817600bdfc08.zip
NFS just finished a major weight reduction program
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4838 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--apps/nshlib/nsh_fscmds.c79
-rw-r--r--apps/nshlib/nsh_parse.c2
-rw-r--r--nuttx/Documentation/NuttX.html20
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html79
-rw-r--r--nuttx/configs/README.txt5
-rw-r--r--nuttx/fs/nfs/Kconfig18
-rw-r--r--nuttx/fs/nfs/nfs.h194
-rw-r--r--nuttx/fs/nfs/nfs_mount.h41
-rw-r--r--nuttx/fs/nfs/nfs_node.h6
-rw-r--r--nuttx/fs/nfs/nfs_proto.h28
-rw-r--r--nuttx/fs/nfs/nfs_socket.c8
-rw-r--r--nuttx/fs/nfs/nfs_util.c103
-rw-r--r--nuttx/fs/nfs/nfs_vfsops.c659
-rw-r--r--nuttx/fs/nfs/rpc.h14
-rw-r--r--nuttx/fs/nfs/rpc_clnt.c280
-rw-r--r--nuttx/include/nuttx/fs/nfs.h9
-rw-r--r--nuttx/tools/mkconfig.c12
17 files changed, 480 insertions, 1077 deletions
diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c
index b3b4ae770..39174a862 100644
--- a/apps/nshlib/nsh_fscmds.c
+++ b/apps/nshlib/nsh_fscmds.c
@@ -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 */
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index f95444f0b..bc6f8576a 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -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
diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html
index 8a4489ff6..a3f87f917 100644
--- a/nuttx/Documentation/NuttX.html
+++ b/nuttx/Documentation/NuttX.html
@@ -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>
@@ -429,6 +429,15 @@
<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>
+ <p>
+ <li>
NXFFS. The tiny NuttX wear-leveling FLASH file system.
</li>
</p>
@@ -566,6 +575,15 @@
<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>
+ <p>
+ <li>
A NuttX port of Jeff Poskanzer's <a href="http://acme.com/software/thttpd">THTTPD</a> HTTP server
integrated with <a href="NuttXNxFlat.html">NXFLAT</a> to provide true, embedded CGI.
</li>
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 18ff07d19..ee3c9a5e9 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -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>(DHCP server source files)</i>
+|-- ftpc/
+| |-- Kconfig
+| |-- Make.defs
+| `-- <i>(FTP client source files)</i>
+|-- ftpd/
+| |-- Kconfig
| |-- Make.defs
-| `-- <i>(dhcpd source files)</i>
+| `-- <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>
@@ -4438,6 +4490,13 @@ build
<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
implemented by copying whole files into memory.
diff --git a/nuttx/configs/README.txt b/nuttx/configs/README.txt
index 56659fe36..692c7792e 100644
--- a/nuttx/configs/README.txt
+++ b/nuttx/configs/README.txt
@@ -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.
diff --git a/nuttx/fs/nfs/Kconfig b/nuttx/fs/nfs/Kconfig
index 841b1ab8e..3838efffa 100644
--- a/nuttx/fs/nfs/Kconfig
+++ b/nuttx/fs/nfs/Kconfig
@@ -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 \ No newline at end of file
+#endif
diff --git a/nuttx/fs/nfs/nfs.h b/nuttx/fs/nfs/nfs.h
index 0fe30f5f0..b35ef2c8d 100644
--- a/nuttx/fs/nfs/nfs.h
+++ b/nuttx/fs/nfs/nfs.h
@@ -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
{
diff --git a/nuttx/fs/nfs/nfs_mount.h b/nuttx/fs/nfs/nfs_mount.h
index 66343f90e..d3be1a598 100644
--- a/nuttx/fs/nfs/nfs_mount.h
+++ b/nuttx/fs/nfs/nfs_mount.h
@@ -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
diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h
index 02e14cbde..4ae9e162c 100644
--- a/nuttx/fs/nfs/nfs_node.h
+++ b/nuttx/fs/nfs/nfs_node.h
@@ -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 */
diff --git a/nuttx/fs/nfs/nfs_proto.h b/nuttx/fs/nfs/nfs_proto.h
index 245f3e189..645b6bdf0 100644
--- a/nuttx/fs/nfs/nfs_proto.h
+++ b/nuttx/fs/nfs/nfs_proto.h
@@ -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.
diff --git a/nuttx/fs/nfs/nfs_socket.c b/nuttx/fs/nfs/nfs_socket.c
index d429e6852..c5fe9f1e4 100644
--- a/nuttx/fs/nfs/nfs_socket.c
+++ b/nuttx/fs/nfs/nfs_socket.c
@@ -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;
diff --git a/nuttx/fs/nfs/nfs_util.c b/nuttx/fs/nfs/nfs_util.c
index 2dd7613df..643117e22 100644
--- a/nuttx/fs/nfs/nfs_util.c
+++ b/nuttx/fs/nfs/nfs_util.c
@@ -197,102 +197,6 @@ int nfs_checkmount(struct nfsmount *nmp)
}
/****************************************************************************
- * 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
*
* Desciption:
@@ -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)
{
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
index c030422ca..cd8a5ab7a 100644
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ b/nuttx/fs/nfs/nfs_vfsops.c
@@ -87,10 +87,7 @@
* Pre-processor Definitions
****************************************************************************/
-#define NFS_DIRHDSIZ (sizeof (struct nfs_dirent) - (MAXNAMLEN + 1))
-#define NFS_DIRENT_OVERHEAD offsetof(struct nfs_dirent, dirent)
-
-/* The V3 EXCLUSIVE file creation logic is not fully support. */
+/* The V3 EXCLUSIVE file creation logic is not fully supported. */
#define USE_GUARDED_CREATE 1
@@ -110,12 +107,6 @@
* Private Type Definitions
****************************************************************************/
-struct nfs_dirent
-{
- uint32_t cookie[2];
- struct dirent dirent;
-};
-
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@@ -126,6 +117,7 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
FAR const char *relpath, int oflags, mode_t mode);
static int nfs_open(FAR struct file *filep, const char *relpath,
int oflags, mode_t mode);
+static int nfs_close(FAR struct file *filep);
static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen);
static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
size_t buflen);
@@ -153,7 +145,7 @@ static int nfs_stat(struct inode *mountpt, const char *relpath,
const struct mountpt_operations nfs_operations =
{
nfs_open, /* open */
- NULL, /* close */
+ nfs_close, /* close */
nfs_read, /* read */
nfs_write, /* write */
NULL, /* seek */
@@ -220,7 +212,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
/* Create the CREATE RPC call arguments */
- ptr = (FAR uint32_t *)&((FAR struct rpc_call_create *)np->n_iobuffer)->create;
+ ptr = (FAR uint32_t *)&((FAR struct rpc_call_create *)nmp->nm_iobuffer)->create;
reqlen = 0;
/* Copy the variable length, directory file handle */
@@ -285,13 +277,13 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
*ptr++ = nfs_true; /* True: Uid value follows */
*ptr++ = 0; /* UID = 0 (nobody) */
reqlen += 2*sizeof(uint32_t);
-
+
/* Set the group ID to one */
*ptr++ = nfs_true; /* True: Gid value follows */
*ptr++ = HTONL(1); /* GID = 1 (nogroup) */
reqlen += 2*sizeof(uint32_t);
-
+
/* Set the size to zero */
*ptr++ = nfs_true; /* True: Size value follows */
@@ -314,7 +306,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
{
nfs_statistics(NFSPROC_CREATE);
error = nfs_request(nmp, NFSPROC_CREATE,
- (FAR void *)np->n_iobuffer, reqlen,
+ (FAR void *)nmp->nm_iobuffer, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_create));
}
#ifdef USE_GUARDED_CREATE
@@ -347,7 +339,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
np->n_fhsize = (uint8_t)tmp;
memcpy(&np->n_fhandle, ptr, tmp);
ptr += uint32_increment(tmp);
-
+
/* Save the attributes in the file data structure */
tmp = *ptr++; /* handle_follows */
@@ -480,11 +472,8 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
static int nfs_open(FAR struct file *filep, FAR const char *relpath,
int oflags, mode_t mode)
{
- struct inode *in;
struct nfsmount *nmp;
- struct nfsnode *np;
- uint32_t buflen;
- uint32_t tmp;
+ struct nfsnode *np = NULL;
int error;
/* Sanity checks */
@@ -495,54 +484,18 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
* mountpoint private data from the inode structure
*/
- in = filep->f_inode;
- nmp = (struct nfsmount*)in->i_private;
-
+ nmp = (struct nfsmount*)filep->f_inode->i_private;
DEBUGASSERT(nmp != NULL);
- /* Determine the size of a buffer that will hold one RPC data transfer */
-
- {
- /* Get the maximum size of a read and a write transfer */
-
- buflen = SIZEOF_rpc_call_write(nmp->nm_wsize);
- tmp = SIZEOF_rpc_reply_read(nmp->nm_rsize);
-
- /* The buffer size will be the maximum of those two sizes */
-
- if (tmp > buflen)
- {
- buflen = tmp;
- }
-
- /* But don't let the buffer size exceed the MSS of the socket type */
-
-#ifdef CONFIG_NFS_TCPIP
- if (buflen > UIP_TCP_MSS)
- {
- buflen = UIP_TCP_MSS;
- }
-#else
- if (buflen > UIP_UDP_MSS)
- {
- buflen = UIP_UDP_MSS;
- }
-#endif
- }
-
/* Pre-allocate the file private data to describe the opened file. */
- np = (struct nfsnode *)kzalloc(SIZEOF_nfsnode(buflen));
+ np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
if (!np)
{
fdbg("ERROR: Failed to allocate private data\n");
return -ENOMEM;
}
- /* Save the allocated I/O buffer size */
-
- np->n_buflen = (uint16_t)buflen;
-
/* Check if the mount is still healthy */
nfs_semtake(nmp);
@@ -582,10 +535,10 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
*/
fdbg("ERROR: File does not exist\n");
- error = ENOENT;
+ error = ENOENT;
goto errout_with_semaphore;
}
-
+
/* Create the file */
error = nfs_filecreate(nmp, np, relpath, mode);
@@ -604,64 +557,99 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
filep->f_priv = np;
- /* Then insert the new instance into the mountpoint structure.
- * It needs to be there (1) to handle error conditions that effect
- * all files, and (2) to inform the umount logic that we are busy
- * (but a simple reference count could have done that).
+ /* Then insert the new instance at the head of the list in the mountpoint
+ * tructure. It needs to be there (1) to handle error conditions that effect
+ * all files, and (2) to inform the umount logic that we are busy. We
+ * cannot unmount the file system if this list is not empty!
*/
np->n_next = nmp->nm_head;
- np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED);
- nmp->nm_head = np->n_next;
+ nmp->nm_head = np;
+ np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED);
nfs_semgive(nmp);
return OK;
errout_with_semaphore:
- kfree(np);
+ if (np)
+ {
+ kfree(np);
+ }
nfs_semgive(nmp);
return -error;
}
-#undef COMP
-#ifdef COMP
/****************************************************************************
* Name: nfs_close
*
+ * Description:
+ * Close a file.
+ *
* Returned Value:
* 0 on success; a negated errno value on failure.
*
****************************************************************************/
-static int nfs_close(FAR struct file *filep) done
+static int nfs_close(FAR struct file *filep)
{
- struct nfsmount *nmp;
- struct nfsnode *np;
- int error = 0;
-
- fvdbg("Closing\n");
+ FAR struct nfsmount *nmp;
+ FAR struct nfsnode *np;
+ FAR struct nfsnode *prev;
+ FAR struct nfsnode *curr;
+ int error;
/* Sanity checks */
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover our private data from the struct file instance */
+ DEBUGASSERT(filep->f_inode != NULL);
- np = filep->f_priv;
- nmp = filep->f_inode->i_private;
+ /* Get the mountpoint inode reference from the file structure and the
+ * mountpoint private data from the inode structure
+ */
+ nmp = (struct nfsmount*)filep->f_inode->i_private;
DEBUGASSERT(nmp != NULL);
- if (np->n_type == NFREG)
- {
- error = nfs_sync(filep);
- kfree(np);
- filep->f_priv = NULL;
- }
+ /* Get exclusive access to the mount structure. */
- return -error;
+ nfs_semtake(nmp);
+
+ /* Find our file structure in the list of file structures containted in the
+ * mount structure.
+ */
+
+ error = EINVAL;
+ for (prev = NULL, curr = nmp->nm_head; curr; prev = curr, curr = curr->n_next)
+ {
+ /* Check if this node is ours */
+
+ if (np == curr)
+ {
+ /* Yes.. remove it from the list of file structures */
+
+ if (prev)
+ {
+ /* Remove from mid-list */
+
+ prev->n_next = np->n_next;
+ }
+ else
+ {
+ /* Remove from the head of the list */
+
+ nmp->nm_head = np->n_next;
+ }
+
+ /* Then deallocate the file structure and return success */
+
+ kfree(np);
+ error = OK;
+ break;
+ }
+ }
+
+ nfs_semgive(nmp);
+ return error;
}
-#endif
/****************************************************************************
* Name: nfs_read
@@ -680,7 +668,6 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
ssize_t tmp;
ssize_t bytesread;
size_t reqlen;
- struct rpc_call_read request;
FAR uint32_t *ptr;
int error = 0;
@@ -723,7 +710,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
for (bytesread = 0; bytesread < buflen; )
{
/* Make sure that the attempted read size does not exceed the RPC maximum */
-
+
readsize = buflen;
if (readsize > nmp->nm_rsize)
{
@@ -733,14 +720,14 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
/* Make sure that the attempted read size does not exceed the IO buffer size */
tmp = SIZEOF_rpc_reply_read(readsize);
- if (tmp > np->n_buflen)
+ if (tmp > nmp->nm_buflen)
{
- readsize -= (tmp - np->n_buflen);
+ readsize -= (tmp - nmp->nm_buflen);
}
/* Initialize the request */
- ptr = (FAR uint32_t*)&request.read;
+ ptr = (FAR uint32_t*)&nmp->nm_msgbuffer.read.read;
reqlen = 0;
/* Copy the variable length, file handle */
@@ -764,12 +751,12 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
reqlen += sizeof(uint32_t);
/* Perform the read */
-
+
fvdbg("Reading %d bytes\n", readsize);
nfs_statistics(NFSPROC_READ);
error = nfs_request(nmp, NFSPROC_READ,
- (FAR void *)&request, reqlen,
- (FAR void *)np->n_iobuffer, np->n_buflen);
+ (FAR void *)&nmp->nm_msgbuffer.read, reqlen,
+ (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
if (error)
{
fdbg("ERROR: nfs_request failed: %d\n", error);
@@ -780,7 +767,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
* response data.
*/
- ptr = (FAR uint32_t *)&((FAR struct rpc_reply_read *)np->n_iobuffer)->read;
+ ptr = (FAR uint32_t *)&((FAR struct rpc_reply_read *)nmp->nm_iobuffer)->read;
/* Check if attributes are included in the responses */
@@ -850,7 +837,6 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
{
struct nfsmount *nmp;
struct nfsnode *np;
- struct rpc_reply_write resok;
ssize_t writesize;
ssize_t bufsize;
ssize_t byteswritten;
@@ -897,7 +883,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
for (byteswritten = 0; byteswritten < buflen; )
{
/* Make sure that the attempted write size does not exceed the RPC maximum */
-
+
writesize = buflen;
if (writesize > nmp->nm_wsize)
{
@@ -907,9 +893,9 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
/* Make sure that the attempted read size does not exceed the IO buffer size */
bufsize = SIZEOF_rpc_call_write(writesize);
- if (bufsize > np->n_buflen)
+ if (bufsize > nmp->nm_buflen)
{
- writesize -= (bufsize - np->n_buflen);
+ writesize -= (bufsize - nmp->nm_buflen);
}
/* Initialize the request. Here we need an offset pointer to the write
@@ -917,7 +903,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
* RPC calls in that the entry RPC calls messasge lies in the I/O buffer
*/
- ptr = (FAR uint32_t *)&((FAR struct rpc_call_write *)np->n_iobuffer)->write;
+ ptr = (FAR uint32_t *)&((FAR struct rpc_call_write *)nmp->nm_iobuffer)->write;
reqlen = 0;
/* Copy the variable length, file handle */
@@ -952,8 +938,8 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
nfs_statistics(NFSPROC_WRITE);
error = nfs_request(nmp, NFSPROC_WRITE,
- (FAR void *)np->n_iobuffer, reqlen,
- (FAR void *)&resok, sizeof(struct rpc_reply_write));
+ (FAR void *)nmp->nm_iobuffer, reqlen,
+ (FAR void *)&nmp->nm_msgbuffer.write, sizeof(struct rpc_reply_write));
if (error)
{
fdbg("ERROR: nfs_request failed: %d\n", error);
@@ -962,7 +948,7 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
/* Get a pointer to the WRITE reply data */
- ptr = (FAR uint32_t *)&resok.write;
+ ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.write.write;
/* Parse file_wcc. First, check if WCC attributes follow. */
@@ -1129,8 +1115,6 @@ errout_with_semaphore:
static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
{
struct nfsmount *nmp;
- uint32_t buffer[64];
- struct rpc_call_readdir request;
struct file_handle fhandle;
struct nfs_fattr obj_attributes;
uint32_t tmp;
@@ -1164,7 +1148,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
* the dirent structure.
*/
- ptr = (FAR uint32_t*)&request.readdir;
+ ptr = (FAR uint32_t*)&nmp->nm_msgbuffer.readdir.readdir;
reqlen = 0;
/* Copy the variable length, directory file handle */
@@ -1196,8 +1180,8 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
nfs_statistics(NFSPROC_READDIR);
error = nfs_request(nmp, NFSPROC_READDIR,
- (FAR void *)&request, reqlen,
- (FAR void *)buffer, sizeof(buffer));
+ (FAR void *)&nmp->nm_msgbuffer.readdir, reqlen,
+ (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
if (error != OK)
{
fdbg("ERROR: nfs_request failed: %d\n", error);
@@ -1214,7 +1198,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
* 4) Values follows indication - 4 bytes
*/
- ptr = (uint32_t *)&((FAR struct rpc_reply_readdir *)buffer)->readdir;
+ ptr = (uint32_t *)&((FAR struct rpc_reply_readdir *)nmp->nm_iobuffer)->readdir;
/* Check if attributes follow, if 0 so Skip over the attributes */
@@ -1363,48 +1347,35 @@ errout_with_semaphore:
*
****************************************************************************/
-void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
+void nfs_decode_args(struct nfs_mount_parameters *nprmt, struct nfs_args *argp)
{
- int adjsock = 0;
int maxio;
-#ifdef CONFIG_NFS_TCPIP
- /* Re-bind if rsrvd port requested and wasn't on one */
-
- adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
- && (argp->flags & NFSMNT_RESVPORT);
-#endif
-
- /* Also re-bind if we're switching to/from a connected UDP socket */
-
- adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != (argp->flags & NFSMNT_NOCONN));
-
/* Update flags atomically. Don't change the lock bits. */
- nmp->nm_flag =
- (argp->flags & ~NFSMNT_INTERNAL) | (nmp->nm_flag & NFSMNT_INTERNAL);
+ nprmt->flag = (argp->flags & ~NFSMNT_INTERNAL) | (nprmt->flag & NFSMNT_INTERNAL);
if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0)
{
- nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
- if (nmp->nm_timeo < NFS_MINTIMEO)
+ nprmt->timeo = (argp->timeo * NFS_HZ + 5) / 10;
+ if (nprmt->timeo < NFS_MINTIMEO)
{
- nmp->nm_timeo = NFS_MINTIMEO;
+ nprmt->timeo = NFS_MINTIMEO;
}
- else if (nmp->nm_timeo > NFS_MAXTIMEO)
+ else if (nprmt->timeo > NFS_MAXTIMEO)
{
- nmp->nm_timeo = NFS_MAXTIMEO;
+ nprmt->timeo = NFS_MAXTIMEO;
}
}
if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1)
{
- nmp->nm_retry = (argp->retrans < NFS_MAXREXMIT)? argp->retrans : NFS_MAXREXMIT;
+ nprmt->retry = (argp->retrans < NFS_MAXREXMIT)? argp->retrans : NFS_MAXREXMIT;
}
- if (!(nmp->nm_flag & NFSMNT_SOFT))
+ if (!(nprmt->flag & NFSMNT_SOFT))
{
- nmp->nm_retry = NFS_MAXREXMIT + 1; /* past clip limit */
+ nprmt->retry = NFS_MAXREXMIT + 1; /* Past clip limit */
}
if (argp->flags & NFSMNT_NFSV3)
@@ -1425,88 +1396,70 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0)
{
- int osize = nmp->nm_wsize;
- nmp->nm_wsize = argp->wsize;
+ nprmt->wsize = argp->wsize;
/* Round down to multiple of blocksize */
- nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_wsize <= 0)
+ nprmt->wsize &= ~(NFS_FABLKSIZE - 1);
+ if (nprmt->wsize <= 0)
{
- nmp->nm_wsize = NFS_FABLKSIZE;
+ nprmt->wsize = NFS_FABLKSIZE;
}
-
- adjsock |= (nmp->nm_wsize != osize);
}
- if (nmp->nm_wsize > maxio)
+ if (nprmt->wsize > maxio)
{
- nmp->nm_wsize = maxio;
+ nprmt->wsize = maxio;
}
- if (nmp->nm_wsize > MAXBSIZE)
+ if (nprmt->wsize > MAXBSIZE)
{
- nmp->nm_wsize = MAXBSIZE;
+ nprmt->wsize = MAXBSIZE;
}
if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0)
{
- int osize = nmp->nm_rsize;
- nmp->nm_rsize = argp->rsize;
+ nprmt->rsize = argp->rsize;
/* Round down to multiple of blocksize */
- nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_rsize <= 0)
+ nprmt->rsize &= ~(NFS_FABLKSIZE - 1);
+ if (nprmt->rsize <= 0)
{
- nmp->nm_rsize = NFS_FABLKSIZE;
+ nprmt->rsize = NFS_FABLKSIZE;
}
-
- adjsock |= (nmp->nm_rsize != osize);
}
- if (nmp->nm_rsize > maxio)
+ if (nprmt->rsize > maxio)
{
- nmp->nm_rsize = maxio;
+ nprmt->rsize = maxio;
}
- if (nmp->nm_rsize > MAXBSIZE)
+ if (nprmt->rsize > MAXBSIZE)
{
- nmp->nm_rsize = MAXBSIZE;
+ nprmt->rsize = MAXBSIZE;
}
if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0)
{
- nmp->nm_readdirsize = argp->readdirsize;
+ nprmt->readdirsize = argp->readdirsize;
/* Round down to multiple of blocksize */
- nmp->nm_readdirsize &= ~(NFS_DIRBLKSIZ - 1);
- if (nmp->nm_readdirsize < NFS_DIRBLKSIZ)
+ nprmt->readdirsize &= ~(NFS_DIRBLKSIZ - 1);
+ if (nprmt->readdirsize < NFS_DIRBLKSIZ)
{
- nmp->nm_readdirsize = NFS_DIRBLKSIZ;
+ nprmt->readdirsize = NFS_DIRBLKSIZ;
}
}
else if (argp->flags & NFSMNT_RSIZE)
{
- nmp->nm_readdirsize = nmp->nm_rsize;
- }
-
- if (nmp->nm_readdirsize > maxio)
- {
- nmp->nm_readdirsize = maxio;
+ nprmt->readdirsize = nprmt->rsize;
}
- if (nmp->nm_so && adjsock)
+ if (nprmt->readdirsize > maxio)
{
- nfs_disconnect(nmp);
- if (nmp->nm_sotype == SOCK_DGRAM)
- {
- while (nfs_connect(nmp))
- {
- fvdbg("nfs_args: retrying connect\n");
- }
- }
+ nprmt->readdirsize = maxio;
}
}
@@ -1523,21 +1476,58 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
int mountnfs(struct nfs_args *argp, void **handle)
{
- FAR struct nfsmount *nmp;
- struct nfsnode *np = NULL;
- struct rpc_call_fs getattr;
- struct rpc_reply_getattr resok;
- int error = 0;
+ FAR struct nfsmount *nmp;
+ struct rpc_call_fs getattr;
+ struct rpc_reply_getattr resok;
+ struct nfs_mount_parameters nprmt;
+ uint32_t buflen;
+ uint32_t tmp;
+ int error = 0;
+
+ /* Set initial values of the parameters for decode */
+
+ nprmt.flag = argp->flags;
+ nprmt.timeo = NFS_TIMEO;
+ nprmt.retry = NFS_RETRANS;
+ nprmt.wsize = NFS_WSIZE;
+ nprmt.rsize = NFS_RSIZE;
+ nprmt.readdirsize = NFS_READDIRSIZE;
+
+ nfs_decode_args(&nprmt, argp);
+
+ /* Determine the size of a buffer that will hold one RPC data transfer.
+ * First, get the maximum size of a read and a write transfer */
+
+ buflen = SIZEOF_rpc_call_write(nprmt.wsize);
+ tmp = SIZEOF_rpc_reply_read(nprmt.rsize);
+
+ /* The buffer size will be the maximum of those two sizes */
+
+ if (tmp > buflen)
+ {
+ buflen = tmp;
+ }
+
+ /* But don't let the buffer size exceed the MSS of the socket type */
+
+ if (buflen > UIP_UDP_MSS)
+ {
+ buflen = UIP_UDP_MSS;
+ }
/* Create an instance of the mountpt state structure */
- nmp = (FAR struct nfsmount *)kzalloc(sizeof(struct nfsmount));
+ nmp = (FAR struct nfsmount *)kzalloc(SIZEOF_nfsmount(buflen));
if (!nmp)
{
fdbg("ERROR: Failed to allocate mountpoint structure\n");
return ENOMEM;
}
+ /* Save the allocated I/O buffer size */
+
+ nmp->nm_buflen = (uint16_t)buflen;
+
/* Initialize the allocated mountpt state structure. */
/* Initialize the semaphore that controls access. The initial count
@@ -1553,27 +1543,20 @@ int mountnfs(struct nfs_args *argp, void **handle)
/* Set initial values of other fields */
- nmp->nm_flag = argp->flags;
- nmp->nm_timeo = NFS_TIMEO;
- nmp->nm_retry = NFS_RETRANS;
- nmp->nm_wsize = NFS_WSIZE;
- nmp->nm_rsize = NFS_RSIZE;
- nmp->nm_readdirsize = NFS_READDIRSIZE;
+ nmp->nm_flag = nprmt.flag;
+ nmp->nm_timeo = nprmt.timeo;
+ nmp->nm_retry = nprmt.retry;
+ nmp->nm_wsize = nprmt.wsize;
+ nmp->nm_rsize = nprmt.rsize;
+ nmp->nm_readdirsize = nprmt.readdirsize;
nmp->nm_fhsize = NFSX_V3FHMAX;
strncpy(nmp->nm_path, argp->path, 90);
memcpy(&nmp->nm_nam, &argp->addr, argp->addrlen);
- nfs_decode_args(nmp, argp);
-
/* Set up the sockets and per-host congestion */
nmp->nm_sotype = argp->sotype;
- nmp->nm_soproto = argp->proto;
-
- /* For Connection based sockets (TCP,...) defer the connect until
- * the first request, in case the server is not responding.
- */
if (nmp->nm_sotype == SOCK_DGRAM)
{
@@ -1587,33 +1570,12 @@ int mountnfs(struct nfs_args *argp, void **handle)
}
}
- /* Create an instance of the file private data to describe the opened
- * file.
- */
-
- np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
- if (!np)
- {
- fdbg("ERROR: Failed to allocate private data\n");
- error = ENOMEM;
- goto bad;
- }
-
- np->n_type = NFDIR;
- np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED);
- nmp->nm_head = np;
nmp->nm_mounted = true;
- memcpy(&nmp->nm_fh, &nmp->nm_rpcclnt->rc_fh, sizeof(nfsfh_t));
- nmp->nm_fhsize = NFSX_V3FHMAX;
- memcpy(&nmp->nm_head->n_fhandle, &nmp->nm_fh, sizeof(nfsfh_t));
- nmp->nm_head->n_fhsize = nmp->nm_fhsize;
nmp->nm_so = nmp->nm_rpcclnt->rc_so;
+ memcpy(&nmp->nm_fh, &nmp->nm_rpcclnt->rc_fh, sizeof(nfsfh_t));
/* Get the file attributes */
- memset(&getattr, 0, sizeof(struct rpc_call_fs));
- memset(&resok, 0, sizeof(struct rpc_reply_getattr));
-
getattr.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
memcpy(&getattr.fs.fsroot.handle, &nmp->nm_fh, sizeof(nfsfh_t));
@@ -1629,7 +1591,6 @@ int mountnfs(struct nfs_args *argp, void **handle)
/* Save the file attributes */
memcpy(&nmp->nm_fattr, &resok.attr, sizeof(struct nfs_fattr));
- nfs_attrupdate(np, &resok.attr);
/* Mounted! */
@@ -1637,16 +1598,9 @@ int mountnfs(struct nfs_args *argp, void **handle)
nfs_semgive(nmp);
fvdbg("Successfully mounted\n");
- return 0;
+ return OK;
bad:
- /* Free all memory that was successfully allocated */
-
- if (np)
- {
- kfree(np);
- }
-
if (nmp)
{
/* Disconnect from the server */
@@ -1718,21 +1672,32 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle)
*
****************************************************************************/
-int nfs_unbind(void *handle, struct inode **blkdriver)
+int nfs_unbind(FAR void *handle, FAR struct inode **blkdriver)
{
- struct nfsmount *nmp = (struct nfsmount *)handle;
+ FAR struct nfsmount *nmp = (FAR struct nfsmount *)handle;
int error;
fvdbg("Entry\n");
+ DEBUGASSERT(nmp);
- if (!nmp)
- {
- return -EINVAL;
- }
+ /* Get exclusive access to the mount structure */
nfs_semtake(nmp);
- /* Umount */
+ /* Are there any open files? We can tell if there are open files by looking
+ * at the list of file structures in the mount structure. If this list
+ * not empty, then there are open files and we cannot unmount now (or a
+ * crash is sure to follow).
+ */
+
+ if (nmp->nm_head != NULL)
+ {
+ fdbg("ERROR; There are open files\n");
+ error = EBUSY;
+ goto errout_with_semaphore;
+ }
+
+ /* No open file... Umount the file system. */
error = rpcclnt_umount(nmp->nm_rpcclnt);
if (error)
@@ -1740,19 +1705,112 @@ int nfs_unbind(void *handle, struct inode **blkdriver)
fdbg("ERROR: rpcclnt_umount failed: %d\n", error);
}
- /* Disconnect */
+ /* Disconnect from the server */
nfs_disconnect(nmp);
- /* And free resources */
+ /* And free any allocated resources */
sem_destroy(&nmp->nm_sem);
- kfree(nmp->nm_head);
kfree(nmp->nm_so);
kfree(nmp->nm_rpcclnt);
kfree(nmp);
return -error;
+
+errout_with_semaphore:
+ nfs_semgive(nmp);
+ return -error;
+}
+
+/****************************************************************************
+ * 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;
+
+ 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 void *)&fsinfo, sizeof(struct FS3args),
+ (FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo));
+ if (error)
+ {
+ return error;
+ }
+
+ /* Save the root file system attributes */
+
+//memcpy(&nmp->nm_fattr. &fsp.obj_attributes, sizeof(struct nfs_fattr));
+
+ 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;
+ }
+ }
+
+ return OK;
}
/****************************************************************************
@@ -1794,16 +1852,9 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
/* Fill in the statfs info */
- memset(sbp, 0, sizeof(struct statfs));
sbp->f_type = NFS_SUPER_MAGIC;
- if ((nmp->nm_flag & NFSMNT_GOTFSINFO) == 0)
- {
- (void)nfs_fsinfo(nmp);
- }
-
- memset(&fsstat, 0, sizeof(struct rpc_call_fs));
- memset(&sfp, 0, sizeof(struct rpc_reply_fsstat));
+ (void)nfs_fsinfo(nmp);
fsstat.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
fsstat.fs.fsroot.handle = nmp->nm_fh;
@@ -1852,7 +1903,6 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
struct file_handle fhandle;
struct nfs_fattr fattr;
char filename[NAME_MAX + 1];
- struct rpc_call_remove remove;
struct rpc_reply_remove resok;
FAR uint32_t *ptr;
int namelen;
@@ -1888,7 +1938,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
/* Create the REMOVE RPC call arguments */
- ptr = (FAR uint32_t *)&remove.remove;
+ ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.removef.remove;
reqlen = 0;
/* Copy the variable length, directory file handle */
@@ -1914,23 +1964,9 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
nfs_statistics(NFSPROC_REMOVE);
error = nfs_request(nmp, NFSPROC_REMOVE,
- (FAR void *)&remove, reqlen,
+ (FAR void *)&nmp->nm_msgbuffer.removef, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_remove));
- /* Check if the file removal was successful */
-
-#ifdef CONFIG_NFS_TCPIP
- if (error == ENOENT)
- {
- /* If the first reply to the remove rpc is lost, the reply to the
- * retransmitted request may be ENOENT if the file was in fact removed.
- * Therefore, we cheat and return success.
- */
-
- error = OK;
- }
-#endif
-
errout_with_semaphore:
nfs_semgive(nmp);
return -error;
@@ -1953,7 +1989,6 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
struct file_handle fhandle;
struct nfs_fattr fattr;
char dirname[NAME_MAX + 1];
- struct rpc_call_mkdir request;
struct rpc_reply_mkdir resok;
FAR uint32_t *ptr;
uint32_t tmp;
@@ -1990,7 +2025,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
/* Format the MKDIR call message arguments */
- ptr = (FAR uint32_t *)&request.mkdir;
+ ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.mkdir.mkdir;
reqlen = 0;
/* Copy the variable length, directory file handle */
@@ -2031,13 +2066,13 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
*ptr++ = nfs_true; /* True: Uid value follows */
*ptr++ = 0; /* UID = 0 (nobody) */
reqlen += 2*sizeof(uint32_t);
-
+
/* Set the group ID to one */
*ptr++ = nfs_true; /* True: Gid value follows */
*ptr++ = HTONL(1); /* GID = 1 (nogroup) */
reqlen += 2*sizeof(uint32_t);
-
+
/* No size */
*ptr++ = nfs_false; /* False: No size value follows */
@@ -2053,7 +2088,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
nfs_statistics(NFSPROC_MKDIR);
error = nfs_request(nmp, NFSPROC_MKDIR,
- (FAR void *)&request, reqlen,
+ (FAR void *)&nmp->nm_msgbuffer.mkdir, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_mkdir));
if (error)
{
@@ -2082,7 +2117,6 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
struct file_handle fhandle;
struct nfs_fattr fattr;
char dirname[NAME_MAX + 1];
- struct rpc_call_rmdir request;
struct rpc_reply_rmdir resok;
FAR uint32_t *ptr;
int namelen;
@@ -2118,7 +2152,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
/* Set up the RMDIR call message arguments */
- ptr = (FAR uint32_t *)&request.rmdir;
+ ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.rmdir.rmdir;
reqlen = 0;
/* Copy the variable length, directory file handle */
@@ -2144,22 +2178,9 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
nfs_statistics(NFSPROC_RMDIR);
error = nfs_request(nmp, NFSPROC_RMDIR,
- (FAR void *)&request, reqlen,
+ (FAR void *)&nmp->nm_msgbuffer.rmdir, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_rmdir));
- /* Check if the removal was successful */
-
-#ifdef CONFIG_NFS_TCPIP
- if (error == ENOENT)
- {
- /* If the first reply to the remove rpc is lost, the reply to the
- * retransmitted request may be ENOENT if the file was in fact removed.
- * Therefore, we cheat and return success.
- */
- error = 0;
- }
-#endif
-
errout_with_semaphore:
nfs_semgive(nmp);
return -error;
@@ -2185,7 +2206,6 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
char from_name[NAME_MAX+1];
char to_name[NAME_MAX+1];
struct nfs_fattr fattr;
- struct rpc_call_rename request;
struct rpc_reply_rename resok;
FAR uint32_t *ptr;
int namelen;
@@ -2230,7 +2250,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
/* Format the RENAME RPC arguments */
- ptr = (FAR uint32_t *)&request.rename;
+ ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.renamef.rename;
reqlen = 0;
/* Copy the variable length, 'from' directory file handle */
@@ -2276,23 +2296,9 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
nfs_statistics(NFSPROC_RENAME);
error = nfs_request(nmp, NFSPROC_RENAME,
- (FAR void *)&request, reqlen,
+ (FAR void *)&nmp->nm_msgbuffer.renamef, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_rename));
- /* Check if the rename was successful */
-
-#ifdef CONFIG_NFS_TCPIP
- if (error == ENOENT)
- {
- /* If the first reply to the remove rpc is lost, the reply to the
- * retransmitted request may be ENOENT if the file was in fact removed.
- * Therefore, we cheat and return success.
- */
-
- error = 0;
- }
-#endif
-
errout_with_semaphore:
nfs_semgive(nmp);
return -error;
@@ -2352,7 +2358,7 @@ static int nfs_stat(struct inode *mountpt, const char *relpath,
*/
tmp = fxdr_unsigned(uint32_t, obj_attributes.fa_mode);
-
+
/* Here we exploit the fact that most mode bits are the same in NuttX
* as in the NFSv3 spec.
*/
@@ -2423,58 +2429,3 @@ errout_with_semaphore:
nfs_semgive(nmp);
return -error;
}
-
-#ifdef COMP
-/****************************************************************************
- * Name: nfs_sync
- *
- * Description: Flush out the buffer cache
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int nfs_sync(struct file *filep)
-{
- struct inode *inode;
- struct nfsmount *nmp;
- struct nfsnode *np;
- int error = 0;
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover our private data from the struct file instance */
-
- np = filep->f_priv;
- inode = filep->f_inode;
- nmp = inode->i_private;
-
- DEBUGASSERT(nmp != NULL);
-
- /* Make sure that the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Force stale buffer cache information to be flushed. */
-
- /* Check if the has been modified in any way */
-
- if ((np->n_flags & NFSNODE_MODIFIED) != 0)
- {
- //error = VOP_FSYNC(vp, cred, waitfor, p);
- }
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-#endif
diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h
index 82d5e46ee..5177108b7 100644
--- a/nuttx/fs/nfs/rpc.h
+++ b/nuttx/fs/nfs/rpc.h
@@ -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
};
/****************************************************************************
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
index a749d7411..0dcb7f2b7 100644
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ b/nuttx/fs/nfs/rpc_clnt.c
@@ -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));
diff --git a/nuttx/include/nuttx/fs/nfs.h b/nuttx/include/nuttx/fs/nfs.h
index fcf9c3f7b..3ce62dfc1 100644
--- a/nuttx/include/nuttx/fs/nfs.h
+++ b/nuttx/include/nuttx/fs/nfs.h
@@ -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) */
};
diff --git a/nuttx/tools/mkconfig.c b/nuttx/tools/mkconfig.c
index 5bacb24a6..97e2a9c34 100644
--- a/nuttx/tools/mkconfig.c
+++ b/nuttx/tools/mkconfig.c
@@ -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");