NFS update + make some examples configurable as NSH built-ins

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4501 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo
2012-03-22 00:51:01 +00:00
parent a58d4b265f
commit 1018c9e441
25 changed files with 5290 additions and 1003 deletions
+4
View File
@@ -208,3 +208,7 @@
* apps/examples/can: Add conditional compilation so that the test can be
configured to only send messages or to only receive messages. This will
let the test work in other modes than simple loopback testing.
* apps/examples/hello and apps/examples/ostest: Can now be built as NSH
built-int functions.
* vsn/hello: Removed. The modified apps/examples/hello is enough "Hello,
World!"
+6
View File
@@ -59,6 +59,9 @@ ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
CNTXTDIRS += adc can cdcacm composite ftpd dhcpd nettest qencoder telnetd
endif
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
CNTXTDIRS += hello
endif
ifeq ($(CONFIG_EXAMPLES_HELLOXX_BUILTIN),y)
CNTXTDIRS += helloxx
endif
@@ -80,6 +83,9 @@ endif
ifeq ($(CONFIG_EXAMPLES_NXTEXT_BUILTIN),y)
CNTXTDIRS += nxtext
endif
ifeq ($(CONFIG_EXAMPLES_OSTEST_BUILTIN),y)
CNTXTDIRS += ostest
endif
ifeq ($(CONFIG_EXAMPLES_TIFF_BUILTIN),y)
CNTXTDIRS += tiff
endif
+5
View File
@@ -384,6 +384,9 @@ examples/hello
than examples/null with a single printf statement. Really useful only
for bringing up new NuttX architectures.
* CONFIG_EXAMPLES_HELLO_BUILTIN
Build the "Hello, World" example as an NSH built-in application.
examples/helloxx
^^^^^^^^^^^^^^^^
@@ -848,6 +851,8 @@ examples/ostest
The behavior of the ostest can be modified with the following
settings in the configs/<board-name>/defconfig file:
* CONFIG_EXAMPLES_OSTEST_BUILTIN
Build the OS test example as an NSH built-in application.
* CONFIG_EXAMPLES_OSTEST_LOOPS
Used to control the number of executions of the test. If
undefined, the test executes one time. If defined to be
+15 -3
View File
@@ -1,8 +1,8 @@
############################################################################
# apps/examples/hello/Makefile
#
# Copyright (C) 2008, 2010-2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
# Copyright (C) 2008, 2010-2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -37,6 +37,12 @@
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# Hello, World! built-in application info
APPNAME = hello
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
# Hello, World! Example
ASRCS =
@@ -75,7 +81,13 @@ $(COBJS): %$(OBJEXT): %.c
done ; )
@touch .built
context:
.context:
ifeq ($(CONFIG_EXAMPLES_HELLO_BUILTIN),y)
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+10 -4
View File
@@ -1,8 +1,8 @@
/****************************************************************************
* examples/hello/main.c
*
* Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2008, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,10 +53,16 @@
****************************************************************************/
/****************************************************************************
* user_start
* user_start/hello_main
****************************************************************************/
int user_start(int argc, char *argv[])
#ifdef CONFIG_EXAMPLES_HELLO_BUILTIN
# define MAIN_NAME hello_main
#else
# define MAIN_NAME user_start
#endif
int MAIN_NAME(int argc, char *argv[])
{
printf("Hello, World!!\n");
return 0;
+13 -1
View File
@@ -37,6 +37,12 @@
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# ostest built-in application info
APPNAME = ostest
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
# NuttX OS Test
ASRCS =
@@ -119,7 +125,13 @@ $(COBJS): %$(OBJEXT): %.c
done ; )
@touch .built
context:
.context:
ifeq ($(CONFIG_EXAMPLES_OSTEST_BUILTIN),y)
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
endif
context: .context
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+19 -11
View File
@@ -458,10 +458,18 @@ static void stdio_test(void)
****************************************************************************/
/****************************************************************************
* user_start
* user_start/ostest_main
****************************************************************************/
int user_start(int argc, char *argv[])
#ifdef CONFIG_EXAMPLES_OSTEST_BUILTIN
# define MAIN_NAME ostest_main
# define MAIN_STRING "ostest_main: "
#else
# define MAIN_NAME user_start
# define MAIN_STRING "user_start: "
#endif
int MAIN_NAME(int argc, char *argv[])
{
int result;
@@ -484,19 +492,19 @@ int user_start(int argc, char *argv[])
/* Set up some environment variables */
#ifndef CONFIG_DISABLE_ENVIRON
printf("user_start: putenv(%s)\n", g_putenv_value);
printf(MAIN_STRING "putenv(%s)\n", g_putenv_value);
putenv(g_putenv_value); /* Varaible1=BadValue3 */
printf("user_start: setenv(%s, %s, TRUE)\n", g_var1_name, g_var1_value);
printf(MAIN_STRING "setenv(%s, %s, TRUE)\n", g_var1_name, g_var1_value);
setenv(g_var1_name, g_var1_value, TRUE); /* Variable1=GoodValue1 */
printf("user_start: setenv(%s, %s, FALSE)\n", g_var2_name, g_bad_value1);
printf(MAIN_STRING "setenv(%s, %s, FALSE)\n", g_var2_name, g_bad_value1);
setenv(g_var2_name, g_bad_value1, FALSE); /* Variable2=BadValue1 */
printf("user_start: setenv(%s, %s, TRUE)\n", g_var2_name, g_var2_value);
printf(MAIN_STRING "setenv(%s, %s, TRUE)\n", g_var2_name, g_var2_value);
setenv(g_var2_name, g_var2_value, TRUE); /* Variable2=GoodValue2 */
printf("user_start: setenv(%s, %s, FALSE)\n", g_var3_name, g_var3_name);
printf(MAIN_STRING "setenv(%s, %s, FALSE)\n", g_var3_name, g_var3_name);
setenv(g_var3_name, g_var3_value, FALSE); /* Variable3=GoodValue3 */
printf("user_start: setenv(%s, %s, FALSE)\n", g_var3_name, g_var3_name);
printf(MAIN_STRING "setenv(%s, %s, FALSE)\n", g_var3_name, g_var3_name);
setenv(g_var3_name, g_bad_value2, FALSE); /* Variable3=GoodValue3 */
show_environment(true, true, true);
#endif
@@ -510,13 +518,13 @@ int user_start(int argc, char *argv[])
#endif
if (result == ERROR)
{
printf("user_start: ERROR Failed to start user_main\n");
printf(MAIN_STRING "ERROR Failed to start user_main\n");
}
else
{
printf("user_start: Started user_main at PID=%d\n", result);
printf(MAIN_STRING "Started user_main at PID=%d\n", result);
}
printf("user_start: Exitting\n");
printf(MAIN_STRING "Exitting\n");
return 0;
}
+3 -3
View File
@@ -1,8 +1,8 @@
############################################################################
# apps/vsn/Makefile
#
# Copyright (C) 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -37,7 +37,7 @@
# Sub-directories
SUBDIRS = hello poweroff ramtron sdcard sysinfo
SUBDIRS = poweroff ramtron sdcard sysinfo
all: nothing
.PHONY: nothing context depend clean distclean
-114
View File
@@ -1,114 +0,0 @@
############################################################################
# Makefile
#
# Copyright (C) 2011 Uros Platise. All rights reserved.
# Author: Uros Platise <uros.platise@isotel.eu>
# Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
# TODO, this makefile should run make under the app dirs, instead of
# sourcing the Make.defs!
-include $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
ifeq ($(WINTOOL),y)
INCDIROPT = -w
endif
# Hello Application
# TODO: appname can be automatically extracted from the directory name
APPNAME = hello
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 768
ASRCS =
CSRCS = hello.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS)
ifeq ($(WINTOOL),y)
BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}"
else
BIN = "$(APPDIR)/libapps$(LIBEXT)"
endif
ROOTDEPPATH = --dep-path .
# Common build
VPATH =
all: .built
.PHONY: context depend clean distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
.built: $(OBJS)
@( for obj in $(OBJS) ; do \
$(call ARCHIVE, $(BIN), $${obj}); \
done ; )
@touch .built
# Register application
.context:
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
@touch $@
context: .context
# Create dependencies
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
@touch $@
depend: .depend
clean:
@rm -f *.o *~ .*.swp .built
$(call CLEAN)
distclean: clean
@rm -f .context Make.dep .depend
-include Make.dep
-5
View File
@@ -1,5 +0,0 @@
This application provides Hello Builtin Application skeleton
Source: NuttX
Date: 13. March 2011
+1 -1
View File
@@ -42,7 +42,7 @@ CSRCS +=
# Files required for NFS RPC
ASRCS +=
CSRCS += rpc_clnt.c
CSRCS += rpc_clnt.c nfs_socket.c
# Argument for dependency checking
+136 -137
View File
@@ -1,6 +1,14 @@
/*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
/****************************************************************************
* fs/nfs/nfs.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
@@ -30,11 +38,18 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nfs.h 8.4 (Berkeley) 5/1/95
*/
****************************************************************************/
#ifndef _NFS_NFS_H_
#define _NFS_NFS_H_
#ifndef __FS_NFS_NFS_H
#define __FS_NFS_NFS_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define NFS_TICKINTVL 5 /* Desired time for a tick (msec) */
#define NFS_HZ (CLOCKS_PER_SEC / nfs_ticks) /* Ticks/sec */
@@ -62,9 +77,7 @@
#define NFS_DIRBLKSIZ 1024 /* Must be a multiple of DIRBLKSIZ */
#define NFS_READDIRBLKSIZ 512 /* Size of read dir blocks. XXX */
/*
* Oddballs
*/
/* Oddballs */
#define NFS_CMPFH(n, f, s) \
((n)->n_fhsize == (s) && !bcmp((void *)(n)->n_fhp, (void *)(f), (s)))
@@ -73,9 +86,7 @@
(((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.
*/
/* sys/malloc.h needs M_NFSDIROFF, M_NFSRVDESC and M_NFSBIGFH added. */
#ifndef M_NFSRVDESC
# define M_NFSRVDESC M_TEMP
@@ -87,15 +98,104 @@
# define M_NFSBIGFH M_TEMP
#endif
/*
* The B_INVAFTERWRITE flag should be set to whatever is required by the
/*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
/* fs.nfs sysctl(3) identifiers */
#define NFS_NFSSTATS 1 /* struct: struct nfsstats */
#define NFS_NIOTHREADS 2 /* number of i/o threads */
#define NFS_MAXID 3
#define FS_NFS_NAMES { \
{ 0, 0 }, \
{ "nfsstats", CTLTYPE_STRUCT }, \
{ "iothreads", CTLTYPE_INT } \
}
#define NFSINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
sigmask(SIGHUP)|sigmask(SIGQUIT))
/*
* Structures for the nfssvc(2) syscall.
* Socket errors ignored for connectionless sockets??
* For now, ignore them all
*/
#define NFSIGNORE_SOERROR(s, e) \
((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \
((s) & PR_CONNREQUIRED) == 0)
/* Flag values for r_flags */
#define R_TIMING 0x01/* timing request (in mntp) */
#define R_SENT 0x02/* request has been sent */
#define R_SOFTTERM 0x04/* soft mnt, too many retries */
#define R_INTR 0x08/* intr mnt, signal pending */
#define R_SOCKERR 0x10/* Fatal error on socket */
#define R_TPRINTFMSG 0x20/* Did a tprintf msg. */
#define R_MUSTRESEND 0x40/* Must resend request */
/* 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
/****************************************************************************
* Public Types
****************************************************************************/
/* Structures for the nfssvc(2) syscall.
* Not that anyone besides nfsd(8) should ever use it.
*/
@@ -119,9 +219,7 @@ struct nfsd_srvargs
uint32_t nsd_ttl; /* credential ttl (sec) */
};
/*
* Stats structure
*/
/* Stats structure */
struct nfsstats
{
@@ -161,34 +259,11 @@ struct nfsstats
uint64_t srvvop_writes;
};
/*
* Flags for nfssvc() system call.
*/
/****************************************************************************
* Public Types
****************************************************************************/
#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
/*
* fs.nfs sysctl(3) identifiers
*/
#define NFS_NFSSTATS 1 /* struct: struct nfsstats */
#define NFS_NIOTHREADS 2 /* number of i/o threads */
#define NFS_MAXID 3
#define FS_NFS_NAMES { \
{ 0, 0 }, \
{ "nfsstats", CTLTYPE_STRUCT }, \
{ "iothreads", CTLTYPE_INT } \
}
/*
* The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts.
/* 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
@@ -196,34 +271,16 @@ struct nfsstats
* by them and break.
*/
#ifdef _KERNEL
extern int nfs_niothreads;
struct uio;
struct buf;
struct vattr;
struct nameidata; /* XXX */
#define NFSINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
sigmask(SIGHUP)|sigmask(SIGQUIT))
/*
* Socket errors ignored for connectionless sockets??
* For now, ignore them all
*/
#define NFSIGNORE_SOERROR(s, e) \
((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \
((s) & PR_CONNREQUIRED) == 0)
/*
* Nfs outstanding request list element
*/
/* Nfs outstanding request list element */
struct nfsreq
{
dq_entry_t r_chain;
void *r_dpos;
struct nfsmount *r_nmp;
uint32_t r_xid;
int r_flags; /* flags on request, see below */
@@ -233,31 +290,6 @@ struct nfsreq
int r_rtt; /* RTT for rpc */
};
/* Flag values for r_flags */
#define R_TIMING 0x01/* timing request (in mntp) */
#define R_SENT 0x02/* request has been sent */
#define R_SOFTTERM 0x04/* soft mnt, too many retries */
#define R_INTR 0x08/* intr mnt, signal pending */
#define R_SOCKERR 0x10/* Fatal error on socket */
#define R_TPRINTFMSG 0x20/* Did a tprintf msg. */
#define R_MUSTRESEND 0x40/* Must resend request */
/*
* 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)
enum nfs_rto_timers
{
NFS_DEFAULT_TIMER,
@@ -267,12 +299,7 @@ enum nfs_rto_timers
NFS_WRITE_TIMER,
};
#define NFS_MAX_TIMER (NFS_WRITE_TIMER)
#define NFS_INITRTT (NFS_HZ << 3)
/*
* Network address hash list element
*/
/* Network address hash list element */
union nethostaddr
{
@@ -285,38 +312,14 @@ 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 */
struct mbuf *ns_nam; /* MT_SONAME of client */
struct mbuf *ns_raw; /* head of unpeeked mbufs */
struct mbuf *ns_rawend; /* tail of unpeeked mbufs */
struct mbuf *ns_rec; /* queued RPC records */
struct mbuf *ns_recend; /* last queued RPC record */
struct mbuf *ns_frag; /* end of record fragment */
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 */
u_int32_t ns_sref; /* # of refs to this struct */
uint32_t ns_sref; /* # of refs to this struct */
};
/* 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 */
extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead;
extern int nfssvc_sockhead_flag;
#define SLP_INIT 0x01/* NFS data undergoing initialization */
#define SLP_WANTINIT 0x02/* thread waiting on NFS initialization */
/*
* One of these structures is allocated for each nfsd.
*/
/* One of these structures is allocated for each nfsd. */
struct nfsd
{
@@ -326,35 +329,31 @@ struct nfsd
struct nfsrv_descript *nfsd_nd; /* Associated nfsrv_descript */
};
/* Bits for "nfsd_flag" */
#define NFSD_WAITING 0x01
#define NFSD_REQINPROG 0x02
#define NFSD_NEEDAUTH 0x04
#define NFSD_AUTHFAIL 0x08
/*
* This structure is used by the server for describing each request.
*/
/* 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 */
u_int32_t nd_retxid; /* Reply xid */
uint32_t nd_retxid; /* Reply xid */
};
/* Bits for "nd_flag" */
/****************************************************************************
* Public Data
****************************************************************************/
#define ND_NFSV3 0x08
extern int nfs_niothreads;
extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead;
extern int nfssvc_sockhead_flag;
extern struct pool nfsreqpl;
extern struct pool nfs_node_pool;
extern TAILQ_HEAD(nfsdhead, nfsd) nfsd_head;
extern int nfsd_head_flag;
#define NFSD_CHECKSLP 0x01
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#endif /* _KERNEL */
#endif /* _NFS_NFS_H */
+145
View File
@@ -0,0 +1,145 @@
/****************************************************************************
* fs/nfs/nfs_args.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
#ifndef __FS_NFS_NFS_ARGS_H
#define __FS_NFS_NFS_ARGS_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* File identifier */
#define MAXFIDSZ 16
/* NFS mount option flags */
#define NFSMNT_SOFT 0x00000001 /* soft mount (hard is default) */
#define NFSMNT_WSIZE 0x00000002 /* set write size */
#define NFSMNT_RSIZE 0x00000004 /* set read size */
#define NFSMNT_TIMEO 0x00000008 /* set initial timeout */
#define NFSMNT_RETRANS 0x00000010 /* set number of request retries */
#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */
#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */
#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */
/* 0x100 free, was NFSMNT_NQNFS */
#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */
/* 0x400 free, was NFSMNT_KERB */
#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */
/* 0x1000 free, was NFSMNT_LEASETERM */
#define NFSMNT_READAHEAD 0x00002000 /* set read ahead */
#define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */
#define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */
#define NFSMNT_RDIRPLUS 0x00010000 /* Use Readdirplus for V3 */
#define NFSMNT_READDIRSIZE 0x00020000 /* Set readdir size */
#define NFSMNT_ACREGMIN 0x00040000
#define NFSMNT_ACREGMAX 0x00080000
#define NFSMNT_ACDIRMIN 0x00100000
#define NFSMNT_ACDIRMAX 0x00200000
#define NFSMNT_NOLOCKD 0x00400000 /* Locks are local */
#define NFSMNT_NFSV4 0x00800000 /* Use NFS Version 4 protocol */
#define NFSMNT_HASWRITEVERF 0x01000000 /* NFSv4 Write verifier */
/****************************************************************************
* Public Types
****************************************************************************/
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;
/* Arguments to mount NFS */
struct nfs_args
{
int version; /* args structure version number */
struct sockaddr *addr; /* file server address */
int addrlen; /* length of address */
int sotype; /* Socket type */
int proto; /* and Protocol */
unsigned char *fh; /* File handle to be mounted */
int fhsize; /* Size, in bytes, of fh */
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 *hostname; /* server's name */
};
#endif /* __FS_NFS_NFS_ARGS_H */
@@ -1,6 +1,14 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
/****************************************************************************
* fs/nfs/nfs_mount.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
@@ -29,13 +37,33 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
*
****************************************************************************/
#ifndef _NFSCLIENT_NFSMOUNT_H_
#define _NFSCLIENT_NFSMOUNT_H_
#ifndef __FS_NFS_NFS_MOUNT_H
#define __FS_NFS_NFS_MOUNT_H
/*
* Mount structure.
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define NFSOP(nmp, op) (*nmp->nm_nfsops->nn_##op)
#define NFSHASOP(nmp, op) (nmp->nm_nfsops->nn_##op != NULL)
#define NFSDAT(nmp, nam) (nmp->nm_nfsops->nn_##nam)
/* Convert mount ptr to nfsmount ptr. */
#define VFSTONFS(mp) ((struct nfsmount *)((mp)->i_private))
/****************************************************************************
* Public Types
****************************************************************************/
/* Mount structure.
* One allocated on every NFS mount.
* Holds NFS specific information for mount.
*/
@@ -44,7 +72,7 @@ struct nfsmount
{
int nm_flag; /* Flags for soft/hard... */
int nm_state; /* Internal state flags */
struct mount *nm_mountp; /* Vfs structure for this filesystem */
struct inode *nm_mountp; /* Vfs structure for this filesystem */
int nm_numgrps; /* Max. size of groupslist */
nfsfh_t nm_fh; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
@@ -70,37 +98,30 @@ struct nfsmount
int nm_acdirmax; /* Directory attr cache max lifetime */
int nm_acregmin; /* Reg file attr cache min lifetime */
int nm_acregmax; /* Reg file attr cache max lifetime */
u_char nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */
TAILQ_HEAD(, buf) nm_bufq; /* async io buffer queue */
short nm_bufqlen; /* number of buffers in queue */
short nm_bufqwant; /* process wants to add to the queue */
int nm_bufqiods; /* number of iods processing queue */
u_int64_t nm_maxfilesize; /* maximum file size */
struct nfsx_nfsops *nm_nfsops; /* Version specific ops. */
/* NFSv4 */
uint64_t nm_clientid;
fsid_t nm_fsid;
u_int nm_lease_time;
time_t nm_last_renewal;
struct vnode *nm_dvp;
unsigned char nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */
};
#define NFSOP(nmp, op) (*nmp->nm_nfsops->nn_##op)
#define NFSHASOP(nmp, op) (nmp->nm_nfsops->nn_##op != NULL)
#define NFSDAT(nmp, nam) (nmp->nm_nfsops->nn_##nam)
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#if defined(_KERNEL)
/* Prototypes for NFS mount operations: */
/*
* Convert mount ptr to nfsmount ptr.
*/
# define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data))
#endif
int nfs_mount(struct mount *, const char *, void *, struct nameidata *,
struct proc *);
int mountnfs(struct nfs_args *, struct mount *, struct mbuf *, char *, char *);
void nfs_decode_args(struct nfsmount *, struct nfs_args *, struct nfs_args *);
int nfs_start(struct mount *, int, struct proc *);
int nfs_unmount(struct mount *, int, struct proc *);
int nfs_root(struct mount *, struct vnode **);
int nfs_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *);
int nfs_statfs(struct mount *, struct statfs *, struct proc *);
int nfs_sync(struct mount *, int, struct ucred *, struct proc *);
int nfs_vget(struct mount *, ino_t, struct vnode **);
int nfs_fhtovp(struct mount *, struct fid *, struct vnode **);
int nfs_vptofh(struct vnode *, struct fid *);
int nfs_fsinfo(struct nfsmount *, struct vnode *, struct ucred *,
struct proc *);
void nfs_init(void);
#endif
+157
View File
@@ -0,0 +1,157 @@
/****************************************************************************
* fs/nfs/nfs_mount.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
#ifndef __FS_NFS_NFS_NODE_H
#define __FS_NFS_NFS_NODE_H
/****************************************************************************
* Included Files
****************************************************************************/
#ifndef _NFS_NFS_H_
# include <nfs/nfs.h>
#endif
#include <sys/rwlock.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Values for n_commitflags */
#define NFS_COMMIT_PUSH_VALID 0x0001/* push range valid */
#define NFS_COMMIT_PUSHED_VALID 0x0002/* pushed range valid */
#define n_atim n_un1.nf_atim
#define n_mtim n_un2.nf_mtim
#define n_cookieverf n_un1.nd_cookieverf
#define n_direofoffset n_un2.nd_direof
/* Flags for n_flag */
#define NFLUSHWANT 0x0001/* Want wakeup from a flush in prog. */
#define NFLUSHINPROG 0x0002/* Avoid multiple calls to vinvalbuf() */
#define NMODIFIED 0x0004/* Might have a modified buffer in bio */
#define NWRITEERR 0x0008/* Flag write errors so close will know */
#define NACC 0x0100/* Special file accessed */
#define NUPD 0x0200/* Special file updated */
#define NCHG 0x0400/* Special file times changed */
#define NFS_INVALIDATE_ATTRCACHE(np) ((np)->n_attrstamp = 0)
/* Convert between nfsnode pointers and vnode pointers */
#define VTONFS(vp) ((struct nfsnode *)(vp)->f_priv)
#define NFSTOV(np) ((np)->n_vnode)
/****************************************************************************
* Public Types
****************************************************************************/
/* Silly rename structure that hangs off the nfsnode until the name
* can be removed by nfs_inactive()
struct sillyrename
{
struct ucred *s_cred;
struct vnode *s_dvp;
long s_namlen;
char s_name[24];
};
*/
/* The nfsnode is the nfs equivalent to ufs's inode. Any similarity
* is purely coincidental.
* There is a unique nfsnode allocated for each active file,
* each current directory, each mounted-on file, text file, and the root.
* An nfsnode is 'named' by its file handle. (nget/nfs_node.c)
* If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite
* type definitions), file handles of > 32 bytes should probably be split out
* into a separate malloc()'d data structure. (Reduce the size of nfsfh_t by
* changing the definition in sys/mount.h of NFS_SMALLFH.)
* NB: Hopefully the current order of the fields is such that everything will
* be well aligned and, therefore, tightly packed.
*/
struct nfsnode
{
RB_ENTRY(nfsnode) n_entry; /* filehandle/node tree. */
uint64_t n_size; /* Current size of file */
//struct vattr n_vattr; /* Vnode attribute cache */
time_t n_attrstamp; /* Attr. cache timestamp */
struct timespec n_mtime; /* Prev modify time. */
time_t n_ctime; /* Prev create time. */
nfsfh_t *n_fhp; /* NFS File Handle */
struct inode *n_inode; /* associated inode */
//struct lockf *n_lockf; /* Locking record of file */
int n_error; /* Save write error value */
union
{
struct timespec nf_atim; /* Special file times */
nfsuint64 nd_cookieverf; /* Cookie verifier (dir only) */
} n_un1;
union
{
struct timespec nf_mtim;
off_t nd_direof; /* Dir. EOF offset cache */
} n_un2;
//struct sillyrename *n_sillyrename; /* Ptr to silly rename struct */
short n_fhsize; /* size in bytes, of fh */
short n_flag; /* Flag for locking.. */
nfsfh_t n_fh; /* Small File Handle */
time_t n_accstamp; /* Access cache timestamp */
uid_t n_accuid; /* Last access requester */
int n_accmode; /* Last mode requested */
int n_accerror; /* Last returned error */
//struct ucred *n_rcred;
//struct ucred *n_wcred;
off_t n_pushedlo; /* 1st blk in commited range */
off_t n_pushedhi; /* Last block in range */
off_t n_pushlo; /* 1st block in commit range */
off_t n_pushhi; /* Last block in range */
//struct rwlock n_commitlock; /* Serialize commits */
int n_commitflags;
};
#endif /* __FS_NFS_NFS_NODE_H */
+42 -33
View File
@@ -1,6 +1,14 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
/****************************************************************************
* fs/nfs/nfs_proto.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
@@ -29,13 +37,21 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
*
****************************************************************************/
#ifndef _NFS_NFSPROTO_H_
#define _NFS_NFSPROTO_H_
#ifndef __FS_NFS_NFS_PROTO_H
#define __FS_NFS_NFS_PROTO_H
/*
* Constants as defined in the Sun NFS Version 2 and 3 specs.
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Constants as defined in the Sun NFS Version 2 and 3 specs.
* "NFS: Network File System Protocol Specification" RFC1094
* and in the "NFS: Network File System Version 3 Protocol
* Specification"
@@ -124,7 +140,8 @@
#define NFSX_V3FSINFO 48
#define NFSX_V3PATHCONF 24
/* variants for both versions */
/* Variants for both versions */
#define NFSX_FH(v3) ((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
NFSX_V2FH)
#define NFSX_SRVFH(v3) ((v3) ? NFSX_V3FH : NFSX_V2FH)
@@ -142,7 +159,7 @@
(2 * NFSX_UNSIGNED))
#define NFSX_STATFS(v3) ((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)
/* nfs rpc procedure numbers (before version mapping) */
/* NFS RPC procedure numbers (before version mapping) */
#define NFSPROC_NULL 0
#define NFSPROC_GETATTR 1
@@ -191,9 +208,7 @@
#define NFSV2PROC_READDIR 16
#define NFSV2PROC_STATFS 17
/*
* Constants used by the Version 3 protocol for various RPCs
*/
/* Constants used by the Version 3 protocol for various RPCs */
#define NFSV3SATTRTIME_DONTCHANGE 0
#define NFSV3SATTRTIME_TOSERVER 1
@@ -230,6 +245,14 @@
#define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(uint32_t,(a))&0x7]
#define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(uint32_t,(a))&0x7]
#ifndef NFS_MAXFHSIZE
# define NFS_MAXFHSIZE 64
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* File types */
typedef enum
@@ -244,15 +267,7 @@ typedef enum
NFFIFO = 7
} nfstype;
/* Structs for common parts of the rpc's */
/*
* File Handle (32 bytes for version 2), variable up to 64 for version 3.
*/
#ifndef NFS_MAXFHSIZE
# define NFS_MAXFHSIZE 64
#endif
/* File Handle (32 bytes for version 2), variable up to 64 for version 3. */
union nfsfh
{
@@ -275,8 +290,7 @@ struct nfsv3_time
};
typedef struct nfsv3_time nfstime3;
/*
* Quads are defined as arrays of 2 longs to ensure dense packing for the
/* Quads are defined as arrays of 2 longs to ensure dense packing for the
* protocol and to facilitate xdr conversion.
*/
@@ -286,9 +300,7 @@ struct nfs_uquad
};
typedef struct nfs_uquad nfsuint64;
/*
* NFS Version 3 special file number.
*/
/* NFS Version 3 special file number. */
struct nfsv3_spec
{
@@ -297,8 +309,7 @@ struct nfsv3_spec
};
typedef struct nfsv3_spec nfsv3spec;
/*
* File attributes and setable attributes. These structures cover both
/* File attributes and setable attributes. These structures cover both
* NFS version 2 and the version 3 protocol. Note that the union is only
* used so that one pointer can refer to both variants. These structures
* go out on the wire and must be densely packed, so no quad data types
@@ -342,7 +353,7 @@ struct nfs_fattr
} fa_un;
};
/* and some ugly defines for accessing union components */
/* And some ugly defines for accessing union components */
#define fa2_size fa_un.fa_nfsv2.nfsv2fa_size
#define fa2_blocksize fa_un.fa_nfsv2.nfsv2fa_blocksize
@@ -372,9 +383,7 @@ struct nfsv2_sattr
nfstime2 sa_mtime;
};
/*
* NFS Version 3 sattr structure for the new node creation case.
*/
/* NFS Version 3 sattr structure for the new node creation case. */
struct nfsv3_sattr
{
+76 -88
View File
@@ -1,7 +1,15 @@
/*
* copyright (c) 2004
* the regents of the university of michigan
* all rights reserved
/****************************************************************************
* fs/nfs/nfs_socket.c
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* copyright (c) 2004
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
@@ -20,54 +28,72 @@
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
*
****************************************************************************/
/* wrappers around rpcclnt */
/****************************************************************************
* Included Files
****************************************************************************/
/* XXX add tryagain code in nfs_request_xx */
/*
* Socket operations for use by nfs
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <queue.h>
#include <time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <debug.h>
#include "rpc_clnt.h"
#include "nfs_args.h"
#include "rpc.h"
#include "rpc_v2.h"
#include "nfs_proto.h
#include "nfs_proto.h"
#include "nfs.h"
#include "xdr_subs.h"
#include "nfsmount.h"
//#include <nfsx/nfs_common.h>
#include "nfs_mount.h"
#include "nfs_socket.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Flag translations */
#define nfsmnt_to_rpcclnt(nf, rf, name) do { \
if (nf & NFSMNT_##name)) { \
rf |= RPCCLNT_##name \
if (nf & NFSMNT_##name) { \
rf |= RPCCLNT_##name; \
} \
} while(0)
static struct rpc_program nfs2_program =
{
NFS_PROG, NFS_VER2, "NFSv2"
};
/****************************************************************************
* Private Variables
****************************************************************************/
static struct rpc_program nfs3_program =
{
NFS_PROG, NFS_VER3, "NFSv3"
};
static struct rpc_program nfs4_program =
/****************************************************************************
* Public Variables
****************************************************************************/
int nfs_ticks;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
void nfs_init(void)
{
NFS_PROG, NFS_VER4, "NFSv4"
};
rpcclnt_init();
}
/* XXXMARIUS: name collision */
int nfsx_connect(struct nfsmount *nmp)
@@ -91,10 +117,10 @@ int nfsx_connect(struct nfsmount *nmp)
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, NOCONN);
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, DUMBTIMR);
rpc->rc_flag |= RPCCLNT_REDIRECT; /* Make this a mount option. */
//rpc->rc_flag |= RPCCLNT_REDIRECT; /* Make this a mount option. */
rpc->rc_authtype = RPCAUTH_NULL; /* for now */
rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname;
//rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname;
rpc->rc_name = (struct sockaddr *)nmp->nm_nam;
rpc->rc_sotype = nmp->nm_sotype;
@@ -132,93 +158,55 @@ void nfsx_safedisconnect(struct nfsmount *nmp)
}
#endif
int
nfsx_request_xx(struct nfsmount *nm, struct vnode *vp, struct mbuf *mrest,
int procnum, cthread_t * td, struct ucred *cred,
struct mbuf **mrp, struct mbuf **mdp, caddr_t * dposp)
int nfsx_request_xx(struct nfsmount *nm, int procnum)
{
int error;
u_int32_t *tl;
struct nfsmount *nmp;
struct rpcclnt *clnt;
struct mbuf *md, *mrep;
caddr_t dpos;
struct rpc_reply reply;
#if 0
int t1;
#endif /* 0 */
if (vp != NULL)
nmp = VFSTONFS(vp->v_mount);
else
nmp = nm;
int trylater_delay;
nmp = nm;
clnt = &nmp->nm_rpcclnt;
#if 0
tryagain:
#endif
memset(&reply, 0, sizeof(reply));
if ((error = rpcclnt_request(clnt, mrest, procnum, td, cred, &reply)) != 0)
if ((error = rpcclnt_request(clnt, procnum, &reply)) != 0)
goto out;
mrep = reply.mrep;
md = reply.result_md;
dpos = reply.result_dpos;
tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
if (*tl != 0)
if (reply->rpc_verfi.authtype != 0)
{
error = fxdr_unsigned(int, *tl);
#if 0
error = fxdr_unsigned(int, reply->rpc_verfi.authtype);
if ((nmp->nm_flag & NFSMNT_NFSV3) && error == NFSERR_TRYLATER)
{
m_freem(mrep);
error = 0;
waituntil = time_second + trylater_delay;
while (time_second < waituntil)
(void)tsleep(&lbolt, PSOCK, "nqnfstry", 0);
trylater_delay *= nfs_backoff[trylater_cnt];
if (trylater_cnt < NFS_NBACKOFF - 1)
trylater_cnt++;
trylater_delay *= NFS_TIMEOUTMUL;
if (trylater_delay > NFS_MAXTIMEO)
{
trylater_delay = NFS_MAXTIMEO;
}
goto tryagain;
}
#endif
/*
** If the File Handle was stale, invalidate the
** lookup cache, just in case.
**/
if (error == ESTALE)
if (vp != NULL)
cache_purge(vp);
else
printf("%s: ESTALE on mount from server %s\n",
nmp->nm_rpcclnt.rc_prog->prog_name,
nmp->nm_rpcclnt.rc_servername);
printf("%s: ESTALE on mount from server \n",
nmp->nm_rpcclnt.rc_prog->prog_name);
else
printf("%s: unknown error %d from server %s\n",
nmp->nm_rpcclnt.rc_prog->prog_name, error,
nmp->nm_rpcclnt.rc_servername);
printf("%s: unknown error %d from server \n",
nmp->nm_rpcclnt.rc_prog->prog_name, error);
goto out;
}
m_freem(mrest);
*mrp = mrep;
*mdp = md;
*dposp = dpos;
return (0);
nfsmout:
out:
/* XXX: don't free mrest if an error occured, to allow caller to retry */
m_freem(mrest);
m_freem(reply.mrep);
*mrp = NULL;
*mdp = NULL;
return (error);
}
+36 -36
View File
@@ -1,7 +1,15 @@
/*
* copyright (c) 2004
* the regents of the university of michigan
* all rights reserved
/****************************************************************************
* fs/nfs/nfs_socket.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* copyright (c) 2004
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
@@ -20,50 +28,42 @@
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
*
****************************************************************************/
#ifndef __NFSX_H_
#define __NFSX_H_
#ifndef __FS_NFS_NFS_SOCKET_H
#define __FS_NFS_NFS_SOCKET_H
/* nfs_socket interface */
/****************************************************************************
* Included Files
****************************************************************************/
/* XXXMARIUS: name collision */
/****************************************************************************
* Pre-processor definitions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
int nfsx_connect(struct nfsmount *);
void nfsx_disconnect(struct nfsmount *);
#ifdef CONFIG_NFS_TCPIP
int nfsx_sigintr(struct nfsmount *, struct nfsreq *, cthread_t *);
void nfsx_safedisconnect(struct nfsmount *);
int nfsx_request_xx(struct nfsmount *, struct vnode *, struct mbuf *, int,
cthread_t *, struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *);
#define nfs_safedisconnect nfsx_safedisconnect
#endif
int nfsx_request_xx(struct nfsmount *, int);
int nfsx_nmcancelreqs(struct nfsmount *);
#define nfs_connect nfs_connect_nfsx
#define nfs_disconnect nfs_disconnect_nfsx
#define nfs_nmcancelreqs nfsx_nmcancelreqs
#define nfsx_request(nmp, m) \
nfsx_request_xx(nmp, m)
#ifdef CONFIG_NFS_TCPIP
#define nfs_sigintr nfs_sigintr_nfsx
/* XXX dros: defined in nfs.h */
#if 0
void nfs_safedisconnect(struct nfsmount *);
#endif
#define nfsx_request(vp, m, p, td, cr, m2, m3, c) \
nfsx_request_xx(NULL, vp, m, p, td, cr, m2, m3, c)
#define nfsx_request_mnt(nmp, m, p, td, cr, m2, m3, c) \
nfsx_request_xx(nmp, NULL, m, p, td, cr, m2, m3, c)
/* don't use this.. use nfsx_request() of nfsx_request_mnt() */
int nfs_request_xx(struct nfsmount *, struct vnode *, struct mbuf *, int,
cthread_t *, struct ucred *, struct mbuf **, struct mbuf **,
caddr_t *);
/* XXX dros: defined in nfs.h */
#if 0
int nfs_nmcancelreqs(struct nfsmount *);
#endif
#endif /* __NFSX_H_ */
#endif /* __FS_NFS_NFS_SOCKET_H */
+927
View File
@@ -0,0 +1,927 @@
/****************************************************************************
* fs/nfs/nfs_vfsops.c
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/ioctl.h>
#include <sys/signal.h>
#include <sys/proc.h>
#include <sys/namei.h>
#include <sys/vnode.h>
#include <sys/kernel.h>
#include <sys/mount.h>
#include <sys/buf.h>
#include <sys/mbuf.h>
#include <sys/dirent.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/statfs>
#include <sys/queue.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfs/nfsnode.h>
#include <nfs/nfs.h>
#include <nfs/nfsmount.h>
#include <nfs/xdr_subs.h>
#include <nfs/nfsm_subs.h>
#include <nfs/nfsdiskless.h>
#include <nfs/nfs_var.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Definitions
****************************************************************************/
/* nfs vfs operations. */
const struct vfsops nfs_vfsops =
{
nfs_mount,
nfs_start,
nfs_unmount,
nfs_root,
nfs_quotactl,
nfs_statfs,
nfs_sync,
nfs_vget,
nfs_fhtovp,
nfs_vptofh,
nfs_vfs_init,
nfs_sysctl,
nfs_checkexp
};
/****************************************************************************
* External Public Data (this belong in a header file)
****************************************************************************/
extern struct nfsstats nfsstats;
extern int nfs_ticks;
extern uint32_t nfs_procids[NFS_NPROCS];
/****************************************************************************
* Public Function Prototypes (this belong in a header file)
****************************************************************************/
int nfs_sysctl(int *, u_int, void *, size_t *, void *, size_t, struct proc *);
int nfs_checkexp(struct mount *, struct mbuf *, int *, struct ucred **);
struct mount *nfs_mount_diskless(struct nfs_dlmount *, char *, int);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Publikc Functions
****************************************************************************/
/* nfs statfs call */
int nfs_statfs(struct file *filep, struct statfs *sbp)
{
struct nfs_statfs *sfp = NULL;
struct nfsmount *nmp = VFSTONFS(filep->f_inode);
int error = 0;
struct nfsnode *np = VTONFS(filep->f_priv);
uint64_t tquad;
error = nfs_nget(mp, (nfsfh_t *) nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
return (error);
if ((nmp->nm_flag & NFSMNT_GOTFSINFO) == 0)
(void)nfs_fsinfo(nmp);
nfsstats.rpccnt[NFSPROC_FSSTAT]++;
error = nfs_request(nmp, NFSPROC_FSSTAT);
if (error)
goto nfsmout;
sbp->f_iosize = min(nmp->nm_rsize, nmp->nm_wsize);
if (info.nmi_v3)
{
sbp->f_bsize = NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_tbytes);
sbp->f_blocks = tquad / (u_quad_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_fbytes);
sbp->f_bfree = tquad / (u_quad_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_abytes);
sbp->f_bavail = (quad_t) tquad / (quad_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp->sf_tfiles);
sbp->f_files = tquad;
tquad = fxdr_hyper(&sfp->sf_ffiles);
sbp->f_ffree = tquad;
sbp->f_favail = tquad;
sbp->f_namemax = MAXNAMLEN;
}
else
{
sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
sbp->f_files = 0;
sbp->f_ffree = 0;
}
copy_statfs_info(sbp, mp);
nfsmout:
return (error);
}
/* nfs version 3 fsinfo rpc call */
int nfs_fsinfo(struct nfsmount *nmp)
{
struct nfsv3_fsinfo *fsp;
struct nfsm_info info;
uint32_t pref, max;
int error = 0;
nfsstats.rpccnt[NFSPROC_FSINFO]++;
error = nfs_request(nmp, NFSPROC_FSINFO);
if (error)
{
goto nfsmout;
}
pref = fxdr_unsigned(uint32_t, fsp->fs_wtpref);
if (pref < nmp->nm_wsize)
nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
max = fxdr_unsigned(uint32_t, fsp->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->fs_rtpref);
if (pref < nmp->nm_rsize)
nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
max = fxdr_unsigned(uint32_t, fsp->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->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;
nfsmout:
return (error);
}
/* Mount a remote root fs via. NFS. It goes like this:
* - Call nfs_boot_init() to fill in the nfs_diskless struct
* (using RARP, bootparam RPC, mountd RPC)
* - hand craft the swap nfs vnode hanging off a fake mount point
* if swdevt[0].sw_dev == NODEV
* - build the rootfs mount point and call mountnfs() to do the rest.
*/
int nfs_mountroot(void)
{
struct nfs_diskless nd;
struct vattr attr;
struct mount *mp;
struct vnode *vp;
struct proc *procp;
long n;
int error;
procp = curproc; /* XXX */
/* Call nfs_boot_init() to fill in the nfs_diskless struct.
* Side effect: Finds and configures a network interface.
*/
bzero((caddr_t) & nd, sizeof(nd));
nfs_boot_init(&nd, procp);
/* Create the root mount point. */
if (nfs_boot_getfh(&nd.nd_boot, "root", &nd.nd_root, -1))
panic("nfs_mountroot: root");
mp = nfs_mount_diskless(&nd.nd_root, "/", 0);
nfs_root(mp, &rootvp);
printf("root on %s\n", nd.nd_root.ndm_host);
/* Link it into the mount list. */
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
vfs_unbusy(mp);
/* Get root attributes (for the time). */
error = VOP_GETATTR(rootvp, &attr, procp->p_ucred, procp);
if (error)
panic("nfs_mountroot: getattr for root");
n = attr.va_atime.tv_sec;
#ifdef DEBUG
printf("root time: 0x%lx\n", n);
#endif
inittodr(n);
#ifdef notyet
/* Set up swap credentials. */
proc0.p_ucred->cr_uid = ntohl(nd.swap_ucred.cr_uid);
proc0.p_ucred->cr_gid = ntohl(nd.swap_ucred.cr_gid);
if ((proc0.p_ucred->cr_ngroups = ntohs(nd.swap_ucred.cr_ngroups)) > NGROUPS)
proc0.p_ucred->cr_ngroups = NGROUPS;
for (i = 0; i < proc0.p_ucred->cr_ngroups; i++)
proc0.p_ucred->cr_groups[i] = ntohl(nd.swap_ucred.cr_groups[i]);
#endif
/* "Mount" the swap device.
*
* On a "dataless" configuration (swap on disk) we will have:
* (swdevt[0].sw_dev != NODEV) identifying the swap device.
*/
if (bdevvp(swapdev, &swapdev_vp))
panic("nfs_mountroot: can't setup swap vp");
if (swdevt[0].sw_dev != NODEV)
{
printf("swap on device 0x%x\n", swdevt[0].sw_dev);
return (0);
}
/* If swapping to an nfs node: (swdevt[0].sw_dev == NODEV)
* Create a fake mount point just for the swap vnode so that the
* swap file can be on a different server from the rootfs.
*
* Wait 5 retries, finally no swap is cool. -mickey
*/
error = nfs_boot_getfh(&nd.nd_boot, "swap", &nd.nd_swap, 5);
if (!error)
{
mp = nfs_mount_diskless(&nd.nd_swap, "/swap", 0);
nfs_root(mp, &vp);
vfs_unbusy(mp);
/* Since the swap file is not the root dir of a file system,
* hack it to a regular file.
*/
vp->v_type = VREG;
vp->v_flag = 0;
/* Next line is a hack to make swapmount() work on NFS
* swap files.
* XXX-smurph
*/
swdevt[0].sw_dev = NETDEV;
/* end hack */
swdevt[0].sw_vp = vp;
/* Find out how large the swap file is. */
error = VOP_GETATTR(vp, &attr, procp->p_ucred, procp);
if (error)
printf("nfs_mountroot: getattr for swap\n");
n = (long)(attr.va_size >> DEV_BSHIFT);
printf("swap on %s\n", nd.nd_swap.ndm_host);
#ifdef DEBUG
printf("swap size: 0x%lx (blocks)\n", n);
#endif
return (0);
}
printf("WARNING: no swap\n");
swdevt[0].sw_dev = NODEV;
swdevt[0].sw_vp = NULL;
return (0);
}
/* Internal version of mount system call for diskless setup. */
struct mount *nfs_mount_diskless(struct nfs_dlmount *ndmntp, char *mntname,
int mntflag)
{
struct nfs_args args;
struct mount *mp;
struct mbuf *m;
int error;
if (vfs_rootmountalloc("nfs", mntname, &mp))
panic("nfs_mount_diskless: vfs_rootmountalloc failed");
mp->mnt_flag |= mntflag;
/* Initialize mount args. */
bzero((caddr_t) & args, sizeof(args));
args.addr = (struct sockaddr *)&ndmntp->ndm_saddr;
args.addrlen = args.addr->sa_len;
args.sotype = SOCK_DGRAM;
args.fh = ndmntp->ndm_fh;
args.fhsize = NFSX_V2FH;
args.hostname = ndmntp->ndm_host;
#ifdef NFS_BOOT_OPTIONS
args.flags |= NFS_BOOT_OPTIONS;
#endif
#ifdef NFS_BOOT_RWSIZE
/* Reduce rsize,wsize for interfaces that consistently
* drop fragments of long UDP messages. (i.e. wd8003).
* You can always change these later via remount.
*/
args.flags |= NFSMNT_WSIZE | NFSMNT_RSIZE;
args.wsize = NFS_BOOT_RWSIZE;
args.rsize = NFS_BOOT_RWSIZE;
#endif
/* Get mbuf for server sockaddr. */
m = m_get(M_WAIT, MT_SONAME);
bcopy((caddr_t) args.addr, mtod(m, caddr_t), (m->m_len = args.addr->sa_len));
error = mountnfs(&args, mp, m, mntname, args.hostname);
if (error)
panic("nfs_mountroot: mount %s failed: %d", mntname, error);
return (mp);
}
void
nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp,
struct nfs_args *nargp)
{
int s;
int adjsock = 0;
int maxio;
s = splsoftnet();
#if 0
/* 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);
splx(s);
if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0)
{
nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
if (nmp->nm_timeo < NFS_MINTIMEO)
nmp->nm_timeo = NFS_MINTIMEO;
else if (nmp->nm_timeo > NFS_MAXTIMEO)
nmp->nm_timeo = NFS_MAXTIMEO;
}
if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1)
nmp->nm_retry = MIN(argp->retrans, NFS_MAXREXMIT);
if (!(nmp->nm_flag & NFSMNT_SOFT))
nmp->nm_retry = NFS_MAXREXMIT + 1; /* past clip limit */
if (argp->flags & NFSMNT_NFSV3)
{
if (argp->sotype == SOCK_DGRAM)
maxio = NFS_MAXDGRAMDATA;
else
maxio = NFS_MAXDATA;
}
else
maxio = NFS_V2MAXDATA;
if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0)
{
int osize = nmp->nm_wsize;
nmp->nm_wsize = argp->wsize;
/* Round down to multiple of blocksize */
nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize <= 0)
nmp->nm_wsize = NFS_FABLKSIZE;
adjsock |= (nmp->nm_wsize != osize);
}
if (nmp->nm_wsize > maxio)
nmp->nm_wsize = maxio;
if (nmp->nm_wsize > MAXBSIZE)
nmp->nm_wsize = MAXBSIZE;
if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0)
{
int osize = nmp->nm_rsize;
nmp->nm_rsize = argp->rsize;
/* Round down to multiple of blocksize */
nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize <= 0)
nmp->nm_rsize = NFS_FABLKSIZE;
adjsock |= (nmp->nm_rsize != osize);
}
if (nmp->nm_rsize > maxio)
nmp->nm_rsize = maxio;
if (nmp->nm_rsize > MAXBSIZE)
nmp->nm_rsize = MAXBSIZE;
if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0)
{
nmp->nm_readdirsize = argp->readdirsize;
/* Round down to multiple of blocksize */
nmp->nm_readdirsize &= ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize < NFS_DIRBLKSIZ)
nmp->nm_readdirsize = NFS_DIRBLKSIZ;
}
else if (argp->flags & NFSMNT_RSIZE)
nmp->nm_readdirsize = nmp->nm_rsize;
if (nmp->nm_readdirsize > maxio)
nmp->nm_readdirsize = maxio;
if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 &&
argp->maxgrouplist <= NFS_MAXGRPS)
nmp->nm_numgrps = argp->maxgrouplist;
if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 &&
argp->readahead <= NFS_MAXRAHEAD)
nmp->nm_readahead = argp->readahead;
if (argp->flags & NFSMNT_ACREGMIN && argp->acregmin >= 0)
{
if (argp->acregmin > 0xffff)
nmp->nm_acregmin = 0xffff;
else
nmp->nm_acregmin = argp->acregmin;
}
if (argp->flags & NFSMNT_ACREGMAX && argp->acregmax >= 0)
{
if (argp->acregmax > 0xffff)
nmp->nm_acregmax = 0xffff;
else
nmp->nm_acregmax = argp->acregmax;
}
if (nmp->nm_acregmin > nmp->nm_acregmax)
nmp->nm_acregmin = nmp->nm_acregmax;
if (argp->flags & NFSMNT_ACDIRMIN && argp->acdirmin >= 0)
{
if (argp->acdirmin > 0xffff)
nmp->nm_acdirmin = 0xffff;
else
nmp->nm_acdirmin = argp->acdirmin;
}
if (argp->flags & NFSMNT_ACDIRMAX && argp->acdirmax >= 0)
{
if (argp->acdirmax > 0xffff)
nmp->nm_acdirmax = 0xffff;
else
nmp->nm_acdirmax = argp->acdirmax;
}
if (nmp->nm_acdirmin > nmp->nm_acdirmax)
nmp->nm_acdirmin = nmp->nm_acdirmax;
if (nmp->nm_so && adjsock)
{
nfs_disconnect(nmp);
if (nmp->nm_sotype == SOCK_DGRAM)
while (nfs_connect(nmp, NULL))
{
printf("nfs_args: retrying connect\n");
(void)tsleep((caddr_t) & lbolt, PSOCK, "nfscon", 0);
}
}
/* Update nargp based on nmp */
nargp->wsize = nmp->nm_wsize;
nargp->rsize = nmp->nm_rsize;
nargp->readdirsize = nmp->nm_readdirsize;
nargp->timeo = nmp->nm_timeo;
nargp->retrans = nmp->nm_retry;
nargp->maxgrouplist = nmp->nm_numgrps;
nargp->readahead = nmp->nm_readahead;
nargp->acregmin = nmp->nm_acregmin;
nargp->acregmax = nmp->nm_acregmax;
nargp->acdirmin = nmp->nm_acdirmin;
nargp->acdirmax = nmp->nm_acdirmax;
}
/* VFS Operations.
*
* mount system call
* It seems a bit dumb to copyinstr() the host and path here and then
* bcopy() them in mountnfs(), but I wanted to detect errors before
* doing the sockargs() call because sockargs() allocates an mbuf and
* an error after that means that I have to release the mbuf.
*/
/* ARGSUSED */
int
nfs_mount(struct mount *mp, const char *path, void *data,
struct nameidata *ndp, struct proc *p)
{
int error;
struct nfs_args args;
struct mbuf *nam;
char pth[MNAMELEN], hst[MNAMELEN];
size_t len;
u_char nfh[NFSX_V3FHMAX];
error = copyin(data, &args, sizeof(args.version));
if (error)
return (error);
if (args.version == 3)
{
error = copyin(data, (caddr_t) & args, sizeof(struct nfs_args3));
args.flags &= ~(NFSMNT_INTERNAL | NFSMNT_NOAC);
}
else if (args.version == NFS_ARGSVERSION)
{
error = copyin(data, (caddr_t) & args, sizeof(struct nfs_args));
args.flags &= ~NFSMNT_NOAC; /* XXX - compatibility */
}
else
return (EPROGMISMATCH);
if (error)
return (error);
if ((args.flags & (NFSMNT_NFSV3 | NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS)
return (EINVAL);
if (nfs_niothreads < 0)
{
nfs_niothreads = 4;
nfs_getset_niothreads(1);
}
if (mp->mnt_flag & MNT_UPDATE)
{
struct nfsmount *nmp = VFSTONFS(mp);
if (nmp == NULL)
return (EIO);
/* When doing an update, we can't change from or to v3. */
args.flags = (args.flags & ~(NFSMNT_NFSV3)) |
(nmp->nm_flag & (NFSMNT_NFSV3));
nfs_decode_args(nmp, &args, &mp->mnt_stat.mount_info.nfs_args);
return (0);
}
if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX)
return (EINVAL);
error = copyin((caddr_t) args.fh, (caddr_t) nfh, args.fhsize);
if (error)
return (error);
error = copyinstr(path, pth, MNAMELEN - 1, &len);
if (error)
return (error);
bzero(&pth[len], MNAMELEN - len);
error = copyinstr(args.hostname, hst, MNAMELEN - 1, &len);
if (error)
return (error);
bzero(&hst[len], MNAMELEN - len);
/* sockargs() call must be after above copyin() calls */
error = sockargs(&nam, args.addr, args.addrlen, MT_SONAME);
if (error)
return (error);
args.fh = nfh;
error = mountnfs(&args, mp, nam, pth, hst);
return (error);
}
/* Common code for mount and mountroot */
int
mountnfs(struct nfs_args *argp, struct mount *mp, struct mbuf *nam, char *pth,
char *hst)
{
struct nfsmount *nmp;
int error;
if (mp->mnt_flag & MNT_UPDATE)
{
nmp = VFSTONFS(mp);
/* update paths, file handles, etc, here XXX */
m_freem(nam);
return (0);
}
else
{
nmp = malloc(sizeof(struct nfsmount), M_NFSMNT, M_WAITOK | M_ZERO);
mp->mnt_data = (qaddr_t) nmp;
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
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_numgrps = NFS_MAXGRPS;
nmp->nm_readahead = NFS_DEFRAHEAD;
nmp->nm_fhsize = argp->fhsize;
nmp->nm_acregmin = NFS_MINATTRTIMO;
nmp->nm_acregmax = NFS_MAXATTRTIMO;
nmp->nm_acdirmin = NFS_MINATTRTIMO;
nmp->nm_acdirmax = NFS_MAXATTRTIMO;
bcopy((caddr_t) argp->fh, (caddr_t) nmp->nm_fh, argp->fhsize);
strncpy(&mp->mnt_stat.f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN);
bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN);
bcopy(argp, &mp->mnt_stat.mount_info.nfs_args, sizeof(*argp));
nmp->nm_nam = nam;
nfs_decode_args(nmp, argp, &mp->mnt_stat.mount_info.nfs_args);
RB_INIT(&nmp->nm_ntree);
TAILQ_INIT(&nmp->nm_reqsq);
timeout_set(&nmp->nm_rtimeout, nfs_timer, nmp);
/* 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 && (error = nfs_connect(nmp, NULL)))
goto bad;
/* This is silly, but it has to be set so that vinifod() works.
* We do not want to do an nfs_statfs() here since we can get
* stuck on a dead server and we are holding a lock on the mount
* point.
*/
mp->mnt_stat.f_iosize = NFS_MAXDGRAMDATA;
return (0);
bad:
nfs_disconnect(nmp);
free((caddr_t) nmp, M_NFSMNT);
m_freem(nam);
return (error);
}
/* unmount system call */
int nfs_unmount(struct mount *mp, int mntflags, struct proc *p)
{
struct nfsmount *nmp;
int error, flags;
nmp = VFSTONFS(mp);
flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
error = vflush(mp, NULL, flags);
if (error)
return (error);
nfs_disconnect(nmp);
m_freem(nmp->nm_nam);
timeout_del(&nmp->nm_rtimeout);
free(nmp, M_NFSMNT);
return (0);
}
/* Return root of a filesystem */
int nfs_root(struct mount *mp, struct vnode **vpp)
{
struct nfsmount *nmp;
struct nfsnode *np;
int error;
nmp = VFSTONFS(mp);
error = nfs_nget(mp, (nfsfh_t *) nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
return (error);
*vpp = NFSTOV(np);
return (0);
}
/* Flush out the buffer cache */
int nfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
{
struct vnode *vp;
int error, allerror = 0;
/* Don't traverse the vnode list if we want to skip all of them. */
if (waitfor == MNT_LAZY)
return (allerror);
/* Force stale buffer cache information to be flushed. */
loop:
LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes)
{
/* If the vnode that we are about to sync is no longer
* associated with this mount point, start over.
*/
if (vp->v_mount != mp)
goto loop;
if (VOP_ISLOCKED(vp) || LIST_FIRST(&vp->v_dirtyblkhd) == NULL)
continue;
if (vget(vp, LK_EXCLUSIVE, p))
goto loop;
error = VOP_FSYNC(vp, cred, waitfor, p);
if (error)
allerror = error;
vput(vp);
}
return (allerror);
}
/* NFS flat namespace lookup.
* Currently unsupported.
*/
/* ARGSUSED */
int nfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
{
return (EOPNOTSUPP);
}
/* Do that sysctl thang... */
int
nfs_sysctl(int *name, u_int namelen, void *oldp, size_t * oldlenp, void *newp,
size_t newlen, struct proc *p)
{
int rv;
/* All names at this level are terminal. */
if (namelen > 1)
return ENOTDIR; /* overloaded */
switch (name[0])
{
case NFS_NFSSTATS:
if (!oldp)
{
*oldlenp = sizeof nfsstats;
return 0;
}
if (*oldlenp < sizeof nfsstats)
{
*oldlenp = sizeof nfsstats;
return ENOMEM;
}
rv = copyout(&nfsstats, oldp, sizeof nfsstats);
if (rv)
return rv;
if (newp && newlen != sizeof nfsstats)
return EINVAL;
if (newp)
{
return copyin(newp, &nfsstats, sizeof nfsstats);
}
return 0;
case NFS_NIOTHREADS:
nfs_getset_niothreads(0);
rv = sysctl_int(oldp, oldlenp, newp, newlen, &nfs_niothreads);
if (newp)
nfs_getset_niothreads(1);
return rv;
default:
return EOPNOTSUPP;
}
}
/* At this point, this should never happen */
/* ARGSUSED */
int nfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
{
return (EINVAL);
}
/* Vnode pointer to File handle, should never happen either */
/* ARGSUSED */
int nfs_vptofh(struct vnode *vp, struct fid *fhp)
{
return (EINVAL);
}
/* Vfs start routine, a no-op. */
/* ARGSUSED */
int nfs_start(struct mount *mp, int flags, struct proc *p)
{
return (0);
}
/* Do operations associated with quotas, not supported */
/* ARGSUSED */
int
nfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, struct proc *p)
{
return (EOPNOTSUPP);
}
/* check export permission, not supported */
/* ARGUSED */
int
nfs_checkexp(struct mount *mp, struct mbuf *nam, int *exflagsp,
struct ucred **credanonp)
{
return (EOPNOTSUPP);
}
File diff suppressed because it is too large Load Diff
+37 -16
View File
@@ -1,7 +1,15 @@
/*
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
/****************************************************************************
* fs/nfs/rpc.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
@@ -20,11 +28,9 @@
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
@@ -57,13 +63,22 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
*
****************************************************************************/
#ifndef _RPCCLNT_H_
#define _RPCCLNT_H_
#ifndef __FS_NFS_RPC_H
#define __FS_NFS_RPC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/types.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* for rpcclnt's rc_flags */
#define RPCCLNT_SOFT 0x001 /* soft mount (hard is details) */
@@ -78,6 +93,10 @@
#define RPCCLNT_RCVLOCK 0x400
#define RPCCLNT_WANTRCV 0x800
/****************************************************************************
* Public Types
****************************************************************************/
struct rpc_program
{
uint32_t prog_id;
@@ -155,8 +174,7 @@ struct rpc_reply
struct rpc_auth_info rpc_verfi;
};
/*
* RPC Client connection context.
/* RPC Client connection context.
* One allocated on every NFS mount.
* Holds RPC specific information for mount.
*/
@@ -202,19 +220,22 @@ struct rpcclnt
struct rpc_program * rc_prog;
char *rc_servername;
//char *rc_servername;
int rc_proctlen; /* if == 0 then rc_proct == NULL */
int * rc_proct;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/*
void rpcclnt_create(struct rpcclnt ** rpc);
void rpcclnt_destroy(struct rpcclnt * rpc);
#define rpcclnt_get(X) rpcclnt_create(&(X))
#define rpcclnt_put(X) rpcclnt_destroy(X)
*/
void rpcclnt_init(void);
+497 -434
View File
File diff suppressed because it is too large Load Diff
+32 -13
View File
@@ -1,7 +1,15 @@
/*
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
/****************************************************************************
* fs/nfs/rpc_clnt_private.h
*
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Leveraged from OpenBSD:
*
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
@@ -20,11 +28,9 @@
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
@@ -57,10 +63,19 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
*
****************************************************************************/
#ifndef _RPCCLNT_PRIVATE_H_
#define _RPCCLNT_PRIVATE_H_
#ifndef __FS_NFS_RPC_CLIENT_PRIVATE_H
#define __FS_NFS_RPC_CLIENT_PRIVATE_H
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define RPCCLNT_DEBUG 1
@@ -114,6 +129,10 @@
SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \
SIGISMEMBER(set, SIGQUIT))
/****************************************************************************
* Public Types
****************************************************************************/
/* global rpcstats
* XXX should be per rpcclnt */
@@ -126,4 +145,4 @@ struct rpcstats
int rpcinvalid;
};
#endif /* _RPCCLNT_PRIVATE_H_ */
#endif /* __FS_NFS_RPC_CLIENT_PRIVATE_H */
-28
View File
@@ -59,34 +59,6 @@ struct lock
int dummy;
};
typedef struct { int32_t val[2]; } fsid_t; /* file system id type */
/*
* File identifier.
* These are unique per filesystem on a single machine.
*/
#define MAXFIDSZ 16
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;
struct componentname
{
/* Arguments to lookup. */
@@ -1,8 +1,9 @@
/****************************************************************************
* hello/hello.c
* include/nuttx/fs/nfs.h
*
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,43 +34,39 @@
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#ifndef __INCLUDE_NUTTX_FS_NFS_H
#define __INCLUDE_NUTTX_FS_NFS_H
/****************************************************************************
* Included Files
****************************************************************************/
void memtest(void)
{
char *p;
int i, j;
for (i=0; i<1000; i++) {
p = malloc(40000);
if (!p) {
printf("No memory\n");
break;
}
for (j=0; j<40000; j++) p[j] = 0;
free(p);
}
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Type Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C" {
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
/** Example of a standalone application
*/
int hello_main(int argc, char *argv[])
{
int i;
printf("Hello Builtin Application\n"
"Found argc=%d arguments and are as follows:\n", argc);
// note that stdout is bufferred and that fflush() and is called on exit.
fflush(stdout);
for (i=0; i<argc; i++)
printf("%s\n", argv[i]);
//memtest();
return 0;
}
#endif /* __INCLUDE_NUTTX_FS_NFS_H */