diff options
-rw-r--r-- | nuttx/fs/nfs/nfs.h | 46 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_args.h | 41 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_mount.h | 2 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_node.h | 12 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_proto.h | 65 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_socket.c | 18 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_socket.h | 44 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_vfsops.c | 1038 | ||||
-rw-r--r-- | nuttx/fs/nfs/rpc.h | 23 | ||||
-rw-r--r-- | nuttx/fs/nfs/rpc_clnt.c | 1 | ||||
-rw-r--r-- | nuttx/fs/nfs/xdr_subs.h | 7 |
11 files changed, 645 insertions, 652 deletions
diff --git a/nuttx/fs/nfs/nfs.h b/nuttx/fs/nfs/nfs.h index 497cfd666..a88e5b91c 100644 --- a/nuttx/fs/nfs/nfs.h +++ b/nuttx/fs/nfs/nfs.h @@ -46,6 +46,8 @@ /**************************************************************************** * Included Files ****************************************************************************/ + +#include "nfs_mount.h" /**************************************************************************** * Pre-processor Definitions @@ -207,15 +209,15 @@ struct nfsd_args struct nfsd_srvargs { - struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */ - uid_t nsd_uid; /* Effective uid mapped to cred */ - uint32_t nsd_haddr; /* IP address of client */ - int nsd_authlen; /* Length of auth string (ret) */ - unsigned char *nsd_authstr; /* Auth string (ret) */ - int nsd_verflen; /* and the verifier */ + struct nfsd *nsd_nfsd; /* Pointer to in kernel nfsd struct */ + uid_t nsd_uid; /* Effective uid mapped to cred */ + uint32_t nsd_haddr; /* IP address of client */ + int nsd_authlen; /* Length of auth string (ret) */ + unsigned char *nsd_authstr; /* Auth string (ret) */ + int nsd_verflen; /* and the verifier */ unsigned char *nsd_verfstr; struct timeval nsd_timestamp; /* timestamp from verifier */ - uint32_t nsd_ttl; /* credential ttl (sec) */ + uint32_t nsd_ttl; /* credential ttl (sec) */ }; /* Stats structure */ @@ -258,10 +260,6 @@ struct nfsstats uint64_t srvvop_writes; }; -/**************************************************************************** - * Public Types - ****************************************************************************/ - /* The set of signals the interrupt an I/O in progress for NFSMNT_INT mounts. * What should be in this set is open to debate, but I believe that since * I/O system calls on ufs are never interrupted by signals the set should @@ -336,19 +334,25 @@ struct nfsrv_descript /**************************************************************************** * Public Data ****************************************************************************/ -/* -extern int nfs_niothreads; -extern TAILQ_HEAD(nfssvc_sockhead, nfssvc_sock) nfssvc_sockhead; -extern int nfssvc_sockhead_flag; - -extern struct pool nfsreqpl; -extern struct pool nfs_node_pool; -extern TAILQ_HEAD(nfsdhead, nfsd) nfsd_head; -extern int nfsd_head_flag; -*/ /**************************************************************************** * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +EXTERN void nfs_semtake(struct nfsmount *nmp); +EXTERN void nfs_semgive(struct nfsmount *nmp); +EXTERN int nfs_checkmount(struct nfsmount *nmp); +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* _NFS_NFS_H */ diff --git a/nuttx/fs/nfs/nfs_args.h b/nuttx/fs/nfs/nfs_args.h index 57c735c17..fd81968f4 100644 --- a/nuttx/fs/nfs/nfs_args.h +++ b/nuttx/fs/nfs/nfs_args.h @@ -85,6 +85,11 @@ #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 NFS_ARGSVERSION 3 /* change when nfs_args changes */ /**************************************************************************** * Public Types @@ -94,24 +99,28 @@ struct nfs_args { - int version; /* args structure version number */ + int version; /* args structure version number */ struct sockaddr *addr; /* file server address */ - int addrlen; /* length of address */ - int sotype; /* Socket type */ - int proto; /* and Protocol */ - nfsfh_t *fh; /* File handle to be mounted */ - int fhsize; /* Size, in bytes, of fh */ - int flags; /* flags */ - int wsize; /* write size in bytes */ - int rsize; /* read size in bytes */ - int readdirsize; /* readdir size in bytes */ - int timeo; /* initial timeout in .1 secs */ - int retrans; /* times to retry send */ - int maxgrouplist; /* Max. size of group list */ - int readahead; /* # of blocks to readahead */ - int leaseterm; /* Term (sec) of lease */ - int deadthresh; /* Retrans threshold */ + int addrlen; /* length of address */ + int sotype; /* Socket type */ + int proto; /* and Protocol */ + nfsfh_t fh; /* File handle to be mounted */ + int fhsize; /* Size, in bytes, of fh */ + int flags; /* flags */ + int wsize; /* write size in bytes */ + int rsize; /* read size in bytes */ + int readdirsize; /* readdir size in bytes */ + int timeo; /* initial timeout in .1 secs */ + int retrans; /* times to retry send */ + int maxgrouplist; /* Max. size of group list */ + int readahead; /* # of blocks to readahead */ + int leaseterm; /* Term (sec) of lease */ + int deadthresh; /* Retrans threshold */ char *hostname; /* server's name */ + int acregmin; /* cache attrs for reg files min time */ + int acregmax; /* cache attrs for reg files max time */ + int acdirmin; /* cache attrs for dirs min time */ + int acdirmax; /* cache attrs for dirs max time */ }; #endif /* __FS_NFS_NFS_ARGS_H */ diff --git a/nuttx/fs/nfs/nfs_mount.h b/nuttx/fs/nfs/nfs_mount.h index 78048f443..a07963a43 100644 --- a/nuttx/fs/nfs/nfs_mount.h +++ b/nuttx/fs/nfs/nfs_mount.h @@ -97,7 +97,7 @@ struct nfsmount int nm_acdirmax; /* Directory attr cache max lifetime */ int nm_acregmin; /* Reg file attr cache min lifetime */ int nm_acregmax; /* Reg file attr cache max lifetime */ - unsigned char nm_verf[NFSX_V3WRITEVERF]; /* V3 write verifier */ + unsigned char *nm_verf; /* V3 write verifier */ //char nm_mntonname[90]; /* directory on which mounted */ //uint8_t *nm_buffer; /* This is an allocated buffer to hold one sector*/ }; diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h index dd7fe12a8..3ca0762ef 100644 --- a/nuttx/fs/nfs/nfs_node.h +++ b/nuttx/fs/nfs/nfs_node.h @@ -80,6 +80,14 @@ #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_direofoffset n_un2.nd_direof +#define n_cookies n_un3.nd_cook + /**************************************************************************** * Public Types ****************************************************************************/ @@ -119,7 +127,7 @@ struct nfsnode 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 */ + nfsfh_t n_fhp; /* NFS File Handle */ struct inode *n_inode; /* associated inode */ int n_error; /* Save write error value */ union @@ -130,7 +138,7 @@ struct nfsnode union { struct timespec nf_mtim; - off_t nd_direoffset; /* Directory EOF offset cache */ + off_t nd_direof; /* Directory EOF offset cache */ } n_un2; short n_fhsize; /* size in bytes, of fh */ short n_flag; /* Flag for locking.. */ diff --git a/nuttx/fs/nfs/nfs_proto.h b/nuttx/fs/nfs/nfs_proto.h index d8e7e990c..0f874e28a 100644 --- a/nuttx/fs/nfs/nfs_proto.h +++ b/nuttx/fs/nfs/nfs_proto.h @@ -57,20 +57,21 @@ * Specification" */ -#define NFS_PORT 2049 -#define NFS_PROG 100003 -#define NFS_VER2 2 -#define NFS_VER3 3 -#define NFS_VER4 4 -#define NFS_V2MAXDATA 8192 -#define NFS_MAXDGRAMDATA 32768 -#define NFS_MAXDATA MAXBSIZE -#define NFS_MAXPATHLEN 1024 -#define NFS_MAXNAMLEN 255 -#define NFS_MAXPKTHDR 404 -#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA) -#define NFS_MINPACKET 20 -#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ +#define NFS_PORT 2049 +#define NFS_PROG 100003 +#define NFS_VER2 2 +#define NFS_VER3 3 +#define NFS_VER4 4 +#define NFS_V2MAXDATA 8192 +#define NFS_MAXDGRAMDATA 32768 +#define MAXBSIZE 64000 +#define NFS_MAXDATA MAXBSIZE +#define NFS_MAXPATHLEN 1024 +#define NFS_MAXNAMLEN 255 +#define NFS_MAXPKTHDR 404 +#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA) +#define NFS_MINPACKET 20 +#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */ /* Stat numbers for rpc returns (version 2 and 3) */ @@ -108,21 +109,20 @@ #define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */ #define NFSERR_RETVOID 0x20000000 /* Return void, not error */ -#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error - */ +#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */ #define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */ /* Sizes in bytes of various nfs rpc components */ -#define NFSX_UNSIGNED 4 +#define NFSX_UNSIGNED 4 /* specific to NFS Version 2 */ -#define NFSX_V2FH 32 -#define NFSX_V2FATTR 68 -#define NFSX_V2SATTR 32 -#define NFSX_V2COOKIE 4 -#define NFSX_V2STATFS 20 +#define NFSX_V2FH 32 +#define NFSX_V2FATTR 68 +#define NFSX_V2SATTR 32 +#define NFSX_V2COOKIE 4 +#define NFSX_V2STATFS 20 /* specific to NFS Version 3 */ @@ -235,6 +235,7 @@ #define NFSV3FSINFO_CANSETTIME 0x10 /* Conversion macros */ + #define vtonfsv2_mode(t,m) \ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ MAKEIMODE((t), (m))) @@ -274,7 +275,7 @@ typedef enum typedef struct { int32_t val[2]; -} fsid_t; /* file system id type */ +} fsid_t; /* file system id type */ /* File identifier. * These are unique per filesystem on a single machine. @@ -282,17 +283,17 @@ typedef struct struct fid { - unsigned short fid_len; /* length of data in bytes */ - unsigned short fid_reserved; /* force longword alignment */ - char fid_data[MAXFIDSZ]; /* data (variable length) */ + unsigned short fid_len; /* length of data in bytes */ + unsigned short fid_reserved; /* force longword alignment */ + char fid_data[MAXFIDSZ]; /* data (variable length) */ }; /* Generic file handle */ struct fhandle { - fsid_t fh_fsid; /* File system id of mount point */ - struct fid fh_fid; /* File sys specific id */ + fsid_t fh_fsid; /* File system id of mount point */ + struct fid fh_fid; /* File sys specific id */ }; typedef struct fhandle fhandle_t; @@ -500,7 +501,7 @@ struct wcc_data struct diropargs3 { nfsfh_t dir; - const char name; + const char *name; }; struct CREATE3args @@ -528,7 +529,7 @@ struct READ3resok struct nfs_fattr file_attributes; uint32_t count; bool eof; - const char data; + const char *data; }; enum stable_how @@ -544,7 +545,7 @@ struct WRITE3args uint64_t offset; uint32_t count; enum stable_how stable; - const char data; + const char *data; }; struct WRITE3resok @@ -552,7 +553,7 @@ struct WRITE3resok struct wcc_data file_wcc; uint32_t count; enum stable_how committed; - unsigned char verf; + unsigned char *verf; }; struct REMOVE3args diff --git a/nuttx/fs/nfs/nfs_socket.c b/nuttx/fs/nfs/nfs_socket.c index 0dbca8297..8b0f28660 100644 --- a/nuttx/fs/nfs/nfs_socket.c +++ b/nuttx/fs/nfs/nfs_socket.c @@ -107,7 +107,7 @@ int nfsx_connect(struct nfsmount *nmp) return EFAULT; } - rpc = &nmp->nm_rpcclnt; + rpc = nmp->nm_rpcclnt; rpc->rc_prog = &nfs3_program; @@ -125,7 +125,7 @@ int nfsx_connect(struct nfsmount *nmp) rpc->rc_authtype = RPCAUTH_NULL; /* for now */ //rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname; - rpc->rc_name = (struct sockaddr *)nmp->nm_nam; + rpc->rc_name = nmp->nm_nam; rpc->rc_sotype = nmp->nm_sotype; rpc->rc_soproto = nmp->nm_soproto; @@ -153,26 +153,24 @@ int nfsx_connect(struct nfsmount *nmp) void nfsx_disconnect(struct nfsmount *nmp) { - rpcclnt_disconnect(&nmp->nm_rpcclnt); + rpcclnt_disconnect(nmp->nm_rpcclnt); } #ifdef CONFIG_NFS_TCPIP void nfsx_safedisconnect(struct nfsmount *nmp) { - rpcclnt_safedisconnect(&nmp->nm_rpcclnt); + rpcclnt_safedisconnect(nmp->nm_rpcclnt); } #endif -int nfsx_request_xx(struct nfsmount *nm, int procnum, void *datain, void *dataout) +int nfsx_request_xx(struct nfsmount *nmp, int procnum, void *datain, void *dataout) { int error; - struct nfsmount *nmp; struct rpcclnt *clnt; - struct rpc_reply *reply; + struct rpc_reply *reply = NULL; int trylater_delay; - nmp = nm; - clnt = &nmp->nm_rpcclnt; + clnt = nmp->nm_rpcclnt; tryagain: @@ -227,5 +225,5 @@ out: int nfsx_nmcancelreqs(struct nfsmount *nmp) { - return rpcclnt_cancelreqs(&nmp->nm_rpcclnt); + return rpcclnt_cancelreqs(nmp->nm_rpcclnt); } diff --git a/nuttx/fs/nfs/nfs_socket.h b/nuttx/fs/nfs/nfs_socket.h index e668e85fb..31987dff3 100644 --- a/nuttx/fs/nfs/nfs_socket.h +++ b/nuttx/fs/nfs/nfs_socket.h @@ -42,28 +42,42 @@ * Pre-processor definitions ****************************************************************************/ -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ +#define nfs_connect(nmp) nfs_connect_nfsx (nmp) +#define nfs_disconnect(nmp) nfs_disconnect_nfsx(nmp) +#define nfs_nmcancelreqs (nmp) nfsx_nmcancelreqs(nmp) +#define nfsx_request(nmp, m, i, o) \ + nfsx_request_xx(nmp, m, i, o) -int nfsx_connect(struct nfsmount *); -void nfsx_disconnect(struct nfsmount *); #ifdef CONFIG_NFS_TCPIP -int nfsx_sigintr(struct nfsmount *, struct nfsreq *, cthread_t *); -void nfsx_safedisconnect(struct nfsmount *); +# define nfs_sigintr nfs_sigintr_nfsx #define nfs_safedisconnect nfsx_safedisconnect #endif -int nfsx_request_xx(struct nfsmount *, int, void*, void*); -int nfsx_nmcancelreqs(struct nfsmount *); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ -#define nfs_connect nfs_connect_nfsx -#define nfs_disconnect nfs_disconnect_nfsx -#define nfs_nmcancelreqs nfsx_nmcancelreqs -#define nfsx_request(nmp, m, i, o) \ - nfsx_request_xx(nmp, m, i, o) +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif +EXTERN void nfs_init(void); +EXTERN int nfsx_connect(struct nfsmount *); +EXTERN void nfsx_disconnect(struct nfsmount *); #ifdef CONFIG_NFS_TCPIP -# define nfs_sigintr nfs_sigintr_nfsx +EXTERN int nfsx_sigintr(struct nfsmount *, struct nfsreq *, cthread_t *); +EXTERN void nfsx_safedisconnect(struct nfsmount *); +#endif +EXTERN int nfsx_request_xx(struct nfsmount *, int, void*, void*); +EXTERN int nfsx_nmcancelreqs(struct nfsmount *); + +#undef EXTERN +#if defined(__cplusplus) +} #endif #endif /* __FS_NFS_NFS_SOCKET_H */ diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c index 805b48967..856ed6819 100644 --- a/nuttx/fs/nfs/nfs_vfsops.c +++ b/nuttx/fs/nfs/nfs_vfsops.c @@ -60,6 +60,8 @@ #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> @@ -67,11 +69,14 @@ #include <netinet/in.h> #include "rpc_v2.h" +#include "rpc.h" #include "nfs_proto.h" #include "nfs_node.h" #include "nfs.h" #include "nfs_mount.h" #include "xdr_subs.h" +#include "nfs_socket.h" +#include "nfs_args.h" /**************************************************************************** * Pre-processor Definitions @@ -169,20 +174,19 @@ const struct mountpt_operations nfs_ops = * Description: if oflags == O_CREAT it creates a file, if not it * check to see if the type is ok and that deletion is not in progress. ****************************************************************************/ - static int nfs_open(FAR struct file *filep, FAR const char *relpath, int oflags, mode_t mode) { struct inode *in; - struct nfs_fattr *vap; - struct nfsv3_sattr *sp; + struct nfs_fattr vap; + struct nfsv3_sattr sp; struct nfsmount *nmp; struct nfsnode *np; - struct CREATE3args *create; - struct CREATE3resok *resok; - void *replydata; + struct CREATE3args *create = NULL; + struct CREATE3resok *resok = NULL; + void *datareply = NULL; int error = 0; /* Sanity checks */ @@ -216,29 +220,28 @@ nfs_open(FAR struct file *filep, FAR const char *relpath, again: nfsstats.rpccnt[NFSPROC_CREATE]++; vap = nmp->nm_head->n_fattr; - sp->sa_modetrue = nfs_true; - sp->sa_mode = txdr_unsigned(vap->fa_mode); - sp->sa_uid = nfs_xdrneg1; - sp->sa_gid = nfs_xdrneg1; - sp->sa_size = nfs_xdrneg1; - sp->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - sp->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - - txdr_nfsv3time(&vap->fa_atime, &sp->sa_atime); - txdr_nfsv3time(&vap->fa_mtime, &sp->sa_mtime); + sp.sa_modetrue = nfs_true; + sp.sa_mode = txdr_unsigned(vap.fa_mode); + sp.sa_uidfalse = nfs_xdrneg1; + sp.sa_gidfalse = nfs_xdrneg1; + sp.sa_sizefalse = nfs_xdrneg1; + sp.sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + sp.sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + sp.sa_atime = vap.fa3_atime; + sp.sa_mtime = vap.fa3_mtime; create->how = sp; - create->where->dir= nmp->nm_fh; - create->where->name = relpath; + create->where.dir = nmp->nm_fh; + create->where.name = relpath; - error = nfs_request(in, NFSPROC_CREATE, create, replydata); + error = nfs_request(nmp, NFSPROC_CREATE, create, datareply); if (!error) { /* Create an instance of the file private data to describe the opened * file. */ - np = (struct nfsnode *)zalloc(sizeof(struct nfsnode)); + np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode)); if (!np) { fdbg("Failed to allocate private data\n", error); @@ -250,14 +253,14 @@ again: * non-zero elements) */ - resok = (struct CREATE3resok *) replydata; + resok = (struct CREATE3resok *) datareply; np->n_open = true; np->nfsv3_type = NFREG; np->n_fhp = resok->handle; - np->n_size = (struct uint64_t *)resok->attributes->nfsv3fa_size; + np->n_size = fxdr_hyper(&resok->attributes.fa3_size); np->n_fattr = resok->attributes; - np->n_mtime = (struct timespec*) resok->attributes->nfsv3fa_mtime - np->n_ctime = (struct time_t*) resok->attributes->nfsv3fa_ctime + fxdr_nfsv3time(&resok->attributes.fa3_mtime, &np->n_mtime) + np->n_ctime = fxdr_hyper(&resok->attributes.fa3_ctime); /* Attach the private date to the struct file instance */ @@ -275,7 +278,7 @@ again: } else { - if (info_v3 && error == NFSERR_NOTSUPP) + if (error == NFSERR_NOTSUPP) { goto again; } @@ -309,7 +312,8 @@ errout_with_semaphore: return error; } -#ifdef 0 +#undef COMP +#ifdef COMP /**************************************************************************** * Name: nfs_close ****************************************************************************/ @@ -355,11 +359,10 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) unsigned int readsize; int bytesleft; uint64_t offset; - void *datareply; - struct READ3args *read; - struct READ3resok *resok; + void *datareply = NULL; + struct READ3args *read = NULL; + struct READ3resok *resok = NULL; uint8_t *userbuffer = (uint8_t*)buffer; - int info_v3; int error = 0; int len; bool eof; @@ -381,7 +384,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) /* Make sure that the mount is still healthy */ - nfafs_semtake(nmp); + nfs_semtake(nmp); error = nfs_checkmount(nmp); if (error != 0) { @@ -417,7 +420,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) len = nmp->nm_rsize; if (len < buflen) { - error = EFBIG + error = EFBIG; goto errout_with_semaphore; } @@ -439,7 +442,7 @@ again: { readsize = resok->count; np->n_fattr = resok->file_attributes; - memcpy(userbuffer, resok->data, (struct size_t)readsize); + memcpy(userbuffer, resok->data, readsize); } else { @@ -465,14 +468,14 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) struct nfsmount *nmp; struct nfsnode *np; unsigned int writesize; - void *datareply; - struct WRITE3args *write; - struct WRITE3resok *resok; + void *datareply = NULL; + struct WRITE3args *write = NULL; + struct WRITE3resok *resok =NULL; uint8_t *userbuffer = (uint8_t*)buffer; int error = 0; uint64_t offset; int len; - struct stable_how commit; + enum stable_how commit; int committed = NFSV3WRITE_FILESYNC; /* Sanity checks */ @@ -490,7 +493,7 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) /* Make sure that the mount is still healthy */ - nfs_semtake(); + nfs_semtake(nmp); error = nfs_checkmount(nmp); if (error != 0) { @@ -501,14 +504,14 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) if (np->n_size + buflen < np->n_size) { - ret = -EFBIG; + error = -EFBIG; goto errout_with_semaphore; } len = nmp->nm_wsize; if (len < buflen) { - error = -EFBIG + error = -EFBIG; goto errout_with_semaphore; } writesize = 0; @@ -518,7 +521,7 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) write->offset = offset; write->count = buflen; write->stable = committed; - memcpy(write->data, userbuffer, buflen); + memcpy((void *)write->data, userbuffer, buflen); error = nfs_request(nmp, NFSPROC_WRITE, write, datareply); if (error) @@ -530,12 +533,12 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) writesize = resok->count; if (writesize == 0) { - error = -NFSERR_IO; + error = NFSERR_IO; goto errout_with_semaphore; } commit = resok->committed; - np->n_fattr = resok->file_wcc->after; + np->n_fattr = resok->file_wcc.after; /* Return the lowest committment level obtained by any of the RPCs. */ @@ -551,15 +554,15 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0) { - bcopy((void) resok->verf, (void) nmp->nm_verf, NFSX_V3WRITEVERF); + bcopy((void*) resok->verf, (void*) nmp->nm_verf, NFSX_V3WRITEVERF); nmp->nm_flag |= NFSMNT_HASWRITEVERF; } - else if (strncmp((char) resok->verf, (char) nmp->nm_verf, NFSX_V3WRITEVERF)) + else if (strncmp((char*) resok->verf, (char*) nmp->nm_verf, NFSX_V3WRITEVERF)) { - bcopy((void) resok->verf, (void) nmp->nm_verf, NFSX_V3WRITEVERF); + bcopy((void*) resok->verf, (void*) nmp->nm_verf, NFSX_V3WRITEVERF); } - np->n_mtime = np->n_fattr.nfsv3fa_mtime; + fxdr_nfsv3time(&np->n_fattr.fa3_mtime, &np->n_mtime) nfs_semgive(nmp); return writesize; @@ -570,6 +573,110 @@ errout_with_semaphore: } /**************************************************************************** + * Name: nfs_readdirrpc + * + * Description: The function below stuff the cookies in after the name. + ****************************************************************************/ + +int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool end_of_directory, struct fs_dirent_s *dir) +{ + int error = 0; + void *datareply = NULL; + struct READDIR3args *readir = NULL; + struct READDIR3resok *resok = NULL; + + /* Loop around doing readdir rpc's of size nm_readdirsize + * truncated to a multiple of NFS_READDIRBLKSIZ. + * The stopping criteria is EOF. + */ + + while (end_of_directory == false) + { + nfsstats.rpccnt[NFSPROC_READDIR]++; + readir->dir = np->n_fhp; + readir->count = nmp->nm_readdirsize; + if (nfsstats.rpccnt[NFSPROC_READDIR] == 1) + { + readir->cookie.nfsuquad[0] = 0; + readir->cookie.nfsuquad[1] = 0; + readir->cookieverf.nfsuquad[0] = 0; + readir->cookieverf.nfsuquad[1] = 0; + } + else + { + readir->cookie.nfsuquad[0] = dir->u.nfs.cookie[0]; + readir->cookie.nfsuquad[1] = dir->u.nfs.cookie[1]; + readir->cookieverf.nfsuquad[0] = np->n_cookieverf.nfsuquad[0]; + readir->cookieverf.nfsuquad[1] = np->n_cookieverf.nfsuquad[1]; + } + + error = nfs_request(nmp, NFSPROC_READDIR, readir, datareply); + + if (error) + { + goto nfsmout; + } + + resok = (struct READDIR3resok*) datareply; + np->n_fattr = resok->dir_attributes; + np->n_cookieverf.nfsuquad[0] = resok->cookieverf.nfsuquad[0]; + np->n_cookieverf.nfsuquad[1] = resok->cookieverf.nfsuquad[1]; + dir->fd_dir.d_type = resok->reply.entries->fileid; + memcpy(&dir->fd_dir.d_name[NAME_MAX], &resok->reply.entries->name, NAME_MAX); + //dir->fd_dir.d_name = resok->reply.entries->name;// + dir->u.nfs.cookie[0] = resok->reply.entries->cookie.nfsuquad[0]; + dir->u.nfs.cookie[1] = resok->reply.entries->cookie.nfsuquad[1]; + + if(resok->reply.eof == true) + { + end_of_directory = true; + } + + //more_dirs = fxdr_unsigned(int, *dp); + + /* loop thru the dir entries*/ +/* + while (more_dirs && bigenough) + { + if (bigenough) + { + if (info_v3) + { + dir->u.nfs.cookie[0] = cookie.nfsuquad[0]; + } + else + { + dir->u.nfs.cookie[0] = ndp->cookie[0] = 0; + } + + dir->u.nfs.cookie[1] = ndp->cookie[1] = cookie.nfsuquad[1]; + } + + more_dirs = fxdr_unsigned(int, *ndp); + } + */ + } + + /* We are now either at the end of the directory */ + + if (resok->reply.entries == NULL) + { + np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]); + + /* We signal the end of the directory by returning the + * special error -ENOENT + */ + + fdbg("End of directory\n"); + error = -ENOENT; + } + +nfsmout: + return error; +} + + +/**************************************************************************** * Name: nfs_readdir * * Description: Read the next directory entry @@ -579,8 +686,6 @@ errout_with_semaphore: static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) { int error = 0; - unsigned long *cookies = NULL; - int cnt; struct nfsmount *nmp; struct nfsnode *np; bool eof = false; @@ -595,7 +700,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) /* Recover our private data from the inode instance */ nmp = mountpt->i_private; - np = np->nm_head; + np = nmp->nm_head; dir->fd_root = mountpt; /* Make sure that the mount is still healthy */ @@ -614,7 +719,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) goto errout_with_semaphore; } - dir->u.nfs.nd_direoffset = np->nd_direoffset; + dir->u.nfs.nd_direoffset = np->n_direofoffset; /* First, check for hit on the EOF offset */ @@ -630,7 +735,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) (void)nfs_fsinfo(mountpt, NULL, NULL); } - error = nfs_readdirrpc(nmp, np, &eof, dir); + error = nfs_readdirrpc(nmp, np, eof, dir); if (error == NFSERR_BAD_COOKIE) { @@ -650,173 +755,222 @@ errout_with_semaphore: } /**************************************************************************** - * Name: nfs_readdirrpc - * - * Description: The function below stuff the cookies in after the name. + * Name: nfs_decode_args ****************************************************************************/ -static int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool *end_of_directory, fs_dirent_s *dir) +void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) { - int error = 0; - void *datareply; - struct READDIR3args *readdir; - struct READDIR3resok *resok; + int adjsock = 0; + int maxio; - /* Loop around doing readdir rpc's of size nm_readdirsize - * truncated to a multiple of NFS_READDIRBLKSIZ. - * The stopping criteria is EOF. - */ +#ifdef CONFIG_NFS_TCPIP + /* Re-bind if rsrvd port requested and wasn't on one */ - while (end_of_directory == false) + adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT) + && (argp->flags & NFSMNT_RESVPORT); +#endif + + /* Also re-bind if we're switching to/from a connected UDP socket */ + + adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != (argp->flags & NFSMNT_NOCONN)); + + /* Update flags atomically. Don't change the lock bits. */ + + nmp->nm_flag = + (argp->flags & ~NFSMNT_INTERNAL) | (nmp->nm_flag & NFSMNT_INTERNAL); + + if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) { - nfsstats.rpccnt[NFSPROC_READDIR]++; - readdir->dir = np->n_fhp; - readdir->count = nmp->nm_readdirsiz; - if (nfsstats.rpccnt[NFSPROC_READDIR] == 1) + nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10; + if (nmp->nm_timeo < NFS_MINTIMEO) { - readdir->cookie.nfsuquad[0] = 0; - readdir->cookie.nfsuquad[1] = 0; - readdir->cookieverf.nfsuquad[0] = 0; - readdir->cookieverf.nfsuquad[1] = 0; + nmp->nm_timeo = NFS_MINTIMEO; } - else + else if (nmp->nm_timeo > NFS_MAXTIMEO) { - readdir->cookie.nfsuquad[0] = dir->u.nfs.cookie[0]; - readdir->cookie.nfsuquad[1] = dir->u.nfs.cookie[1]; - readdir->cookieverf.nfsuquad[0] = np->n_cookieverf.nfsuquad[0]; - readdir->cookieverf.nfsuquad[1] = np->n_cookieverf.nfsuquad[1]; + nmp->nm_timeo = NFS_MAXTIMEO; } + } - error = nfs_request(nmp, NFSPROC_READDIR, readdir, datareply); + if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) + { + nmp->nm_retry = (argp->retrans < NFS_MAXREXMIT)? argp->retrans : NFS_MAXREXMIT; + } - if (error) + if (!(nmp->nm_flag & NFSMNT_SOFT)) + { + nmp->nm_retry = NFS_MAXREXMIT + 1; /* past clip limit */ + } + + if (argp->flags & NFSMNT_NFSV3) + { + if (argp->sotype == SOCK_DGRAM) { - goto nfsmout; + maxio = NFS_MAXDGRAMDATA; } + else + { + maxio = NFS_MAXDATA; + } + } + else + { + maxio = NFS_V2MAXDATA; + } - resok = (void READDIR3resok*) datareply; - np->n_fattr = resok->dir_attributes; - np->nd_cookieverf.nfsuquad[0] = resok->cookieverf.nfsuquad[0]; - np->nd_cookieverf.nfsuquad[1] = resok->cookieverf.nfsuquad[1]; - dir->fd_dir->d_type = resok->reply->entries->fileid; - dir->fd_dir->d_name = resok->reply->entries->name; - dir->u.nfs.cookie[0] = resok->reply->entries->cookie.nfsuquad[0]; - dir->u.nfs.cookie[1] = resok->reply->entries->cookie.nfsuquad[1]; - - if(resok->reply->eof == true) - { - end_of_directory = true; - } + if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) + { + int osize = nmp->nm_wsize; + nmp->nm_wsize = argp->wsize; - //more_dirs = fxdr_unsigned(int, *dp); + /* Round down to multiple of blocksize */ - /* loop thru the dir entries*/ -/* - while (more_dirs && bigenough) + nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1); + if (nmp->nm_wsize <= 0) { - if (bigenough) - { - if (info_v3) - { - dir->u.nfs.cookie[0] = cookie.nfsuquad[0]; - } - else - { - dir->u.nfs.cookie[0] = ndp->cookie[0] = 0; - } + nmp->nm_wsize = NFS_FABLKSIZE; + } - dir->u.nfs.cookie[1] = ndp->cookie[1] = cookie.nfsuquad[1]; - } + adjsock |= (nmp->nm_wsize != osize); + } - more_dirs = fxdr_unsigned(int, *ndp); - } - */ + if (nmp->nm_wsize > maxio) + { + nmp->nm_wsize = maxio; } - /* We are now either at the end of the directory */ + if (nmp->nm_wsize > MAXBSIZE) + { + nmp->nm_wsize = MAXBSIZE; + } - if (resok->reply->entries == NULL) + if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) { - np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]); + int osize = nmp->nm_rsize; + nmp->nm_rsize = argp->rsize; - /* We signal the end of the directory by returning the - * special error -ENOENT - */ + /* Round down to multiple of blocksize */ - fdbg("End of directory\n"); - error = -ENOENT; + nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1); + if (nmp->nm_rsize <= 0) + { + nmp->nm_rsize = NFS_FABLKSIZE; + } + + adjsock |= (nmp->nm_rsize != osize); } -nfsmout: - return error; -} + if (nmp->nm_rsize > maxio) + { + nmp->nm_rsize = maxio; + } -/**************************************************************************** - * Name: nfs_mount - * - * Description: This implements a portion of the mount operation. This - * function allocates and initializes the mountpoint private data and - * binds the blockdriver inode to the filesystem private data. The final - * binding of the private data (containing the blockdriver) to the - * mountpoint is performed by mount(). - * - ****************************************************************************/ + if (nmp->nm_rsize > MAXBSIZE) + { + nmp->nm_rsize = MAXBSIZE; + } -static int nfs_mount(struct inode *blkdriver, void *data, void **handle) -{ - int error; - struct nfs_args args; - struct sockaddr *nam; - nfsfh_t nfh[NFSX_V3FHMAX]; + if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) + { + nmp->nm_readdirsize = argp->readdirsize; - bcopy(data, &args, sizeof(args.version)); - if (args.version == 3) + /* Round down to multiple of blocksize */ + + nmp->nm_readdirsize &= ~(NFS_DIRBLKSIZ - 1); + if (nmp->nm_readdirsize < NFS_DIRBLKSIZ) + { + nmp->nm_readdirsize = NFS_DIRBLKSIZ; + } + } + else if (argp->flags & NFSMNT_RSIZE) { - bcopy(data, &args, sizeof(struct nfs_args3)); - args.flags &= ~(NFSMNT_INTERNAL | NFSMNT_NOAC); + nmp->nm_readdirsize = nmp->nm_rsize; } - else if (args.version == NFS_ARGSVERSION) + + if (nmp->nm_readdirsize > maxio) { - error = copyin(data, &args, sizeof(struct nfs_args)); - args.flags &= ~NFSMNT_NOAC; + nmp->nm_readdirsize = maxio; } - else + + if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 && + argp->maxgrouplist <= NFS_MAXGRPS) { - return EPROGMISMATCH; + nmp->nm_numgrps = argp->maxgrouplist; } - if ((args.flags & (NFSMNT_NFSV3 | NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS) + if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 && + argp->readahead <= NFS_MAXRAHEAD) { - return EINVAL; + nmp->nm_readahead = argp->readahead; } - if (blkdriver->mnt_flag & MNT_UPDATE) + if (argp->flags & NFSMNT_ACREGMIN && argp->acregmin >= 0) { - struct nfsmount *nmp = (struct nfsmount*)blkdriver->i_private; + if (argp->acregmin > 0xffff) + { + nmp->nm_acregmin = 0xffff; + } + else + { + nmp->nm_acregmin = argp->acregmin; + } + } - if (nmp == NULL) + if (argp->flags & NFSMNT_ACREGMAX && argp->acregmax >= 0) + { + if (argp->acregmax > 0xffff) { - return EIO; + nmp->nm_acregmax = 0xffff; } + else + { + nmp->nm_acregmax = argp->acregmax; + } + } - /* When doing an update, we can't change from or to v3. */ + if (nmp->nm_acregmin > nmp->nm_acregmax) + { + nmp->nm_acregmin = nmp->nm_acregmax; + } - args.flags = (args.flags & ~(NFSMNT_NFSV3)) | - (nmp->nm_flag & (NFSMNT_NFSV3)); - nfs_decode_args(nmp, &args); - return 0; + if (argp->flags & NFSMNT_ACDIRMIN && argp->acdirmin >= 0) + { + if (argp->acdirmin > 0xffff) + { + nmp->nm_acdirmin = 0xffff; + } + else + { + nmp->nm_acdirmin = argp->acdirmin; + } } - if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) + if (argp->flags & NFSMNT_ACDIRMAX && argp->acdirmax >= 0) { - return EINVAL; + if (argp->acdirmax > 0xffff) + { + nmp->nm_acdirmax = 0xffff; + } + else + { + nmp->nm_acdirmax = argp->acdirmax; + } } - bcopy(args.fh, nfh, args.fhsize); - bcopy(args.addr, nam, sizeof(args.addr)); - args.fh = nfh; - error = mountnfs(&args, blkdriver, nam); - return error; + if (nmp->nm_acdirmin > nmp->nm_acdirmax) + { + nmp->nm_acdirmin = nmp->nm_acdirmax; + } + + if (nmp->nm_so && adjsock) + { + nfs_disconnect(nmp); + if (nmp->nm_sotype == SOCK_DGRAM) + while (nfs_connect(nmp)) + { + nvdbg("nfs_args: retrying connect\n"); + } + } } /**************************************************************************** @@ -826,98 +980,87 @@ static int nfs_mount(struct inode *blkdriver, void *data, void **handle) * ****************************************************************************/ -static int mountnfs(struct nfs_args *argp, struct inode *blkdriver, +int mountnfs(struct nfs_args *argp, struct inode *blkdriver, struct sockaddr *nam, void **handle) { struct nfsmount *nmp; int error; - if (blkdriver->mnt_flag & MNT_UPDATE) - { - nmp = (struct nfsmount*)blkdriver->i_private; - - /* update paths, file handles, etc, here XXX */ + /* Open the block driver */ - return 0; - } - else + if (!blkdriver || !blkdriver->u.i_bops) { - /* Open the block driver */ - - if (!blkdriver || !blkdriver->u.i_bops) - { - fdbg("No block driver/ops\n"); - return -ENODEV; - } + fdbg("No block driver/ops\n"); + return -ENODEV; + } - if (blkdriver->u.i_bops->open && - blkdriver->u.i_bops->open(blkdriver) != OK) - { - fdbg("No open method\n"); - return -ENODEV; - } + if (blkdriver->u.i_bops->open && + blkdriver->u.i_bops->open(blkdriver) != OK) + { + fdbg("No open method\n"); + return -ENODEV; + } - /* Create an instance of the mountpt state structure */ + /* Create an instance of the mountpt state structure */ - nmp = (struct nfsmount*)zalloc(sizeof(struct nfmount)); - if (!nmp) - { - fdbg("Failed to allocate mountpoint structure\n"); - return -ENOMEM; - } + nmp = (struct nfsmount *)kzalloc(sizeof(struct nfsmount)); + if (!nmp) + { + fdbg("Failed to allocate mountpoint structure\n"); + return -ENOMEM; + } - /* Initialize the allocated mountpt state structure. The filesystem is - * responsible for one reference ont the blkdriver inode and does not - * have to addref() here (but does have to release in ubind(). - */ + /* Initialize the allocated mountpt state structure. The filesystem is + * responsible for one reference ont the blkdriver inode and does not + * have to addref() here (but does have to release in ubind(). + */ - sem_init(&rm->rm_sem, 0, 0); /* Initialize the semaphore that controls access */ - - //vfs_getnewfsid(mp); - nmp->nm_blkdriver = blkdriver; /* Save the block driver reference */ - nmp->nm_timeo = NFS_TIMEO; - nmp->nm_retry = NFS_RETRANS; - nmp->nm_wsize = NFS_WSIZE; - nmp->nm_rsize = NFS_RSIZE; - nmp->nm_readdirsize = NFS_READDIRSIZE; - nmp->nm_numgrps = NFS_MAXGRPS; - nmp->nm_readahead = NFS_DEFRAHEAD; - nmp->nm_fhsize = argp->fhsize; - nmp->nm_acregmin = NFS_MINATTRTIMO; - nmp->nm_acregmax = NFS_MAXATTRTIMO; - nmp->nm_acdirmin = NFS_MINATTRTIMO; - nmp->nm_acdirmax = NFS_MAXATTRTIMO; - memmove(nmp->nm_fh, argp->fh, argp->fhsize); - //strncpy(&mp->mnt_stat.f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN); - //memmove(hst, mp->mnt_stat.f_mntfromname, MNAMELEN); - // bcopy(pth, nmp->nm_mntonname, 90); - //memmove(argp, &mp->mnt_stat.mount_info.nfs_args, sizeof(*argp)); - nmp->nm_nam = nam; - nfs_decode_args(nmp, argp); - - /* Set up the sockets and per-host congestion */ - - nmp->nm_sotype = argp->sotype; - nmp->nm_soproto = argp->proto; - - /* For Connection based sockets (TCP,...) defer the connect until - * the first request, in case the server is not responding. - */ + sem_init(&nmp->nm_sem, 0, 0); /* Initialize the semaphore that controls access */ + +//vfs_getnewfsid(mp); + nmp->nm_blkdriver = blkdriver; /* Save the block driver reference */ + nmp->nm_timeo = NFS_TIMEO; + nmp->nm_retry = NFS_RETRANS; + nmp->nm_wsize = NFS_WSIZE; + nmp->nm_rsize = NFS_RSIZE; + nmp->nm_readdirsize = NFS_READDIRSIZE; + nmp->nm_numgrps = NFS_MAXGRPS; + nmp->nm_readahead = NFS_DEFRAHEAD; + nmp->nm_fhsize = argp->fhsize; + nmp->nm_acregmin = NFS_MINATTRTIMO; + nmp->nm_acregmax = NFS_MAXATTRTIMO; + nmp->nm_acdirmin = NFS_MINATTRTIMO; + nmp->nm_acdirmax = NFS_MAXATTRTIMO; + nmp->nm_fh = argp->fh; +//strncpy(&mp->mnt_stat.f_fstypename[0], mp->mnt_vfc->vfc_name, MFSNAMELEN); +//memmove(hst, mp->mnt_stat.f_mntfromname, MNAMELEN); +//bcopy(pth, nmp->nm_mntonname, 90); +//memmove(argp, &mp->mnt_stat.mount_info.nfs_args, sizeof(*argp)); + nmp->nm_nam = nam; + nfs_decode_args(nmp, argp); + + /* Set up the sockets and per-host congestion */ + + nmp->nm_sotype = argp->sotype; + nmp->nm_soproto = argp->proto; + + /* For Connection based sockets (TCP,...) defer the connect until + * the first request, in case the server is not responding. + */ - if (nmp->nm_sotype == SOCK_DGRAM && (error = nfs_connect(nmp))) - { - goto bad; - } + if (nmp->nm_sotype == SOCK_DGRAM && (error = nfs_connect(nmp))) + { + goto bad; + } - /* Mounted! */ + /* Mounted! */ - nmp->nfs_mounted = true; - nfs_init(); - *handle = blkdriver->i_private = &nmp; - nfs_semgive(nmp); + nmp->nm_mounted = true; + nfs_init(); + *handle = blkdriver->i_private = &nmp; + nfs_semgive(nmp); - return 0; - } + return 0; bad: nfs_disconnect(nmp); @@ -927,6 +1070,48 @@ bad: } /**************************************************************************** + * Name: nfs_mount + * + * Description: This implements a portion of the mount operation. This + * function allocates and initializes the mountpoint private data and + * binds the blockdriver inode to the filesystem private data. The final + * binding of the private data (containing the blockdriver) to the + * mountpoint is performed by mount(). + * + ****************************************************************************/ + +static int nfs_mount(struct inode *blkdriver, const void *data, void **handle) +{ + int error; + struct nfs_args args; + struct sockaddr *nam; + + bcopy(data, &args, sizeof(struct nfs_args)); + if (args.version == NFS_ARGSVERSION) + { + args.flags &= ~(NFSMNT_INTERNAL | NFSMNT_NOAC); + } + else + { + return -EINVAL; + } + + if ((args.flags & (NFSMNT_NFSV3 | NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS) + { + return -EINVAL; + } + + if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) + { + return -EINVAL; + } + + nam = args.addr; + error = mountnfs(&args, blkdriver, nam, handle); + return error; +} + +/**************************************************************************** * Name: nfs_unmount * * Description: This implements the filesystem portion of the umount @@ -934,9 +1119,9 @@ bad: * ****************************************************************************/ -int nfs_unmount(struct inode *blkdriver, void *handle) +int nfs_unmount(void *handle, struct inode **blkdriver) { - struct nfsmount *nmp = (struct nfsmount*) handle ; + struct nfsmount *nmp = (struct nfsmount *) handle ; int error; fvdbg("Entry\n"); @@ -946,7 +1131,7 @@ int nfs_unmount(struct inode *blkdriver, void *handle) return -EINVAL; } - nfs_semtake(nmp) + nfs_semtake(nmp); if (nmp->nm_head) { /* We cannot unmount now.. there are open files */ @@ -955,7 +1140,7 @@ int nfs_unmount(struct inode *blkdriver, void *handle) } else { - /* Unmount ... close the block driver */ + /* Unmount ... close the block driver */ if (nmp->nm_blkdriver) { @@ -981,12 +1166,7 @@ int nfs_unmount(struct inode *blkdriver, void *handle) } /* Release the mountpoint private data */ - - if (blkdriver->i_private) - { - kfree(blkdriver->nm_buffer); - } - + nfs_disconnect(nmp); sem_destroy(&nmp->nm_sem); kfree(nmp); @@ -994,8 +1174,8 @@ int nfs_unmount(struct inode *blkdriver, void *handle) return 0; } - nfs_semgive(nmp) - return 0; + nfs_semgive(nmp); + return error; } /**************************************************************************** @@ -1011,8 +1191,8 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) struct nfsmount *nmp; int error = 0; uint64_t tquad; - void *datareply; - struct FSSTAT3args *fsstat + void *datareply = NULL; + struct FSSTAT3args *fsstat = NULL; int info_v3; /* Sanity checks */ @@ -1053,7 +1233,7 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) } sfp = (struct nfs_statfs *)datareply; - nmp->nm_head->n_fattr = sfp->obj_attributes + nmp->nm_head->n_fattr = sfp->obj_attributes; if (info_v3) { sbp->f_bsize = NFS_FABLKSIZE; @@ -1062,13 +1242,13 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) tquad = fxdr_hyper(&sfp->sf_fbytes); sbp->f_bfree = tquad / (uint64_t) NFS_FABLKSIZE; tquad = fxdr_hyper(&sfp->sf_abytes); - sbp->f_bavail = (quad_t) tquad / (quad_t) NFS_FABLKSIZE; + sbp->f_bavail = tquad / (uint64_t) NFS_FABLKSIZE; tquad = fxdr_hyper(&sfp->sf_tfiles); sbp->f_files = tquad; tquad = fxdr_hyper(&sfp->sf_ffiles); sbp->f_ffree = tquad; - sbp->f_namelen = MAXNAMLEN; + sbp->f_namelen = NAME_MAX; } else { @@ -1094,11 +1274,11 @@ errout_with_semaphore: static int nfs_remove(struct inode *mountpt, const char *relpath) { - struct nsfmount *nmp; + struct nfsmount *nmp; struct nfsnode *np; - void *datreply; - struct REMOVE3args *remove; - struct REMOVE3resok *resok; + void *datareply = NULL; + struct REMOVE3args *remove = NULL; + struct REMOVE3resok *resok = NULL; int error = 0; /* Sanity checks */ @@ -1107,13 +1287,13 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) /* Get the mountpoint private data from the inode structure */ - nmp = (struct nfsmount *)mountpt->i_private; + nmp = (struct nfsmount*)mountpt->i_private; np = nmp->nm_head; /* Check if the mount is still healthy */ nfs_semtake(nmp); - error = fat_checkmount(nmp); + error = nfs_checkmount(nmp); if (error == 0) { /* If the file is open, the correct behavior is to remove the file @@ -1123,7 +1303,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) /* Remove the file */ - if (np->n_type != NFREG) + if (np->nfsv3_type != NFREG) { error = EPERM; goto errout_with_semaphore; @@ -1132,8 +1312,8 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) /* Do the rpc */ nfsstats.rpccnt[NFSPROC_REMOVE]++; - remove->object->dir = np->n_fhp; - remove->object->name = relpath; + remove->object.dir = np->n_fhp; + remove->object.name = relpath; error = nfs_request(nmp, NFSPROC_REMOVE, remove, datareply); @@ -1154,7 +1334,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) } resok = (struct REMOVE3resok *)datareply; - np->n_fattr = resok->dir_wcc->after; + np->n_fattr = resok->dir_wcc.after; np->n_flag |= NMODIFIED; } NFS_INVALIDATE_ATTRCACHE(np); @@ -1173,14 +1353,13 @@ errout_with_semaphore: static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) { - struct nfsv3_sattr *vap; - struct nfsv3_sattr *sp; + struct nfs_fattr vap; + struct nfsv3_sattr sp; struct nfsmount *nmp; struct nfsnode *np; - struct MKDIR3args *mkdir; - struct MKDIR3resok *resok; - void *datareply; - int len; + struct MKDIR3args *mkir = NULL; + struct MKDIR3resok *resok = NULL; + void *datareply = NULL; int error = 0; /* Sanity checks */ @@ -1203,21 +1382,21 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) } nfsstats.rpccnt[NFSPROC_MKDIR]++; - mkdir->where->dir = nmp->nm_fh; - mkdir->where->name = relpath; + mkir->where.dir = nmp->nm_fh; + mkir->where.name = relpath; - sp->sa_modetrue = nfs_true; - sp->sa_mode = txdr_unsigned(vap->sa_mode); - sp->sa_uid = nfs_xdrneg1; - sp->sa_gid = nfs_xdrneg1; - sp->sa_size = nfs_xdrneg1; - sp->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - sp->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + sp.sa_modetrue = nfs_true; + sp.sa_mode = txdr_unsigned(vap.fa_mode); + sp.sa_uidfalse = nfs_xdrneg1; + sp.sa_gidfalse = nfs_xdrneg1; + sp.sa_sizefalse = nfs_xdrneg1; + sp.sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + sp.sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&vap->sa_atime, &sp->sa_atime); - txdr_nfsv3time(&vap->sa_mtime, &sp->sa_mtime); + fxdr_nfsv3time2(&vap.fa3_atime, &sp.sa_atime); + fxdr_nfsv3time2(&vap.fa3_mtime, &sp.sa_mtime); - mkdir->attributes = sp; + mkir->attributes = sp; error = nfs_request(nmp, NFSPROC_MKDIR, mkdir, datareply); if (error) @@ -1226,10 +1405,10 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) } resok = (struct MKDIR3resok *) datareply; - np->nfsv3_type = NDIR; + np->nfsv3_type = NFDIR; np->n_fhp = resok->handle; np->n_fattr = resok->obj_attributes; - nmp->n_flag |= NMODIFIED; + np->n_flag |= NMODIFIED; NFS_INVALIDATE_ATTRCACHE(np); errout_with_semaphore: @@ -1248,9 +1427,9 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) { struct nfsmount *nmp; struct nfsnode *np; - struct RMDIR3args *rmdir; - struct RMDIR3resok *resok; - void *datareply; + struct RMDIR3args *rmdir = NULL; + struct RMDIR3resok *resok = NULL; + void *datareply = NULL; int error = 0; /* Sanity checks */ @@ -1265,12 +1444,12 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) /* Check if the mount is still healthy */ nfs_semtake(nmp); - error = fat_checkmount(nmp); + error = nfs_checkmount(nmp); if (error == 0) { /* Remove the directory */ - if (np->n_type != NDIR) + if (np->nfsv3_type != NFDIR) { error = EPERM; goto errout_with_semaphore; @@ -1279,9 +1458,9 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) /* Do the rpc */ nfsstats.rpccnt[NFSPROC_RMDIR]++; - rmdir->object->dir = np->n_fhp; - rmdir->object->name = relpath; - error = nfs_request(dvp, NFSPROC_RMDIR, rmdir, datareply); + rmdir->object.dir = np->n_fhp; + rmdir->object.name = relpath; + error = nfs_request(nmp, NFSPROC_RMDIR, rmdir, datareply); if (error == ENOENT) { @@ -1293,8 +1472,8 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) goto errout_with_semaphore; } - resok = (struct REMOVE3resok *)datareply; - np->n_fattr = resok->dir_wcc->after; + resok = (struct RMDIR3resok *)datareply; + np->n_fattr = resok->dir_wcc.after; np->n_flag |= NMODIFIED; } NFS_INVALIDATE_ATTRCACHE(np); @@ -1314,11 +1493,11 @@ errout_with_semaphore: static int nfs_rename(struct inode *mountpt, const char *oldrelpath, const char *newrelpath) { - struct nsfmount *nmp; + struct nfsmount *nmp; struct nfsnode *np; - void *datreply; - struct RENAME3args *rename; - struct RENAME3resok *resok; + void *datareply = NULL; + struct RENAME3args *rename = NULL; + struct RENAME3resok *resok = NULL; int error = 0; /* Sanity checks */ @@ -1347,12 +1526,12 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, } nfsstats.rpccnt[NFSPROC_RENAME]++; - rename->from->dir = np->n_fhp; - rename->from->name = oldrelpath; - rename->to->dir = np->n_fhp; - rename->to->name = newrelpath; + rename->from.dir = np->n_fhp; + rename->from.name = oldrelpath; + rename->to.dir = np->n_fhp; + rename->to.name = newrelpath; - error = nfs_request(fdvp, NFSPROC_RENAME, rename, datareply); + error = nfs_request(nmp, NFSPROC_RENAME, rename, datareply); /* Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. */ @@ -1367,7 +1546,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, } resok = (struct RENAME3resok *) datareply; - np->n_fattr = resok->todir_wcc->after; + np->n_fattr = resok->todir_wcc.after; np->n_flag |= NMODIFIED; NFS_INVALIDATE_ATTRCACHE(np); @@ -1386,11 +1565,11 @@ errout_with_semaphore: static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *buf) { struct nfsv3_fsinfo *fsp; - struct FSINFOargs *fsinfo; + struct FSINFOargs *fsinfo = NULL; struct nfsmount *nmp; uint32_t pref, max; int error = 0; - void *datareply; + void *datareply = NULL; /* Sanity checks */ @@ -1403,7 +1582,7 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b /* Check if the mount is still healthy */ nfs_semtake(nmp); - error = nfd_checkmount(nmp); + error = nfs_checkmount(nmp); if (error != 0) { goto errout_with_semaphore; @@ -1415,7 +1594,7 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b error = nfs_request(nmp, NFSPROC_FSINFO, fsinfo, datareply); if (error) { - goto errout_with_semaphoret; + goto errout_with_semaphore; } fsp = (struct nfsv3_fsinfo *)datareply; @@ -1465,13 +1644,13 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b } } - buf->st_mode = fxdr_hyper(&fsp->obj_attributes->fa_mode); - buf->st_size = fxdr_hyper(&fsp->obj_attributes->fa3_size); + buf->st_mode = fxdr_hyper(&fsp->obj_attributes.fa_mode); + buf->st_size = fxdr_hyper(&fsp->obj_attributes.fa3_size); buf->st_blksize = 0; buf->st_blocks = 0; - buf->st_mtime = fxdr_hyper(&fsp->obj_attributes->fa3_mtime); - buf->st_atime = fxdr_hyper(&fsp->obj_attributes->fa3_atime); - buf->st_ctime = fxdr_hyper(&fsp->obj_attributes->fa3_ctime); + buf->st_mtime = fxdr_hyper(&fsp->obj_attributes.fa3_mtime); + buf->st_atime = fxdr_hyper(&fsp->obj_attributes.fa3_atime); + buf->st_ctime = fxdr_hyper(&fsp->obj_attributes.fa3_ctime); nmp->nm_flag |= NFSMNT_GOTFSINFO; errout_with_semaphore: @@ -1479,226 +1658,7 @@ errout_with_semaphore: return error; } -/**************************************************************************** - * Name: nfs_decode_args - ****************************************************************************/ - -void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) -{ - int adjsock = 0; - int maxio; - -#ifdef CONFIG_NFS_TCPIP - /* Re-bind if rsrvd port requested and wasn't on one */ - - adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT) - && (argp->flags & NFSMNT_RESVPORT); -#endif - - /* Also re-bind if we're switching to/from a connected UDP socket */ - - adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != (argp->flags & NFSMNT_NOCONN)); - - /* Update flags atomically. Don't change the lock bits. */ - - nmp->nm_flag = - (argp->flags & ~NFSMNT_INTERNAL) | (nmp->nm_flag & NFSMNT_INTERNAL); - - if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) - { - nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10; - if (nmp->nm_timeo < NFS_MINTIMEO) - { - nmp->nm_timeo = NFS_MINTIMEO; - } - else if (nmp->nm_timeo > NFS_MAXTIMEO) - { - nmp->nm_timeo = NFS_MAXTIMEO; - } - } - - if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) - { - nmp->nm_retry = MIN(argp->retrans, NFS_MAXREXMIT); - } - - if (!(nmp->nm_flag & NFSMNT_SOFT)) - { - nmp->nm_retry = NFS_MAXREXMIT + 1; /* past clip limit */ - } - - if (argp->flags & NFSMNT_NFSV3) - { - if (argp->sotype == SOCK_DGRAM) - { - maxio = NFS_MAXDGRAMDATA; - } - else - { - maxio = NFS_MAXDATA; - } - } - else - { - maxio = NFS_V2MAXDATA; - } - - if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) - { - int osize = nmp->nm_wsize; - nmp->nm_wsize = argp->wsize; - - /* Round down to multiple of blocksize */ - - nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1); - if (nmp->nm_wsize <= 0) - { - nmp->nm_wsize = NFS_FABLKSIZE; - } - - adjsock |= (nmp->nm_wsize != osize); - } - - if (nmp->nm_wsize > maxio) - { - nmp->nm_wsize = maxio; - } - - if (nmp->nm_wsize > MAXBSIZE) - { - nmp->nm_wsize = MAXBSIZE; - } - - if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) - { - int osize = nmp->nm_rsize; - nmp->nm_rsize = argp->rsize; - - /* Round down to multiple of blocksize */ - - nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1); - if (nmp->nm_rsize <= 0) - { - nmp->nm_rsize = NFS_FABLKSIZE; - } - - adjsock |= (nmp->nm_rsize != osize); - } - - if (nmp->nm_rsize > maxio) - { - nmp->nm_rsize = maxio; - } - - if (nmp->nm_rsize > MAXBSIZE) - { - nmp->nm_rsize = MAXBSIZE; - } - - if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) - { - nmp->nm_readdirsize = argp->readdirsize; - - /* Round down to multiple of blocksize */ - - nmp->nm_readdirsize &= ~(NFS_DIRBLKSIZ - 1); - if (nmp->nm_readdirsize < NFS_DIRBLKSIZ) - { - nmp->nm_readdirsize = NFS_DIRBLKSIZ; - } - } - else if (argp->flags & NFSMNT_RSIZE) - { - nmp->nm_readdirsize = nmp->nm_rsize; - } - - if (nmp->nm_readdirsize > maxio) - { - nmp->nm_readdirsize = maxio; - } - - if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 && - argp->maxgrouplist <= NFS_MAXGRPS) - { - nmp->nm_numgrps = argp->maxgrouplist; - } - - if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 && - argp->readahead <= NFS_MAXRAHEAD) - { - nmp->nm_readahead = argp->readahead; - } - - if (argp->flags & NFSMNT_ACREGMIN && argp->acregmin >= 0) - { - if (argp->acregmin > 0xffff) - { - nmp->nm_acregmin = 0xffff; - } - else - { - nmp->nm_acregmin = argp->acregmin; - } - } - - if (argp->flags & NFSMNT_ACREGMAX && argp->acregmax >= 0) - { - if (argp->acregmax > 0xffff) - { - nmp->nm_acregmax = 0xffff; - } - else - { - nmp->nm_acregmax = argp->acregmax; - } - } - - if (nmp->nm_acregmin > nmp->nm_acregmax) - { - nmp->nm_acregmin = nmp->nm_acregmax; - } - - if (argp->flags & NFSMNT_ACDIRMIN && argp->acdirmin >= 0) - { - if (argp->acdirmin > 0xffff) - { - nmp->nm_acdirmin = 0xffff; - } - else - { - nmp->nm_acdirmin = argp->acdirmin; - } - } - - if (argp->flags & NFSMNT_ACDIRMAX && argp->acdirmax >= 0) - { - if (argp->acdirmax > 0xffff) - { - nmp->nm_acdirmax = 0xffff; - } - else - { - nmp->nm_acdirmax = argp->acdirmax; - } - } - - if (nmp->nm_acdirmin > nmp->nm_acdirmax) - { - nmp->nm_acdirmin = nmp->nm_acdirmax; - } - - if (nmp->nm_so && adjsock) - { - nfs_disconnect(nmp); - if (nmp->nm_sotype == SOCK_DGRAM) - while (nfs_connect(nmp)) - { - nvdbg("nfs_args: retrying connect\n"); - } - } -} - -#ifdef 0 +#ifdef COMP /**************************************************************************** * Name: nfs_sync * diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h index 39b2040c2..fcbffe7f5 100644 --- a/nuttx/fs/nfs/rpc.h +++ b/nuttx/fs/nfs/rpc.h @@ -111,12 +111,12 @@ struct rpctask struct rpcclnt *r_rpcclnt; uint32_t r_xid; - int r_flags; /* flags on request, see below */ - int r_retry; /* max retransmission count */ - int r_rexmit; /* current retrans count */ - int r_timer; /* tick counter on reply */ - int r_procnum; /* NFS procedure number */ - int r_rtt; /* RTT for rpc */ + int r_flags; /* flags on request, see below */ + int r_retry; /* max retransmission count */ + int r_rexmit; /* current retrans count */ + int r_timer; /* tick counter on reply */ + int r_procnum; /* NFS procedure number */ + int r_rtt; /* RTT for rpc */ }; /* Generic RPC headers */ @@ -233,18 +233,10 @@ struct rpcclnt * Public Function Prototypes ****************************************************************************/ -/* -void rpcclnt_create(struct rpcclnt ** rpc); -void rpcclnt_destroy(struct rpcclnt * rpc); - -#define rpcclnt_get(X) rpcclnt_create(&(X)) -#define rpcclnt_put(X) rpcclnt_destroy(X) -*/ - void rpcclnt_init(void); //void rpcclnt_uninit(void); -int rpcclnt_setup(struct rpcclnt *, struct rpc_program *, struct sockaddr *, int, int, struct rpc_auth_info *, int, int, int); +//int rpcclnt_setup(struct rpcclnt *, struct rpc_program *, struct sockaddr *, int, int, struct rpc_auth_info *, int, int, int); int rpcclnt_connect(struct rpcclnt *); int rpcclnt_reconnect(struct rpctask *); void rpcclnt_disconnect(struct rpcclnt *); @@ -252,4 +244,5 @@ void rpcclnt_safedisconnect(struct rpcclnt *); int rpcclnt_request(struct rpcclnt *, int, struct rpc_reply *, void *); int rpcclnt_cancelreqs(struct rpcclnt *); + #endif /* _RPCCLNT_H_ */ diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c index 7f54c6965..0709fbf3c 100644 --- a/nuttx/fs/nfs/rpc_clnt.c +++ b/nuttx/fs/nfs/rpc_clnt.c @@ -549,7 +549,6 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, * until ours is found. */ -/* ARGSUSED */ static int rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call, struct rpc_reply *reply) diff --git a/nuttx/fs/nfs/xdr_subs.h b/nuttx/fs/nfs/xdr_subs.h index 6752d1f41..223f00fee 100644 --- a/nuttx/fs/nfs/xdr_subs.h +++ b/nuttx/fs/nfs/xdr_subs.h @@ -49,6 +49,8 @@ * Included Files ****************************************************************************/ +#include <arpa/inet.h> + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -86,6 +88,11 @@ (t)->tv_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \ } +#define fxdr_nfsv3time2(f, t) { \ + (t)->nfsv3_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \ + (t)->nfsv3_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \ +} + #define txdr_nfsv3time(f, t) { \ ((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \ ((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \ |