summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Norum <WENorum@lbl.gov>2006-06-09 18:44:03 +0000
committerEric Norum <WENorum@lbl.gov>2006-06-09 18:44:03 +0000
commit856b0f3fe1f11b8e7777c03406882e5a3ba65b97 (patch)
treed3055d06005ea901c9968d9eba6c2b1c7ff1d2f4
parentc69ba5253db1a59872ab9d77e383c0d4c6401ca2 (diff)
Bring up to date with latest version from SLAC.
-rw-r--r--rtemsNfs/ChangeLog36
-rw-r--r--rtemsNfs/README6
-rw-r--r--rtemsNfs/proto/Makefile3
-rw-r--r--rtemsNfs/proto/mount_prot.h182
-rw-r--r--rtemsNfs/proto/mount_prot_xdr.c138
-rw-r--r--rtemsNfs/proto/nfs_prot.h449
-rw-r--r--rtemsNfs/proto/nfs_prot_xdr.c887
-rw-r--r--rtemsNfs/rfc1094.txt1258
-rw-r--r--rtemsNfs/src/Makefile2
-rw-r--r--rtemsNfs/src/dirutils.c104
-rw-r--r--rtemsNfs/src/nfs.c251
-rw-r--r--rtemsNfs/src/rpcio.c9
-rw-r--r--rtemsNfs/src/sock_mbuf.c2
13 files changed, 2513 insertions, 814 deletions
diff --git a/rtemsNfs/ChangeLog b/rtemsNfs/ChangeLog
index ab2a1f1..2bea5a4 100644
--- a/rtemsNfs/ChangeLog
+++ b/rtemsNfs/ChangeLog
@@ -1,3 +1,39 @@
+Changes since RTEMS-NFS 1.2:
+ NFS:
+ - replaced inet_aton -> inet_pton
+ - replaced unsigned32 -> uint32_t
+ - added _KERNEL definition for 4.7 compilation
+ - silenced compiler warnings (4.7)
+ - added -Wno-unused-variable in 'proto' -- rpcgen produces a lot of them.
+ - new locking scheme. The 'in-use' counters cannot be protected by a mutex
+ because files might be closed when a thread is deleted from a dispatch-disabled
+ section where mutexes must not be locked. The counters are now protected by
+ disabling interrupts.
+ The only critical race-condition I can see ATM is while the NFS is being
+ unmounted and the mount point is crossed by another thread. It should be the
+ generic FS code's responsibility to handle that (but AFAIK, it doesn't) --
+ it's out of our scope...
+ - ftruncate didn't work. The functionality is achieved by nfs_sattr()
+ setting the file size to 0. However, nfs_sattr() always tried to set
+ all attributes (re-applying the current values to fields we didn't
+ want to change) which failed (EPERM) if we were not the owner.
+ Now, we restrict modifications to the requested fields (in case of
+ ftruncate this is *only* the size), adhering to rfc1094 (which states
+ that unused fields shall be set to -1).
+ - lseek(SEEK_END) didn't work. The underlying RTEMS filesystem code
+ uses an internal file 'size' field to compute the offset whence SEEK_END.
+ Instead of painfully maintaining 'size' across all system calls, we
+ just tweak the offset for SEEK_END and leave 'size' unused.
+ - fix: O_APPEND wasn't honoured. Note that there is no NFS 'append' call -
+ the client simply uses the currently available idea of the file size
+ to set the write offset. This obviously is subject to race conditions
+ if multiple clients are writing the same file.
+ dirutils:
+ - replaced read/write calls by stdio; In case of copying to stdout, I
+ experienced occasional crashes when write(fileno(stdout),...) -- according
+ to the standard, mixing low-level i/o with stdio might produce undefined
+ results; there we go...
+
Changes since RTEMS-NFS 1.1:
NFS:
- unlink() didnt work. The underlying RTEMS filesystem code evaluates
diff --git a/rtemsNfs/README b/rtemsNfs/README
index 3291329..6c261ec 100644
--- a/rtemsNfs/README
+++ b/rtemsNfs/README
@@ -458,6 +458,12 @@ I recommend to use the patch distributed with RTEMS-NFS.
o NOTE: RTEMS 'mount()' / 'unmount()' are NOT THREAD SAFE.
+ o The NFS protocol has no 'append' or 'seek_end' primitive. The client
+ must query the current file size (this client uses cached info) and
+ change the local file pointer accordingly (in 'O_APPEND' mode).
+ Obviously, this involves a race condition and hence multiple clients
+ writing the same file may lead to corruption.
+
IV Licensing & Disclaimers
--------------------------
diff --git a/rtemsNfs/proto/Makefile b/rtemsNfs/proto/Makefile
index 57a9830..e95eaa1 100644
--- a/rtemsNfs/proto/Makefile
+++ b/rtemsNfs/proto/Makefile
@@ -42,7 +42,8 @@ include $(RTEMS_ROOT)/make/lib.cfg
DEFINES +=
CPPFLAGS +=
# inline declarations require -O
-CFLAGS += -O2 -Winline
+# rpcgen produces unused variables
+CFLAGS += -O2 -Winline -Wno-unused-variable
#
# Add your list of files to delete here. The config files
diff --git a/rtemsNfs/proto/mount_prot.h b/rtemsNfs/proto/mount_prot.h
index 1cde517..f9ba450 100644
--- a/rtemsNfs/proto/mount_prot.h
+++ b/rtemsNfs/proto/mount_prot.h
@@ -6,18 +6,23 @@
#ifndef _MOUNT_PROT_H_RPCGEN
#define _MOUNT_PROT_H_RPCGEN
-#include <rpc/rpc.h>
-
+#define RPCGEN_VERSION 199506
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <rpc/rpc.h>
#define MNTPATHLEN 1024
#define MNTNAMLEN 255
#define FHSIZE 32
typedef char fhandle[FHSIZE];
+#ifdef __cplusplus
+extern "C" bool_t xdr_fhandle(XDR *, fhandle);
+#elif __STDC__
+extern bool_t xdr_fhandle(XDR *, fhandle);
+#else /* Old Style C */
+bool_t xdr_fhandle();
+#endif /* Old Style C */
+
struct fhstatus {
u_int fhs_status;
@@ -26,12 +31,44 @@ struct fhstatus {
} fhstatus_u;
};
typedef struct fhstatus fhstatus;
+#ifdef __cplusplus
+extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
+#elif __STDC__
+extern bool_t xdr_fhstatus(XDR *, fhstatus*);
+#else /* Old Style C */
+bool_t xdr_fhstatus();
+#endif /* Old Style C */
+
typedef char *dirpath;
+#ifdef __cplusplus
+extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
+#elif __STDC__
+extern bool_t xdr_dirpath(XDR *, dirpath*);
+#else /* Old Style C */
+bool_t xdr_dirpath();
+#endif /* Old Style C */
+
typedef char *name;
+#ifdef __cplusplus
+extern "C" bool_t xdr_name(XDR *, name*);
+#elif __STDC__
+extern bool_t xdr_name(XDR *, name*);
+#else /* Old Style C */
+bool_t xdr_name();
+#endif /* Old Style C */
+
typedef struct mountbody *mountlist;
+#ifdef __cplusplus
+extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
+#elif __STDC__
+extern bool_t xdr_mountlist(XDR *, mountlist*);
+#else /* Old Style C */
+bool_t xdr_mountlist();
+#endif /* Old Style C */
+
struct mountbody {
name ml_hostname;
@@ -39,16 +76,48 @@ struct mountbody {
mountlist ml_next;
};
typedef struct mountbody mountbody;
+#ifdef __cplusplus
+extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
+#elif __STDC__
+extern bool_t xdr_mountbody(XDR *, mountbody*);
+#else /* Old Style C */
+bool_t xdr_mountbody();
+#endif /* Old Style C */
+
typedef struct groupnode *groups;
+#ifdef __cplusplus
+extern "C" bool_t xdr_groups(XDR *, groups*);
+#elif __STDC__
+extern bool_t xdr_groups(XDR *, groups*);
+#else /* Old Style C */
+bool_t xdr_groups();
+#endif /* Old Style C */
+
struct groupnode {
name gr_name;
groups gr_next;
};
typedef struct groupnode groupnode;
+#ifdef __cplusplus
+extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
+#elif __STDC__
+extern bool_t xdr_groupnode(XDR *, groupnode*);
+#else /* Old Style C */
+bool_t xdr_groupnode();
+#endif /* Old Style C */
+
typedef struct exportnode *exports;
+#ifdef __cplusplus
+extern "C" bool_t xdr_exports(XDR *, exports*);
+#elif __STDC__
+extern bool_t xdr_exports(XDR *, exports*);
+#else /* Old Style C */
+bool_t xdr_exports();
+#endif /* Old Style C */
+
struct exportnode {
dirpath ex_dir;
@@ -56,89 +125,86 @@ struct exportnode {
exports ex_next;
};
typedef struct exportnode exportnode;
+#ifdef __cplusplus
+extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
+#elif __STDC__
+extern bool_t xdr_exportnode(XDR *, exportnode*);
+#else /* Old Style C */
+bool_t xdr_exportnode();
+#endif /* Old Style C */
+
-#define MOUNTPROG 100005
-#define MOUNTVERS 1
+#define MOUNTPROG ((u_long)100005)
+#define MOUNTVERS ((u_long)1)
-#if defined(__STDC__) || defined(__cplusplus)
-#define MOUNTPROC_NULL 0
+#ifdef __cplusplus
+#define MOUNTPROC_NULL ((u_long)0)
+extern "C" void * mountproc_null_1(void *, CLIENT *);
+extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_MNT ((u_long)1)
+extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
+extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_DUMP ((u_long)2)
+extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
+extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_UMNT ((u_long)3)
+extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
+extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_UMNTALL ((u_long)4)
+extern "C" void * mountproc_umntall_1(void *, CLIENT *);
+extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORT ((u_long)5)
+extern "C" exports * mountproc_export_1(void *, CLIENT *);
+extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORTALL ((u_long)6)
+extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
+extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+
+#elif __STDC__
+#define MOUNTPROC_NULL ((u_long)0)
extern void * mountproc_null_1(void *, CLIENT *);
extern void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT 1
+#define MOUNTPROC_MNT ((u_long)1)
extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP 2
+#define MOUNTPROC_DUMP ((u_long)2)
extern mountlist * mountproc_dump_1(void *, CLIENT *);
extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT 3
+#define MOUNTPROC_UMNT ((u_long)3)
extern void * mountproc_umnt_1(dirpath *, CLIENT *);
extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL 4
+#define MOUNTPROC_UMNTALL ((u_long)4)
extern void * mountproc_umntall_1(void *, CLIENT *);
extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT 5
+#define MOUNTPROC_EXPORT ((u_long)5)
extern exports * mountproc_export_1(void *, CLIENT *);
extern exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL 6
+#define MOUNTPROC_EXPORTALL ((u_long)6)
extern exports * mountproc_exportall_1(void *, CLIENT *);
extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
-#else /* K&R C */
-#define MOUNTPROC_NULL 0
+#else /* Old Style C */
+#define MOUNTPROC_NULL ((u_long)0)
extern void * mountproc_null_1();
extern void * mountproc_null_1_svc();
-#define MOUNTPROC_MNT 1
+#define MOUNTPROC_MNT ((u_long)1)
extern fhstatus * mountproc_mnt_1();
extern fhstatus * mountproc_mnt_1_svc();
-#define MOUNTPROC_DUMP 2
+#define MOUNTPROC_DUMP ((u_long)2)
extern mountlist * mountproc_dump_1();
extern mountlist * mountproc_dump_1_svc();
-#define MOUNTPROC_UMNT 3
+#define MOUNTPROC_UMNT ((u_long)3)
extern void * mountproc_umnt_1();
extern void * mountproc_umnt_1_svc();
-#define MOUNTPROC_UMNTALL 4
+#define MOUNTPROC_UMNTALL ((u_long)4)
extern void * mountproc_umntall_1();
extern void * mountproc_umntall_1_svc();
-#define MOUNTPROC_EXPORT 5
+#define MOUNTPROC_EXPORT ((u_long)5)
extern exports * mountproc_export_1();
extern exports * mountproc_export_1_svc();
-#define MOUNTPROC_EXPORTALL 6
+#define MOUNTPROC_EXPORTALL ((u_long)6)
extern exports * mountproc_exportall_1();
extern exports * mountproc_exportall_1_svc();
-extern int mountprog_1_freeresult ();
-#endif /* K&R C */
-
-/* the xdr functions */
-
-#if defined(__STDC__) || defined(__cplusplus)
-extern bool_t xdr_fhandle (XDR *, fhandle);
-extern bool_t xdr_fhstatus (XDR *, fhstatus*);
-extern bool_t xdr_dirpath (XDR *, dirpath*);
-extern bool_t xdr_name (XDR *, name*);
-extern bool_t xdr_mountlist (XDR *, mountlist*);
-extern bool_t xdr_mountbody (XDR *, mountbody*);
-extern bool_t xdr_groups (XDR *, groups*);
-extern bool_t xdr_groupnode (XDR *, groupnode*);
-extern bool_t xdr_exports (XDR *, exports*);
-extern bool_t xdr_exportnode (XDR *, exportnode*);
-
-#else /* K&R C */
-extern bool_t xdr_fhandle ();
-extern bool_t xdr_fhstatus ();
-extern bool_t xdr_dirpath ();
-extern bool_t xdr_name ();
-extern bool_t xdr_mountlist ();
-extern bool_t xdr_mountbody ();
-extern bool_t xdr_groups ();
-extern bool_t xdr_groupnode ();
-extern bool_t xdr_exports ();
-extern bool_t xdr_exportnode ();
-
-#endif /* K&R C */
-
-#ifdef __cplusplus
-}
-#endif
+#endif /* Old Style C */
#endif /* !_MOUNT_PROT_H_RPCGEN */
diff --git a/rtemsNfs/proto/mount_prot_xdr.c b/rtemsNfs/proto/mount_prot_xdr.c
index b83350b..7d605bb 100644
--- a/rtemsNfs/proto/mount_prot_xdr.c
+++ b/rtemsNfs/proto/mount_prot_xdr.c
@@ -6,119 +6,129 @@
#include "mount_prot.h"
bool_t
-xdr_fhandle (XDR *xdrs, fhandle objp)
+xdr_fhandle(xdrs, objp)
+ XDR *xdrs;
+ fhandle objp;
{
- register int32_t *buf;
- if (!xdr_opaque (xdrs, objp, FHSIZE))
- return FALSE;
- return TRUE;
+ if (!xdr_opaque(xdrs, objp, FHSIZE))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_fhstatus (XDR *xdrs, fhstatus *objp)
+xdr_fhstatus(xdrs, objp)
+ XDR *xdrs;
+ fhstatus *objp;
{
- register int32_t *buf;
- if (!xdr_u_int (xdrs, &objp->fhs_status))
- return FALSE;
+ if (!xdr_u_int(xdrs, &objp->fhs_status))
+ return (FALSE);
switch (objp->fhs_status) {
case 0:
- if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
- return FALSE;
+ if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_dirpath (XDR *xdrs, dirpath *objp)
+xdr_dirpath(xdrs, objp)
+ XDR *xdrs;
+ dirpath *objp;
{
- register int32_t *buf;
- if (!xdr_string (xdrs, objp, MNTPATHLEN))
- return FALSE;
- return TRUE;
+ if (!xdr_string(xdrs, objp, MNTPATHLEN))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_name (XDR *xdrs, name *objp)
+xdr_name(xdrs, objp)
+ XDR *xdrs;
+ name *objp;
{
- register int32_t *buf;
- if (!xdr_string (xdrs, objp, MNTNAMLEN))
- return FALSE;
- return TRUE;
+ if (!xdr_string(xdrs, objp, MNTNAMLEN))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_mountlist (XDR *xdrs, mountlist *objp)
+xdr_mountlist(xdrs, objp)
+ XDR *xdrs;
+ mountlist *objp;
{
- register int32_t *buf;
- if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
- return FALSE;
- return TRUE;
+ if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody), (xdrproc_t)xdr_mountbody))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_mountbody (XDR *xdrs, mountbody *objp)
+xdr_mountbody(xdrs, objp)
+ XDR *xdrs;
+ mountbody *objp;
{
- register int32_t *buf;
-
- if (!xdr_name (xdrs, &objp->ml_hostname))
- return FALSE;
- if (!xdr_dirpath (xdrs, &objp->ml_directory))
- return FALSE;
- if (!xdr_mountlist (xdrs, &objp->ml_next))
- return FALSE;
- return TRUE;
+
+ if (!xdr_name(xdrs, &objp->ml_hostname))
+ return (FALSE);
+ if (!xdr_dirpath(xdrs, &objp->ml_directory))
+ return (FALSE);
+ if (!xdr_mountlist(xdrs, &objp->ml_next))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_groups (XDR *xdrs, groups *objp)
+xdr_groups(xdrs, objp)
+ XDR *xdrs;
+ groups *objp;
{
- register int32_t *buf;
- if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
- return FALSE;
- return TRUE;
+ if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), (xdrproc_t)xdr_groupnode))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_groupnode (XDR *xdrs, groupnode *objp)
+xdr_groupnode(xdrs, objp)
+ XDR *xdrs;
+ groupnode *objp;
{
- register int32_t *buf;
- if (!xdr_name (xdrs, &objp->gr_name))
- return FALSE;
- if (!xdr_groups (xdrs, &objp->gr_next))
- return FALSE;
- return TRUE;
+ if (!xdr_name(xdrs, &objp->gr_name))
+ return (FALSE);
+ if (!xdr_groups(xdrs, &objp->gr_next))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_exports (XDR *xdrs, exports *objp)
+xdr_exports(xdrs, objp)
+ XDR *xdrs;
+ exports *objp;
{
- register int32_t *buf;
- if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
- return FALSE;
- return TRUE;
+ if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), (xdrproc_t)xdr_exportnode))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_exportnode (XDR *xdrs, exportnode *objp)
+xdr_exportnode(xdrs, objp)
+ XDR *xdrs;
+ exportnode *objp;
{
- register int32_t *buf;
-
- if (!xdr_dirpath (xdrs, &objp->ex_dir))
- return FALSE;
- if (!xdr_groups (xdrs, &objp->ex_groups))
- return FALSE;
- if (!xdr_exports (xdrs, &objp->ex_next))
- return FALSE;
- return TRUE;
+
+ if (!xdr_dirpath(xdrs, &objp->ex_dir))
+ return (FALSE);
+ if (!xdr_groups(xdrs, &objp->ex_groups))
+ return (FALSE);
+ if (!xdr_exports(xdrs, &objp->ex_next))
+ return (FALSE);
+ return (TRUE);
}
diff --git a/rtemsNfs/proto/nfs_prot.h b/rtemsNfs/proto/nfs_prot.h
index de812db..83a8c40 100644
--- a/rtemsNfs/proto/nfs_prot.h
+++ b/rtemsNfs/proto/nfs_prot.h
@@ -6,12 +6,9 @@
#ifndef _NFS_PROT_H_RPCGEN
#define _NFS_PROT_H_RPCGEN
-#include <rpc/rpc.h>
-
+#define RPCGEN_VERSION 199506
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <rpc/rpc.h>
#define NFS_PORT 2049
#define NFS_MAXDATA 8192
@@ -50,6 +47,14 @@ enum nfsstat {
NFSERR_WFLUSH = 99,
};
typedef enum nfsstat nfsstat;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nfsstat(XDR *, nfsstat*);
+#elif __STDC__
+extern bool_t xdr_nfsstat(XDR *, nfsstat*);
+#else /* Old Style C */
+bool_t xdr_nfsstat();
+#endif /* Old Style C */
+
enum ftype {
NFNON = 0,
@@ -63,17 +68,41 @@ enum ftype {
NFFIFO = 8,
};
typedef enum ftype ftype;
+#ifdef __cplusplus
+extern "C" bool_t xdr_ftype(XDR *, ftype*);
+#elif __STDC__
+extern bool_t xdr_ftype(XDR *, ftype*);
+#else /* Old Style C */
+bool_t xdr_ftype();
+#endif /* Old Style C */
+
struct nfs_fh {
char data[NFS_FHSIZE];
};
typedef struct nfs_fh nfs_fh;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nfs_fh(XDR *, nfs_fh*);
+#elif __STDC__
+extern bool_t xdr_nfs_fh(XDR *, nfs_fh*);
+#else /* Old Style C */
+bool_t xdr_nfs_fh();
+#endif /* Old Style C */
+
struct nfstime {
u_int seconds;
u_int useconds;
};
typedef struct nfstime nfstime;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nfstime(XDR *, nfstime*);
+#elif __STDC__
+extern bool_t xdr_nfstime(XDR *, nfstime*);
+#else /* Old Style C */
+bool_t xdr_nfstime();
+#endif /* Old Style C */
+
struct fattr {
ftype type;
@@ -92,6 +121,14 @@ struct fattr {
nfstime ctime;
};
typedef struct fattr fattr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_fattr(XDR *, fattr*);
+#elif __STDC__
+extern bool_t xdr_fattr(XDR *, fattr*);
+#else /* Old Style C */
+bool_t xdr_fattr();
+#endif /* Old Style C */
+
struct sattr {
u_int mode;
@@ -102,10 +139,34 @@ struct sattr {
nfstime mtime;
};
typedef struct sattr sattr;
+#ifdef __cplusplus
+extern "C" bool_t xdr_sattr(XDR *, sattr*);
+#elif __STDC__
+extern bool_t xdr_sattr(XDR *, sattr*);
+#else /* Old Style C */
+bool_t xdr_sattr();
+#endif /* Old Style C */
+
typedef char *filename;
+#ifdef __cplusplus
+extern "C" bool_t xdr_filename(XDR *, filename*);
+#elif __STDC__
+extern bool_t xdr_filename(XDR *, filename*);
+#else /* Old Style C */
+bool_t xdr_filename();
+#endif /* Old Style C */
+
typedef char *nfspath;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nfspath(XDR *, nfspath*);
+#elif __STDC__
+extern bool_t xdr_nfspath(XDR *, nfspath*);
+#else /* Old Style C */
+bool_t xdr_nfspath();
+#endif /* Old Style C */
+
struct attrstat {
nfsstat status;
@@ -114,24 +175,56 @@ struct attrstat {
} attrstat_u;
};
typedef struct attrstat attrstat;
+#ifdef __cplusplus
+extern "C" bool_t xdr_attrstat(XDR *, attrstat*);
+#elif __STDC__
+extern bool_t xdr_attrstat(XDR *, attrstat*);
+#else /* Old Style C */
+bool_t xdr_attrstat();
+#endif /* Old Style C */
+
struct sattrargs {
nfs_fh file;
sattr attributes;
};
typedef struct sattrargs sattrargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_sattrargs(XDR *, sattrargs*);
+#elif __STDC__
+extern bool_t xdr_sattrargs(XDR *, sattrargs*);
+#else /* Old Style C */
+bool_t xdr_sattrargs();
+#endif /* Old Style C */
+
struct diropargs {
nfs_fh dir;
filename name;
};
typedef struct diropargs diropargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_diropargs(XDR *, diropargs*);
+#elif __STDC__
+extern bool_t xdr_diropargs(XDR *, diropargs*);
+#else /* Old Style C */
+bool_t xdr_diropargs();
+#endif /* Old Style C */
+
struct diropokres {
nfs_fh file;
fattr attributes;
};
typedef struct diropokres diropokres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_diropokres(XDR *, diropokres*);
+#elif __STDC__
+extern bool_t xdr_diropokres(XDR *, diropokres*);
+#else /* Old Style C */
+bool_t xdr_diropokres();
+#endif /* Old Style C */
+
struct diropres {
nfsstat status;
@@ -140,6 +233,14 @@ struct diropres {
} diropres_u;
};
typedef struct diropres diropres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_diropres(XDR *, diropres*);
+#elif __STDC__
+extern bool_t xdr_diropres(XDR *, diropres*);
+#else /* Old Style C */
+bool_t xdr_diropres();
+#endif /* Old Style C */
+
struct readlinkres {
nfsstat status;
@@ -148,6 +249,14 @@ struct readlinkres {
} readlinkres_u;
};
typedef struct readlinkres readlinkres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_readlinkres(XDR *, readlinkres*);
+#elif __STDC__
+extern bool_t xdr_readlinkres(XDR *, readlinkres*);
+#else /* Old Style C */
+bool_t xdr_readlinkres();
+#endif /* Old Style C */
+
struct readargs {
nfs_fh file;
@@ -156,6 +265,14 @@ struct readargs {
u_int totalcount;
};
typedef struct readargs readargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_readargs(XDR *, readargs*);
+#elif __STDC__
+extern bool_t xdr_readargs(XDR *, readargs*);
+#else /* Old Style C */
+bool_t xdr_readargs();
+#endif /* Old Style C */
+
struct readokres {
fattr attributes;
@@ -165,6 +282,14 @@ struct readokres {
} data;
};
typedef struct readokres readokres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_readokres(XDR *, readokres*);
+#elif __STDC__
+extern bool_t xdr_readokres(XDR *, readokres*);
+#else /* Old Style C */
+bool_t xdr_readokres();
+#endif /* Old Style C */
+
struct readres {
nfsstat status;
@@ -173,6 +298,14 @@ struct readres {
} readres_u;
};
typedef struct readres readres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_readres(XDR *, readres*);
+#elif __STDC__
+extern bool_t xdr_readres(XDR *, readres*);
+#else /* Old Style C */
+bool_t xdr_readres();
+#endif /* Old Style C */
+
struct writeargs {
nfs_fh file;
@@ -185,24 +318,56 @@ struct writeargs {
} data;
};
typedef struct writeargs writeargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_writeargs(XDR *, writeargs*);
+#elif __STDC__
+extern bool_t xdr_writeargs(XDR *, writeargs*);
+#else /* Old Style C */
+bool_t xdr_writeargs();
+#endif /* Old Style C */
+
struct createargs {
diropargs where;
sattr attributes;
};
typedef struct createargs createargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_createargs(XDR *, createargs*);
+#elif __STDC__
+extern bool_t xdr_createargs(XDR *, createargs*);
+#else /* Old Style C */
+bool_t xdr_createargs();
+#endif /* Old Style C */
+
struct renameargs {
diropargs from;
diropargs to;
};
typedef struct renameargs renameargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_renameargs(XDR *, renameargs*);
+#elif __STDC__
+extern bool_t xdr_renameargs(XDR *, renameargs*);
+#else /* Old Style C */
+bool_t xdr_renameargs();
+#endif /* Old Style C */
+
struct linkargs {
nfs_fh from;
diropargs to;
};
typedef struct linkargs linkargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_linkargs(XDR *, linkargs*);
+#elif __STDC__
+extern bool_t xdr_linkargs(XDR *, linkargs*);
+#else /* Old Style C */
+bool_t xdr_linkargs();
+#endif /* Old Style C */
+
struct symlinkargs {
diropargs from;
@@ -210,11 +375,27 @@ struct symlinkargs {
sattr attributes;
};
typedef struct symlinkargs symlinkargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_symlinkargs(XDR *, symlinkargs*);
+#elif __STDC__
+extern bool_t xdr_symlinkargs(XDR *, symlinkargs*);
+#else /* Old Style C */
+bool_t xdr_symlinkargs();
+#endif /* Old Style C */
+
struct nfscookie {
char data[NFS_COOKIESIZE];
};
typedef struct nfscookie nfscookie;
+#ifdef __cplusplus
+extern "C" bool_t xdr_nfscookie(XDR *, nfscookie*);
+#elif __STDC__
+extern bool_t xdr_nfscookie(XDR *, nfscookie*);
+#else /* Old Style C */
+bool_t xdr_nfscookie();
+#endif /* Old Style C */
+
struct readdirargs {
nfs_fh dir;
@@ -222,6 +403,14 @@ struct readdirargs {
u_int count;
};
typedef struct readdirargs readdirargs;
+#ifdef __cplusplus
+extern "C" bool_t xdr_readdirargs(XDR *, readdirargs*);
+#elif __STDC__
+extern bool_t xdr_readdirargs(XDR *, readdirargs*);
+#else /* Old Style C */
+bool_t xdr_readdirargs();
+#endif /* Old Style C */
+
struct entry {
u_int fileid;
@@ -230,12 +419,28 @@ struct entry {
struct entry *nextentry;
};
typedef struct entry entry;
+#ifdef __cplusplus
+extern "C" bool_t xdr_entry(XDR *, entry*);
+#elif __STDC__
+extern bool_t xdr_entry(XDR *, entry*);
+#else /* Old Style C */
+bool_t xdr_entry();
+#endif /* Old Style C */
+
struct dirlist {
entry *entries;
bool_t eof;
};
typedef struct dirlist dirlist;
+#ifdef __cplusplus
+extern "C" bool_t xdr_dirlist(XDR *, dirlist*);
+#elif __STDC__
+extern bool_t xdr_dirlist(XDR *, dirlist*);
+#else /* Old Style C */
+bool_t xdr_dirlist();
+#endif /* Old Style C */
+
struct readdirres {
nfsstat status;
@@ -244,6 +449,14 @@ struct readdirres {
} readdirres_u;
};
typedef struct readdirres readdirres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_readdirres(XDR *, readdirres*);
+#elif __STDC__
+extern bool_t xdr_readdirres(XDR *, readdirres*);
+#else /* Old Style C */
+bool_t xdr_readdirres();
+#endif /* Old Style C */
+
struct statfsokres {
u_int tsize;
@@ -253,6 +466,14 @@ struct statfsokres {
u_int bavail;
};
typedef struct statfsokres statfsokres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_statfsokres(XDR *, statfsokres*);
+#elif __STDC__
+extern bool_t xdr_statfsokres(XDR *, statfsokres*);
+#else /* Old Style C */
+bool_t xdr_statfsokres();
+#endif /* Old Style C */
+
struct statfsres {
nfsstat status;
@@ -261,193 +482,185 @@ struct statfsres {
} statfsres_u;
};
typedef struct statfsres statfsres;
+#ifdef __cplusplus
+extern "C" bool_t xdr_statfsres(XDR *, statfsres*);
+#elif __STDC__
+extern bool_t xdr_statfsres(XDR *, statfsres*);
+#else /* Old Style C */
+bool_t xdr_statfsres();
+#endif /* Old Style C */
-#define NFS_PROGRAM 100003
-#define NFS_VERSION 2
-#if defined(__STDC__) || defined(__cplusplus)
-#define NFSPROC_NULL 0
+#define NFS_PROGRAM ((u_long)100003)
+#define NFS_VERSION ((u_long)2)
+
+#ifdef __cplusplus
+#define NFSPROC_NULL ((u_long)0)
+extern "C" void * nfsproc_null_2(void *, CLIENT *);
+extern "C" void * nfsproc_null_2_svc(void *, struct svc_req *);
+#define NFSPROC_GETATTR ((u_long)1)
+extern "C" attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *);
+extern "C" attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *);
+#define NFSPROC_SETATTR ((u_long)2)
+extern "C" attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *);
+extern "C" attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *);
+#define NFSPROC_ROOT ((u_long)3)
+extern "C" void * nfsproc_root_2(void *, CLIENT *);
+extern "C" void * nfsproc_root_2_svc(void *, struct svc_req *);
+#define NFSPROC_LOOKUP ((u_long)4)
+extern "C" diropres * nfsproc_lookup_2(diropargs *, CLIENT *);
+extern "C" diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *);
+#define NFSPROC_READLINK ((u_long)5)
+extern "C" readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *);
+extern "C" readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *);
+#define NFSPROC_READ ((u_long)6)
+extern "C" readres * nfsproc_read_2(readargs *, CLIENT *);
+extern "C" readres * nfsproc_read_2_svc(readargs *, struct svc_req *);
+#define NFSPROC_WRITECACHE ((u_long)7)
+extern "C" void * nfsproc_writecache_2(void *, CLIENT *);
+extern "C" void * nfsproc_writecache_2_svc(void *, struct svc_req *);
+#define NFSPROC_WRITE ((u_long)8)
+extern "C" attrstat * nfsproc_write_2(writeargs *, CLIENT *);
+extern "C" attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *);
+#define NFSPROC_CREATE ((u_long)9)
+extern "C" diropres * nfsproc_create_2(createargs *, CLIENT *);
+extern "C" diropres * nfsproc_create_2_svc(createargs *, struct svc_req *);
+#define NFSPROC_REMOVE ((u_long)10)
+extern "C" nfsstat * nfsproc_remove_2(diropargs *, CLIENT *);
+extern "C" nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *);
+#define NFSPROC_RENAME ((u_long)11)
+extern "C" nfsstat * nfsproc_rename_2(renameargs *, CLIENT *);
+extern "C" nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *);
+#define NFSPROC_LINK ((u_long)12)
+extern "C" nfsstat * nfsproc_link_2(linkargs *, CLIENT *);
+extern "C" nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *);
+#define NFSPROC_SYMLINK ((u_long)13)
+extern "C" nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *);
+extern "C" nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *);
+#define NFSPROC_MKDIR ((u_long)14)
+extern "C" diropres * nfsproc_mkdir_2(createargs *, CLIENT *);
+extern "C" diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *);
+#define NFSPROC_RMDIR ((u_long)15)
+extern "C" nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *);
+extern "C" nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *);
+#define NFSPROC_READDIR ((u_long)16)
+extern "C" readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *);
+extern "C" readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *);
+#define NFSPROC_STATFS ((u_long)17)
+extern "C" statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *);
+extern "C" statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *);
+
+#elif __STDC__
+#define NFSPROC_NULL ((u_long)0)
extern void * nfsproc_null_2(void *, CLIENT *);
extern void * nfsproc_null_2_svc(void *, struct svc_req *);
-#define NFSPROC_GETATTR 1
+#define NFSPROC_GETATTR ((u_long)1)
extern attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *);
extern attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *);
-#define NFSPROC_SETATTR 2
+#define NFSPROC_SETATTR ((u_long)2)
extern attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *);
extern attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *);
-#define NFSPROC_ROOT 3
+#define NFSPROC_ROOT ((u_long)3)
extern void * nfsproc_root_2(void *, CLIENT *);
extern void * nfsproc_root_2_svc(void *, struct svc_req *);
-#define NFSPROC_LOOKUP 4
+#define NFSPROC_LOOKUP ((u_long)4)
extern diropres * nfsproc_lookup_2(diropargs *, CLIENT *);
extern diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_READLINK 5
+#define NFSPROC_READLINK ((u_long)5)
extern readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *);
extern readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *);
-#define NFSPROC_READ 6
+#define NFSPROC_READ ((u_long)6)
extern readres * nfsproc_read_2(readargs *, CLIENT *);
extern readres * nfsproc_read_2_svc(readargs *, struct svc_req *);
-#define NFSPROC_WRITECACHE 7
+#define NFSPROC_WRITECACHE ((u_long)7)
extern void * nfsproc_writecache_2(void *, CLIENT *);
extern void * nfsproc_writecache_2_svc(void *, struct svc_req *);
-#define NFSPROC_WRITE 8
+#define NFSPROC_WRITE ((u_long)8)
extern attrstat * nfsproc_write_2(writeargs *, CLIENT *);
extern attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *);
-#define NFSPROC_CREATE 9
+#define NFSPROC_CREATE ((u_long)9)
extern diropres * nfsproc_create_2(createargs *, CLIENT *);
extern diropres * nfsproc_create_2_svc(createargs *, struct svc_req *);
-#define NFSPROC_REMOVE 10
+#define NFSPROC_REMOVE ((u_long)10)
extern nfsstat * nfsproc_remove_2(diropargs *, CLIENT *);
extern nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_RENAME 11
+#define NFSPROC_RENAME ((u_long)11)
extern nfsstat * nfsproc_rename_2(renameargs *, CLIENT *);
extern nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *);
-#define NFSPROC_LINK 12
+#define NFSPROC_LINK ((u_long)12)
extern nfsstat * nfsproc_link_2(linkargs *, CLIENT *);
extern nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *);
-#define NFSPROC_SYMLINK 13
+#define NFSPROC_SYMLINK ((u_long)13)
extern nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *);
extern nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *);
-#define NFSPROC_MKDIR 14
+#define NFSPROC_MKDIR ((u_long)14)
extern diropres * nfsproc_mkdir_2(createargs *, CLIENT *);
extern diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *);
-#define NFSPROC_RMDIR 15
+#define NFSPROC_RMDIR ((u_long)15)
extern nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *);
extern nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_READDIR 16
+#define NFSPROC_READDIR ((u_long)16)
extern readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *);
extern readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *);
-#define NFSPROC_STATFS 17
+#define NFSPROC_STATFS ((u_long)17)
extern statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *);
extern statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *);
-extern int nfs_program_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
-#else /* K&R C */
-#define NFSPROC_NULL 0
+#else /* Old Style C */
+#define NFSPROC_NULL ((u_long)0)
extern void * nfsproc_null_2();
extern void * nfsproc_null_2_svc();
-#define NFSPROC_GETATTR 1
+#define NFSPROC_GETATTR ((u_long)1)
extern attrstat * nfsproc_getattr_2();
extern attrstat * nfsproc_getattr_2_svc();
-#define NFSPROC_SETATTR 2
+#define NFSPROC_SETATTR ((u_long)2)
extern attrstat * nfsproc_setattr_2();
extern attrstat * nfsproc_setattr_2_svc();
-#define NFSPROC_ROOT 3
+#define NFSPROC_ROOT ((u_long)3)
extern void * nfsproc_root_2();
extern void * nfsproc_root_2_svc();
-#define NFSPROC_LOOKUP 4
+#define NFSPROC_LOOKUP ((u_long)4)
extern diropres * nfsproc_lookup_2();
extern diropres * nfsproc_lookup_2_svc();
-#define NFSPROC_READLINK 5
+#define NFSPROC_READLINK ((u_long)5)
extern readlinkres * nfsproc_readlink_2();
extern readlinkres * nfsproc_readlink_2_svc();
-#define NFSPROC_READ 6
+#define NFSPROC_READ ((u_long)6)
extern readres * nfsproc_read_2();
extern readres * nfsproc_read_2_svc();
-#define NFSPROC_WRITECACHE 7
+#define NFSPROC_WRITECACHE ((u_long)7)
extern void * nfsproc_writecache_2();
extern void * nfsproc_writecache_2_svc();
-#define NFSPROC_WRITE 8
+#define NFSPROC_WRITE ((u_long)8)
extern attrstat * nfsproc_write_2();
extern attrstat * nfsproc_write_2_svc();
-#define NFSPROC_CREATE 9
+#define NFSPROC_CREATE ((u_long)9)
extern diropres * nfsproc_create_2();
extern diropres * nfsproc_create_2_svc();
-#define NFSPROC_REMOVE 10
+#define NFSPROC_REMOVE ((u_long)10)
extern nfsstat * nfsproc_remove_2();
extern nfsstat * nfsproc_remove_2_svc();
-#define NFSPROC_RENAME 11
+#define NFSPROC_RENAME ((u_long)11)
extern nfsstat * nfsproc_rename_2();
extern nfsstat * nfsproc_rename_2_svc();
-#define NFSPROC_LINK 12
+#define NFSPROC_LINK ((u_long)12)
extern nfsstat * nfsproc_link_2();
extern nfsstat * nfsproc_link_2_svc();
-#define NFSPROC_SYMLINK 13
+#define NFSPROC_SYMLINK ((u_long)13)
extern nfsstat * nfsproc_symlink_2();
extern nfsstat * nfsproc_symlink_2_svc();
-#define NFSPROC_MKDIR 14
+#define NFSPROC_MKDIR ((u_long)14)
extern diropres * nfsproc_mkdir_2();
extern diropres * nfsproc_mkdir_2_svc();
-#define NFSPROC_RMDIR 15
+#define NFSPROC_RMDIR ((u_long)15)
extern nfsstat * nfsproc_rmdir_2();
extern nfsstat * nfsproc_rmdir_2_svc();
-#define NFSPROC_READDIR 16
+#define NFSPROC_READDIR ((u_long)16)
extern readdirres * nfsproc_readdir_2();
extern readdirres * nfsproc_readdir_2_svc();
-#define NFSPROC_STATFS 17
+#define NFSPROC_STATFS ((u_long)17)
extern statfsres * nfsproc_statfs_2();
extern statfsres * nfsproc_statfs_2_svc();
-extern int nfs_program_2_freeresult ();
-#endif /* K&R C */
-
-/* the xdr functions */
-
-#if defined(__STDC__) || defined(__cplusplus)
-extern bool_t xdr_nfsstat (XDR *, nfsstat*);
-extern bool_t xdr_ftype (XDR *, ftype*);
-extern bool_t xdr_nfs_fh (XDR *, nfs_fh*);
-extern bool_t xdr_nfstime (XDR *, nfstime*);
-extern bool_t xdr_fattr (XDR *, fattr*);
-extern bool_t xdr_sattr (XDR *, sattr*);
-extern bool_t xdr_filename (XDR *, filename*);
-extern bool_t xdr_nfspath (XDR *, nfspath*);
-extern bool_t xdr_attrstat (XDR *, attrstat*);
-extern bool_t xdr_sattrargs (XDR *, sattrargs*);
-extern bool_t xdr_diropargs (XDR *, diropargs*);
-extern bool_t xdr_diropokres (XDR *, diropokres*);
-extern bool_t xdr_diropres (XDR *, diropres*);
-extern bool_t xdr_readlinkres (XDR *, readlinkres*);
-extern bool_t xdr_readargs (XDR *, readargs*);
-extern bool_t xdr_readokres (XDR *, readokres*);
-extern bool_t xdr_readres (XDR *, readres*);
-extern bool_t xdr_writeargs (XDR *, writeargs*);
-extern bool_t xdr_createargs (XDR *, createargs*);
-extern bool_t xdr_renameargs (XDR *, renameargs*);
-extern bool_t xdr_linkargs (XDR *, linkargs*);
-extern bool_t xdr_symlinkargs (XDR *, symlinkargs*);
-extern bool_t xdr_nfscookie (XDR *, nfscookie*);
-extern bool_t xdr_readdirargs (XDR *, readdirargs*);
-extern bool_t xdr_entry (XDR *, entry*);
-extern bool_t xdr_dirlist (XDR *, dirlist*);
-extern bool_t xdr_readdirres (XDR *, readdirres*);
-extern bool_t xdr_statfsokres (XDR *, statfsokres*);
-extern bool_t xdr_statfsres (XDR *, statfsres*);
-
-#else /* K&R C */
-extern bool_t xdr_nfsstat ();
-extern bool_t xdr_ftype ();
-extern bool_t xdr_nfs_fh ();
-extern bool_t xdr_nfstime ();
-extern bool_t xdr_fattr ();
-extern bool_t xdr_sattr ();
-extern bool_t xdr_filename ();
-extern bool_t xdr_nfspath ();
-extern bool_t xdr_attrstat ();
-extern bool_t xdr_sattrargs ();
-extern bool_t xdr_diropargs ();
-extern bool_t xdr_diropokres ();
-extern bool_t xdr_diropres ();
-extern bool_t xdr_readlinkres ();
-extern bool_t xdr_readargs ();
-extern bool_t xdr_readokres ();
-extern bool_t xdr_readres ();
-extern bool_t xdr_writeargs ();
-extern bool_t xdr_createargs ();
-extern bool_t xdr_renameargs ();
-extern bool_t xdr_linkargs ();
-extern bool_t xdr_symlinkargs ();
-extern bool_t xdr_nfscookie ();
-extern bool_t xdr_readdirargs ();
-extern bool_t xdr_entry ();
-extern bool_t xdr_dirlist ();
-extern bool_t xdr_readdirres ();
-extern bool_t xdr_statfsokres ();
-extern bool_t xdr_statfsres ();
-
-#endif /* K&R C */
-
-#ifdef __cplusplus
-}
-#endif
+#endif /* Old Style C */
#endif /* !_NFS_PROT_H_RPCGEN */
diff --git a/rtemsNfs/proto/nfs_prot_xdr.c b/rtemsNfs/proto/nfs_prot_xdr.c
index 7e222ec..97246a5 100644
--- a/rtemsNfs/proto/nfs_prot_xdr.c
+++ b/rtemsNfs/proto/nfs_prot_xdr.c
@@ -11,603 +11,617 @@ static char rcsid[] = "$Id$";
#endif /* not lint */
bool_t
-xdr_nfsstat (XDR *xdrs, nfsstat *objp)
+xdr_nfsstat(xdrs, objp)
+ XDR *xdrs;
+ nfsstat *objp;
{
- register int32_t *buf;
- if (!xdr_enum (xdrs, (enum_t *) objp))
- return FALSE;
- return TRUE;
+ if (!xdr_enum(xdrs, (enum_t *)objp))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_ftype (XDR *xdrs, ftype *objp)
+xdr_ftype(xdrs, objp)
+ XDR *xdrs;
+ ftype *objp;
{
- register int32_t *buf;
- if (!xdr_enum (xdrs, (enum_t *) objp))
- return FALSE;
- return TRUE;
+ if (!xdr_enum(xdrs, (enum_t *)objp))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_nfs_fh (XDR *xdrs, nfs_fh *objp)
+xdr_nfs_fh(xdrs, objp)
+ XDR *xdrs;
+ nfs_fh *objp;
{
- register int32_t *buf;
- int i;
- if (!xdr_opaque (xdrs, objp->data, NFS_FHSIZE))
- return FALSE;
- return TRUE;
+ if (!xdr_opaque(xdrs, objp->data, NFS_FHSIZE))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_nfstime (XDR *xdrs, nfstime *objp)
+xdr_nfstime(xdrs, objp)
+ XDR *xdrs;
+ nfstime *objp;
{
- register int32_t *buf;
- if (!xdr_u_int (xdrs, &objp->seconds))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->useconds))
- return FALSE;
- return TRUE;
+ if (!xdr_u_int(xdrs, &objp->seconds))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->useconds))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_fattr (XDR *xdrs, fattr *objp)
+xdr_fattr(xdrs, objp)
+ XDR *xdrs;
+ fattr *objp;
{
- register int32_t *buf;
-
+ int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
- if (!xdr_ftype (xdrs, &objp->type))
- return FALSE;
- buf = XDR_INLINE (xdrs, 10 * BYTES_PER_XDR_UNIT);
+ if (!xdr_ftype(xdrs, &objp->type))
+ return (FALSE);
+ buf = (int32_t *)XDR_INLINE(xdrs, 10 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->mode))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->nlink))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->size))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocksize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->rdev))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocks))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->fsid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->fileid))
- return FALSE;
-
+ if (!xdr_u_int(xdrs, &objp->mode))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->nlink))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->size))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocksize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->rdev))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocks))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->fsid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->fileid))
+ return (FALSE);
} else {
- IXDR_PUT_U_LONG(buf, objp->mode);
- IXDR_PUT_U_LONG(buf, objp->nlink);
- IXDR_PUT_U_LONG(buf, objp->uid);
- IXDR_PUT_U_LONG(buf, objp->gid);
- IXDR_PUT_U_LONG(buf, objp->size);
- IXDR_PUT_U_LONG(buf, objp->blocksize);
- IXDR_PUT_U_LONG(buf, objp->rdev);
- IXDR_PUT_U_LONG(buf, objp->blocks);
- IXDR_PUT_U_LONG(buf, objp->fsid);
- IXDR_PUT_U_LONG(buf, objp->fileid);
+ IXDR_PUT_U_LONG(buf, objp->mode);
+ IXDR_PUT_U_LONG(buf, objp->nlink);
+ IXDR_PUT_U_LONG(buf, objp->uid);
+ IXDR_PUT_U_LONG(buf, objp->gid);
+ IXDR_PUT_U_LONG(buf, objp->size);
+ IXDR_PUT_U_LONG(buf, objp->blocksize);
+ IXDR_PUT_U_LONG(buf, objp->rdev);
+ IXDR_PUT_U_LONG(buf, objp->blocks);
+ IXDR_PUT_U_LONG(buf, objp->fsid);
+ IXDR_PUT_U_LONG(buf, objp->fileid);
}
- if (!xdr_nfstime (xdrs, &objp->atime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->mtime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->ctime))
- return FALSE;
- return TRUE;
+ if (!xdr_nfstime(xdrs, &objp->atime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->mtime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->ctime))
+ return (FALSE);
} else if (xdrs->x_op == XDR_DECODE) {
- if (!xdr_ftype (xdrs, &objp->type))
- return FALSE;
- buf = XDR_INLINE (xdrs, 10 * BYTES_PER_XDR_UNIT);
+ if (!xdr_ftype(xdrs, &objp->type))
+ return (FALSE);
+ buf = (int32_t *)XDR_INLINE(xdrs, 10 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->mode))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->nlink))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->size))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocksize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->rdev))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocks))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->fsid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->fileid))
- return FALSE;
-
+ if (!xdr_u_int(xdrs, &objp->mode))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->nlink))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->size))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocksize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->rdev))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocks))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->fsid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->fileid))
+ return (FALSE);
} else {
- objp->mode = IXDR_GET_U_LONG(buf);
- objp->nlink = IXDR_GET_U_LONG(buf);
- objp->uid = IXDR_GET_U_LONG(buf);
- objp->gid = IXDR_GET_U_LONG(buf);
- objp->size = IXDR_GET_U_LONG(buf);
- objp->blocksize = IXDR_GET_U_LONG(buf);
- objp->rdev = IXDR_GET_U_LONG(buf);
- objp->blocks = IXDR_GET_U_LONG(buf);
- objp->fsid = IXDR_GET_U_LONG(buf);
- objp->fileid = IXDR_GET_U_LONG(buf);
+ objp->mode = IXDR_GET_U_LONG(buf);
+ objp->nlink = IXDR_GET_U_LONG(buf);
+ objp->uid = IXDR_GET_U_LONG(buf);
+ objp->gid = IXDR_GET_U_LONG(buf);
+ objp->size = IXDR_GET_U_LONG(buf);
+ objp->blocksize = IXDR_GET_U_LONG(buf);
+ objp->rdev = IXDR_GET_U_LONG(buf);
+ objp->blocks = IXDR_GET_U_LONG(buf);
+ objp->fsid = IXDR_GET_U_LONG(buf);
+ objp->fileid = IXDR_GET_U_LONG(buf);
}
- if (!xdr_nfstime (xdrs, &objp->atime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->mtime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->ctime))
- return FALSE;
- return TRUE;
+ if (!xdr_nfstime(xdrs, &objp->atime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->mtime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->ctime))
+ return (FALSE);
+ } else {
+ if (!xdr_ftype(xdrs, &objp->type))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->mode))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->nlink))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->size))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocksize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->rdev))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocks))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->fsid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->fileid))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->atime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->mtime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->ctime))
+ return (FALSE);
}
-
- if (!xdr_ftype (xdrs, &objp->type))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->mode))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->nlink))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->size))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocksize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->rdev))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocks))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->fsid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->fileid))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->atime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->mtime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->ctime))
- return FALSE;
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_sattr (XDR *xdrs, sattr *objp)
+xdr_sattr(xdrs, objp)
+ XDR *xdrs;
+ sattr *objp;
{
- register int32_t *buf;
-
+ int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ buf = (int32_t *)XDR_INLINE(xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->mode))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->size))
- return FALSE;
-
+ if (!xdr_u_int(xdrs, &objp->mode))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->size))
+ return (FALSE);
} else {
- IXDR_PUT_U_LONG(buf, objp->mode);
- IXDR_PUT_U_LONG(buf, objp->uid);
- IXDR_PUT_U_LONG(buf, objp->gid);
- IXDR_PUT_U_LONG(buf, objp->size);
+ IXDR_PUT_U_LONG(buf, objp->mode);
+ IXDR_PUT_U_LONG(buf, objp->uid);
+ IXDR_PUT_U_LONG(buf, objp->gid);
+ IXDR_PUT_U_LONG(buf, objp->size);
}
- if (!xdr_nfstime (xdrs, &objp->atime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->mtime))
- return FALSE;
- return TRUE;
+ if (!xdr_nfstime(xdrs, &objp->atime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->mtime))
+ return (FALSE);
} else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ buf = (int32_t *)XDR_INLINE(xdrs, 4 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->mode))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->size))
- return FALSE;
-
+ if (!xdr_u_int(xdrs, &objp->mode))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->size))
+ return (FALSE);
} else {
- objp->mode = IXDR_GET_U_LONG(buf);
- objp->uid = IXDR_GET_U_LONG(buf);
- objp->gid = IXDR_GET_U_LONG(buf);
- objp->size = IXDR_GET_U_LONG(buf);
+ objp->mode = IXDR_GET_U_LONG(buf);
+ objp->uid = IXDR_GET_U_LONG(buf);
+ objp->gid = IXDR_GET_U_LONG(buf);
+ objp->size = IXDR_GET_U_LONG(buf);
}
- if (!xdr_nfstime (xdrs, &objp->atime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->mtime))
- return FALSE;
- return TRUE;
+ if (!xdr_nfstime(xdrs, &objp->atime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->mtime))
+ return (FALSE);
+ } else {
+ if (!xdr_u_int(xdrs, &objp->mode))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->uid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->gid))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->size))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->atime))
+ return (FALSE);
+ if (!xdr_nfstime(xdrs, &objp->mtime))
+ return (FALSE);
}
-
- if (!xdr_u_int (xdrs, &objp->mode))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->uid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->gid))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->size))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->atime))
- return FALSE;
- if (!xdr_nfstime (xdrs, &objp->mtime))
- return FALSE;
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_filename (XDR *xdrs, filename *objp)
+xdr_filename(xdrs, objp)
+ XDR *xdrs;
+ filename *objp;
{
- register int32_t *buf;
- if (!xdr_string (xdrs, objp, NFS_MAXNAMLEN))
- return FALSE;
- return TRUE;
+ if (!xdr_string(xdrs, objp, NFS_MAXNAMLEN))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_nfspath (XDR *xdrs, nfspath *objp)
+xdr_nfspath(xdrs, objp)
+ XDR *xdrs;
+ nfspath *objp;
{
- register int32_t *buf;
- if (!xdr_string (xdrs, objp, NFS_MAXPATHLEN))
- return FALSE;
- return TRUE;
+ if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_attrstat (XDR *xdrs, attrstat *objp)
+xdr_attrstat(xdrs, objp)
+ XDR *xdrs;
+ attrstat *objp;
{
- register int32_t *buf;
- if (!xdr_nfsstat (xdrs, &objp->status))
- return FALSE;
+ if (!xdr_nfsstat(xdrs, &objp->status))
+ return (FALSE);
switch (objp->status) {
case NFS_OK:
- if (!xdr_fattr (xdrs, &objp->attrstat_u.attributes))
- return FALSE;
+ if (!xdr_fattr(xdrs, &objp->attrstat_u.attributes))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_sattrargs (XDR *xdrs, sattrargs *objp)
+xdr_sattrargs(xdrs, objp)
+ XDR *xdrs;
+ sattrargs *objp;
{
- register int32_t *buf;
- if (!xdr_nfs_fh (xdrs, &objp->file))
- return FALSE;
- if (!xdr_sattr (xdrs, &objp->attributes))
- return FALSE;
- return TRUE;
+ if (!xdr_nfs_fh(xdrs, &objp->file))
+ return (FALSE);
+ if (!xdr_sattr(xdrs, &objp->attributes))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_diropargs (XDR *xdrs, diropargs *objp)
+xdr_diropargs(xdrs, objp)
+ XDR *xdrs;
+ diropargs *objp;
{
- register int32_t *buf;
- if (!xdr_nfs_fh (xdrs, &objp->dir))
- return FALSE;
- if (!xdr_filename (xdrs, &objp->name))
- return FALSE;
- return TRUE;
+ if (!xdr_nfs_fh(xdrs, &objp->dir))
+ return (FALSE);
+ if (!xdr_filename(xdrs, &objp->name))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_diropokres (XDR *xdrs, diropokres *objp)
+xdr_diropokres(xdrs, objp)
+ XDR *xdrs;
+ diropokres *objp;
{
- register int32_t *buf;
- if (!xdr_nfs_fh (xdrs, &objp->file))
- return FALSE;
- if (!xdr_fattr (xdrs, &objp->attributes))
- return FALSE;
- return TRUE;
+ if (!xdr_nfs_fh(xdrs, &objp->file))
+ return (FALSE);
+ if (!xdr_fattr(xdrs, &objp->attributes))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_diropres (XDR *xdrs, diropres *objp)
+xdr_diropres(xdrs, objp)
+ XDR *xdrs;
+ diropres *objp;
{
- register int32_t *buf;
- if (!xdr_nfsstat (xdrs, &objp->status))
- return FALSE;
+ if (!xdr_nfsstat(xdrs, &objp->status))
+ return (FALSE);
switch (objp->status) {
case NFS_OK:
- if (!xdr_diropokres (xdrs, &objp->diropres_u.diropres))
- return FALSE;
+ if (!xdr_diropokres(xdrs, &objp->diropres_u.diropres))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_readlinkres (XDR *xdrs, readlinkres *objp)
+xdr_readlinkres(xdrs, objp)
+ XDR *xdrs;
+ readlinkres *objp;
{
- register int32_t *buf;
- if (!xdr_nfsstat (xdrs, &objp->status))
- return FALSE;
+ if (!xdr_nfsstat(xdrs, &objp->status))
+ return (FALSE);
switch (objp->status) {
case NFS_OK:
- if (!xdr_nfspath (xdrs, &objp->readlinkres_u.data))
- return FALSE;
+ if (!xdr_nfspath(xdrs, &objp->readlinkres_u.data))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_readargs (XDR *xdrs, readargs *objp)
+xdr_readargs(xdrs, objp)
+ XDR *xdrs;
+ readargs *objp;
{
- register int32_t *buf;
-
- if (!xdr_nfs_fh (xdrs, &objp->file))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->offset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->count))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->totalcount))
- return FALSE;
- return TRUE;
+
+ if (!xdr_nfs_fh(xdrs, &objp->file))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->offset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->count))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->totalcount))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_readokres (XDR *xdrs, readokres *objp)
+xdr_readokres(xdrs, objp)
+ XDR *xdrs;
+ readokres *objp;
{
- register int32_t *buf;
- if (!xdr_fattr (xdrs, &objp->attributes))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
- return FALSE;
- return TRUE;
+ if (!xdr_fattr(xdrs, &objp->attributes))
+ return (FALSE);
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_readres (XDR *xdrs, readres *objp)
+xdr_readres(xdrs, objp)
+ XDR *xdrs;
+ readres *objp;
{
- register int32_t *buf;
- if (!xdr_nfsstat (xdrs, &objp->status))
- return FALSE;
+ if (!xdr_nfsstat(xdrs, &objp->status))
+ return (FALSE);
switch (objp->status) {
case NFS_OK:
- if (!xdr_readokres (xdrs, &objp->readres_u.reply))
- return FALSE;
+ if (!xdr_readokres(xdrs, &objp->readres_u.reply))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_writeargs (XDR *xdrs, writeargs *objp)
+xdr_writeargs(xdrs, objp)
+ XDR *xdrs;
+ writeargs *objp;
{
- register int32_t *buf;
-
+ int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
- if (!xdr_nfs_fh (xdrs, &objp->file))
- return FALSE;
- buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (!xdr_nfs_fh(xdrs, &objp->file))
+ return (FALSE);
+ buf = (int32_t *)XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->beginoffset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->offset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->totalcount))
- return FALSE;
-
+ if (!xdr_u_int(xdrs, &objp->beginoffset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->offset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->totalcount))
+ return (FALSE);
} else {
- IXDR_PUT_U_LONG(buf, objp->beginoffset);
- IXDR_PUT_U_LONG(buf, objp->offset);
- IXDR_PUT_U_LONG(buf, objp->totalcount);
+ IXDR_PUT_U_LONG(buf, objp->beginoffset);
+ IXDR_PUT_U_LONG(buf, objp->offset);
+ IXDR_PUT_U_LONG(buf, objp->totalcount);
}
- if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
- return FALSE;
- return TRUE;
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA))
+ return (FALSE);
} else if (xdrs->x_op == XDR_DECODE) {
- if (!xdr_nfs_fh (xdrs, &objp->file))
- return FALSE;
- buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (!xdr_nfs_fh(xdrs, &objp->file))
+ return (FALSE);
+ buf = (int32_t *)XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->beginoffset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->offset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->totalcount))
- return FALSE;
-
+ if (!xdr_u_int(xdrs, &objp->beginoffset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->offset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->totalcount))
+ return (FALSE);
} else {
- objp->beginoffset = IXDR_GET_U_LONG(buf);
- objp->offset = IXDR_GET_U_LONG(buf);
- objp->totalcount = IXDR_GET_U_LONG(buf);
+ objp->beginoffset = IXDR_GET_U_LONG(buf);
+ objp->offset = IXDR_GET_U_LONG(buf);
+ objp->totalcount = IXDR_GET_U_LONG(buf);
}
- if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
- return FALSE;
- return TRUE;
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA))
+ return (FALSE);
+ } else {
+ if (!xdr_nfs_fh(xdrs, &objp->file))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->beginoffset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->offset))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->totalcount))
+ return (FALSE);
+ if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA))
+ return (FALSE);
}
-
- if (!xdr_nfs_fh (xdrs, &objp->file))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->beginoffset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->offset))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->totalcount))
- return FALSE;
- if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
- return FALSE;
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_createargs (XDR *xdrs, createargs *objp)
+xdr_createargs(xdrs, objp)
+ XDR *xdrs;
+ createargs *objp;
{
- register int32_t *buf;
- if (!xdr_diropargs (xdrs, &objp->where))
- return FALSE;
- if (!xdr_sattr (xdrs, &objp->attributes))
- return FALSE;
- return TRUE;
+ if (!xdr_diropargs(xdrs, &objp->where))
+ return (FALSE);
+ if (!xdr_sattr(xdrs, &objp->attributes))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_renameargs (XDR *xdrs, renameargs *objp)
+xdr_renameargs(xdrs, objp)
+ XDR *xdrs;
+ renameargs *objp;
{
- register int32_t *buf;
- if (!xdr_diropargs (xdrs, &objp->from))
- return FALSE;
- if (!xdr_diropargs (xdrs, &objp->to))
- return FALSE;
- return TRUE;
+ if (!xdr_diropargs(xdrs, &objp->from))
+ return (FALSE);
+ if (!xdr_diropargs(xdrs, &objp->to))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_linkargs (XDR *xdrs, linkargs *objp)
+xdr_linkargs(xdrs, objp)
+ XDR *xdrs;
+ linkargs *objp;
{
- register int32_t *buf;
- if (!xdr_nfs_fh (xdrs, &objp->from))
- return FALSE;
- if (!xdr_diropargs (xdrs, &objp->to))
- return FALSE;
- return TRUE;
+ if (!xdr_nfs_fh(xdrs, &objp->from))
+ return (FALSE);
+ if (!xdr_diropargs(xdrs, &objp->to))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_symlinkargs (XDR *xdrs, symlinkargs *objp)
+xdr_symlinkargs(xdrs, objp)
+ XDR *xdrs;
+ symlinkargs *objp;
{
- register int32_t *buf;
-
- if (!xdr_diropargs (xdrs, &objp->from))
- return FALSE;
- if (!xdr_nfspath (xdrs, &objp->to))
- return FALSE;
- if (!xdr_sattr (xdrs, &objp->attributes))
- return FALSE;
- return TRUE;
+
+ if (!xdr_diropargs(xdrs, &objp->from))
+ return (FALSE);
+ if (!xdr_nfspath(xdrs, &objp->to))
+ return (FALSE);
+ if (!xdr_sattr(xdrs, &objp->attributes))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_nfscookie (XDR *xdrs, nfscookie *objp)
+xdr_nfscookie(xdrs, objp)
+ XDR *xdrs;
+ nfscookie *objp;
{
- register int32_t *buf;
- int i;
- if (!xdr_opaque (xdrs, objp->data, NFS_COOKIESIZE))
- return FALSE;
- return TRUE;
+ if (!xdr_opaque(xdrs, objp->data, NFS_COOKIESIZE))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_readdirargs (XDR *xdrs, readdirargs *objp)
+xdr_readdirargs(xdrs, objp)
+ XDR *xdrs;
+ readdirargs *objp;
{
- register int32_t *buf;
-
- if (!xdr_nfs_fh (xdrs, &objp->dir))
- return FALSE;
- if (!xdr_nfscookie (xdrs, &objp->cookie))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->count))
- return FALSE;
- return TRUE;
+
+ if (!xdr_nfs_fh(xdrs, &objp->dir))
+ return (FALSE);
+ if (!xdr_nfscookie(xdrs, &objp->cookie))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->count))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_entry (XDR *xdrs, entry *objp)
+xdr_entry(xdrs, objp)
+ XDR *xdrs;
+ entry *objp;
{
- register int32_t *buf;
-
- if (!xdr_u_int (xdrs, &objp->fileid))
- return FALSE;
- if (!xdr_filename (xdrs, &objp->name))
- return FALSE;
- if (!xdr_nfscookie (xdrs, &objp->cookie))
- return FALSE;
- if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entry), (xdrproc_t) xdr_entry))
- return FALSE;
- return TRUE;
+
+ if (!xdr_u_int(xdrs, &objp->fileid))
+ return (FALSE);
+ if (!xdr_filename(xdrs, &objp->name))
+ return (FALSE);
+ if (!xdr_nfscookie(xdrs, &objp->cookie))
+ return (FALSE);
+ if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof(entry), (xdrproc_t)xdr_entry))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_dirlist (XDR *xdrs, dirlist *objp)
+xdr_dirlist(xdrs, objp)
+ XDR *xdrs;
+ dirlist *objp;
{
- register int32_t *buf;
- if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entry), (xdrproc_t) xdr_entry))
- return FALSE;
- if (!xdr_bool (xdrs, &objp->eof))
- return FALSE;
- return TRUE;
+ if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof(entry), (xdrproc_t)xdr_entry))
+ return (FALSE);
+ if (!xdr_bool(xdrs, &objp->eof))
+ return (FALSE);
+ return (TRUE);
}
bool_t
-xdr_readdirres (XDR *xdrs, readdirres *objp)
+xdr_readdirres(xdrs, objp)
+ XDR *xdrs;
+ readdirres *objp;
{
- register int32_t *buf;
- if (!xdr_nfsstat (xdrs, &objp->status))
- return FALSE;
+ if (!xdr_nfsstat(xdrs, &objp->status))
+ return (FALSE);
switch (objp->status) {
case NFS_OK:
- if (!xdr_dirlist (xdrs, &objp->readdirres_u.reply))
- return FALSE;
+ if (!xdr_dirlist(xdrs, &objp->readdirres_u.reply))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_statfsokres (XDR *xdrs, statfsokres *objp)
+xdr_statfsokres(xdrs, objp)
+ XDR *xdrs;
+ statfsokres *objp;
{
- register int32_t *buf;
-
+ int32_t *buf;
if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
+ buf = (int32_t *)XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->tsize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bsize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocks))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bfree))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bavail))
- return FALSE;
+ if (!xdr_u_int(xdrs, &objp->tsize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bsize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocks))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bfree))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bavail))
+ return (FALSE);
} else {
IXDR_PUT_U_LONG(buf, objp->tsize);
IXDR_PUT_U_LONG(buf, objp->bsize);
@@ -615,20 +629,19 @@ xdr_statfsokres (XDR *xdrs, statfsokres *objp)
IXDR_PUT_U_LONG(buf, objp->bfree);
IXDR_PUT_U_LONG(buf, objp->bavail);
}
- return TRUE;
} else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
+ buf = (int32_t *)XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
- if (!xdr_u_int (xdrs, &objp->tsize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bsize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocks))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bfree))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bavail))
- return FALSE;
+ if (!xdr_u_int(xdrs, &objp->tsize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bsize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocks))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bfree))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bavail))
+ return (FALSE);
} else {
objp->tsize = IXDR_GET_U_LONG(buf);
objp->bsize = IXDR_GET_U_LONG(buf);
@@ -636,36 +649,36 @@ xdr_statfsokres (XDR *xdrs, statfsokres *objp)
objp->bfree = IXDR_GET_U_LONG(buf);
objp->bavail = IXDR_GET_U_LONG(buf);
}
- return TRUE;
+ } else {
+ if (!xdr_u_int(xdrs, &objp->tsize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bsize))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->blocks))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bfree))
+ return (FALSE);
+ if (!xdr_u_int(xdrs, &objp->bavail))
+ return (FALSE);
}
-
- if (!xdr_u_int (xdrs, &objp->tsize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bsize))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->blocks))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bfree))
- return FALSE;
- if (!xdr_u_int (xdrs, &objp->bavail))
- return FALSE;
- return TRUE;
+ return (TRUE);
}
bool_t
-xdr_statfsres (XDR *xdrs, statfsres *objp)
+xdr_statfsres(xdrs, objp)
+ XDR *xdrs;
+ statfsres *objp;
{
- register int32_t *buf;
- if (!xdr_nfsstat (xdrs, &objp->status))
- return FALSE;
+ if (!xdr_nfsstat(xdrs, &objp->status))
+ return (FALSE);
switch (objp->status) {
case NFS_OK:
- if (!xdr_statfsokres (xdrs, &objp->statfsres_u.reply))
- return FALSE;
+ if (!xdr_statfsokres(xdrs, &objp->statfsres_u.reply))
+ return (FALSE);
break;
default:
break;
}
- return TRUE;
+ return (TRUE);
}
diff --git a/rtemsNfs/rfc1094.txt b/rtemsNfs/rfc1094.txt
new file mode 100644
index 0000000..7ad0f73
--- /dev/null
+++ b/rtemsNfs/rfc1094.txt
@@ -0,0 +1,1258 @@
+
+ RFC 1094 (RFC1094)
+
+Internet RFC/STD/FYI/BCP Archives
+
+
+ RFC 1094 - NFS: Network File System Protocol specification
+
+------------------------------------------------------------------------
+
+
+Network Working Group Sun Microsystems, Inc.
+Request for Comments: 1094 March 1989
+
+ NFS: Network File System Protocol Specification
+
+STATUS OF THIS MEMO
+
+ This RFC describes a protocol that Sun Microsystems, Inc., and others
+ are using. A new version of the protocol is under development, but
+ others may benefit from the descriptions of the current protocol, and
+ discussion of some of the design issues. Distribution of this memo
+ is unlimited.
+
+1. INTRODUCTION
+
+ The Sun Network Filesystem (NFS) protocol provides transparent remote
+ access to shared files across networks. The NFS protocol is designed
+ to be portable across different machines, operating systems, network
+ architectures, and transport protocols. This portability is achieved
+ through the use of Remote Procedure Call (RPC) primitives built on
+ top of an eXternal Data Representation (XDR). Implementations
+ already exist for a variety of machines, from personal computers to
+ supercomputers.
+
+ The supporting mount protocol allows the server to hand out remote
+ access privileges to a restricted set of clients. It performs the
+ operating system-specific functions that allow, for example, to
+ attach remote directory trees to some local file system.
+
+1.1. Remote Procedure Call
+
+ Sun's Remote Procedure Call specification provides a procedure-
+ oriented interface to remote services. Each server supplies a
+ "program" that is a set of procedures. NFS is one such program. The
+ combination of host address, program number, and procedure number
+ specifies one remote procedure. A goal of NFS was to not require any
+ specific level of reliability from its lower levels, so it could
+ potentially be used on many underlying transport protocols, or even
+ another remote procedure call implementation. For ease of
+ discussion, the rest of this document will assume NFS is implemented
+ on top of Sun RPC, described in RFC 1057 </rfcs/rfc1057.html>, "RPC: Remote Procedure
+ Call Protocol Specification".
+
+1.2. External Data Representation
+
+ The eXternal Data Representation (XDR) standard provides a common way
+ of representing a set of data types over a network. The NFS Protocol
+
+ Specification is written using the RPC data description language.
+ For more information, see RFC 1014 </rfcs/rfc1014.html>, "XDR: External Data
+ Representation Standard". Although automated RPC/XDR compilers exist
+ to generate server and client "stubs", NFS does not require their
+ use. Any software that provides equivalent functionality can be
+ used, and if the encoding is exactly the same it can interoperate
+ with other implementations of NFS.
+
+1.3. Stateless Servers
+
+ The NFS protocol was intended to be as stateless as possible. That
+ is, a server should not need to maintain any protocol state
+ information about any of its clients in order to function correctly.
+ Stateless servers have a distinct advantage over stateful servers in
+ the event of a failure. With stateless servers, a client need only
+ retry a request until the server responds; it does not even need to
+ know that the server has crashed, or the network temporarily went
+ down. The client of a stateful server, on the other hand, needs to
+ either detect a server failure and rebuild the server's state when it
+ comes back up, or cause client operations to fail.
+
+ This may not sound like an important issue, but it affects the
+ protocol in some unexpected ways. We feel that it may be worth a bit
+ of extra complexity in the protocol to be able to write very simple
+ servers that do not require fancy crash recovery. Note that even if
+ a so-called "reliable" transport protocol such as TCP is used, the
+ client must still be able to handle interruptions of service by re-
+ opening connections when they time out. Thus, a stateless protocol
+ may actually simplify the implementation.
+
+ On the other hand, NFS deals with objects such as files and
+ directories that inherently have state -- what good would a file be
+ if it did not keep its contents intact? The goal was to not
+ introduce any extra state in the protocol itself. Inherently
+ stateful operations such as file or record locking, and remote
+ execution, were implemented as separate services, not described in
+ this document.
+
+ The basic way to simplify recovery was to make operations as
+ "idempotent" as possible (so that they can potentially be repeated).
+ Some operations in this version of the protocol did not attain this
+ goal; luckily most of the operations (such as Read and Write) are
+ idempotent. Also, most server failures occur between operations, not
+ between the receipt of an operation and the response. Finally,
+ although actual server failures may be rare, in complex networks,
+ failures of any network, router, or bridge may be indistinguishable
+ from a server failure.
+
+2. NFS PROTOCOL DEFINITION
+
+ Servers change over time, and so can the protocol that they use. RPC
+ provides a version number with each RPC request. This RFC describes
+ version two of the NFS protocol. Even in the second version, there
+ are a few obsolete procedures and parameters, which will be removed
+ in later versions. An RFC for version three of the NFS protocol is
+ currently under preparation.
+
+2.1. File System Model
+
+ NFS assumes a file system that is hierarchical, with directories as
+ all but the bottom level of files. Each entry in a directory (file,
+ directory, device, etc.) has a string name. Different operating
+ systems may have restrictions on the depth of the tree or the names
+ used, as well as using different syntax to represent the "pathname",
+ which is the concatenation of all the "components" (directory and
+ file names) in the name. A "file system" is a tree on a single
+ server (usually a single disk or physical partition) with a specified
+ "root". Some operating systems provide a "mount" operation to make
+ all file systems appear as a single tree, while others maintain a
+ "forest" of file systems. Files are unstructured streams of
+ uninterpreted bytes. Version 3 of NFS uses slightly more general
+ file system model.
+
+ NFS looks up one component of a pathname at a time. It may not be
+ obvious why it does not just take the whole pathname, traipse down
+ the directories, and return a file handle when it is done. There are
+ several good reasons not to do this. First, pathnames need
+ separators between the directory components, and different operating
+ systems use different separators. We could define a Network Standard
+ Pathname Representation, but then every pathname would have to be
+ parsed and converted at each end. Other issues are discussed in
+ section 3, NFS Implementation Issues.
+
+ Although files and directories are similar objects in many ways,
+ different procedures are used to read directories and files. This
+ provides a network standard format for representing directories. The
+ same argument as above could have been used to justify a procedure
+ that returns only one directory entry per call. The problem is
+ efficiency. Directories can contain many entries, and a remote call
+ to return each would be just too slow.
+
+2.2. Server Procedures
+
+ The protocol definition is given as a set of procedures with
+ arguments and results defined using the RPC language (XDR language
+ extended with program, version, and procedure declarations). A brief
+
+ description of the function of each procedure should provide enough
+ information to allow implementation. Section 2.3 describes the basic
+ data types in more detail.
+
+ All of the procedures in the NFS protocol are assumed to be
+ synchronous. When a procedure returns to the client, the client can
+ assume that the operation has completed and any data associated with
+ the request is now on stable storage. For example, a client WRITE
+ request may cause the server to update data blocks, filesystem
+ information blocks (such as indirect blocks), and file attribute
+ information (size and modify times). When the WRITE returns to the
+ client, it can assume that the write is safe, even in case of a
+ server crash, and it can discard the data written. This is a very
+ important part of the statelessness of the server. If the server
+ waited to flush data from remote requests, the client would have to
+ save those requests so that it could resend them in case of a server
+ crash.
+
+ /*
+ * Remote file service routines
+ */
+ program NFS_PROGRAM {
+ version NFS_VERSION {
+ void
+ NFSPROC_NULL(void) = 0;
+
+ attrstat
+ NFSPROC_GETATTR(fhandle) = 1;
+
+ attrstat
+ NFSPROC_SETATTR(sattrargs) = 2;
+
+ void
+ NFSPROC_ROOT(void) = 3;
+
+ diropres
+ NFSPROC_LOOKUP(diropargs) = 4;
+
+ readlinkres
+ NFSPROC_READLINK(fhandle) = 5;
+
+ readres
+ NFSPROC_READ(readargs) = 6;
+
+ void
+ NFSPROC_WRITECACHE(void) = 7;
+
+ attrstat
+ NFSPROC_WRITE(writeargs) = 8;
+
+ diropres
+ NFSPROC_CREATE(createargs) = 9;
+
+ stat
+ NFSPROC_REMOVE(diropargs) = 10;
+
+ stat
+ NFSPROC_RENAME(renameargs) = 11;
+
+ stat
+ NFSPROC_LINK(linkargs) = 12;
+
+ stat
+ NFSPROC_SYMLINK(symlinkargs) = 13;
+
+ diropres
+ NFSPROC_MKDIR(createargs) = 14;
+
+ stat
+ NFSPROC_RMDIR(diropargs) = 15;
+
+ readdirres
+ NFSPROC_READDIR(readdirargs) = 16;
+
+ statfsres
+ NFSPROC_STATFS(fhandle) = 17;
+ } = 2;
+ } = 100003;
+
+2.2.1. Do Nothing
+
+ void
+ NFSPROC_NULL(void) = 0;
+
+ This procedure does no work. It is made available in all RPC
+ services to allow server response testing and timing.
+
+2.2.2. Get File Attributes
+
+ attrstat
+ NFSPROC_GETATTR (fhandle) = 1;
+
+ If the reply status is NFS_OK, then the reply attributes contains the
+ attributes for the file given by the input fhandle.
+
+2.2.3. Set File Attributes
+
+ struct sattrargs {
+ fhandle file;
+ sattr attributes;
+ };
+
+ attrstat
+ NFSPROC_SETATTR (sattrargs) = 2;
+
+ The "attributes" argument contains fields which are either -1 or are
+ the new value for the attributes of "file". If the reply status is
+ NFS_OK, then the reply attributes have the attributes of the file
+ after the "SETATTR" operation has completed.
+
+ Notes: The use of -1 to indicate an unused field in "attributes" is
+ changed in the next version of the protocol.
+
+2.2.4. Get Filesystem Root
+
+ void
+ NFSPROC_ROOT(void) = 3;
+
+ Obsolete. This procedure is no longer used because finding the root
+ file handle of a filesystem requires moving pathnames between client
+ and server. To do this right, we would have to define a network
+ standard representation of pathnames. Instead, the function of
+ looking up the root file handle is done by the MNTPROC_MNT procedure.
+ (See Appendix A, "Mount Protocol Definition", for details).
+
+2.2.5. Look Up File Name
+
+ diropres
+ NFSPROC_LOOKUP(diropargs) = 4;
+
+ If the reply "status" is NFS_OK, then the reply "file" and reply
+ "attributes" are the file handle and attributes for the file "name"
+ in the directory given by "dir" in the argument.
+
+2.2.6. Read From Symbolic Link
+
+ union readlinkres switch (stat status) {
+ case NFS_OK:
+ path data;
+ default:
+ void;
+ };
+
+ readlinkres
+ NFSPROC_READLINK(fhandle) = 5;
+
+ If "status" has the value NFS_OK, then the reply "data" is the data
+ in the symbolic link given by the file referred to by the fhandle
+ argument.
+
+ Notes: Since NFS always parses pathnames on the client, the pathname
+ in a symbolic link may mean something different (or be meaningless)
+ on a different client or on the server if a different pathname syntax
+ is used.
+
+2.2.7. Read From File
+
+ struct readargs {
+ fhandle file;
+ unsigned offset;
+ unsigned count;
+ unsigned totalcount;
+ };
+
+ union readres switch (stat status) {
+ case NFS_OK:
+ fattr attributes;
+ nfsdata data;
+ default:
+ void;
+ };
+
+ readres
+ NFSPROC_READ(readargs) = 6;
+
+ Returns up to "count" bytes of "data" from the file given by "file",
+ starting at "offset" bytes from the beginning of the file. The first
+ byte of the file is at offset zero. The file attributes after the
+ read takes place are returned in "attributes".
+
+ Notes: The argument "totalcount" is unused, and is removed in the
+ next protocol revision.
+
+2.2.8. Write to Cache
+
+ void
+ NFSPROC_WRITECACHE(void) = 7;
+
+ To be used in the next protocol revision.
+
+2.2.9. Write to File
+
+ struct writeargs {
+ fhandle file;
+ unsigned beginoffset;
+ unsigned offset;
+ unsigned totalcount;
+ nfsdata data;
+ };
+
+ attrstat
+ NFSPROC_WRITE(writeargs) = 8;
+
+ Writes "data" beginning "offset" bytes from the beginning of "file".
+ The first byte of the file is at offset zero. If the reply "status"
+ is NFS_OK, then the reply "attributes" contains the attributes of the
+ file after the write has completed. The write operation is atomic.
+ Data from this "WRITE" will not be mixed with data from another
+ client's "WRITE".
+
+ Notes: The arguments "beginoffset" and "totalcount" are ignored and
+ are removed in the next protocol revision.
+
+2.2.10. Create File
+
+ struct createargs {
+ diropargs where;
+ sattr attributes;
+ };
+
+ diropres
+ NFSPROC_CREATE(createargs) = 9;
+
+ The file "name" is created in the directory given by "dir". The
+ initial attributes of the new file are given by "attributes". A
+ reply "status" of NFS_OK indicates that the file was created, and
+ reply "file" and reply "attributes" are its file handle and
+ attributes. Any other reply "status" means that the operation failed
+ and no file was created.
+
+ Notes: This routine should pass an exclusive create flag, meaning
+ "create the file only if it is not already there".
+
+2.2.11. Remove File
+
+ stat
+ NFSPROC_REMOVE(diropargs) = 10;
+
+ The file "name" is removed from the directory given by "dir". A
+ reply of NFS_OK means the directory entry was removed.
+
+ Notes: possibly non-idempotent operation.
+
+2.2.12. Rename File
+
+ struct renameargs {
+ diropargs from;
+ diropargs to;
+ };
+
+ stat
+ NFSPROC_RENAME(renameargs) = 11;
+
+ The existing file "from.name" in the directory given by "from.dir" is
+ renamed to "to.name" in the directory given by "to.dir". If the
+ reply is NFS_OK, the file was renamed. The RENAME operation is
+ atomic on the server; it cannot be interrupted in the middle.
+
+ Notes: possibly non-idempotent operation.
+
+2.2.13. Create Link to File
+
+ Procedure 12, Version 2.
+
+ struct linkargs {
+ fhandle from;
+ diropargs to;
+ };
+
+ stat
+ NFSPROC_LINK(linkargs) = 12;
+
+ Creates the file "to.name" in the directory given by "to.dir", which
+ is a hard link to the existing file given by "from". If the return
+ value is NFS_OK, a link was created. Any other return value
+ indicates an error, and the link was not created.
+
+ A hard link should have the property that changes to either of the
+ linked files are reflected in both files. When a hard link is made
+ to a file, the attributes for the file should have a value for
+ "nlink" that is one greater than the value before the link.
+
+ Notes: possibly non-idempotent operation.
+
+2.2.14. Create Symbolic Link
+
+ struct symlinkargs {
+ diropargs from;
+ path to;
+ sattr attributes;
+ };
+
+ stat
+ NFSPROC_SYMLINK(symlinkargs) = 13;
+
+ Creates the file "from.name" with ftype NFLNK in the directory given
+ by "from.dir". The new file contains the pathname "to" and has
+ initial attributes given by "attributes". If the return value is
+ NFS_OK, a link was created. Any other return value indicates an
+ error, and the link was not created.
+
+ A symbolic link is a pointer to another file. The name given in "to"
+ is not interpreted by the server, only stored in the newly created
+ file. When the client references a file that is a symbolic link, the
+ contents of the symbolic link are normally transparently
+ reinterpreted as a pathname to substitute. A READLINK operation
+ returns the data to the client for interpretation.
+
+ Notes: On UNIX servers the attributes are never used, since symbolic
+ links always have mode 0777.
+
+2.2.15. Create Directory
+
+ diropres
+ NFSPROC_MKDIR (createargs) = 14;
+
+ The new directory "where.name" is created in the directory given by
+ "where.dir". The initial attributes of the new directory are given
+ by "attributes". A reply "status" of NFS_OK indicates that the new
+ directory was created, and reply "file" and reply "attributes" are
+ its file handle and attributes. Any other reply "status" means that
+ the operation failed and no directory was created.
+
+ Notes: possibly non-idempotent operation.
+
+2.2.16. Remove Directory
+
+ stat
+ NFSPROC_RMDIR(diropargs) = 15;
+
+ The existing empty directory "name" in the directory given by "dir"
+ is removed. If the reply is NFS_OK, the directory was removed.
+
+ Notes: possibly non-idempotent operation.
+
+2.2.17. Read From Directory
+
+ struct readdirargs {
+ fhandle dir;
+ nfscookie cookie;
+ unsigned count;
+ };
+
+ struct entry {
+ unsigned fileid;
+ filename name;
+ nfscookie cookie;
+ entry *nextentry;
+ };
+
+ union readdirres switch (stat status) {
+ case NFS_OK:
+ struct {
+ entry *entries;
+ bool eof;
+ } readdirok;
+ default:
+ void;
+ };
+
+ readdirres
+ NFSPROC_READDIR (readdirargs) = 16;
+
+ Returns a variable number of directory entries, with a total size of
+ up to "count" bytes, from the directory given by "dir". If the
+ returned value of "status" is NFS_OK, then it is followed by a
+ variable number of "entry"s. Each "entry" contains a "fileid" which
+ consists of a unique number to identify the file within a filesystem,
+ the "name" of the file, and a "cookie" which is an opaque pointer to
+ the next entry in the directory. The cookie is used in the next
+ READDIR call to get more entries starting at a given point in the
+ directory. The special cookie zero (all bits zero) can be used to
+ get the entries starting at the beginning of the directory. The
+ "fileid" field should be the same number as the "fileid" in the the
+ attributes of the file. (See section "2.3.5. fattr" under "Basic
+ Data Types".) The "eof" flag has a value of TRUE if there are no
+ more entries in the directory.
+
+2.2.18. Get Filesystem Attributes
+
+ union statfsres (stat status) {
+ case NFS_OK:
+ struct {
+ unsigned tsize;
+ unsigned bsize;
+ unsigned blocks;
+ unsigned bfree;
+ unsigned bavail;
+ } info;
+ default:
+ void;
+ };
+
+ statfsres
+ NFSPROC_STATFS(fhandle) = 17;
+
+ If the reply "status" is NFS_OK, then the reply "info" gives the
+ attributes for the filesystem that contains file referred to by the
+ input fhandle. The attribute fields contain the following values:
+
+ tsize The optimum transfer size of the server in bytes. This is
+ the number of bytes the server would like to have in the
+ data part of READ and WRITE requests.
+
+ bsize The block size in bytes of the filesystem.
+
+ blocks The total number of "bsize" blocks on the filesystem.
+
+ bfree The number of free "bsize" blocks on the filesystem.
+
+ bavail The number of "bsize" blocks available to non-privileged
+ users.
+
+ Notes: This call does not work well if a filesystem has variable
+ size blocks.
+
+2.3. Basic Data Types
+
+ The following XDR definitions are basic structures and types used in
+ other structures described further on.
+
+2.3.1. stat
+
+ enum stat {
+ NFS_OK = 0,
+ NFSERR_PERM=1,
+
+ NFSERR_NOENT=2,
+ NFSERR_IO=5,
+ NFSERR_NXIO=6,
+ NFSERR_ACCES=13,
+ NFSERR_EXIST=17,
+ NFSERR_NODEV=19,
+ NFSERR_NOTDIR=20,
+ NFSERR_ISDIR=21,
+ NFSERR_FBIG=27,
+ NFSERR_NOSPC=28,
+ NFSERR_ROFS=30,
+ NFSERR_NAMETOOLONG=63,
+ NFSERR_NOTEMPTY=66,
+ NFSERR_DQUOT=69,
+ NFSERR_STALE=70,
+ NFSERR_WFLUSH=99
+ };
+
+ The "stat" type is returned with every procedure's results. A value
+ of NFS_OK indicates that the call completed successfully and the
+ results are valid. The other values indicate some kind of error
+ occurred on the server side during the servicing of the procedure.
+ The error values are derived from UNIX error numbers.
+
+ NFSERR_PERM
+ Not owner. The caller does not have correct ownership to perform
+ the requested operation.
+
+ NFSERR_NOENT
+ No such file or directory. The file or directory specified does
+ not exist.
+
+ NFSERR_IO
+ Some sort of hard error occurred when the operation was in
+ progress. This could be a disk error, for example.
+
+ NFSERR_NXIO
+ No such device or address.
+
+ NFSERR_ACCES
+ Permission denied. The caller does not have the correct
+ permission to perform the requested operation.
+
+ NFSERR_EXIST
+ File exists. The file specified already exists.
+
+ NFSERR_NODEV
+ No such device.
+
+ NFSERR_NOTDIR
+ Not a directory. The caller specified a non-directory in a
+ directory operation.
+
+ NFSERR_ISDIR
+ Is a directory. The caller specified a directory in a non-
+ directory operation.
+
+ NFSERR_FBIG
+ File too large. The operation caused a file to grow beyond the
+ server's limit.
+
+ NFSERR_NOSPC
+ No space left on device. The operation caused the server's
+ filesystem to reach its limit.
+
+ NFSERR_ROFS
+ Read-only filesystem. Write attempted on a read-only filesystem.
+
+ NFSERR_NAMETOOLONG
+ File name too long. The file name in an operation was too long.
+
+ NFSERR_NOTEMPTY
+ Directory not empty. Attempted to remove a directory that was not
+ empty.
+
+ NFSERR_DQUOT
+ Disk quota exceeded. The client's disk quota on the server has
+ been exceeded.
+
+ NFSERR_STALE
+ The "fhandle" given in the arguments was invalid. That is, the
+ file referred to by that file handle no longer exists, or access
+ to it has been revoked.
+
+ NFSERR_WFLUSH
+ The server's write cache used in the "WRITECACHE" call got flushed
+ to disk.
+
+2.3.2. ftype
+
+ enum ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5
+ };
+
+ The enumeration "ftype" gives the type of a file. The type NFNON
+ indicates a non-file, NFREG is a regular file, NFDIR is a
+ directory, NFBLK is a block-special device, NFCHR is a character-
+ special device, and NFLNK is a symbolic link.
+
+2.3.3. fhandle
+
+ typedef opaque fhandle[FHSIZE];
+
+ The "fhandle" is the file handle passed between the server and the
+ client. All file operations are done using file handles to refer
+ to a file or directory. The file handle can contain whatever
+ information the server needs to distinguish an individual file.
+
+2.3.4. timeval
+
+ struct timeval {
+ unsigned int seconds;
+ unsigned int useconds;
+ };
+
+ The "timeval" structure is the number of seconds and microseconds
+ since midnight January 1, 1970, Greenwich Mean Time. It is used
+ to pass time and date information.
+
+2.3.5. fattr
+
+ struct fattr {
+ ftype type;
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int size;
+ unsigned int blocksize;
+ unsigned int rdev;
+ unsigned int blocks;
+
+ unsigned int fsid;
+ unsigned int fileid;
+ timeval atime;
+ timeval mtime;
+ timeval ctime;
+ };
+
+ The "fattr" structure contains the attributes of a file; "type" is
+ the type of the file; "nlink" is the number of hard links to the
+ file (the number of different names for the same file); "uid" is
+ the user identification number of the owner of the file; "gid" is
+ the group identification number of the group of the file; "size"
+ is the size in bytes of the file; "blocksize" is the size in bytes
+ of a block of the file; "rdev" is the device number of the file if
+ it is type NFCHR or NFBLK; "blocks" is the number of blocks the
+ file takes up on disk; "fsid" is the file system identifier for
+ the filesystem containing the file; "fileid" is a number that
+ uniquely identifies the file within its filesystem; "atime" is the
+ time when the file was last accessed for either read or write;
+ "mtime" is the time when the file data was last modified
+ (written); and "ctime" is the time when the status of the file was
+ last changed. Writing to the file also changes "ctime" if the
+ size of the file changes.
+
+ "Mode" is the access mode encoded as a set of bits. Notice that
+ the file type is specified both in the mode bits and in the file
+ type. This is really a bug in the protocol and will be fixed in
+ future versions. The descriptions given below specify the bit
+ positions using octal numbers.
+
+ 0040000 This is a directory; "type" field should be NFDIR.
+ 0020000 This is a character special file; "type" field should
+ be NFCHR.
+ 0060000 This is a block special file; "type" field should be
+ NFBLK.
+ 0100000 This is a regular file; "type" field should be NFREG.
+ 0120000 This is a symbolic link file; "type" field should be
+ NFLNK.
+ 0140000 This is a named socket; "type" field should be NFNON.
+ 0004000 Set user id on execution.
+ 0002000 Set group id on execution.
+ 0001000 Save swapped text even after use.
+ 0000400 Read permission for owner.
+ 0000200 Write permission for owner.
+ 0000100 Execute and search permission for owner.
+ 0000040 Read permission for group.
+ 0000020 Write permission for group.
+ 0000010 Execute and search permission for group.
+
+ 0000004 Read permission for others.
+ 0000002 Write permission for others.
+ 0000001 Execute and search permission for others.
+
+ Notes: The bits are the same as the mode bits returned by the
+ stat(2) system call in UNIX. The file type is specified both in
+ the mode bits and in the file type. This is fixed in future
+ versions.
+
+ The "rdev" field in the attributes structure is an operating
+ system specific device specifier. It will be removed and
+ generalized in the next revision of the protocol.
+
+2.3.6. sattr
+
+ struct sattr {
+ unsigned int mode;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int size;
+ timeval atime;
+ timeval mtime;
+ };
+
+ The "sattr" structure contains the file attributes which can be
+ set from the client. The fields are the same as for "fattr"
+ above. A "size" of zero means the file should be truncated. A
+ value of -1 indicates a field that should be ignored.
+
+2.3.7. filename
+
+ typedef string filename<MAXNAMLEN>;
+
+ The type "filename" is used for passing file names or pathname
+ components.
+
+2.3.8. path
+
+ typedef string path<MAXPATHLEN>;
+
+ The type "path" is a pathname. The server considers it as a
+ string with no internal structure, but to the client it is the
+ name of a node in a filesystem tree.
+
+2.3.9. attrstat
+
+ union attrstat switch (stat status) {
+ case NFS_OK:
+
+ fattr attributes;
+ default:
+ void;
+ };
+
+ The "attrstat" structure is a common procedure result. It
+ contains a "status" and, if the call succeeded, it also contains
+ the attributes of the file on which the operation was done.
+
+2.3.10. diropargs
+
+ struct diropargs {
+ fhandle dir;
+ filename name;
+ };
+
+ The "diropargs" structure is used in directory operations. The
+ "fhandle" "dir" is the directory in which to find the file "name".
+ A directory operation is one in which the directory is affected.
+
+2.3.11. diropres
+
+ union diropres switch (stat status) {
+ case NFS_OK:
+ struct {
+ fhandle file;
+ fattr attributes;
+ } diropok;
+ default:
+ void;
+ };
+
+ The results of a directory operation are returned in a "diropres"
+ structure. If the call succeeded, a new file handle "file" and
+ the "attributes" associated with that file are returned along with
+ the "status".
+
+3. NFS IMPLEMENTATION ISSUES
+
+ The NFS protocol was designed to allow different operating systems to
+ share files. However, since it was designed in a UNIX environment,
+ many operations have semantics similar to the operations of the UNIX
+ file system. This section discusses some of the implementation-
+ specific details and semantic issues.
+
+3.1. Server/Client Relationship
+
+ The NFS protocol is designed to allow servers to be as simple and
+
+ general as possible. Sometimes the simplicity of the server can be a
+ problem, if the client wants to implement complicated filesystem
+ semantics.
+
+ For example, some operating systems allow removal of open files. A
+ process can open a file and, while it is open, remove it from the
+ directory. The file can be read and written as long as the process
+ keeps it open, even though the file has no name in the filesystem.
+ It is impossible for a stateless server to implement these semantics.
+ The client can do some tricks such as renaming the file on remove,
+ and only removing it on close. We believe that the server provides
+ enough functionality to implement most file system semantics on the
+ client.
+
+ Every NFS client can also potentially be a server, and remote and
+ local mounted filesystems can be freely intermixed. This leads to
+ some interesting problems when a client travels down the directory
+ tree of a remote filesystem and reaches the mount point on the server
+ for another remote filesystem. Allowing the server to follow the
+ second remote mount would require loop detection, server lookup, and
+ user revalidation. Instead, we decided not to let clients cross a
+ server's mount point. When a client does a LOOKUP on a directory on
+ which the server has mounted a filesystem, the client sees the
+ underlying directory instead of the mounted directory.
+
+ For example, if a server has a file system called "/usr" and mounts
+ another file system on "/usr/src", if a client mounts "/usr", it
+ does NOT see the mounted version of "/usr/src". A client could do
+ remote mounts that match the server's mount points to maintain the
+ server's view. In this example, the client would also have to mount
+ "/usr/src" in addition to "/usr", even if they are from the same
+ server.
+
+3.2. Pathname Interpretation
+
+ There are a few complications to the rule that pathnames are always
+ parsed on the client. For example, symbolic links could have
+ different interpretations on different clients. Another common
+ problem for non-UNIX implementations is the special interpretation of
+ the pathname ".." to mean the parent of a given directory. The next
+ revision of the protocol uses an explicit flag to indicate the parent
+ instead.
+
+3.3. Permission Issues
+
+ The NFS protocol, strictly speaking, does not define the permission
+ checking used by servers. However, it is expected that a server will
+ do normal operating system permission checking using AUTH_UNIX style
+
+ authentication as the basis of its protection mechanism. The server
+ gets the client's effective "uid", effective "gid", and groups on
+ each call and uses them to check permission. There are various
+ problems with this method that can been resolved in interesting ways.
+
+ Using "uid" and "gid" implies that the client and server share the
+ same "uid" list. Every server and client pair must have the same
+ mapping from user to "uid" and from group to "gid". Since every
+ client can also be a server, this tends to imply that the whole
+ network shares the same "uid/gid" space. AUTH_DES (and the next
+ revision of the NFS protocol) uses string names instead of numbers,
+ but there are still complex problems to be solved.
+
+ Another problem arises due to the usually stateful open operation.
+ Most operating systems check permission at open time, and then check
+ that the file is open on each read and write request. With stateless
+ servers, the server has no idea that the file is open and must do
+ permission checking on each read and write call. On a local
+ filesystem, a user can open a file and then change the permissions so
+ that no one is allowed to touch it, but will still be able to write
+ to the file because it is open. On a remote filesystem, by contrast,
+ the write would fail. To get around this problem, the server's
+ permission checking algorithm should allow the owner of a file to
+ access it regardless of the permission setting.
+
+ A similar problem has to do with paging in from a file over the
+ network. The operating system usually checks for execute permission
+ before opening a file for demand paging, and then reads blocks from
+ the open file. The file may not have read permission, but after it
+ is opened it does not matter. An NFS server can not tell the
+ difference between a normal file read and a demand page-in read. To
+ make this work, the server allows reading of files if the "uid" given
+ in the call has either execute or read permission on the file.
+
+ In most operating systems, a particular user (on UNIX, the user ID
+ zero) has access to all files no matter what permission and ownership
+ they have. This "super-user" permission may not be allowed on the
+ server, since anyone who can become super-user on their workstation
+ could gain access to all remote files. The UNIX server by default
+ maps user id 0 to -2 before doing its access checking. This works
+ except for NFS root filesystems, where super-user access cannot be
+ avoided.
+
+3.4. RPC Information
+
+ Authentication
+ The NFS service uses AUTH_UNIX, AUTH_DES, or AUTH_SHORT style
+ authentication, except in the NULL procedure where AUTH_NONE is
+
+ also allowed.
+
+ Transport Protocols
+ NFS is supported normally on UDP.
+
+ Port Number
+ The NFS protocol currently uses the UDP port number 2049. This is
+ not an officially assigned port, so later versions of the protocol
+ use the "Portmapping" facility of RPC.
+
+3.5. Sizes of XDR Structures
+
+ These are the sizes, given in decimal bytes, of various XDR
+ structures used in the protocol:
+
+ /*
+ * The maximum number of bytes of data in a READ or WRITE
+ * request.
+ */
+ const MAXDATA = 8192;
+
+ /* The maximum number of bytes in a pathname argument. */
+ const MAXPATHLEN = 1024;
+
+ /* The maximum number of bytes in a file name argument. */
+ const MAXNAMLEN = 255;
+
+ /* The size in bytes of the opaque "cookie" passed by READDIR. */
+ const COOKIESIZE = 4;
+
+ /* The size in bytes of the opaque file handle. */
+ const FHSIZE = 32;
+
+3.6. Setting RPC Parameters
+
+ Various file system parameters and options should be set at mount
+ time. The mount protocol is described in the appendix below. For
+ example, "Soft" mounts as well as "Hard" mounts are usually both
+ provided. Soft mounted file systems return errors when RPC
+ operations fail (after a given number of optional retransmissions),
+ while hard mounted file systems continue to retransmit forever. The
+ maximum transfer sizes are implementation dependent. For efficient
+ operation over a local network, 8192 bytes of data are normally used.
+ This may result in lower-level fragmentation (such as at the IP
+ level). Since some network interfaces may not allow such packets,
+ for operation over slower-speed networks or hosts, or through
+ gateways, transfer sizes of 512 or 1024 bytes often provide better
+ results.
+
+ Clients and servers may need to keep caches of recent operations to
+ help avoid problems with non-idempotent operations. For example, if
+ the transport protocol drops the response for a Remove File
+ operation, upon retransmission the server may return an error code of
+ NFSERR_NOENT instead of NFS_OK. But if the server keeps around the
+ last operation requested and its result, it could return the proper
+ success code. Of course, the server could be crashed and rebooted
+ between retransmissions, but a small cache (even a single entry)
+ would solve most problems.
+
+ Appendix A. MOUNT PROTOCOL DEFINITION
+
+A.1. Introduction
+
+ The mount protocol is separate from, but related to, the NFS
+ protocol. It provides operating system specific services to get the
+ NFS off the ground -- looking up server path names, validating user
+ identity, and checking access permissions. Clients use the mount
+ protocol to get the first file handle, which allows them entry into a
+ remote filesystem.
+
+ The mount protocol is kept separate from the NFS protocol to make it
+ easy to plug in new access checking and validation methods without
+ changing the NFS server protocol.
+
+ Notice that the protocol definition implies stateful servers because
+ the server maintains a list of client's mount requests. The mount
+ list information is not critical for the correct functioning of
+ either the client or the server. It is intended for advisory use
+ only, for example, to warn possible clients when a server is going
+ down.
+
+ Version one of the mount protocol is used with version two of the NFS
+ protocol. The only information communicated between these two
+ protocols is the "fhandle" structure.
+
+A.2. RPC Information
+
+ Authentication
+ The mount service uses AUTH_UNIX and AUTH_NONE style
+ authentication only.
+
+ Transport Protocols
+ The mount service is supported on both UDP and TCP.
+
+ Port Number
+ Consult the server's portmapper, described in RFC 1057 </rfcs/rfc1057.html>, "RPC:
+ Remote Procedure Call Protocol Specification", to find the port
+ number on which the mount service is registered.
+
+A.3. Sizes of XDR Structures
+
+ These are the sizes, given in decimal bytes, of various XDR
+ structures used in the protocol:
+
+ /* The maximum number of bytes in a pathname argument. */
+ const MNTPATHLEN = 1024;
+
+ /* The maximum number of bytes in a name argument. */
+ const MNTNAMLEN = 255;
+
+ /* The size in bytes of the opaque file handle. */
+ const FHSIZE = 32;
+
+A.4. Basic Data Types
+
+ This section presents the data types used by the mount protocol. In
+ many cases they are similar to the types used in NFS.
+
+A.4.1. fhandle
+
+ typedef opaque fhandle[FHSIZE];
+
+ The type "fhandle" is the file handle that the server passes to the
+ client. All file operations are done using file handles to refer to
+ a file or directory. The file handle can contain whatever
+ information the server needs to distinguish an individual file.
+
+ This is the same as the "fhandle" XDR definition in version 2 of the
+ NFS protocol; see section "2.3.3. fhandle" under "Basic Data Types".
+
+A.4.2. fhstatus
+
+ union fhstatus switch (unsigned status) {
+ case 0:
+ fhandle directory;
+ default:
+ void;
+ }
+
+ The type "fhstatus" is a union. If a "status" of zero is returned,
+ the call completed successfully, and a file handle for the
+ "directory" follows. A non-zero status indicates some sort of error.
+ In this case, the status is a UNIX error number.
+
+A.4.3. dirpath
+
+ typedef string dirpath<MNTPATHLEN>;
+
+ The type "dirpath" is a server pathname of a directory.
+
+A.4.4. name
+
+ typedef string name<MNTNAMLEN>;
+
+ The type "name" is an arbitrary string used for various names.
+
+A.5. Server Procedures
+
+ The following sections define the RPC procedures supplied by a mount
+ server.
+
+ /*
+ * Protocol description for the mount program
+ */
+ program MOUNTPROG {
+ /*
+ * Version 1 of the mount protocol used with
+ * version 2 of the NFS protocol.
+ */
+ version MOUNTVERS {
+
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ fhstatus
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ exportlist
+ MOUNTPROC_EXPORT(void) = 5;
+ } = 1;
+ } = 100005;
+
+A.5.1. Do Nothing
+
+ void
+ MNTPROC_NULL(void) = 0;
+
+ This procedure does no work. It is made available in all RPC
+ services to allow server response testing and timing.
+
+A.5.2. Add Mount Entry
+
+ fhstatus
+ MNTPROC_MNT(dirpath) = 1;
+
+ If the reply "status" is 0, then the reply "directory" contains the
+ file handle for the directory "dirname". This file handle may be
+ used in the NFS protocol. This procedure also adds a new entry to
+ the mount list for this client mounting "dirname".
+
+A.5.3. Return Mount Entries
+
+ struct *mountlist {
+ name hostname;
+ dirpath directory;
+ mountlist nextentry;
+ };
+
+ mountlist
+ MNTPROC_DUMP(void) = 2;
+
+ Returns the list of remote mounted filesystems. The "mountlist"
+ contains one entry for each "hostname" and "directory" pair.
+
+A.5.4. Remove Mount Entry
+
+ void
+ MNTPROC_UMNT(dirpath) = 3;
+
+ Removes the mount list entry for the input "dirpath".
+
+A.5.5. Remove All Mount Entries
+
+ void
+ MNTPROC_UMNTALL(void) = 4;
+
+ Removes all of the mount list entries for this client.
+
+A.5.6. Return Export List
+
+ struct *groups {
+ name grname;
+ groups grnext;
+ };
+
+ struct *exportlist {
+ dirpath filesys;
+ groups groups;
+ exportlist next;
+ };
+
+ exportlist
+ MNTPROC_EXPORT(void) = 5;
+
+ Returns a variable number of export list entries. Each entry
+ contains a filesystem name and a list of groups that are allowed to
+ import it. The filesystem name is in "filesys", and the group name
+ is in the list "groups".
+
+ Notes: The exportlist should contain more information about the
+ status of the filesystem, such as a read-only flag.
+
+Author's Address:
+
+ Bill Nowicki
+ Sun Microsystems, Inc.
+ Mail Stop 1-40
+ 2550 Garcia Avenue
+ Mountain View, CA 94043
+
+ Phone: (415) 336-7278
+
+ Email: nowicki@SUN.COM <mailto:nowicki@SUN.COM>
+
+Comment on RFC 1094 </rfccomment.php?rfcnum=1094>
+
+
+
+Comments about this RFC:
+
+ * RFC 1094: I am preparing for doing a project in File System in
+ Network. can you specify... </qa/rfcc-377.html> by Ravik (12/4/2003)
+
+
+Previous: RFC 1093 - NSFNET routing architecture </rfcs/rfc1093.html>
+
+
+
+Next: RFC 1095 - Common Management Information Services and Protocol
+over TCP/IP (CMOT) </rfcs/rfc1095.html>
+
+
+
+------------------------------------------------------------------------
diff --git a/rtemsNfs/src/Makefile b/rtemsNfs/src/Makefile
index 431b5ad..584ee00 100644
--- a/rtemsNfs/src/Makefile
+++ b/rtemsNfs/src/Makefile
@@ -7,7 +7,7 @@
# if you have CEXP set this variable to 'YES'
# and some "help" info will be compiled in.
-HAVE_CEXP=YES
+HAVE_CEXP=NO
# C source names, if any, go here -- minus the .c
C_PIECES_YES=rpcio nfs sock_mbuf xdr_mbuf dirutils rpcio.modini nfs.modini cexphelp
diff --git a/rtemsNfs/src/dirutils.c b/rtemsNfs/src/dirutils.c
index 91b1858..d6c47fe 100644
--- a/rtemsNfs/src/dirutils.c
+++ b/rtemsNfs/src/dirutils.c
@@ -60,8 +60,6 @@
#include <cexpHelp.h>
#endif
-#define BUFFERSZ 10000
-
#ifndef __vxworks
int
pwd(void)
@@ -158,16 +156,15 @@ int
cp(char *from, char *to, char *opts)
{
struct stat st;
-int got,put,tot;
-char *buf = 0;
int rval = -1;
-int ffd = -1;
-int tfd = -1;
+int fd = -1;
+FILE *fst = 0;
+FILE *tst = 0;
int flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL;
if (from) {
- if ((ffd=open(from,O_RDONLY,0)) < 0) {
+ if ((fd=open(from,O_RDONLY,0)) < 0) {
fprintf(stderr,
"Opening %s for reading: %s\n",
from,
@@ -175,7 +172,7 @@ int flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL;
goto cleanup;
}
- if (fstat(ffd, &st)) {
+ if (fstat(fd, &st)) {
fprintf(stderr,
"rstat(%s): %s\n",
from,
@@ -189,58 +186,95 @@ int flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL;
errno = EINVAL;
goto cleanup;
}
+ /* Now create a stream -- I experienced occasional weirdness
+ * when circumventing the streams attached to fildno(stdin)
+ * by reading/writing to the underlying fd's directly ->
+ * for now we always go through buffered I/O...
+ */
+ if ( !(fst=fdopen(fd,"r")) ) {
+ fprintf(stderr,
+ "Opening input stream [fdopen()] failed: %s\n",
+ strerror(errno));
+ goto cleanup;
+ }
+ /* at this point, we have a stream and don't need 'fd' anymore */
+ fd = -1;
} else {
- ffd = fileno(stdin);
- st.st_mode = 0644;
+ fst = stdin;
+ st.st_mode = 0644;
}
if (opts && strchr(opts,'f'))
flags &= ~ O_EXCL;
if (to) {
- if ((tfd=open(to,flags,st.st_mode)) < 0) {
+ if ( (fd=open(to,flags,st.st_mode)) < 0 ) {
fprintf(stderr,
"Opening %s for writing: %s\n",
to,
strerror(errno));
goto cleanup;
}
+ if ( !(tst=fdopen(fd, "w")) ) {
+ fprintf(stderr,
+ "Opening output stream [fdopen()] failed: %s\n",
+ strerror(errno));
+ goto cleanup;
+ }
+ /* at this point we have a stream and don't need 'fd' anymore */
+ fd = -1;
} else {
- tfd = fileno(stdout);
+ tst = stdout;
}
- if ( !(buf = malloc(BUFFERSZ)) ) {
- fprintf(stderr,"cp: unable to allocate buffer - out of memory\n");
- errno = ENOMEM;
- goto cleanup;
+ /* clear old errors */
+ clearerr(fst);
+ clearerr(tst);
+
+ /* use macro versions on register vars; stdio is already buffered,
+ * there's nothing to be gained by reading/writing blocks into
+ * a secondary buffer...
+ */
+ {
+ register int ch;
+ register FILE *f = fst;
+ register FILE *t = tst;
+ while ( EOF != (ch = getc(f)) && EOF != putc(ch, t) )
+ /* nothing else */;
}
- tot = 0;
- while ( (got=read(ffd,buf,BUFFERSZ)) > 0 ) {
- if (got !=(put=write(tfd,buf,got))) {
- if (put<0) {
- fprintf(stderr,"Write error: %s\n",strerror(errno));
- } else {
- fprintf(stderr,"Write error: unable to write whole block\n");
- }
- goto cleanup;
- }
- tot += got;
- }
- if (got < 0) {
+ if ( ferror(fst) ) {
fprintf(stderr,"Read error: %s\n",strerror(errno));
goto cleanup;
}
+ if ( ferror(tst) ) {
+ fprintf(stderr,"Write error: %s\n",strerror(errno));
+ goto cleanup;
+ }
+
rval = 0;
cleanup:
- free(buf);
- if (from && ffd>=0)
- close(ffd);
- if (to && tfd>=0)
- close(tfd);
+ if ( fd >= 0 )
+ close(fd);
+
+ if ( fst ) {
+ if ( from )
+ fclose(fst);
+ else
+ clearerr(fst);
+ }
+ if ( tst ) {
+ if ( to )
+ fclose(tst);
+ else {
+ /* flush stdout */
+ fflush(tst);
+ clearerr(tst);
+ }
+ }
return rval;
}
@@ -288,7 +322,7 @@ cd(char *path)
}
#ifdef HAVE_CEXP
-static CexpHelpTabRec _cexpHelpTabDirutils[]={
+static CexpHelpTabRec _cexpHelpTabDirutils[] __attribute__((unused)) = {
HELP(
"copy a file: cp(""from"",[""to""[,""-f""]])\n\
from = NULL <-- stdin\n\
diff --git a/rtemsNfs/src/nfs.c b/rtemsNfs/src/nfs.c
index 73f4354..c95e39a 100644
--- a/rtemsNfs/src/nfs.c
+++ b/rtemsNfs/src/nfs.c
@@ -1,4 +1,4 @@
-/* nfs.c,v 1.33 2004/09/22 22:10:41 till Exp */
+/* $Id$ */
/* NFS client implementation for RTEMS; hooks into the RTEMS filesystem */
@@ -173,7 +173,8 @@ static struct timeval _nfscalltimeout = { 10, 0 }; /* {secs, us } */
RTEMS_INHERIT_PRIORITY | \
RTEMS_BINARY_SEMAPHORE)
-#define LOCK(s) do { rtems_semaphore_obtain((s), \
+#define LOCK(s) do { \
+ rtems_semaphore_obtain((s), \
RTEMS_WAIT, \
RTEMS_NO_TIMEOUT); \
} while (0)
@@ -323,7 +324,7 @@ DirInfo dip;
/* we pass a 0 size - size is unused since
* we always pass a non-NULL pointer
*/
- if ( !xdr_pointer(xdrs, (caddr_t*)&dip, 0 /* size */, xdr_dir_info_entry) )
+ if ( !xdr_pointer(xdrs, (void*)&dip, 0 /* size */, (xdrproc_t)xdr_dir_info_entry) )
return FALSE;
}
@@ -457,12 +458,12 @@ xdr_serporid(XDR *xdrs, serporid *objp)
/* assume reading a long word is atomic */
#define READ_LONG_IS_ATOMIC
-typedef rtems_unsigned32 TimeStamp;
+typedef uint32_t TimeStamp;
static inline TimeStamp
nowSeconds(void)
{
-register rtems_unsigned32 rval;
+register uint32_t rval;
#ifndef READ_LONG_IS_ATOMIC
rtems_interrupt_level l;
@@ -486,12 +487,12 @@ typedef struct NfsRec_ {
/* statistics; how many NfsNodes are
* currently alive.
*/
- int nodesInUse;
+ volatile int nodesInUse;
#if DEBUG & DEBUG_COUNT_NODES
/* statistics; how many 'NfsNode.str'
* strings are currently allocated.
*/
- int stringsInUse;
+ volatile int stringsInUse;
#endif
/* A small number who uniquely
* identifies a mounted NFS within
@@ -582,10 +583,10 @@ static int
nfs_sattr(NfsNode node, sattr *arg, u_long mask);
extern struct _rtems_filesystem_operations_table nfs_fs_ops;
-extern struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers;
-extern struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers;
-extern struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers;
-extern rtems_driver_address_table drvNfs;
+static struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers;
+static struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers;
+static struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers;
+static rtems_driver_address_table drvNfs;
int
nfsMountsShow(FILE*);
@@ -818,6 +819,7 @@ static NfsNode
nfsNodeCreate(Nfs nfs, nfs_fh *fh)
{
NfsNode rval = malloc(sizeof(*rval));
+unsigned long flags;
#if DEBUG & DEBUG_TRACK_NODES
fprintf(stderr,"NFS: creating a node\n");
@@ -826,11 +828,11 @@ NfsNode rval = malloc(sizeof(*rval));
if (rval) {
if (fh)
memcpy( &SERP_FILE(rval), fh, sizeof(*fh) );
+ rtems_interrupt_disable(flags);
+ nfs->nodesInUse++;
+ rtems_interrupt_enable(flags);
rval->nfs = nfs;
rval->str = 0;
- LOCK(nfsGlob.lock);
- nfs->nodesInUse++;
- UNLOCK(nfsGlob.lock);
} else {
errno = ENOMEM;
}
@@ -842,6 +844,8 @@ NfsNode rval = malloc(sizeof(*rval));
static void
nfsNodeDestroy(NfsNode node)
{
+unsigned long flags;
+
#if DEBUG & DEBUG_TRACK_NODES
fprintf(stderr,"NFS: destroying a node\n");
#endif
@@ -852,13 +856,13 @@ nfsNodeDestroy(NfsNode node)
xdr_free(xdr_serporid, &node->serporid);
#endif
- LOCK(nfsGlob.lock);
- node->nfs->nodesInUse--;
+ rtems_interrupt_disable(flags);
+ node->nfs->nodesInUse--;
#if DEBUG & DEBUG_COUNT_NODES
- if (node->str)
- node->nfs->stringsInUse--;
+ if (node->str)
+ node->nfs->stringsInUse--;
#endif
- UNLOCK(nfsGlob.lock);
+ rtems_interrupt_enable(flags);
if (node->str)
free(node->str);
@@ -897,9 +901,11 @@ NfsNode rval = nfsNodeCreate(node->nfs, 0);
return 0;
}
#if DEBUG & DEBUG_COUNT_NODES
- LOCK(nfsGlob.lock);
+ { unsigned long flags;
+ rtems_interrupt_disable(flags);
node->nfs->stringsInUse++;
- UNLOCK(nfsGlob.lock);
+ rtems_interrupt_enable(flags);
+ }
#endif
}
@@ -928,8 +934,8 @@ nfsInit(int smallPoolDepth, int bigPoolDepth)
{
entry dummy;
- fprintf(stderr,"This is RTEMS-NFS Release SSRL_RTEMS_20041202\n");
- fprintf(stderr,"(nfs.c,v 1.33 2004/09/22 22:10:41 till Exp)\n\n");
+ fprintf(stderr,"This is RTEMS-NFS Release $Name$\n");
+ fprintf(stderr,"($Id$)\n\n");
fprintf(stderr,"Till Straumann, Stanford/SLAC/SSRL 2002\n");
fprintf(stderr,"See LICENSE file for licensing info\n");
@@ -956,7 +962,7 @@ entry dummy;
dummy.nextentry = 0;
dummy.name = "somename"; /* guess average length of a filename */
- dirres_entry_size = xdr_sizeof(xdr_entry, &dummy);
+ dirres_entry_size = xdr_sizeof((xdrproc_t)xdr_entry, &dummy);
assert( smallPool = rpcUdpXactPoolCreate(
NFS_PROGRAM,
@@ -1144,8 +1150,8 @@ updateAttr(NfsNode node, int force)
) {
if ( nfscall(node->nfs->server,
NFSPROC_GETATTR,
- xdr_nfs_fh, &SERP_FILE(node),
- xdr_attrstat, &node->serporid) )
+ (xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
+ (xdrproc_t)xdr_attrstat, &node->serporid) )
return -1;
if ( NFS_OK != node->serporid.status ) {
@@ -1221,7 +1227,7 @@ int len;
strncpy(host, chpt, len);
host[len]=0;
- if ( ! inet_aton(host, &psa->sin_addr) ) {
+ if ( ! inet_pton(AF_INET, host, &psa->sin_addr) ) {
errno = ENXIO;
return -1;
}
@@ -1333,6 +1339,10 @@ NfsNode node = pathloc->node_access;
char *p = malloc(MAXPATHLEN+1);
Nfs nfs = (Nfs)pathloc->mt_entry->fs_info;
RpcUdpServer server = nfs->server;
+unsigned long flags;
+#if DEBUG & DEBUG_COUNT_NODES
+unsigned long niu,siu;
+#endif
if ( !p ) {
e = ENOMEM;
@@ -1340,8 +1350,16 @@ RpcUdpServer server = nfs->server;
}
strcpy(p, pathname);
+ LOCK(nfsGlob.lock);
+ node = nfsNodeClone(node);
+ UNLOCK(nfsGlob.lock);
+
+ /* from here on, the NFS is protected from being unmounted
+ * since the node refcount is > 1
+ */
+
/* clone the node */
- if ( !(node = nfsNodeClone(node)) ) {
+ if ( !node ) {
/* nodeClone sets errno */
goto cleanup;
}
@@ -1482,8 +1500,8 @@ RpcUdpServer server = nfs->server;
if ( nfscall(server,
NFSPROC_LOOKUP,
- xdr_diropargs, &SERP_FILE(node),
- xdr_serporid, &node->serporid) ||
+ (xdrproc_t)xdr_diropargs, &SERP_FILE(node),
+ (xdrproc_t)xdr_serporid, &node->serporid) ||
NFS_OK != (errno=node->serporid.status) ) {
e = errno;
goto cleanup;
@@ -1518,8 +1536,8 @@ RpcUdpServer server = nfs->server;
if ( (nfscall(nfs->server,
NFSPROC_GETATTR,
- xdr_nfs_fh, &SERP_FILE(node),
- xdr_attrstat, &node->serporid) && !errno && (errno = EIO)) ||
+ (xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
+ (xdrproc_t)xdr_attrstat, &node->serporid) && !errno && (errno = EIO)) ||
(NFS_OK != (errno=node->serporid.status) ) ) {
goto cleanup;
}
@@ -1538,9 +1556,9 @@ RpcUdpServer server = nfs->server;
/* increment the 'in use' counter since we return one more
* reference to the root node
*/
- LOCK(nfsGlob.lock);
+ rtems_interrupt_disable(flags);
nfs->nodesInUse++;
- UNLOCK(nfsGlob.lock);
+ rtems_interrupt_enable(flags);
nfsNodeDestroy(node);
@@ -1558,9 +1576,9 @@ RpcUdpServer server = nfs->server;
if (node->args.name) {
if (node->str) {
#if DEBUG & DEBUG_COUNT_NODES
- LOCK(nfsGlob.lock);
+ rtems_interrupt_disable(flags);
nfs->stringsInUse--;
- UNLOCK(nfsGlob.lock);
+ rtems_interrupt_enable(flags);
#endif
free(node->str);
}
@@ -1571,9 +1589,9 @@ RpcUdpServer server = nfs->server;
}
#if DEBUG & DEBUG_COUNT_NODES
- LOCK(nfsGlob.lock);
+ rtems_interrupt_disable(flags);
nfs->stringsInUse++;
- UNLOCK(nfsGlob.lock);
+ rtems_interrupt_enable(flags);
#endif
}
@@ -1584,6 +1602,13 @@ RpcUdpServer server = nfs->server;
cleanup:
free(p);
+#if DEBUG & DEBUG_COUNT_NODES
+ /* cache counters; nfs may be unmounted by other thread after the last
+ * node is destroyed
+ */
+ niu = nfs->nodesInUse;
+ siu = nfs->stringsInUse;
+#endif
if (node) {
nfsNodeDestroy(node);
pathloc->node_access = 0;
@@ -1591,7 +1616,7 @@ cleanup:
#if DEBUG & DEBUG_COUNT_NODES
fprintf(stderr,
"leaving evalpath, in use count is %i nodes, %i strings\n",
- nfs->nodesInUse, nfs->stringsInUse);
+ niu,siu);
#endif
if (e) {
#if DEBUG & DEBUG_EVALPATH
@@ -1657,8 +1682,8 @@ NfsNode tNode = to_loc->node_access;
if ( nfscall(tNode->nfs->server,
NFSPROC_LINK,
- xdr_linkargs, &SERP_FILE(tNode),
- xdr_nfsstat, &status)
+ (xdrproc_t)xdr_linkargs, &SERP_FILE(tNode),
+ (xdrproc_t)xdr_nfsstat, &status)
|| (NFS_OK != (errno = status))
) {
#if DEBUG & DEBUG_SYSCALLS
@@ -1697,8 +1722,8 @@ char *name = NFSPROC_REMOVE == proc ?
if ( nfscall(nfs->server,
proc,
- xdr_diropargs, &node->args,
- xdr_nfsstat, &status)
+ (xdrproc_t)xdr_diropargs, &node->args,
+ (xdrproc_t)xdr_nfsstat, &status)
|| (NFS_OK != (errno = status))
) {
#if DEBUG & DEBUG_SYSCALLS
@@ -1739,26 +1764,31 @@ static int nfs_freenode(
{
Nfs nfs = ((NfsNode)pathloc->node_access)->nfs;
+#if DEBUG & DEBUG_COUNT_NODES
+ /* print counts at entry where they are > 0 so 'nfs' is safe from being destroyed
+ * and there's no race condition
+ */
+ fprintf(stderr,
+ "entering freenode, in use count is %i nodes, %i strings\n",
+ nfs->nodesInUse,
+ nfs->stringsInUse);
+#endif
+
/* never destroy the root node; it is released by the unmount
* code
*/
if (locIsRoot(pathloc)) {
+ unsigned long flags;
/* just adjust the references to the root node but
* don't really release it
*/
- LOCK(nfsGlob.lock);
+ rtems_interrupt_disable(flags);
nfs->nodesInUse--;
- UNLOCK(nfsGlob.lock);
+ rtems_interrupt_enable(flags);
} else {
nfsNodeDestroy(pathloc->node_access);
pathloc->node_access = 0;
}
-#if DEBUG & DEBUG_COUNT_NODES
- fprintf(stderr,
- "leaving freenode, in use count is %i nodes, %i strings\n",
- nfs->nodesInUse,
- nfs->stringsInUse);
-#endif
return 0;
}
@@ -1874,8 +1904,8 @@ char *path = mt_entry->dev;
*/
if ( nfscall(nfsServer,
NFSPROC_NULL,
- xdr_void, 0,
- xdr_void, 0) ) {
+ (xdrproc_t)xdr_void, 0,
+ (xdrproc_t)xdr_void, 0) ) {
fputs("NFS Ping ",stderr);
fwrite(host, 1, path-host-1, stderr);
@@ -1896,9 +1926,9 @@ char *path = mt_entry->dev;
stat = mntcall( &saddr,
MOUNTPROC_MNT,
- xdr_dirpath,
+ (xdrproc_t)xdr_dirpath,
&path,
- xdr_fhstatus,
+ (xdrproc_t)xdr_fhstatus,
&fhstat,
uid,
gid );
@@ -1975,11 +2005,11 @@ char *path = mt_entry->dev;
int nodesInUse;
u_long uid,gid;
- LOCK(nfsGlob.lock);
- nodesInUse = ((Nfs)mt_entry->fs_info)->nodesInUse;
- UNLOCK(nfsGlob.lock);
+LOCK(nfsGlob.llock);
+ nodesInUse = ((Nfs)mt_entry->fs_info)->nodesInUse;
if (nodesInUse > 1 /* one ref to the root node used by us */) {
+ UNLOCK(nfsGlob.llock);
fprintf(stderr,
"Refuse to unmount; there are still %i nodes in use (1 used by us)\n",
nodesInUse);
@@ -1990,13 +2020,14 @@ u_long uid,gid;
stat = mntcall( &saddr,
MOUNTPROC_UMNT,
- xdr_dirpath, &path,
- xdr_void, 0,
+ (xdrproc_t)xdr_dirpath, &path,
+ (xdrproc_t)xdr_void, 0,
uid,
gid
);
if (stat) {
+ UNLOCK(nfsGlob.llock);
fprintf(stderr,"NFS UMOUNT -- %s\n", clnt_sperrno(stat));
errno = EIO;
return -1;
@@ -2008,9 +2039,8 @@ u_long uid,gid;
nfsDestroy(mt_entry->fs_info);
mt_entry->fs_info = 0;
- LOCK(nfsGlob.llock);
- nfsGlob.num_mounted_fs--;
- UNLOCK(nfsGlob.llock);
+ nfsGlob.num_mounted_fs--;
+UNLOCK(nfsGlob.llock);
return 0;
}
@@ -2084,8 +2114,8 @@ mode_t type = S_IFMT & mode;
if ( nfscall( node->nfs->server,
NFSPROC_CREATE,
- xdr_createargs, &SERP_FILE(node),
- xdr_diropres, &res)
+ (xdrproc_t)xdr_createargs, &SERP_FILE(node),
+ (xdrproc_t)xdr_diropres, &res)
|| (NFS_OK != (errno = res.status)) ) {
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_mknod");
@@ -2145,8 +2175,8 @@ NfsNode node = loc->node_access;
if ( nfscall( node->nfs->server,
NFSPROC_SYMLINK,
- xdr_symlinkargs, &SERP_FILE(node),
- xdr_nfsstat, &status)
+ (xdrproc_t)xdr_symlinkargs, &SERP_FILE(node),
+ (xdrproc_t)xdr_nfsstat, &status)
|| (NFS_OK != (errno = status)) ) {
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_symlink");
@@ -2174,16 +2204,16 @@ int rval;
if ( (rval = nfscall(nfs->server,
NFSPROC_READLINK,
- xdr_nfs_fh, &SERP_FILE(node),
- xdr_readlinkres_strbuf, &rr)) ) {
+ (xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
+ (xdrproc_t)xdr_readlinkres_strbuf, &rr)) ) {
if (wasAlloced)
- xdr_free( xdr_strbuf, (caddr_t)&rr.strbuf );
+ xdr_free( (xdrproc_t)xdr_strbuf, (caddr_t)&rr.strbuf );
}
if (NFS_OK != rr.status) {
if (wasAlloced)
- xdr_free( xdr_strbuf, (caddr_t)&rr.strbuf );
+ xdr_free( (xdrproc_t)xdr_strbuf, (caddr_t)&rr.strbuf );
rtems_set_errno_and_return_minus_one(rr.status);
}
@@ -2413,10 +2443,10 @@ struct rtems_libio_tt {
rtems_driver_name_t *driver;
off_t size; /* size of file */
off_t offset; /* current offset into file */
- unsigned32 flags;
+ uint32_t flags;
rtems_filesystem_location_info_t pathinfo;
Objects_Id sem;
- unsigned32 data0; /* private to "driver" */
+ uint32_t data0; /* private to "driver" */
void *data1; /* ... */
void *file_info; /* used by file handlers */
rtems_filesystem_file_handlers_r *handlers; /* type specific handlers */
@@ -2427,8 +2457,8 @@ struct rtems_libio_tt {
static int nfs_file_open(
rtems_libio_t *iop,
const char *pathname,
- unsigned32 flag,
- unsigned32 mode
+ uint32_t flag,
+ uint32_t mode
)
{
iop->file_info = 0;
@@ -2443,8 +2473,8 @@ static int nfs_file_open(
static int nfs_dir_open(
rtems_libio_t *iop,
const char *pathname,
- unsigned32 flag,
- unsigned32 mode
+ uint32_t flag,
+ uint32_t mode
)
{
NfsNode node = iop->pathinfo.node_access;
@@ -2499,7 +2529,7 @@ static int nfs_dir_close(
static int nfs_file_read(
rtems_libio_t *iop,
void *buffer,
- unsigned32 count
+ uint32_t count
)
{
readres rr;
@@ -2517,8 +2547,8 @@ Nfs nfs = node->nfs;
if ( nfscall( nfs->server,
NFSPROC_READ,
- xdr_readargs, &SERP_FILE(node),
- xdr_readres, &rr) ) {
+ (xdrproc_t)xdr_readargs, &SERP_FILE(node),
+ (xdrproc_t)xdr_readres, &rr) ) {
return -1;
}
@@ -2544,7 +2574,7 @@ Nfs nfs = node->nfs;
static int nfs_dir_read(
rtems_libio_t *iop,
void *buffer,
- unsigned32 count
+ uint32_t count
)
{
DirInfo di = iop->file_info;
@@ -2585,8 +2615,8 @@ RpcUdpServer server = ((Nfs)iop->pathinfo.mt_entry->fs_info)->server;
if ( nfscall(
server,
NFSPROC_READDIR,
- xdr_readdirargs, &di->readdirargs,
- xdr_dir_info, di) ) {
+ (xdrproc_t)xdr_readdirargs, &di->readdirargs,
+ (xdrproc_t)xdr_dir_info, di) ) {
return -1;
}
@@ -2603,7 +2633,7 @@ RpcUdpServer server = ((Nfs)iop->pathinfo.mt_entry->fs_info)->server;
static int nfs_file_write(
rtems_libio_t *iop,
const void *buffer,
- unsigned32 count
+ uint32_t count
)
{
NfsNode node = iop->pathinfo.node_access;
@@ -2613,8 +2643,16 @@ int e;
if (count > NFS_MAXDATA)
count = NFS_MAXDATA;
+
SERP_ARGS(node).writearg.beginoffset = 0xdeadbeef;
- SERP_ARGS(node).writearg.offset = iop->offset;
+ if ( LIBIO_FLAGS_APPEND & iop->flags ) {
+ if ( updateAttr(node, 0) ) {
+ return -1;
+ }
+ SERP_ARGS(node).writearg.offset = SERP_ATTR(node).size;
+ } else {
+ SERP_ARGS(node).writearg.offset = iop->offset;
+ }
SERP_ARGS(node).writearg.totalcount = 0xdeadbeef;
SERP_ARGS(node).writearg.data.data_len = count;
SERP_ARGS(node).writearg.data.data_val = (void*)buffer;
@@ -2625,8 +2663,8 @@ int e;
if ( nfscall( nfs->server,
NFSPROC_WRITE,
- xdr_writeargs, &SERP_FILE(node),
- xdr_attrstat, &node->serporid) ) {
+ (xdrproc_t)xdr_writeargs, &SERP_FILE(node),
+ (xdrproc_t)xdr_attrstat, &node->serporid) ) {
return -1;
}
@@ -2649,7 +2687,7 @@ int e;
#ifdef DECLARE_BODY
static int nfs_file_ioctl(
rtems_libio_t *iop,
- unsigned32 command,
+ uint32_t command,
void *buffer
)DECLARE_BODY
#else
@@ -2671,6 +2709,21 @@ static int nfs_file_lseek(
length,
whence);
#endif
+ if ( SEEK_END == whence ) {
+ /* rtems (4.6.2) libcsupport code 'lseek' uses iop->size to
+ * compute the offset. We don't want to track the file size
+ * by updating 'iop->size' constantly.
+ * Since lseek is the only place using iop->size, we work
+ * around this by tweaking the offset here...
+ */
+ NfsNode node = iop->pathinfo.node_access;
+ fattr *fa = &SERP_ATTR(node);
+
+ if (updateAttr(node, 0 /* only if old */)) {
+ return -1;
+ }
+ iop->offset = fa->size;
+ }
/* this is particularly easy :-) */
return iop->offset;
@@ -2837,24 +2890,26 @@ u_int mode;
if (mask & SATTR_MODE) {
mode &= S_IFMT;
mode |= arg->mode & ~S_IFMT;
+ } else {
+ mode = -1;
}
SERP_ARGS(node).sattrarg.attributes.mode = mode;
SERP_ARGS(node).sattrarg.attributes.uid =
- (mask & SATTR_UID) ? arg->uid : SERP_ATTR(node).uid;
+ (mask & SATTR_UID) ? arg->uid : -1;
SERP_ARGS(node).sattrarg.attributes.gid =
- (mask & SATTR_GID) ? arg->gid : SERP_ATTR(node).gid;
+ (mask & SATTR_GID) ? arg->gid : -1;
SERP_ARGS(node).sattrarg.attributes.size =
- (mask & SATTR_SIZE) ? arg->size : SERP_ATTR(node).size;
+ (mask & SATTR_SIZE) ? arg->size : -1;
if (mask & SATTR_ATIME)
t = arg->atime;
else if (mask & SATTR_TOUCHA)
t = nfsnow;
else
- t = SERP_ATTR(node).atime;
+ t.seconds = t.useconds = -1;
SERP_ARGS(node).sattrarg.attributes.atime = t;
if (mask & SATTR_ATIME)
@@ -2862,15 +2917,15 @@ u_int mode;
else if (mask & SATTR_TOUCHA)
t = nfsnow;
else
- t = SERP_ATTR(node).mtime;
+ t.seconds = t.useconds = -1;
SERP_ARGS(node).sattrarg.attributes.mtime = t;
node->serporid.status = NFS_OK;
if ( nfscall( node->nfs->server,
NFSPROC_SETATTR,
- xdr_sattrargs, &SERP_FILE(node),
- xdr_attrstat, &node->serporid) ) {
+ (xdrproc_t)xdr_sattrargs, &SERP_FILE(node),
+ (xdrproc_t)xdr_attrstat, &node->serporid) ) {
#if DEBUG & DEBUG_SYSCALLS
fprintf(stderr,
"nfs_sattr (mask 0x%08x): %s",
@@ -2919,9 +2974,13 @@ static int nfs_file_ftruncate(
sattr arg;
arg.size = length;
+ /* must not modify any other attribute; if we are not the owner
+ * of the file or directory but only have write access changing
+ * any attribute besides 'size' will fail...
+ */
return nfs_sattr(iop->pathinfo.node_access,
&arg,
- SATTR_SIZE | SATTR_TOUCH);
+ SATTR_SIZE);
}
#define nfs_dir_ftruncate 0
diff --git a/rtemsNfs/src/rpcio.c b/rtemsNfs/src/rpcio.c
index 667ba6a..922ae5e 100644
--- a/rtemsNfs/src/rpcio.c
+++ b/rtemsNfs/src/rpcio.c
@@ -764,7 +764,7 @@ va_list ap;
/* increment transaction ID */
xact->obuf.xid += XACT_HASHS;
XDR_SETPOS(xdrs, xact->xdrpos);
- if ( !XDR_PUTLONG(xdrs,&proc) || !locked_marshal(srvr, xdrs) ||
+ if ( !XDR_PUTLONG(xdrs,(long*)&proc) || !locked_marshal(srvr, xdrs) ||
!xargs(xdrs, pargs) ) {
va_end(ap);
return(xact->status.re_status=RPC_CANTENCODEARGS);
@@ -1106,7 +1106,7 @@ rtems_interval next_retrans, then, unow;
long now; /* need to do signed comparison with age! */
rtems_event_set events;
ListNode newList;
-rtems_unsigned32 size;
+uint32_t size;
rtems_id q = 0;
ListNodeRec listHead = {0};
unsigned long epoch = RPCIOD_EPOCH_SECS * ticksPerSec;
@@ -1489,8 +1489,8 @@ RpcUdpXact xact;
RpcUdpXact
rpcUdpXactPoolGet(RpcUdpXactPool pool, XactPoolGetMode mode)
{
-RpcUdpXact xact = 0;
-rtems_unsigned32 size;
+RpcUdpXact xact = 0;
+uint32_t size;
if (RTEMS_SUCCESSFUL != rtems_message_queue_receive(
pool->box,
@@ -1534,6 +1534,7 @@ RpcUdpXactPool pool;
*/
#define KERNEL
+#define _KERNEL
#include <sys/mbuf.h>
ssize_t
diff --git a/rtemsNfs/src/sock_mbuf.c b/rtemsNfs/src/sock_mbuf.c
index 70c09d6..217d8b6 100644
--- a/rtemsNfs/src/sock_mbuf.c
+++ b/rtemsNfs/src/sock_mbuf.c
@@ -85,6 +85,8 @@ SOFTWARE.
#include <rtems/error.h>
#define KERNEL
+#define _KERNEL
+#define __BSD_VISIBLE 1
#include <rtems/rtems_bsdnet.h>
#include <sys/errno.h>