diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-06-10 23:17:10 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-06-10 23:17:10 +0000 |
commit | 744fec52392e8d154eacb3ff2bdd5992266d8dd5 (patch) | |
tree | 3c82b2818e6362433b43db3bf37e4799ab287b86 /nuttx | |
parent | 7aecf6e0d49944b5c2a3024cc4b75a82b3ca8078 (diff) | |
download | px4-firmware-744fec52392e8d154eacb3ff2bdd5992266d8dd5.tar.gz px4-firmware-744fec52392e8d154eacb3ff2bdd5992266d8dd5.tar.bz2 px4-firmware-744fec52392e8d154eacb3ff2bdd5992266d8dd5.zip |
NFS update
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4825 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/fs/nfs/nfs.h | 1 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_node.h | 99 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_proto.h | 154 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_socket.c | 1 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_util.c | 2 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_vfsops.c | 431 | ||||
-rw-r--r-- | nuttx/fs/nfs/rpc.h | 7 | ||||
-rw-r--r-- | nuttx/fs/nfs/rpc_clnt.c | 23 | ||||
-rw-r--r-- | nuttx/fs/nfs/xdr_subs.h | 1 |
9 files changed, 405 insertions, 314 deletions
diff --git a/nuttx/fs/nfs/nfs.h b/nuttx/fs/nfs/nfs.h index fb36dafa5..d3f47e026 100644 --- a/nuttx/fs/nfs/nfs.h +++ b/nuttx/fs/nfs/nfs.h @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h index ff0380c85..377d2a88f 100644 --- a/nuttx/fs/nfs/nfs_node.h +++ b/nuttx/fs/nfs/nfs_node.h @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * @@ -53,91 +54,39 @@ * Pre-processor Definitions ****************************************************************************/ -/* Values for n_commitflags */ +/* Flags for struct nfsnode n_flag */ -#define NFS_COMMIT_PUSH_VALID 0x0001 /* Push range valid */ -#define NFS_COMMIT_PUSHED_VALID 0x0002 /* Pushed range valid */ - -#define n_atim n_un1.nf_atim -#define n_mtim n_un2.nf_mtim -#define n_cookieverf n_un1.nd_cookieverf - -/* Flags for n_flag */ - -#define NFLUSHWANT 0x0001/* Want wakeup from a flush in prog. */ -#define NFLUSHINPROG 0x0002/* Avoid multiple calls to vinvalbuf() */ -#define NMODIFIED 0x0004/* Might have a modified buffer in bio */ -#define NWRITEERR 0x0008/* Flag write errors so close will know */ -#define NACC 0x0100/* Special file accessed */ -#define NUPD 0x0200/* Special file updated */ -#define NCHG 0x0400/* Special file times changed */ - -#define NFS_INVALIDATE_ATTRCACHE(np) ((np)->n_attrstamp = 0) - -/* Convert between nfsnode pointers and vnode pointers */ - -#define VTONFS(vp) ((struct nfsnode *)(vp)->f_priv) -#define NFSTOV(np) ((np)->n_vnode) - -#define n_atim n_un1.nf_atim -#define n_mtim n_un2.nf_mtim -#define n_sillyrename n_un3.nf_silly -#define n_cookieverf n_un1.nd_cookieverf -#define n4_cookieverf n_un1.nd4_cookieverf -#define n_cookies n_un3.nd_cook +#define NFSNODE_OPEN (1 << 0) /* File is still open */ +#define NFSNODE_MODIFIED (1 << 1) /* Might have a modified buffer */ /**************************************************************************** * Public Types ****************************************************************************/ -/* The nfsnode is the nfs equivalent to ufs's inode. Any similarity - * is purely coincidental. - * There is a unique nfsnode allocated for each active file, - * each current directory, each mounted-on file, text file, and the root. - * An nfsnode is 'named' by its file handle. (nget/nfs_node.c) - * If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite - * type definitions), file handles of > 32 bytes should probably be split out - * into a separate malloc()'d data structure. (Reduce the size of nfsfh_t by - * changing the definition in sys/mount.h of NFS_SMALLFH.) - * NB: Hopefully the current order of the fields is such that everything will - * be well aligned and, therefore, tightly packed. +/* There is a unique nfsnode allocated for each active file. An nfsnode is + * 'named' by its file handle. + * + * NOTE: n_size, n_mtime, and n_ctime are duplicted withing n_attr. We could + * eliminate those fields and save some memory. */ struct nfsnode { - struct nfsnode *n_next; /* Retained in a singly linked list filehandle/node tree. */ - bool n_open; /* true: The file is (still) open */ - uint64_t n_size; /* Current size of file */ - struct nfs_fattr n_fattr; /* nfs file attribute cache */ - uint8_t nfsv3_type; /* File type */ - time_t n_attrstamp; /* Attr. cache timestamp */ - struct timespec n_mtime; /* Prev modify time. */ - time_t n_ctime; /* Prev create time. */ - nfsfh_t n_fhp; /* NFS File Handle */ - uint32_t n_error; /* Save write error value */ - union - { - struct timespec nf_atim; /* Special file times */ - uint8_t nd_cookieverf[NFSX_V3WRITEVERF]; /* Cookie verifier (dir only) */ - } n_un1; - union - { - struct timespec nf_mtim; - } n_un2; - uint32_t n_fhsize; /* size in bytes, of fh */ - short n_flag; /* Flag for locking.. */ -//nfsfh_t n_fh; /* Small File Handle */ - time_t n_accstamp; /* Access cache timestamp */ - uid_t n_accuid; /* Last access requester */ - int n_accmode; /* Last mode requested */ - int n_accerror; /* Last returned error */ - -//off_t n_pushedlo; /* 1st blk in commited range */ -//off_t n_pushedhi; /* Last block in range */ -//off_t n_pushlo; /* 1st block in commit range */ -//off_t n_pushhi; /* Last block in range */ -//struct rwlock n_commitlock; /* Serialize commits */ -//int n_commitflags; + struct nfsnode *n_next; /* Retained in a singly linked list. */ + uint8_t n_type; /* File type */ + uint8_t n_fhsize; /* Size in bytes of the file handle */ + uint8_t n_flags; /* Node flags */ + uint16_t n_buflen; /* Size of I/O buffer */ + struct nfs_fattr n_fattr; /* nfs file attribute cache (network order) */ + struct timespec n_mtime; /* Prev modify time (see NOTE) */ + time_t n_ctime; /* Prev create time (see NOTE) */ + nfsfh_t n_fhandle; /* NFS File Handle */ + uint64_t n_size; /* Current size of file (see NOTE) */ + + /* I/O buffer (must be a aligned to 32-bit boundaries) */ + + uint8_t n_iobuffer[1]; /* Actual size is given by n_buflen */ }; +#define SIZEOF_nfsnode(n) (sizeof(struct nfsnode) + ((n)-1)) #endif /* __FS_NFS_NFS_NODE_H */ diff --git a/nuttx/fs/nfs/nfs_proto.h b/nuttx/fs/nfs/nfs_proto.h index b9d4655c3..c5800b216 100644 --- a/nuttx/fs/nfs/nfs_proto.h +++ b/nuttx/fs/nfs/nfs_proto.h @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * @@ -214,95 +215,95 @@ #define NFSV3SATTRTIME_TOSERVER 1 #define NFSV3SATTRTIME_TOCLIENT 2 -#define NFSV3ACCESS_READ 0x01 -#define NFSV3ACCESS_LOOKUP 0x02 -#define NFSV3ACCESS_MODIFY 0x04 -#define NFSV3ACCESS_EXTEND 0x08 -#define NFSV3ACCESS_DELETE 0x10 -#define NFSV3ACCESS_EXECUTE 0x20 +#define NFSV3ACCESS_READ 0x01 +#define NFSV3ACCESS_LOOKUP 0x02 +#define NFSV3ACCESS_MODIFY 0x04 +#define NFSV3ACCESS_EXTEND 0x08 +#define NFSV3ACCESS_DELETE 0x10 +#define NFSV3ACCESS_EXECUTE 0x20 -#define NFSV3WRITE_UNSTABLE 0 -#define NFSV3WRITE_DATASYNC 1 -#define NFSV3WRITE_FILESYNC 2 +#define NFSV3WRITE_UNSTABLE 0 +#define NFSV3WRITE_DATASYNC 1 +#define NFSV3WRITE_FILESYNC 2 -#define NFSV3CREATE_UNCHECKED 0 -#define NFSV3CREATE_GUARDED 1 -#define NFSV3CREATE_EXCLUSIVE 2 +#define NFSV3CREATE_UNCHECKED 0 +#define NFSV3CREATE_GUARDED 1 +#define NFSV3CREATE_EXCLUSIVE 2 -#define NFSV3FSINFO_LINK 0x01 -#define NFSV3FSINFO_SYMLINK 0x02 -#define NFSV3FSINFO_HOMOGENEOUS 0x08 -#define NFSV3FSINFO_CANSETTIME 0x10 +#define NFSV3FSINFO_LINK 0x01 +#define NFSV3FSINFO_SYMLINK 0x02 +#define NFSV3FSINFO_HOMOGENEOUS 0x08 +#define NFSV3FSINFO_CANSETTIME 0x10 /* NFS mount option flags */ -#define NFSMNT_SOFT 0x00000001 /* soft mount (hard is default) */ -#define NFSMNT_WSIZE 0x00000002 /* set write size */ -#define NFSMNT_RSIZE 0x00000004 /* set read size */ -#define NFSMNT_TIMEO 0x00000008 /* set initial timeout */ -#define NFSMNT_RETRANS 0x00000010 /* set number of request retries */ -#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */ -#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */ -#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */ +#define NFSMNT_SOFT 0x00000001 /* soft mount (hard is default) */ +#define NFSMNT_WSIZE 0x00000002 /* set write size */ +#define NFSMNT_RSIZE 0x00000004 /* set read size */ +#define NFSMNT_TIMEO 0x00000008 /* set initial timeout */ +#define NFSMNT_RETRANS 0x00000010 /* set number of request retries */ +#define NFSMNT_MAXGRPS 0x00000020 /* set maximum grouplist size */ +#define NFSMNT_INT 0x00000040 /* allow interrupts on hard mount */ +#define NFSMNT_NOCONN 0x00000080 /* Don't Connect the socket */ /* 0x100 free, was NFSMNT_NQNFS */ -#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */ +#define NFSMNT_NFSV3 0x00000200 /* Use NFS Version 3 protocol */ /* 0x400 free, was NFSMNT_KERB */ -#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */ +#define NFSMNT_DUMBTIMR 0x00000800 /* Don't estimate rtt dynamically */ /* 0x1000 free, was NFSMNT_LEASETERM */ -#define NFSMNT_READAHEAD 0x00002000 /* set read ahead */ -#define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */ -#define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */ -#define NFSMNT_RDIRPLUS 0x00010000 /* Use Readdirplus for V3 */ -#define NFSMNT_READDIRSIZE 0x00020000 /* Set readdir size */ -#define NFSMNT_ACREGMIN 0x00040000 -#define NFSMNT_ACREGMAX 0x00080000 -#define NFSMNT_ACDIRMIN 0x00100000 -#define NFSMNT_ACDIRMAX 0x00200000 -#define NFSMNT_NOLOCKD 0x00400000 /* Locks are local */ -#define NFSMNT_NFSV4 0x00800000 /* Use NFS Version 4 protocol */ -#define NFSMNT_HASWRITEVERF 0x01000000 /* NFSv4 Write verifier */ -#define NFSMNT_GOTFSINFO 0x00000004 /* Got the V3 fsinfo */ -#define NFSMNT_INTERNAL 0xfffc0000 /* Bits set internally */ -#define NFSMNT_NOAC 0x00080000 /* Turn off attribute cache */ +#define NFSMNT_READAHEAD 0x00002000 /* set read ahead */ +#define NFSMNT_DEADTHRESH 0x00004000 /* set dead server retry thresh */ +#define NFSMNT_RESVPORT 0x00008000 /* Allocate a reserved port */ +#define NFSMNT_RDIRPLUS 0x00010000 /* Use Readdirplus for V3 */ +#define NFSMNT_READDIRSIZE 0x00020000 /* Set readdir size */ +#define NFSMNT_ACREGMIN 0x00040000 +#define NFSMNT_ACREGMAX 0x00080000 +#define NFSMNT_ACDIRMIN 0x00100000 +#define NFSMNT_ACDIRMAX 0x00200000 +#define NFSMNT_NOLOCKD 0x00400000 /* Locks are local */ +#define NFSMNT_NFSV4 0x00800000 /* Use NFS Version 4 protocol */ +#define NFSMNT_HASWRITEVERF 0x01000000 /* NFSv4 Write verifier */ +#define NFSMNT_GOTFSINFO 0x00000004 /* Got the V3 fsinfo */ +#define NFSMNT_INTERNAL 0xfffc0000 /* Bits set internally */ +#define NFSMNT_NOAC 0x00080000 /* Turn off attribute cache */ /* Conversion macros */ #define vtonfsv2_mode(t,m) \ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ MAKEIMODE((t), (m))) -#define vtonfsv3_mode(m) txdr_unsigned((m) & 07777) -#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777) -#define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))]) -#define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))]) -#define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(uint32_t,(a))&0x7] -#define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(uint32_t,(a))&0x7] +#define vtonfsv3_mode(m) txdr_unsigned((m) & 07777) +#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777) +#define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))]) +#define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))]) +#define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(uint32_t,(a))&0x7] +#define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(uint32_t,(a))&0x7] -#define NFS_MAXFHSIZE 64 +#define NFS_MAXFHSIZE 64 /* Mode bit values */ -#define NFSMMODE_IXOTH 0x00001 /* Execute permission for others on a file */ -#define NFSMMODE_IWOTH 0x00002 /* Write permission for others */ -#define NFSMMODE_IROTH 0x00004 /* Read permission for others */ -#define NFSMMODE_IXGRP 0x00008 /* Execute permission for group on a file */ -#define NFSMMODE_IWGRP 0x00010 /* Write permission for group */ -#define NFSMMODE_IRGRP 0x00020 /* Read permission for group */ -#define NFSMMODE_IXUSR 0x00040 /* Execute permission for owner on a file */ -#define NFSMMODE_IWUSR 0x00080 /* Write permission for owner */ -#define NFSMMODE_IRUSR 0x00100 /* Read permission for owner */ -#define NFSMMODE_SAVETEXT 0x00200 /* Save swapped text */ -#define NFSMMODE_ISGID 0x00400 /* Set group ID on execution */ -#define NFSMMODE_ISUID 0x00800 /* Set user ID on execution */ +#define NFSMODE_IXOTH 0x00001 /* Execute permission for others on a file */ +#define NFSMODE_IWOTH 0x00002 /* Write permission for others */ +#define NFSMODE_IROTH 0x00004 /* Read permission for others */ +#define NFSMODE_IXGRP 0x00008 /* Execute permission for group on a file */ +#define NFSMODE_IWGRP 0x00010 /* Write permission for group */ +#define NFSMODE_IRGRP 0x00020 /* Read permission for group */ +#define NFSMODE_IXUSR 0x00040 /* Execute permission for owner on a file */ +#define NFSMODE_IWUSR 0x00080 /* Write permission for owner */ +#define NFSMODE_IRUSR 0x00100 /* Read permission for owner */ +#define NFSMODE_SAVETEXT 0x00200 /* Save swapped text */ +#define NFSMODE_ISGID 0x00400 /* Set group ID on execution */ +#define NFSMODE_ISUID 0x00800 /* Set user ID on execution */ /* File identifier */ -#define MAXFIDSZ 16 +#define MAXFIDSZ 16 /**************************************************************************** * Public Types @@ -620,29 +621,42 @@ struct LOOKUP3resok struct READ3args { - nfstype file; + struct file_handle fshandle; /* Variable length */ uint64_t offset; uint32_t count; }; -struct READ3resok +struct nfs_rdhdr_s { - struct nfs_fattr file_attributes; - uint32_t count; - bool eof; - const char *data; + uint32_t attributes_follow; + struct nfs_fattr attributes; /* Will not be present if attributes_follow == 0 */ + uint32_t count; /* Number of bytes read */ + uint32_t eof; /* Non-zero if at the end of file */ + uint32_t length; /* Length of data (same as count?) */ }; +struct READ3resok +{ + struct nfs_rdhdr_s hdr; + uint8_t data[1]; /* Actual data size depends on count */ +}; +#define SIZEOF_READ3resok(n) (sizeof(struct nfs_rdhdr_s) + (n)) -struct WRITE3args +struct nfs_wrhdr_s { - nfstype file; + struct file_handle fshandle; /* Variable length */ uint64_t offset; uint32_t count; uint32_t stable; - const char *data; }; +struct WRITE3args +{ + struct nfs_wrhdr_s hdr; + uint8_t data[1]; /* Actual data size depends on count */ +}; +#define SIZEOF_WRITE3args(n) (sizeof(struct nfs_wrhdr_s) + (n)) + struct WRITE3resok { struct wcc_data file_wcc; diff --git a/nuttx/fs/nfs/nfs_socket.c b/nuttx/fs/nfs/nfs_socket.c index 133121b29..998287b79 100644 --- a/nuttx/fs/nfs/nfs_socket.c +++ b/nuttx/fs/nfs/nfs_socket.c @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * diff --git a/nuttx/fs/nfs/nfs_util.c b/nuttx/fs/nfs/nfs_util.c index 5d8ac7bb6..8309b8d78 100644 --- a/nuttx/fs/nfs/nfs_util.c +++ b/nuttx/fs/nfs/nfs_util.c @@ -186,7 +186,7 @@ int nfs_checkmount(struct nfsmount *nmp) for (file = nmp->nm_head; file; file = file->n_next) { - file->n_open = false; + file->n_flags &= ~NFSNODE_OPEN; } return -ENODEV; diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c index 40f482abe..4f19b9a6e 100644 --- a/nuttx/fs/nfs/nfs_vfsops.c +++ b/nuttx/fs/nfs/nfs_vfsops.c @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * @@ -57,15 +58,19 @@ #include <queue.h> #include <string.h> #include <fcntl.h> +#include <time.h> +#include <semaphore.h> #include <assert.h> #include <errno.h> #include <debug.h> -#include <time.h> + #include <nuttx/kmalloc.h> #include <nuttx/fs/dirent.h> #include <nuttx/fs/fs.h> #include <nuttx/fs/nfs.h> -#include <semaphore.h> +#include <nuttx/net/uip/uip.h> +#include <nuttx/net/uip/uip-udp.h> +#include <nuttx/net/uip/uipopt.h> #include <net/if.h> #include <netinet/in.h> @@ -217,7 +222,7 @@ static int nfs_create(FAR struct nfsmount *nmp, struct nfsnode *np, memcpy(&create.how, &sp, sizeof(struct nfsv3_sattr)); #warning "BUG HERE: np has not yet been initialized" create.where.dir.length = txdr_unsigned(np->n_fhsize); - memcpy(&create.where.dir.handle, &np->n_fhp, sizeof(nfsfh_t)); + memcpy(&create.where.dir.handle, &np->n_fhandle, sizeof(nfsfh_t)); create.where.length = txdr_unsigned(64); strncpy(create.where.name, relpath, 64); @@ -229,14 +234,14 @@ static int nfs_create(FAR struct nfsmount *nmp, struct nfsnode *np, if (error == 0) { - //np->nfsv3_type = fxdr_unsigned(uint32_t, resok.attributes.fa_type); + //np->n_type = fxdr_unsigned(uint32_t, resok.attributes.fa_type); - np->n_open = true; - memcpy(&np->n_fhp, &resok.create.fshandle.handle, sizeof(nfsfh_t)); + memcpy(&np->n_fhandle, &resok.create.fshandle.handle, sizeof(nfsfh_t)); np->n_size = fxdr_hyper(&resok.create.attributes.fa3_size); memcpy(&resok.create.attributes, &np->n_fattr, sizeof(struct nfs_fattr)); fxdr_nfsv3time(&resok.create.attributes.fa3_mtime, &np->n_mtime) np->n_ctime = fxdr_hyper(&resok.create.attributes.fa3_ctime); + np->n_flags = NFSNODE_OPEN; } return error; @@ -257,13 +262,13 @@ static int nfs_create(FAR struct nfsmount *nmp, struct nfsnode *np, static int nfs_open(FAR struct file *filep, FAR const char *relpath, int oflags, mode_t mode) { - struct stat buf; - struct inode *in; -//struct nfs_fattr vap; - struct nfsmount *nmp; - struct nfsnode *np; - bool readonly; - int error = 0; + struct file_handle fhandle; + struct inode *in; + struct nfsmount *nmp; + struct nfsnode *np; + uint32_t buflen; + uint32_t tmp; + int error = 0; /* Sanity checks */ @@ -278,15 +283,49 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath, DEBUGASSERT(nmp != NULL); + /* Determine the size of a buffer that will hold one RPC data transfer */ + + { + /* Get the maximum size of a read and a write transfer */ + + buflen = SIZEOF_rpc_call_write(nmp->nm_wsize); + tmp = SIZEOF_rpc_reply_read(nmp->nm_rsize); + + /* The buffer size will be the maximum of those two sizes */ + + if (tmp > buflen) + { + buflen = tmp; + } + + /* But don't let the buffer size exceed the MSS of the socket type */ + +#ifdef CONFIG_NFS_TCPIP + if (buflen > UIP_TCP_MSS) + { + buflen = UIP_TCP_MSS; + } +#else + if (buflen > UIP_UDP_MSS) + { + buflen = UIP_UDP_MSS; + } +#endif + } + /* Pre-allocate the file private data to describe the opened file. */ - np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode)); + np = (struct nfsnode *)kzalloc(SIZEOF_nfsnode(buflen)); if (!np) { fdbg("ERROR: Failed to allocate private data\n"); return -ENOMEM; } + /* Save the allocated I/O buffer size */ + + np->n_buflen = (uint16_t)buflen; + /* Check if the mount is still healthy */ nfs_semtake(nmp); @@ -296,16 +335,17 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath, goto errout_with_semaphore; } - /* First check if the file already exists */ + /* Find the NFS node associate with the path */ - error = nfs_getstat(nmp, relpath, &buf); + error = nfs_findnode(nmp, relpath, &fhandle, &np->n_fattr, NULL); if (error == 0) { - /* Check if the file is a directory */ + /* Check if the path is a directory */ - if (S_ISDIR(buf.st_mode)) + tmp = fxdr_unsigned(uint32_t, np->n_fattr.fa_type); + if (tmp == NFDIR) { - /* Exit with EISDIR if we attempt to open an directory */ + /* Exit with EISDIR if we attempt to open a directory */ fdbg("ERROR: Path is a directory\n"); error = EISDIR; @@ -314,15 +354,23 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath, /* Check if the caller has sufficient privileges to open the file */ - readonly = ((buf.st_mode & (S_IWOTH|S_IWGRP|S_IXUSR)) == 0); - if (((oflags & O_WRONLY) != 0) && readonly) + if ((oflags & O_WRONLY) != 0) { - fdbg("ERROR: File is read-only\n"); - error = EACCES; - goto errout_with_semaphore; + /* Check if anyone has priveleges to write to the file -- owner, + * group, or other (we are probably "other" and may still not be + * able to write). + */ + + tmp = fxdr_unsigned(uint32_t, np->n_fattr.fa_mode); + if ((tmp & (NFSMODE_IWOTH|NFSMODE_IWGRP|NFSMODE_IWUSR)) == 0) + { + fdbg("ERROR: File is read-only: %08x\n", tmp); + error = EACCES; + goto errout_with_semaphore; + } } - /* It would be an error if we are asked to create it exclusively */ + /* It would be an error if we are asked to create the file exclusively */ if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) { @@ -347,25 +395,24 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath, #warning "Missing logic" } - /* Initialize the file private data from the FSINFO return data */ - /* NOTE: This will require some re-structuring */ -#if 0 - np->n_open = true; - memcpy(&np->n_fhp, &resok.fsinfo.fshandle.handle, sizeof(nfsfh_t)); - np->n_size = fxdr_hyper(&resok.fsinfo.attributes.fa3_size); - memcpy(&resok.fsinfo.attributes, &np->n_fattr, sizeof(struct nfs_fattr)); - fxdr_nfsv3time(&resok.fsinfo.attributes.fa3_mtime, &np->n_mtime) - np->n_ctime = fxdr_hyper(&resok.fsinfo.attributes.fa3_ctime); -#else -#warning "Missing logic" - fdbg("ERROR: Logic to open an existing file is not fully implemented"); - errno = ENOSYS; /* Just fail for now */ - goto errout_with_semaphore; -#endif + /* Initialize the file private data */ + /* Copy the file handle */ + + np->n_fhsize = (uint8_t)fhandle.length; + memcpy(&np->n_fhandle, &fhandle.handle, fhandle.length); + + /* Get a convenience version of file size and modification time in host + * byte order. + */ + + np->n_size = fxdr_hyper(&np->n_fattr.fa3_size); + fxdr_nfsv3time(&np->n_fattr.fa3_mtime, &np->n_mtime) + np->n_ctime = fxdr_hyper(&np->n_fattr.fa3_ctime); + /* Fall through to finish the file open operation */ } - /* An error occurred while getting the file status. Check if the stat failed + /* An error occurred while getting the file node. Check if the stat failed * because the file does not exist. That is not necessarily an error; that * may only mean that we have to create the file. */ @@ -421,12 +468,9 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath, */ np->n_next = nmp->nm_head; - np->n_flag |= NMODIFIED; + np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED); nmp->nm_head = np->n_next; - /* For open/close consistency. */ - - NFS_INVALIDATE_ATTRCACHE(np); nfs_semgive(nmp); return OK; @@ -465,7 +509,7 @@ static int nfs_close(FAR struct file *filep) done DEBUGASSERT(nmp != NULL); - if (np->nfsv3_type == NFREG) + if (np->n_type == NFREG) { error = nfs_sync(filep); kfree(np); @@ -487,16 +531,15 @@ static int nfs_close(FAR struct file *filep) done static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) { - struct nfsmount *nmp; - struct nfsnode *np; - uint32_t readsize; - int bytesleft; - uint64_t offset; - struct READ3args read; - struct rpc_reply_read resok; - uint8_t *userbuffer = (uint8_t*)buffer; - int error = 0; - int len; + FAR struct nfsmount *nmp; + FAR struct nfsnode *np; + ssize_t readsize; + ssize_t tmp; + ssize_t bytesread; + size_t reqlen; + struct READ3args read; + FAR uint32_t *ptr; + int error = 0; fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos); @@ -506,9 +549,8 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) /* Recover our private data from the struct file instance */ - np = (struct nfsnode*) filep->f_priv; nmp = (struct nfsmount*) filep->f_inode->i_private; - offset = 0; + np = (struct nfsnode*) filep->f_priv; DEBUGASSERT(nmp != NULL); @@ -522,69 +564,129 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) goto errout_with_semaphore; } - if (np->nfsv3_type != NFREG) + /* Get the number of bytes left in the file and truncate read count so that + * it does not exceed the number of bytes left in the file. + */ + + tmp = np->n_size - filep->f_pos; + if (buflen > tmp) { - fdbg("read eacces typ=%d\n", np->nfsv3_type); - error = EACCES; - goto errout_with_semaphore; + buflen = tmp; + fvdbg("Read size truncated to %d\n", buflen); } - if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3) + /* Now loop until we fill the user buffer (or hit the end of the file) */ + + for (bytesread = 0; bytesread < buflen; ) { - (void)nfs_fsinfo(nmp); - } + /* Make sure that the attempted read size does not exceed the RPC maximum */ + + readsize = buflen; + if (readsize > nmp->nm_rsize) + { + readsize = nmp->nm_rsize; + } - /* Get the number of bytes left in the file */ + /* Make sure that the attempted read size does not exceed the IO buffer size */ - bytesleft = np->n_size - filep->f_pos; - readsize = 0; + tmp = SIZEOF_rpc_reply_read(readsize); + if (tmp > np->n_buflen) + { + readsize -= (tmp - np->n_buflen); + } - /* Truncate read count so that it does not exceed the number - * of bytes left in the file. - */ + /* Initialize the request */ - if (buflen > bytesleft) - { - buflen = bytesleft; - } + ptr = (FAR uint32_t*)&read; + reqlen = 0; - len = nmp->nm_rsize; - if (len < buflen) - { - error = EFBIG; - goto errout_with_semaphore; - } + /* Copy the variable length, directory file handle */ - nfsstats.rpccnt[NFSPROC_READ]++; + *ptr++ = txdr_unsigned((uint32_t)np->n_fhsize); + reqlen += sizeof(uint32_t); -again: - memset(&read, 0, sizeof(struct READ3args)); - memset(&resok, 0, sizeof(struct rpc_reply_read)); - read.file = txdr_unsigned(np->nfsv3_type); - read.count = txdr_unsigned(buflen); - read.offset = txdr_unsigned(offset); + memcpy(ptr, &np->n_fhandle, np->n_fhsize); + reqlen += (int)np->n_fhsize; + ptr += uint32_increment((int)np->n_fhsize); - error = nfs_request(nmp, NFSPROC_READ, - (FAR const void *)&read, sizeof(struct READ3args), - (FAR void *)&resok, sizeof(struct rpc_reply_read)); - if (error) - { - goto errout_with_semaphore; - } + /* Copy the file offset */ - if (resok.read.eof == true) - { - readsize = fxdr_unsigned(uint32_t, resok.read.count); - np->n_fattr = resok.read.file_attributes;// - memcpy(userbuffer, resok.read.data, readsize); - } - else - { - goto again; + txdr_hyper((uint64_t)filep->f_pos, ptr); + ptr += 2; + reqlen += 2*sizeof(uint32_t); + + /* Set the readsize */ + + *ptr = txdr_unsigned(readsize); + reqlen += sizeof(uint32_t); + + /* Perform the read */ + + fvdbg("Reading %d bytes\n", readsize); + nfsstats.rpccnt[NFSPROC_READ]++; + error = nfs_request(nmp, NFSPROC_READ, + (FAR const void *)&read, reqlen, + (FAR void *)np->n_iobuffer, np->n_buflen); + if (error) + { + fdbg("ERROR: nfs_request failed: %d\n", error); + goto errout_with_semaphore; + } + + /* The read was successful. Get a pointer to the beginning of the NFS + * response data. + */ + + ptr = (FAR uint32_t *)&((FAR struct rpc_reply_read *)np->n_iobuffer)->read; + + /* Check if attributes are included in the responses */ + + tmp = *ptr++; + if (*ptr != 0) + { + /* Yes... just skip over the attributes for now */ + + ptr += uint32_increment(sizeof(struct nfs_fattr)); + } + + /* This is followed by the count of data read. Isn't this + * the same as the length that is included in the read data? + * + * Just skip over if for now. + */ + + ptr++; + + /* Next comes an EOF indication. Save that in tmp for now. */ + + tmp = *ptr++; + + /* Then the length of the read data followed by the read data itself */ + + readsize = fxdr_unsigned(uint32_t, *ptr); + ptr++; + + /* Copy the read data into the user buffer */ + + memcpy(buffer, ptr, readsize); + + /* Update the read state data */ + + filep->f_pos += readsize; + bytesread += readsize; + buffer += readsize; + + /* Check if we hit the end of file */ + + if (tmp != 0) + { + break; + } } + fvdbg("Read %d bytes\n", bytesread); nfs_semgive(nmp); - return readsize; + return bytesread; errout_with_semaphore: nfs_semgive(nmp); @@ -603,18 +705,19 @@ errout_with_semaphore: static ssize_t nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) { - struct inode *inode; - struct nfsmount *nmp; - struct nfsnode *np; - unsigned int writesize; - struct WRITE3args write; + struct inode *inode; + struct nfsmount *nmp; + struct nfsnode *np; + unsigned int writesize; struct rpc_reply_write resok; - uint8_t *userbuffer = (uint8_t*)buffer; - int error = 0; - uint64_t offset; - int len; - int commit = 0; - int committed = NFSV3WRITE_FILESYNC; + uint64_t offset; + uint8_t *userbuffer = (uint8_t*)buffer; + size_t reqlen; + uint32_t *ptr; + int len; + int commit = 0; + int committed = NFSV3WRITE_FILESYNC; + int error = 0; /* Sanity checks */ @@ -655,17 +758,38 @@ static ssize_t nfs_write(FAR struct file *filep, const char *buffer, writesize = 0; - nfsstats.rpccnt[NFSPROC_WRITE]++; - memset(&write, 0, sizeof(struct WRITE3args)); - memset(&resok, 0, sizeof(struct rpc_reply_write)); - write.file = txdr_unsigned(np->nfsv3_type); - write.offset = txdr_unsigned(offset); - write.count = txdr_unsigned(buflen); - write.stable = txdr_unsigned(committed); - memcpy((void *)write.data, userbuffer, buflen); + /* Initialize the request */ + + ptr = (FAR uint32_t*)&np->n_iobuffer; + reqlen = 0; + + /* Copy the variable length, directory file handle */ + + *ptr++ = txdr_unsigned((uint32_t)np->n_fhsize); + reqlen += sizeof(uint32_t); + + memcpy(ptr, &np->n_fhandle, np->n_fhsize); + reqlen += (int)np->n_fhsize; + ptr += uint32_increment((int)np->n_fhsize); + + /* Copy the file offset */ + txdr_hyper((uint64_t)filep->f_pos, ptr); + ptr += 2; + reqlen += 2*sizeof(uint32_t); + + /* Copy the count and stable values */ + + *ptr++ = txdr_unsigned(buflen); + *ptr++ = txdr_unsigned(committed); + reqlen += 2*sizeof(uint32_t); + + memcpy(ptr, userbuffer, buflen); + reqlen += buflen; + + nfsstats.rpccnt[NFSPROC_WRITE]++; error = nfs_request(nmp, NFSPROC_WRITE, - (FAR const void *)&write, sizeof(struct WRITE3args), + (FAR const void *)np->n_iobuffer, reqlen, (FAR void *)&resok, sizeof(struct rpc_reply_write)); if (error) { @@ -1394,14 +1518,13 @@ int mountnfs(struct nfs_args *argp, void **handle) goto bad; } - np->nfsv3_type = NFDIR; - np->n_open = true; - np->n_flag |= NMODIFIED; + np->n_type = NFDIR; + np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED); nmp->nm_head = np; nmp->nm_mounted = true; memcpy(&nmp->nm_fh, &nmp->nm_rpcclnt->rc_fh, sizeof(nfsfh_t)); nmp->nm_fhsize = NFSX_V2FH; - memcpy(&nmp->nm_head->n_fhp, &nmp->nm_fh, sizeof(nfsfh_t)); + memcpy(&nmp->nm_head->n_fhandle, &nmp->nm_fh, sizeof(nfsfh_t)); nmp->nm_head->n_fhsize = nmp->nm_fhsize; nmp->nm_so = nmp->nm_rpcclnt->rc_so; @@ -1671,7 +1794,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) /* Remove the file */ - if (np->nfsv3_type != NFREG) + if (np->n_type != NFREG) { error = EPERM; goto errout_with_semaphore; @@ -1683,7 +1806,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) memset(&remove, 0, sizeof(struct REMOVE3args)); memset(&resok, 0, sizeof(struct rpc_reply_remove)); remove.object.dir.length = txdr_unsigned(np->n_fhsize); - memcpy(&remove.object.dir.handle, &np->n_fhp, sizeof(nfsfh_t)); + memcpy(&remove.object.dir.handle, &np->n_fhandle, sizeof(nfsfh_t)); remove.object.length = txdr_unsigned(64); strncpy(remove.object.name, relpath, 64); @@ -1708,11 +1831,9 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) } memcpy(&np->n_fattr, &resok.remove.dir_wcc.after, sizeof(struct nfs_fattr)); - np->n_flag |= NMODIFIED; + np->n_flags |= NFSNODE_MODIFIED; } - NFS_INVALIDATE_ATTRCACHE(np); - errout_with_semaphore: nfs_semgive(nmp); return -error; @@ -1760,7 +1881,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) memset(&mkir, 0, sizeof(struct MKDIR3args)); memset(&resok, 0, sizeof(struct rpc_reply_mkdir)); mkir.where.dir.length = txdr_unsigned(np->n_fhsize); - memcpy(&mkir.where.dir.handle, &np->n_fhp, sizeof(nfsfh_t)); + memcpy(&mkir.where.dir.handle, &np->n_fhandle, sizeof(nfsfh_t)); mkir.where.length = txdr_unsigned(64); strncpy(mkir.where.name, relpath, 64); @@ -1785,16 +1906,13 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) goto errout_with_semaphore; } - np->n_open = true; - np->nfsv3_type = fxdr_unsigned(uint32_t, resok.mkdir.obj_attributes.fa_type); - memcpy(&np->n_fhp, &resok.mkdir.fshandle.handle, sizeof(nfsfh_t)); + np->n_type = fxdr_unsigned(uint32_t, resok.mkdir.obj_attributes.fa_type); + memcpy(&np->n_fhandle, &resok.mkdir.fshandle.handle, sizeof(nfsfh_t)); np->n_size = fxdr_hyper(&resok.mkdir.obj_attributes.fa3_size); memcpy(&np->n_fattr, &resok.mkdir.obj_attributes, sizeof(struct nfs_fattr)); fxdr_nfsv3time(&resok.mkdir.obj_attributes.fa3_mtime, &np->n_mtime) np->n_ctime = fxdr_hyper(&resok.mkdir.obj_attributes.fa3_ctime); - np->n_flag |= NMODIFIED; - - NFS_INVALIDATE_ATTRCACHE(np); + np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED); errout_with_semaphore: nfs_semgive(nmp); @@ -1837,7 +1955,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) { /* Remove the directory */ - if (np->nfsv3_type != NFDIR) + if (np->n_type != NFDIR) { error = EPERM; goto errout_with_semaphore; @@ -1849,7 +1967,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) memset(&rmdir, 0, sizeof(struct RMDIR3args)); memset(&resok, 0, sizeof(struct rpc_reply_rmdir)); rmdir.object.dir.length = txdr_unsigned(np->n_fhsize); - memcpy(&rmdir.object.dir.handle, &np->n_fhp, sizeof(nfsfh_t)); + memcpy(&rmdir.object.dir.handle, &np->n_fhandle, sizeof(nfsfh_t)); rmdir.object.length = txdr_unsigned(64); strncpy(rmdir.object.name, relpath, 64); @@ -1867,11 +1985,9 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) } memcpy(&np->n_fattr, &resok.rmdir.dir_wcc.after, sizeof(struct nfs_fattr)); - np->n_flag |= NMODIFIED; + np->n_flags |= NFSNODE_MODIFIED; } - NFS_INVALIDATE_ATTRCACHE(np); - errout_with_semaphore: nfs_semgive(nmp); return -error; @@ -1915,9 +2031,9 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, goto errout_with_semaphore; } - if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR) + if (np->n_type != NFREG && np->n_type != NFDIR) { - fdbg("open eacces typ=%d\n", np->nfsv3_type); + fdbg("open eacces typ=%d\n", np->n_type); error = EACCES; goto errout_with_semaphore; } @@ -1926,11 +2042,11 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, memset(&rename, 0, sizeof(struct RENAME3args)); memset(&resok, 0, sizeof(struct rpc_reply_rename)); rename.from.dir.length = txdr_unsigned(np->n_fhsize); - memcpy(&rename.from.dir.handle, &np->n_fhp, sizeof(nfsfh_t)); + memcpy(&rename.from.dir.handle, &np->n_fhandle, sizeof(nfsfh_t)); rename.from.length = txdr_unsigned(64); strncpy(rename.from.name, oldrelpath, 64); rename.to.dir.length = txdr_unsigned(np->n_fhsize); - memcpy(&rename.to.dir.handle, &np->n_fhp, sizeof(nfsfh_t)); + memcpy(&rename.to.dir.handle, &np->n_fhandle, sizeof(nfsfh_t)); rename.to.length = txdr_unsigned(64); strncpy(rename.to.name, newrelpath, 64); @@ -1951,8 +2067,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, } memcpy(&np->n_fattr, &resok.rename.todir_wcc.after, sizeof(struct nfs_fattr)); - np->n_flag |= NMODIFIED; - NFS_INVALIDATE_ATTRCACHE(np); + np->n_flags |= NFSNODE_MODIFIED; errout_with_semaphore: nfs_semgive(nmp); @@ -2004,18 +2119,18 @@ static int nfs_getstat(struct nfsmount *nmp, const char *relpath, * as in the NFSv3 spec. */ - mode = tmp & (NFSMMODE_IXOTH|NFSMMODE_IWOTH|NFSMMODE_IROTH| - NFSMMODE_IXGRP|NFSMMODE_IWGRP|NFSMMODE_IRGRP| - NFSMMODE_IXUSR|NFSMMODE_IWUSR|NFSMMODE_IRUSR); + mode = tmp & (NFSMODE_IXOTH|NFSMODE_IWOTH|NFSMODE_IROTH| + NFSMODE_IXGRP|NFSMODE_IWGRP|NFSMODE_IRGRP| + NFSMODE_IXUSR|NFSMODE_IWUSR|NFSMODE_IRUSR); /* Handle the cases that are not the same */ - if ((mode & NFSMMODE_ISGID) != 0) + if ((mode & NFSMODE_ISGID) != 0) { mode |= S_ISGID; } - if ((mode & NFSMMODE_ISUID) != 0) + if ((mode & NFSMODE_ISUID) != 0) { mode |= S_ISUID; } @@ -2152,7 +2267,7 @@ int nfs_sync(struct file *filep) /* Check if the has been modified in any way */ - if ((np->n_flag & NMODIFIED) != 0) + if ((np->n_flags & NFSNODE_MODIFIED) != 0) { //error = VOP_FSYNC(vp, cred, waitfor, p); } diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h index 921dc2ce7..73b6a5eca 100644 --- a/nuttx/fs/nfs/rpc.h +++ b/nuttx/fs/nfs/rpc.h @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * @@ -342,8 +343,9 @@ struct rpc_call_read struct rpc_call_write { struct rpc_call_header ch; - struct WRITE3args write; + struct WRITE3args write; /* Variable length */ }; +#define SIZEOF_rpc_call_write(n) (sizeof(struct rpc_call_header) + SIZEOF_WRITE3args(n)) struct rpc_call_remove { @@ -429,8 +431,9 @@ struct rpc_reply_read { struct rpc_reply_header rh; uint32_t status; - struct READ3resok read; + struct READ3resok read; /* Variable length */ }; +#define SIZEOF_rpc_reply_read(n) (sizeof(struct rpc_reply_header) + sizeof(uint32_t) + SIZEOF_READ3resok(n)) struct rpc_reply_remove { diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c index 8fc3fb5d7..afa383d9c 100644 --- a/nuttx/fs/nfs/rpc_clnt.c +++ b/nuttx/fs/nfs/rpc_clnt.c @@ -4,6 +4,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * @@ -1137,15 +1138,18 @@ static int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int ve case NFSPROC_READ: { - /* Copy the variable, caller-provided data into the call message structure */ + /* Copy the variable length, caller-provided data into the call + * message structure. + */ struct rpc_call_read *callmsg = (struct rpc_call_read *)msgbuf; memcpy(&callmsg->read, request, *reqlen); - /* Return the full size of the message (including messages headers) */ + /* Return the full size of the message (the size of variable data + * plus the size of the messages header). + */ - DEBUGASSERT(*reqlen == sizeof(struct READ3args)); - *reqlen = sizeof(struct rpc_call_read); + *reqlen += sizeof(struct rpc_call_header); /* Format the message header */ @@ -1156,15 +1160,18 @@ static int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int ve case NFSPROC_WRITE: { - /* Copy the variable, caller-provided data into the call message structure */ + /* Copy the variable length, caller-provided data into the call + * message structure. + */ struct rpc_call_write *callmsg = (struct rpc_call_write *)msgbuf; memcpy(&callmsg->write, request, *reqlen); - /* Return the full size of the message (including messages headers) */ + /* Return the full size of the message (the size of variable data + * plus the size of the messages header). + */ - DEBUGASSERT(*reqlen == sizeof(struct WRITE3args)); - *reqlen = sizeof(struct rpc_call_write); + *reqlen += sizeof(struct rpc_call_header); /* Format the message header */ diff --git a/nuttx/fs/nfs/xdr_subs.h b/nuttx/fs/nfs/xdr_subs.h index 028132e0a..891af004c 100644 --- a/nuttx/fs/nfs/xdr_subs.h +++ b/nuttx/fs/nfs/xdr_subs.h @@ -6,6 +6,7 @@ * Copyright (C) 2012 Gregory Nutt. All rights reserved. * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved. * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com> + * Gregory Nutt <gnutt@nuttx.org> * * Leveraged from OpenBSD: * |