From 856b0f3fe1f11b8e7777c03406882e5a3ba65b97 Mon Sep 17 00:00:00 2001 From: Eric Norum Date: Fri, 9 Jun 2006 18:44:03 +0000 Subject: Bring up to date with latest version from SLAC. --- rtemsNfs/ChangeLog | 36 ++ rtemsNfs/README | 6 + rtemsNfs/proto/Makefile | 3 +- rtemsNfs/proto/mount_prot.h | 182 ++++-- rtemsNfs/proto/mount_prot_xdr.c | 138 +++-- rtemsNfs/proto/nfs_prot.h | 449 ++++++++++---- rtemsNfs/proto/nfs_prot_xdr.c | 887 +++++++++++++-------------- rtemsNfs/rfc1094.txt | 1258 +++++++++++++++++++++++++++++++++++++++ rtemsNfs/src/Makefile | 2 +- rtemsNfs/src/dirutils.c | 104 ++-- rtemsNfs/src/nfs.c | 251 +++++--- rtemsNfs/src/rpcio.c | 9 +- rtemsNfs/src/sock_mbuf.c | 2 + 13 files changed, 2513 insertions(+), 814 deletions(-) create mode 100644 rtemsNfs/rfc1094.txt 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 - +#define RPCGEN_VERSION 199506 -#ifdef __cplusplus -extern "C" { -#endif +#include #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 - +#define RPCGEN_VERSION 199506 -#ifdef __cplusplus -extern "C" { -#endif +#include #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 , "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 , "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; + + The type "filename" is used for passing file names or pathname + components. + +2.3.8. path + + typedef string path; + + 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 , "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; + + The type "dirpath" is a server pathname of a directory. + +A.4.4. name + + typedef string name; + + 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 + +Comment on RFC 1094 + + + +Comments about this RFC: + + * RFC 1094: I am preparing for doing a project in File System in + Network. can you specify... by Ravik (12/4/2003) + + +Previous: RFC 1093 - NSFNET routing architecture + + + +Next: RFC 1095 - Common Management Information Services and Protocol +over TCP/IP (CMOT) + + + +------------------------------------------------------------------------ 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 #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 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 #define KERNEL +#define _KERNEL +#define __BSD_VISIBLE 1 #include #include -- cgit v1.2.3