From 5f9ab50192280c587a266d9cee2fdd849cbad97d Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 18 Apr 2012 23:31:47 +0000 Subject: [PATCH] NFS update git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4634 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/fs/nfs/nfs.h | 46 +- nuttx/fs/nfs/nfs_args.h | 41 +- nuttx/fs/nfs/nfs_mount.h | 2 +- nuttx/fs/nfs/nfs_node.h | 12 +- nuttx/fs/nfs/nfs_proto.h | 65 +- nuttx/fs/nfs/nfs_socket.c | 18 +- nuttx/fs/nfs/nfs_socket.h | 48 +- nuttx/fs/nfs/nfs_vfsops.c | 1642 ++++++++++++++++++------------------- nuttx/fs/nfs/rpc.h | 23 +- nuttx/fs/nfs/rpc_clnt.c | 1 - nuttx/fs/nfs/xdr_subs.h | 7 + 11 files changed, 949 insertions(+), 956 deletions(-) diff --git a/nuttx/fs/nfs/nfs.h b/nuttx/fs/nfs/nfs.h index 497cfd666d..a88e5b91c3 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 57c735c175..fd81968f46 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 78048f443f..a07963a43a 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 dd7fe12a89..3ca0762eff 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 d8e7e990cf..0f874e28ae 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 0dbca8297e..8b0f28660b 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 e668e85fb8..31987dff30 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 - ****************************************************************************/ - -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_safedisconnect nfsx_safedisconnect -#endif -int nfsx_request_xx(struct nfsmount *, int, void*, void*); -int nfsx_nmcancelreqs(struct nfsmount *); - -#define nfs_connect nfs_connect_nfsx -#define nfs_disconnect nfs_disconnect_nfsx -#define nfs_nmcancelreqs nfsx_nmcancelreqs +#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) #ifdef CONFIG_NFS_TCPIP # define nfs_sigintr nfs_sigintr_nfsx +#define nfs_safedisconnect nfsx_safedisconnect +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#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 +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 805b489670..856ed68199 100644 --- a/nuttx/fs/nfs/nfs_vfsops.c +++ b/nuttx/fs/nfs/nfs_vfsops.c @@ -60,6 +60,8 @@ #include #include #include +#include +#include #include #include @@ -67,11 +69,14 @@ #include #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; @@ -569,98 +572,18 @@ errout_with_semaphore: return error; } -/**************************************************************************** - * Name: nfs_readdir - * - * Description: Read the next directory entry - * - ****************************************************************************/ - -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; - //struct nfs_dirent *ndp; - - fvdbg("Entry\n"); - - /* Sanity checks */ - - DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); - - /* Recover our private data from the inode instance */ - - nmp = mountpt->i_private; - np = np->nm_head; - dir->fd_root = mountpt; - - /* Make sure that the mount is still healthy */ - - nfs_semtake(nmp); - error = nfs_checkmount(nmp); - if (error != 0) - { - fdbg("romfs_checkmount failed: %d\n", error); - goto errout_with_semaphore; - } - - if (np->nfsv3_type != NFDIR) - { - error = EPERM; - goto errout_with_semaphore; - } - - dir->u.nfs.nd_direoffset = np->nd_direoffset; - - /* First, check for hit on the EOF offset */ - - if (dir->u.nfs.nd_direoffset != 0) - { - nfsstats.direofcache_hits++; - //np->n_open = true; - return 0; - } - - if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3) - { - (void)nfs_fsinfo(mountpt, NULL, NULL); - } - - error = nfs_readdirrpc(nmp, np, &eof, dir); - - if (error == NFSERR_BAD_COOKIE) - { - error = EINVAL; - } - - if (!error && eof) - { - nfsstats.direofcache_misses++; - nfs_semgive(nmp); - return 0; - } - -errout_with_semaphore: - nfs_semgive(nmp); - return error; -} - /**************************************************************************** * Name: nfs_readdirrpc * * Description: The function below stuff the cookies in after the name. ****************************************************************************/ -static int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool *end_of_directory, fs_dirent_s *dir) +int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool end_of_directory, struct fs_dirent_s *dir) { int error = 0; - void *datareply; - struct READDIR3args *readdir; - struct READDIR3resok *resok; + 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. @@ -670,40 +593,41 @@ static int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool *end_of while (end_of_directory == false) { nfsstats.rpccnt[NFSPROC_READDIR]++; - readdir->dir = np->n_fhp; - readdir->count = nmp->nm_readdirsiz; + readir->dir = np->n_fhp; + readir->count = nmp->nm_readdirsize; if (nfsstats.rpccnt[NFSPROC_READDIR] == 1) { - readdir->cookie.nfsuquad[0] = 0; - readdir->cookie.nfsuquad[1] = 0; - readdir->cookieverf.nfsuquad[0] = 0; - readdir->cookieverf.nfsuquad[1] = 0; + readir->cookie.nfsuquad[0] = 0; + readir->cookie.nfsuquad[1] = 0; + readir->cookieverf.nfsuquad[0] = 0; + readir->cookieverf.nfsuquad[1] = 0; } else { - 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]; + 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, readdir, datareply); + error = nfs_request(nmp, NFSPROC_READDIR, readir, datareply); if (error) { goto nfsmout; } - resok = (void READDIR3resok*) datareply; + resok = (struct 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]; + 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) + if(resok->reply.eof == true) { end_of_directory = true; } @@ -735,7 +659,7 @@ static int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool *end_of /* We are now either at the end of the directory */ - if (resok->reply->entries == NULL) + if (resok->reply.entries == NULL) { np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]); @@ -751,729 +675,80 @@ nfsmout: return error; } + /**************************************************************************** - * Name: nfs_mount + * Name: nfs_readdir * - * 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(). + * Description: Read the next directory entry * ****************************************************************************/ -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]; - - bcopy(data, &args, sizeof(args.version)); - if (args.version == 3) - { - bcopy(data, &args, sizeof(struct nfs_args3)); - args.flags &= ~(NFSMNT_INTERNAL | NFSMNT_NOAC); - } - else if (args.version == NFS_ARGSVERSION) - { - error = copyin(data, &args, sizeof(struct nfs_args)); - args.flags &= ~NFSMNT_NOAC; - } - else - { - return EPROGMISMATCH; - } - - if ((args.flags & (NFSMNT_NFSV3 | NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS) - { - return EINVAL; - } - - if (blkdriver->mnt_flag & MNT_UPDATE) - { - struct nfsmount *nmp = (struct nfsmount*)blkdriver->i_private; - - if (nmp == NULL) - { - return EIO; - } - - /* When doing an update, we can't change from or to v3. */ - - args.flags = (args.flags & ~(NFSMNT_NFSV3)) | - (nmp->nm_flag & (NFSMNT_NFSV3)); - nfs_decode_args(nmp, &args); - return 0; - } - - if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) - { - return EINVAL; - } - - bcopy(args.fh, nfh, args.fhsize); - bcopy(args.addr, nam, sizeof(args.addr)); - args.fh = nfh; - error = mountnfs(&args, blkdriver, nam); - return error; -} - -/**************************************************************************** - * Name: mountnfs - * - * Description: Common code for nfs_mount. - * - ****************************************************************************/ - -static int mountnfs(struct nfs_args *argp, struct inode *blkdriver, - struct sockaddr *nam, void **handle) +static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) { + int error = 0; struct nfsmount *nmp; - int error; - - if (blkdriver->mnt_flag & MNT_UPDATE) - { - nmp = (struct nfsmount*)blkdriver->i_private; - - /* update paths, file handles, etc, here XXX */ - - return 0; - } - else - { - /* Open the block driver */ - - if (!blkdriver || !blkdriver->u.i_bops) - { - 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; - } - - /* 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; - } - - /* 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. - */ - - if (nmp->nm_sotype == SOCK_DGRAM && (error = nfs_connect(nmp))) - { - goto bad; - } - - /* Mounted! */ - - nmp->nfs_mounted = true; - nfs_init(); - *handle = blkdriver->i_private = &nmp; - nfs_semgive(nmp); - - return 0; - } - -bad: - nfs_disconnect(nmp); - sem_destroy(&nmp->nm_sem); - kfree(nmp); - return error; -} - -/**************************************************************************** - * Name: nfs_unmount - * - * Description: This implements the filesystem portion of the umount - * operation. - * - ****************************************************************************/ - -int nfs_unmount(struct inode *blkdriver, void *handle) -{ - struct nfsmount *nmp = (struct nfsmount*) handle ; - int error; + struct nfsnode *np; + bool eof = false; + //struct nfs_dirent *ndp; fvdbg("Entry\n"); - if (!nmp) - { - return -EINVAL; - } - - nfs_semtake(nmp) - if (nmp->nm_head) - { - /* We cannot unmount now.. there are open files */ - - error = -EBUSY; - } - else - { - /* Unmount ... close the block driver */ - - if (nmp->nm_blkdriver) - { - struct inode *inode = nmp->nm_blkdriver; - if (inode) - { - if (inode->u.i_bops && inode->u.i_bops->close) - { - (void)inode->u.i_bops->close(inode); - } - - /* We hold a reference to the block driver but should - * not but mucking with inodes in this context. So, we will just return - * our contained reference to the block driver inode and let the umount - * logic dispose of it. - */ - - if (blkdriver) - { - *blkdriver = inode; - } - } - } - - /* Release the mountpoint private data */ - - if (blkdriver->i_private) - { - kfree(blkdriver->nm_buffer); - } - - nfs_disconnect(nmp); - sem_destroy(&nmp->nm_sem); - kfree(nmp); - - return 0; - } - - nfs_semgive(nmp) - return 0; -} - -/**************************************************************************** - * Name: nfs_statfs - * - * Description: Return filesystem statistics - * - ****************************************************************************/ - -static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) -{ - struct nfs_statfs *sfp = NULL; - struct nfsmount *nmp; - int error = 0; - uint64_t tquad; - void *datareply; - struct FSSTAT3args *fsstat - int info_v3; - /* Sanity checks */ - DEBUGASSERT(mountpt && mountpt->i_private); + DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL); - /* Get the mountpoint private data from the inode structure */ + /* Recover our private data from the inode instance */ - nmp = (struct nfsmount*)mountpt->i_private; - info_v3 = (nmp->nm_flag & NFSMNT_NFSV3); + nmp = mountpt->i_private; + np = nmp->nm_head; + dir->fd_root = mountpt; - /* Check if the mount is still healthy */ + /* Make sure that the mount is still healthy */ nfs_semtake(nmp); error = nfs_checkmount(nmp); - if (error < 0) + if (error != 0) { fdbg("romfs_checkmount failed: %d\n", error); goto errout_with_semaphore; } - /* Fill in the statfs info */ + if (np->nfsv3_type != NFDIR) + { + error = EPERM; + goto errout_with_semaphore; + } - memset(sbp, 0, sizeof(struct statfs)); - sbp->f_type = NFS_SUPER_MAGIC; + dir->u.nfs.nd_direoffset = np->n_direofoffset; - if (info_v3 && (nmp->nm_flag & NFSMNT_GOTFSINFO) == 0) + /* First, check for hit on the EOF offset */ + + if (dir->u.nfs.nd_direoffset != 0) + { + nfsstats.direofcache_hits++; + //np->n_open = true; + return 0; + } + + if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3) { (void)nfs_fsinfo(mountpt, NULL, NULL); } - nfsstats.rpccnt[NFSPROC_FSSTAT]++; - fsstat->fsroot = nmp->nm_fh; - error = nfs_request(nmp, NFSPROC_FSSTAT, fsstat, datareply); - if (error) + error = nfs_readdirrpc(nmp, np, eof, dir); + + if (error == NFSERR_BAD_COOKIE) { - goto errout_with_semaphore; + error = EINVAL; } - - sfp = (struct nfs_statfs *)datareply; - nmp->nm_head->n_fattr = sfp->obj_attributes - if (info_v3) - { - sbp->f_bsize = NFS_FABLKSIZE; - tquad = fxdr_hyper(&sfp->sf_tbytes); - sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE; - 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; - - tquad = fxdr_hyper(&sfp->sf_tfiles); - sbp->f_files = tquad; - tquad = fxdr_hyper(&sfp->sf_ffiles); - sbp->f_ffree = tquad; - sbp->f_namelen = MAXNAMLEN; - } - else - { - sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize); - sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks); - sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree); - sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail); - sbp->f_files = 0; - sbp->f_ffree = 0; - } - -errout_with_semaphore: - nfs_semgive(nmp); - return error; -} - -/**************************************************************************** - * Name: nfs_remove - * - * Description: Remove a file - * - ****************************************************************************/ - -static int nfs_remove(struct inode *mountpt, const char *relpath) -{ - struct nsfmount *nmp; - struct nfsnode *np; - void *datreply; - struct REMOVE3args *remove; - struct REMOVE3resok *resok; - int error = 0; - - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - nmp = (struct nfsmount *)mountpt->i_private; - np = nmp->nm_head; - - /* Check if the mount is still healthy */ - - nfs_semtake(nmp); - error = fat_checkmount(nmp); - if (error == 0) - { - /* If the file is open, the correct behavior is to remove the file - * name, but to keep the file cluster chain in place until the last - * open reference to the file is closed. - */ - - /* Remove the file */ - - if (np->n_type != NFREG) - { - error = EPERM; - goto errout_with_semaphore; - } - - /* Do the rpc */ - - nfsstats.rpccnt[NFSPROC_REMOVE]++; - remove->object->dir = np->n_fhp; - remove->object->name = relpath; - - error = nfs_request(nmp, NFSPROC_REMOVE, remove, datareply); - - /* Kludge City: If the first reply to the remove rpc is lost.. - * the reply to the retransmitted request will be ENOENT - * since the file was in fact removed - * Therefore, we cheat and return success. - */ - - if (error == ENOENT) - { - error = 0; - } - - if (error) - { - goto errout_with_semaphore; - } - - resok = (struct REMOVE3resok *)datareply; - np->n_fattr = resok->dir_wcc->after; - np->n_flag |= NMODIFIED; - } - NFS_INVALIDATE_ATTRCACHE(np); - -errout_with_semaphore: - nfs_semgive(nmp); - return error; -} - -/**************************************************************************** - * Name: nfs_mkdir - * - * Description: Create a directory - * - ****************************************************************************/ - -static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) -{ - struct nfsv3_sattr *vap; - struct nfsv3_sattr *sp; - struct nfsmount *nmp; - struct nfsnode *np; - struct MKDIR3args *mkdir; - struct MKDIR3resok *resok; - void *datareply; - int len; - int error = 0; - - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - nmp = (struct nfsmount*) mountpt->i_private; - np = nmp->nm_head; - vap = np->n_fattr; - - /* Check if the mount is still healthy */ - - nfs_semtake(nmp); - error = nfs_checkmount(nmp); - if (error != 0) - { - goto errout_with_semaphore; - } - - nfsstats.rpccnt[NFSPROC_MKDIR]++; - mkdir->where->dir = nmp->nm_fh; - mkdir->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); - - txdr_nfsv3time(&vap->sa_atime, &sp->sa_atime); - txdr_nfsv3time(&vap->sa_mtime, &sp->sa_mtime); - - mkdir->attributes = sp; - - error = nfs_request(nmp, NFSPROC_MKDIR, mkdir, datareply); - if (error) - { - goto errout_with_semaphore; - } - - resok = (struct MKDIR3resok *) datareply; - np->nfsv3_type = NDIR; - np->n_fhp = resok->handle; - np->n_fattr = resok->obj_attributes; - nmp->n_flag |= NMODIFIED; - NFS_INVALIDATE_ATTRCACHE(np); - -errout_with_semaphore: - nfs_semgive(nmp); - return error; -} - -/**************************************************************************** - * Name: nfs_rmdir - * - * Description: Remove a directory - * - ****************************************************************************/ - -static int nfs_rmdir(struct inode *mountpt, const char *relpath) -{ - struct nfsmount *nmp; - struct nfsnode *np; - struct RMDIR3args *rmdir; - struct RMDIR3resok *resok; - void *datareply; - int error = 0; - - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - nmp = (struct nfsmount *)mountpt->i_private; - np = nmp->nm_head; - - /* Check if the mount is still healthy */ - - nfs_semtake(nmp); - error = fat_checkmount(nmp); - if (error == 0) - { - /* Remove the directory */ - - if (np->n_type != NDIR) - { - error = EPERM; - goto errout_with_semaphore; - } - - /* 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); - if (error == ENOENT) - { - error = 0; - } - - if (error) - { - goto errout_with_semaphore; - } - - resok = (struct REMOVE3resok *)datareply; - np->n_fattr = resok->dir_wcc->after; - np->n_flag |= NMODIFIED; - } - NFS_INVALIDATE_ATTRCACHE(np); - -errout_with_semaphore: - nfs_semgive(nmp); - return error; -} - -/**************************************************************************** - * Name: nfs_rename - * - * Description: Rename a file or directory - * - ****************************************************************************/ - -static int nfs_rename(struct inode *mountpt, const char *oldrelpath, - const char *newrelpath) -{ - struct nsfmount *nmp; - struct nfsnode *np; - void *datreply; - struct RENAME3args *rename; - struct RENAME3resok *resok; - int error = 0; - - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - nmp = (struct nfsmount *)mountpt->i_private; - np = nmp->nm_head; - - /* Check if the mount is still healthy */ - - nfs_semtake(nmp); - error = nfs_checkmount(nmp); - if (error != 0) + if (!error && eof) { - goto errout_with_semaphore; + nfsstats.direofcache_misses++; + nfs_semgive(nmp); + return 0; } - if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR) - { - fdbg("open eacces typ=%d\n", np->nfsv3_type); - error= -EACCES; - goto errout_with_semaphore; - } - - nfsstats.rpccnt[NFSPROC_RENAME]++; - 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); - - /* Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. */ - - if (error == ENOENT) - { - error = 0; - } - - if (error) - { - goto errout_with_semaphore; - } - - resok = (struct RENAME3resok *) datareply; - np->n_fattr = resok->todir_wcc->after; - np->n_flag |= NMODIFIED; - NFS_INVALIDATE_ATTRCACHE(np); - -errout_with_semaphore: - nfs_semgive(nmp); - return error; -} - -/**************************************************************************** - * Name: nfs_fsinfo - * - * Description: Return information about a file or directory - * - ****************************************************************************/ - -static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *buf) -{ - struct nfsv3_fsinfo *fsp; - struct FSINFOargs *fsinfo; - struct nfsmount *nmp; - uint32_t pref, max; - int error = 0; - void *datareply; - - /* Sanity checks */ - - DEBUGASSERT(mountpt && mountpt->i_private); - - /* Get the mountpoint private data from the inode structure */ - - nmp = (struct nfsmount*)mountpt->i_private; - - /* Check if the mount is still healthy */ - - nfs_semtake(nmp); - error = nfd_checkmount(nmp); - if (error != 0) - { - goto errout_with_semaphore; - } - - memset(buf, 0, sizeof(struct stat)); - nfsstats.rpccnt[NFSPROC_FSINFO]++; - fsinfo->fsroot = nmp->nm_fh; - error = nfs_request(nmp, NFSPROC_FSINFO, fsinfo, datareply); - if (error) - { - goto errout_with_semaphoret; - } - - fsp = (struct nfsv3_fsinfo *)datareply; - nmp->nm_head->n_fattr = fsp->obj_attributes; - pref = fxdr_unsigned(uint32_t, fsp->fs_wtpref); - if (pref < nmp->nm_wsize) - { - nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1); - } - - max = fxdr_unsigned(uint32_t, fsp->fs_wtmax); - if (max < nmp->nm_wsize) - { - nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1); - if (nmp->nm_wsize == 0) - nmp->nm_wsize = max; - } - - pref = fxdr_unsigned(uint32_t, fsp->fs_rtpref); - if (pref < nmp->nm_rsize) - { - nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1); - } - - max = fxdr_unsigned(uint32_t, fsp->fs_rtmax); - if (max < nmp->nm_rsize) - { - nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1); - if (nmp->nm_rsize == 0) - { - nmp->nm_rsize = max; - } - } - - pref = fxdr_unsigned(uint32_t, fsp->fs_dtpref); - if (pref < nmp->nm_readdirsize) - { - nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & ~(NFS_DIRBLKSIZ - 1); - } - - if (max < nmp->nm_readdirsize) - { - nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1); - if (nmp->nm_readdirsize == 0) - { - nmp->nm_readdirsize = max; - } - } - - 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); - nmp->nm_flag |= NFSMNT_GOTFSINFO; - errout_with_semaphore: nfs_semgive(nmp); return error; @@ -1519,7 +794,7 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) { - nmp->nm_retry = MIN(argp->retrans, NFS_MAXREXMIT); + nmp->nm_retry = (argp->retrans < NFS_MAXREXMIT)? argp->retrans : NFS_MAXREXMIT; } if (!(nmp->nm_flag & NFSMNT_SOFT)) @@ -1698,7 +973,692 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) } } -#ifdef 0 +/**************************************************************************** + * Name: mountnfs + * + * Description: Common code for nfs_mount. + * + ****************************************************************************/ + +int mountnfs(struct nfs_args *argp, struct inode *blkdriver, + struct sockaddr *nam, void **handle) +{ + struct nfsmount *nmp; + int error; + + /* Open the block driver */ + + if (!blkdriver || !blkdriver->u.i_bops) + { + 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; + } + + /* Create an instance of the mountpt state structure */ + + 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(). + */ + + 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; + } + + /* Mounted! */ + + nmp->nm_mounted = true; + nfs_init(); + *handle = blkdriver->i_private = &nmp; + nfs_semgive(nmp); + + return 0; + +bad: + nfs_disconnect(nmp); + sem_destroy(&nmp->nm_sem); + kfree(nmp); + return error; +} + +/**************************************************************************** + * 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 + * operation. + * + ****************************************************************************/ + +int nfs_unmount(void *handle, struct inode **blkdriver) +{ + struct nfsmount *nmp = (struct nfsmount *) handle ; + int error; + + fvdbg("Entry\n"); + + if (!nmp) + { + return -EINVAL; + } + + nfs_semtake(nmp); + if (nmp->nm_head) + { + /* We cannot unmount now.. there are open files */ + + error = -EBUSY; + } + else + { + /* Unmount ... close the block driver */ + + if (nmp->nm_blkdriver) + { + struct inode *inode = nmp->nm_blkdriver; + if (inode) + { + if (inode->u.i_bops && inode->u.i_bops->close) + { + (void)inode->u.i_bops->close(inode); + } + + /* We hold a reference to the block driver but should + * not but mucking with inodes in this context. So, we will just return + * our contained reference to the block driver inode and let the umount + * logic dispose of it. + */ + + if (blkdriver) + { + *blkdriver = inode; + } + } + } + + /* Release the mountpoint private data */ + + nfs_disconnect(nmp); + sem_destroy(&nmp->nm_sem); + kfree(nmp); + + return 0; + } + + nfs_semgive(nmp); + return error; +} + +/**************************************************************************** + * Name: nfs_statfs + * + * Description: Return filesystem statistics + * + ****************************************************************************/ + +static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) +{ + struct nfs_statfs *sfp = NULL; + struct nfsmount *nmp; + int error = 0; + uint64_t tquad; + void *datareply = NULL; + struct FSSTAT3args *fsstat = NULL; + int info_v3; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + nmp = (struct nfsmount*)mountpt->i_private; + info_v3 = (nmp->nm_flag & NFSMNT_NFSV3); + + /* Check if the mount is still healthy */ + + nfs_semtake(nmp); + error = nfs_checkmount(nmp); + if (error < 0) + { + fdbg("romfs_checkmount failed: %d\n", error); + goto errout_with_semaphore; + } + + /* Fill in the statfs info */ + + memset(sbp, 0, sizeof(struct statfs)); + sbp->f_type = NFS_SUPER_MAGIC; + + if (info_v3 && (nmp->nm_flag & NFSMNT_GOTFSINFO) == 0) + { + (void)nfs_fsinfo(mountpt, NULL, NULL); + } + + nfsstats.rpccnt[NFSPROC_FSSTAT]++; + fsstat->fsroot = nmp->nm_fh; + error = nfs_request(nmp, NFSPROC_FSSTAT, fsstat, datareply); + if (error) + { + goto errout_with_semaphore; + } + + sfp = (struct nfs_statfs *)datareply; + nmp->nm_head->n_fattr = sfp->obj_attributes; + if (info_v3) + { + sbp->f_bsize = NFS_FABLKSIZE; + tquad = fxdr_hyper(&sfp->sf_tbytes); + sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE; + tquad = fxdr_hyper(&sfp->sf_fbytes); + sbp->f_bfree = tquad / (uint64_t) NFS_FABLKSIZE; + tquad = fxdr_hyper(&sfp->sf_abytes); + 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 = NAME_MAX; + } + else + { + sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize); + sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks); + sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree); + sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail); + sbp->f_files = 0; + sbp->f_ffree = 0; + } + +errout_with_semaphore: + nfs_semgive(nmp); + return error; +} + +/**************************************************************************** + * Name: nfs_remove + * + * Description: Remove a file + * + ****************************************************************************/ + +static int nfs_remove(struct inode *mountpt, const char *relpath) +{ + struct nfsmount *nmp; + struct nfsnode *np; + void *datareply = NULL; + struct REMOVE3args *remove = NULL; + struct REMOVE3resok *resok = NULL; + int error = 0; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + nmp = (struct nfsmount*)mountpt->i_private; + np = nmp->nm_head; + + /* Check if the mount is still healthy */ + + nfs_semtake(nmp); + error = nfs_checkmount(nmp); + if (error == 0) + { + /* If the file is open, the correct behavior is to remove the file + * name, but to keep the file cluster chain in place until the last + * open reference to the file is closed. + */ + + /* Remove the file */ + + if (np->nfsv3_type != NFREG) + { + error = EPERM; + goto errout_with_semaphore; + } + + /* Do the rpc */ + + nfsstats.rpccnt[NFSPROC_REMOVE]++; + remove->object.dir = np->n_fhp; + remove->object.name = relpath; + + error = nfs_request(nmp, NFSPROC_REMOVE, remove, datareply); + + /* Kludge City: If the first reply to the remove rpc is lost.. + * the reply to the retransmitted request will be ENOENT + * since the file was in fact removed + * Therefore, we cheat and return success. + */ + + if (error == ENOENT) + { + error = 0; + } + + if (error) + { + goto errout_with_semaphore; + } + + resok = (struct REMOVE3resok *)datareply; + np->n_fattr = resok->dir_wcc.after; + np->n_flag |= NMODIFIED; + } + NFS_INVALIDATE_ATTRCACHE(np); + +errout_with_semaphore: + nfs_semgive(nmp); + return error; +} + +/**************************************************************************** + * Name: nfs_mkdir + * + * Description: Create a directory + * + ****************************************************************************/ + +static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) +{ + struct nfs_fattr vap; + struct nfsv3_sattr sp; + struct nfsmount *nmp; + struct nfsnode *np; + struct MKDIR3args *mkir = NULL; + struct MKDIR3resok *resok = NULL; + void *datareply = NULL; + int error = 0; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + nmp = (struct nfsmount*) mountpt->i_private; + np = nmp->nm_head; + vap = np->n_fattr; + + /* Check if the mount is still healthy */ + + nfs_semtake(nmp); + error = nfs_checkmount(nmp); + if (error != 0) + { + goto errout_with_semaphore; + } + + nfsstats.rpccnt[NFSPROC_MKDIR]++; + mkir->where.dir = nmp->nm_fh; + mkir->where.name = relpath; + + 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); + + fxdr_nfsv3time2(&vap.fa3_atime, &sp.sa_atime); + fxdr_nfsv3time2(&vap.fa3_mtime, &sp.sa_mtime); + + mkir->attributes = sp; + + error = nfs_request(nmp, NFSPROC_MKDIR, mkdir, datareply); + if (error) + { + goto errout_with_semaphore; + } + + resok = (struct MKDIR3resok *) datareply; + np->nfsv3_type = NFDIR; + np->n_fhp = resok->handle; + np->n_fattr = resok->obj_attributes; + np->n_flag |= NMODIFIED; + NFS_INVALIDATE_ATTRCACHE(np); + +errout_with_semaphore: + nfs_semgive(nmp); + return error; +} + +/**************************************************************************** + * Name: nfs_rmdir + * + * Description: Remove a directory + * + ****************************************************************************/ + +static int nfs_rmdir(struct inode *mountpt, const char *relpath) +{ + struct nfsmount *nmp; + struct nfsnode *np; + struct RMDIR3args *rmdir = NULL; + struct RMDIR3resok *resok = NULL; + void *datareply = NULL; + int error = 0; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + nmp = (struct nfsmount *)mountpt->i_private; + np = nmp->nm_head; + + /* Check if the mount is still healthy */ + + nfs_semtake(nmp); + error = nfs_checkmount(nmp); + if (error == 0) + { + /* Remove the directory */ + + if (np->nfsv3_type != NFDIR) + { + error = EPERM; + goto errout_with_semaphore; + } + + /* Do the rpc */ + + nfsstats.rpccnt[NFSPROC_RMDIR]++; + rmdir->object.dir = np->n_fhp; + rmdir->object.name = relpath; + error = nfs_request(nmp, NFSPROC_RMDIR, rmdir, datareply); + + if (error == ENOENT) + { + error = 0; + } + + if (error) + { + goto errout_with_semaphore; + } + + resok = (struct RMDIR3resok *)datareply; + np->n_fattr = resok->dir_wcc.after; + np->n_flag |= NMODIFIED; + } + NFS_INVALIDATE_ATTRCACHE(np); + +errout_with_semaphore: + nfs_semgive(nmp); + return error; +} + +/**************************************************************************** + * Name: nfs_rename + * + * Description: Rename a file or directory + * + ****************************************************************************/ + +static int nfs_rename(struct inode *mountpt, const char *oldrelpath, + const char *newrelpath) +{ + struct nfsmount *nmp; + struct nfsnode *np; + void *datareply = NULL; + struct RENAME3args *rename = NULL; + struct RENAME3resok *resok = NULL; + int error = 0; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + nmp = (struct nfsmount *)mountpt->i_private; + np = nmp->nm_head; + + /* Check if the mount is still healthy */ + + nfs_semtake(nmp); + error = nfs_checkmount(nmp); + if (error != 0) + { + goto errout_with_semaphore; + } + + if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR) + { + fdbg("open eacces typ=%d\n", np->nfsv3_type); + error= -EACCES; + goto errout_with_semaphore; + } + + nfsstats.rpccnt[NFSPROC_RENAME]++; + rename->from.dir = np->n_fhp; + rename->from.name = oldrelpath; + rename->to.dir = np->n_fhp; + rename->to.name = newrelpath; + + error = nfs_request(nmp, NFSPROC_RENAME, rename, datareply); + + /* Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. */ + + if (error == ENOENT) + { + error = 0; + } + + if (error) + { + goto errout_with_semaphore; + } + + resok = (struct RENAME3resok *) datareply; + np->n_fattr = resok->todir_wcc.after; + np->n_flag |= NMODIFIED; + NFS_INVALIDATE_ATTRCACHE(np); + +errout_with_semaphore: + nfs_semgive(nmp); + return error; +} + +/**************************************************************************** + * Name: nfs_fsinfo + * + * Description: Return information about a file or directory + * + ****************************************************************************/ + +static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *buf) +{ + struct nfsv3_fsinfo *fsp; + struct FSINFOargs *fsinfo = NULL; + struct nfsmount *nmp; + uint32_t pref, max; + int error = 0; + void *datareply = NULL; + + /* Sanity checks */ + + DEBUGASSERT(mountpt && mountpt->i_private); + + /* Get the mountpoint private data from the inode structure */ + + nmp = (struct nfsmount*)mountpt->i_private; + + /* Check if the mount is still healthy */ + + nfs_semtake(nmp); + error = nfs_checkmount(nmp); + if (error != 0) + { + goto errout_with_semaphore; + } + + memset(buf, 0, sizeof(struct stat)); + nfsstats.rpccnt[NFSPROC_FSINFO]++; + fsinfo->fsroot = nmp->nm_fh; + error = nfs_request(nmp, NFSPROC_FSINFO, fsinfo, datareply); + if (error) + { + goto errout_with_semaphore; + } + + fsp = (struct nfsv3_fsinfo *)datareply; + nmp->nm_head->n_fattr = fsp->obj_attributes; + pref = fxdr_unsigned(uint32_t, fsp->fs_wtpref); + if (pref < nmp->nm_wsize) + { + nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1); + } + + max = fxdr_unsigned(uint32_t, fsp->fs_wtmax); + if (max < nmp->nm_wsize) + { + nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1); + if (nmp->nm_wsize == 0) + nmp->nm_wsize = max; + } + + pref = fxdr_unsigned(uint32_t, fsp->fs_rtpref); + if (pref < nmp->nm_rsize) + { + nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1); + } + + max = fxdr_unsigned(uint32_t, fsp->fs_rtmax); + if (max < nmp->nm_rsize) + { + nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1); + if (nmp->nm_rsize == 0) + { + nmp->nm_rsize = max; + } + } + + pref = fxdr_unsigned(uint32_t, fsp->fs_dtpref); + if (pref < nmp->nm_readdirsize) + { + nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & ~(NFS_DIRBLKSIZ - 1); + } + + if (max < nmp->nm_readdirsize) + { + nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1); + if (nmp->nm_readdirsize == 0) + { + nmp->nm_readdirsize = max; + } + } + + 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); + nmp->nm_flag |= NFSMNT_GOTFSINFO; + +errout_with_semaphore: + nfs_semgive(nmp); + return error; +} + +#ifdef COMP /**************************************************************************** * Name: nfs_sync * diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h index 39b2040c21..fcbffe7f54 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 7f54c6965e..0709fbf3c2 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 6752d1f41f..223f00fee9 100644 --- a/nuttx/fs/nfs/xdr_subs.h +++ b/nuttx/fs/nfs/xdr_subs.h @@ -49,6 +49,8 @@ * Included Files ****************************************************************************/ +#include + /**************************************************************************** * 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); \