diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-06-07 16:53:46 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-06-07 16:53:46 +0000 |
commit | 4b7b29412fa52f77c21953b1d137e886d92d6671 (patch) | |
tree | d27e1f01a73b49e507816dd02e1b4eb96c3d8b2f | |
parent | 0542a2096c1a75e808e4fef4cfe9ae721767403c (diff) | |
download | px4-firmware-4b7b29412fa52f77c21953b1d137e886d92d6671.tar.gz px4-firmware-4b7b29412fa52f77c21953b1d137e886d92d6671.tar.bz2 px4-firmware-4b7b29412fa52f77c21953b1d137e886d92d6671.zip |
NFS update
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4811 7fd9a85b-ad96-42d3-883c-3090e2eb8679
-rwxr-xr-x | nuttx/fs/nfs/nfs_util.c | 2 | ||||
-rw-r--r-- | nuttx/fs/nfs/nfs_vfsops.c | 320 | ||||
-rw-r--r-- | nuttx/fs/nfs/rpc_clnt.c | 132 |
3 files changed, 309 insertions, 145 deletions
diff --git a/nuttx/fs/nfs/nfs_util.c b/nuttx/fs/nfs/nfs_util.c index 3aedfc65c..11d0573e6 100755 --- a/nuttx/fs/nfs/nfs_util.c +++ b/nuttx/fs/nfs/nfs_util.c @@ -105,7 +105,7 @@ void nfs_semtake(struct nfsmount *nmp) void nfs_semgive(struct nfsmount *nmp) { - sem_post(&nmp->nm_sem); + sem_post(&nmp->nm_sem); } /**************************************************************************** diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c index 35afb3c0a..db11355d4 100644 --- a/nuttx/fs/nfs/nfs_vfsops.c +++ b/nuttx/fs/nfs/nfs_vfsops.c @@ -100,25 +100,27 @@ struct nfs_dirent ****************************************************************************/ static int nfs_open(FAR struct file *filep, const char *relpath, - int oflags, mode_t mode); + int oflags, mode_t mode); static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen); static ssize_t nfs_write(FAR struct file *filep, const char *buffer, - size_t buflen); + size_t buflen); static int nfs_opendir(struct inode *mountpt, const char *relpath, - struct fs_dirent_s *dir); + struct fs_dirent_s *dir); static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir); static int nfs_bind(FAR struct inode *blkdriver, const void *data, - void **handle); + void **handle); static int nfs_unbind(void *handle, FAR struct inode **blkdriver); static int nfs_statfs(struct inode *mountpt, struct statfs *buf); static int nfs_remove(struct inode *mountpt, const char *relpath); static int nfs_mkdir(struct inode *mountpt, const char *relpath, - mode_t mode); + mode_t mode); static int nfs_rmdir(struct inode *mountpt, const char *relpath); static int nfs_rename(struct inode *mountpt, const char *oldrelpath, - const char *newrelpath); + const char *newrelpath); +static int nfs_getfsinfo(struct nfsmount *nmp, const char *relpath, + struct stat *buf); static int nfs_fsinfo(struct inode *mountpt, const char *relpath, - struct stat *buf); + struct stat *buf); /**************************************************************************** * External Public Data (this belong in a header file) @@ -172,8 +174,13 @@ const struct mountpt_operations nfs_operations = /**************************************************************************** * Name: nfs_open * - * 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. + * 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. + * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ static int nfs_open(FAR struct file *filep, FAR const char *relpath, @@ -310,7 +317,8 @@ again: if (np->nfsv3_type != NFREG) { fdbg("ERROR: open eacces typ=%d\n", np->nfsv3_type); - return EACCES; + error = EACCES; + goto errout_with_semaphore; } if (np->n_flag & NMODIFIED) @@ -329,13 +337,17 @@ again: errout_with_semaphore: kfree(np); nfs_semgive(nmp); - return error; + return -error; } #undef COMP #ifdef COMP /**************************************************************************** * Name: nfs_close + * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ static int nfs_close(FAR struct file *filep) done @@ -364,12 +376,17 @@ static int nfs_close(FAR struct file *filep) done filep->f_priv = NULL; } - return error; + return -error; } #endif /**************************************************************************** * Name: nfs_read + * + * Returned Value: + * The (non-negative) number of bytes read on success; a negated errno + * value on failure. + * ****************************************************************************/ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) @@ -414,12 +431,13 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen) if (np->nfsv3_type != NFREG) { fdbg("read eacces typ=%d\n", np->nfsv3_type); - return EACCES; + error = EACCES; + goto errout_with_semaphore; } if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3) { - (void)nfs_fsinfo(filep->f_inode, NULL, NULL); + (void)nfs_getfsinfo(nmp, NULL, NULL); } /* Get the number of bytes left in the file */ @@ -470,16 +488,21 @@ again: goto again; } -nfs_semgive(nmp); + nfs_semgive(nmp); return readsize; errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** * Name: nfs_write + * + * Returned Value: + * The (non-negative) number of bytes written on success; a negated errno + * value on failure. + * ****************************************************************************/ static ssize_t @@ -524,14 +547,14 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) if (np->n_size + buflen < np->n_size) { - error = -EFBIG; + error = EFBIG; goto errout_with_semaphore; } len = nmp->nm_wsize; if (len < buflen) { - error = -EFBIG; + error = EFBIG; goto errout_with_semaphore; } @@ -591,7 +614,7 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen) errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** @@ -600,6 +623,9 @@ errout_with_semaphore: * Description: * Open a directory for read access * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ static int nfs_opendir(struct inode *mountpt, const char *relpath, @@ -636,15 +662,15 @@ static int nfs_opendir(struct inode *mountpt, const char *relpath, if (np->nfsv3_type != NFDIR) { fdbg("open eacces type=%d\n", np->nfsv3_type); - nfs_semgive(nmp); - return EACCES; + ret = EACCES; + goto errout_with_semaphore; } /* The requested directory must be the volume-relative "root" directory */ if (relpath && relpath[0] != '\0') { - ret = -ENOENT; + ret = ENOENT; goto errout_with_semaphore; } @@ -659,26 +685,30 @@ static int nfs_opendir(struct inode *mountpt, const char *relpath, } } - nfs_semgive(nmp); - return OK; + ret = OK; errout_with_semaphore: nfs_semgive(nmp); - return ret; + return -ret; } /**************************************************************************** * Name: nfs_readdirrpc * - * Description: The function below stuff the cookies in after the name. + * Description: + * The function below stuff the cookies in after the name. + * + * Returned Value: + * 0 on success; a positive errno value on failure. + * ****************************************************************************/ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, bool end_of_directory, struct fs_dirent_s *dir) { - int error = 0; struct READDIR3args readir; struct rpc_reply_readdir resok; + int error = 0; /* Loop around doing readdir rpc's of size nm_readdirsize * truncated to a multiple of NFS_READDIRBLKSIZ. @@ -764,7 +794,7 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np, */ fdbg("End of directory\n"); - error = -ENOENT; + error = ENOENT; } nfsmout: @@ -776,6 +806,9 @@ nfsmout: * * Description: Read from directory * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) @@ -794,8 +827,8 @@ 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 = nmp->nm_head; + nmp = mountpt->i_private; + np = nmp->nm_head; dir->fd_root = mountpt; /* Make sure that the mount is still healthy */ @@ -804,7 +837,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) error = nfs_checkmount(nmp); if (error != 0) { - fdbg("nfs_checkmount failed: %d\n", error); + fdbg("ERROR: nfs_checkmount failed: %d\n", error); goto errout_with_semaphore; } @@ -824,13 +857,13 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) if (dir->u.nfs.nd_direoffset != 0) { nfsstats.direofcache_hits++; - //np->n_open = true; - return 0; + //np->n_open = true; + goto success_with_semaphore; } if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3) { - (void)nfs_fsinfo(mountpt, NULL, NULL); + (void)nfs_getfsinfo(nmp, NULL, NULL); } error = nfs_readdirrpc(nmp, np, eof, dir); @@ -838,22 +871,28 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir) if (error == NFSERR_BAD_COOKIE) { error = EINVAL; + goto errout_with_semaphore; } if (!error && eof) { nfsstats.direofcache_misses++; - nfs_semgive(nmp); - return 0; } +success_with_semaphore: + error = 0; + errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** * Name: nfs_decode_args + * + * Returned Value: + * None + * ****************************************************************************/ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) @@ -1078,7 +1117,11 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp) /**************************************************************************** * Name: mountnfs * - * Description: Common code for nfs_mount. + * Description: + * Common code for nfs_mount. + * + * Returned Value: + * 0 on success; a positive errno value on failure. * ****************************************************************************/ @@ -1096,18 +1139,24 @@ int mountnfs(struct nfs_args *argp, void **handle) if (!nmp) { fdbg("ERROR: Failed to allocate mountpoint structure\n"); - return -ENOMEM; + 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. */ + + /* Initialize the semaphore that controls access. The initial count + * is zero, but nfs_semgive() is called at the completion of initialization, + * incrementing the count to one. */ sem_init(&nmp->nm_sem, 0, 0); /* Initialize the semaphore that controls access */ + /* Initialize NFS */ + nfs_init(); + /* Set initial values of other fields */ + nmp->nm_flag = argp->flags; nmp->nm_timeo = NFS_TIMEO; nmp->nm_retry = NFS_RETRANS; @@ -1154,7 +1203,7 @@ int mountnfs(struct nfs_args *argp, void **handle) if (!np) { fdbg("ERROR: Failed to allocate private data\n"); - error = -ENOMEM; + error = ENOMEM; goto bad; } @@ -1236,12 +1285,15 @@ bad: * binding of the private data (containing the blockdriver) to the * mountpoint is performed by mount(). * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle) { - int error; struct nfs_args args; + int error; bcopy(data, &args, sizeof(struct nfs_args)); if (args.version == NFS_ARGSVERSION) @@ -1259,7 +1311,7 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle) } error = mountnfs(&args, handle); - return error; + return -error; } /**************************************************************************** @@ -1268,6 +1320,9 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle) * Description: This implements the filesystem portion of the umount * operation. * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ int nfs_unbind(void *handle, struct inode **blkdriver) @@ -1284,31 +1339,37 @@ int nfs_unbind(void *handle, struct inode **blkdriver) nfs_semtake(nmp); + /* Umount */ + error = rpcclnt_umount(nmp->nm_rpcclnt); if (error) { - fdbg("Umounting fails %d\n", error); - goto bad; + fdbg("ERROR: rpcclnt_umount failed: %d\n", error); } + /* Disconnect */ + nfs_disconnect(nmp); + + /* And free resources */ + sem_destroy(&nmp->nm_sem); kfree(nmp->nm_head); kfree(nmp->nm_so); kfree(nmp->nm_rpcclnt); kfree(nmp); - return 0; - -bad: - nfs_disconnect(nmp); - return(error); + return -error; } /**************************************************************************** * Name: nfs_statfs * - * Description: Return filesystem statistics + * Description: + * Return filesystem statistics + * + * Returned Value: + * 0 on success; a negated errno value on failure. * ****************************************************************************/ @@ -1345,7 +1406,7 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) if ((nmp->nm_flag & NFSMNT_GOTFSINFO) == 0) { - (void)nfs_fsinfo(mountpt, NULL, NULL); + (void)nfs_getfsinfo(nmp, NULL, NULL); } nfsstats.rpccnt[NFSPROC_FSSTAT]++; @@ -1377,13 +1438,17 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** * Name: nfs_remove * - * Description: Remove a file + * Description: + * Remove a file + * + * Returned Value: + * 0 on success; a negated errno value on failure. * ****************************************************************************/ @@ -1460,13 +1525,17 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** * Name: nfs_mkdir * - * Description: Create a directory + * Description: + * Create a directory + * + * Returned Value: + * 0 on success; a negated errno value on failure. * ****************************************************************************/ @@ -1538,13 +1607,17 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** * Name: nfs_rmdir * - * Description: Remove a directory + * Description: + * Remove a directory + * + * Returned Value: + * 0 on success; a negated errno value on failure. * ****************************************************************************/ @@ -1609,13 +1682,17 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** * Name: nfs_rename * - * Description: Rename a file or directory + * Description: + * Rename a file or directory + * + * Returned Value: + * 0 on success; a negated errno value on failure. * ****************************************************************************/ @@ -1649,7 +1726,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, if (np->nfsv3_type != NFREG && np->nfsv3_type != NFDIR) { fdbg("open eacces typ=%d\n", np->nfsv3_type); - error= -EACCES; + error = EACCES; goto errout_with_semaphore; } @@ -1686,53 +1763,48 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } /**************************************************************************** - * Name: nfs_fsinfo + * Name: nfs_getfsinfo * - * Description: Return information about root directory + * Description: + * Return information about root directory. This is an internal version + * used only within this file. + * + * Returned Value: + * 0 on success; positive errno value on failure + * + * Assumptions: + * The caller has exclusive access to the NFS mount structure * ****************************************************************************/ -static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *buf) +static int nfs_getfsinfo(struct nfsmount *nmp, const char *relpath, + struct stat *buf) { struct rpc_reply_fsinfo fsp; struct FS3args fsinfo; - struct nfsmount *nmp; //uint32_t pref, max; 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; - - /* Check if the mount is still healthy */ - - nfs_semtake(nmp); - error = nfs_checkmount(nmp); - if (error != 0) - { - goto errout_with_semaphore; - } +#warning "relpath is not used! Additional logic will be required!" - memset(buf, 0, sizeof(struct stat)); memset(&fsinfo, 0, sizeof(struct FS3args)); - memset(&fsp, 0, sizeof(struct rpc_reply_fsinfo)); + memset(&fsp, 0, sizeof(struct rpc_reply_fsinfo)); + nfsstats.rpccnt[NFSPROC_FSINFO]++; fsinfo.fsroot.length = txdr_unsigned(nmp->nm_fhsize); fsinfo.fsroot.handle = nmp->nm_fh; + /* Request FSINFO from the server */ + error = nfs_request(nmp, NFSPROC_FSINFO, (FAR const void *)&fsinfo, (FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo)); if (error) { - goto errout_with_semaphore; + return error; } //nmp->nm_fattr = fsp.obj_attributes; @@ -1781,18 +1853,65 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b } } */ - buf->st_mode = fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode); - buf->st_size = fxdr_hyper(&nmp->nm_fattr.fa3_size); - buf->st_blksize = 0; - buf->st_blocks = 0; - buf->st_mtime = fxdr_hyper(&nmp->nm_fattr.fa3_mtime); - buf->st_atime = fxdr_hyper(&nmp->nm_fattr.fa3_atime); - buf->st_ctime = fxdr_hyper(&nmp->nm_fattr.fa3_ctime); - nmp->nm_flag |= NFSMNT_GOTFSINFO; -errout_with_semaphore: + /* Verify that the caller has provided a non-NULL location to return the + * FSINFO data. + */ + + if (buf) + { + buf->st_mode = fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode); + buf->st_size = fxdr_hyper(&nmp->nm_fattr.fa3_size); + buf->st_blksize = 0; + buf->st_blocks = 0; + buf->st_mtime = fxdr_hyper(&nmp->nm_fattr.fa3_mtime); + buf->st_atime = fxdr_hyper(&nmp->nm_fattr.fa3_atime); + buf->st_ctime = fxdr_hyper(&nmp->nm_fattr.fa3_ctime); + } + + nmp->nm_flag |= NFSMNT_GOTFSINFO; + + return 0; +} + +/**************************************************************************** + * Name: nfs_fsinfo + * + * Description: + * Return information about root directory + * + * Returned Value: + * 0 on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int nfs_fsinfo(struct inode *mountpt, const char *relpath, + struct stat *buf) +{ + struct nfsmount *nmp; + int error; + + /* 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) + { + /* Get the requested FSINFO */ + + error = nfs_getfsinfo(nmp, relpath, buf); + } + nfs_semgive(nmp); - return error; + return -error; } #ifdef COMP @@ -1801,6 +1920,9 @@ errout_with_semaphore: * * Description: Flush out the buffer cache * + * Returned Value: + * 0 on success; a negated errno value on failure. + * ****************************************************************************/ int nfs_sync(struct file *filep) @@ -1840,10 +1962,8 @@ int nfs_sync(struct file *filep) //error = VOP_FSYNC(vp, cred, waitfor, p); } - return error; - errout_with_semaphore: nfs_semgive(nmp); - return error; + return -error; } #endif diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c index 53be61c01..00dac941c 100644 --- a/nuttx/fs/nfs/rpc_clnt.c +++ b/nuttx/fs/nfs/rpc_clnt.c @@ -449,7 +449,7 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, int procid, int prog, } /* Receive a Sun RPC Request/Reply. For SOCK_DGRAM, the work is all - * done by soreceive().For SOCK_STREAM, first get the + * done by psock_recvfrom(). For SOCK_STREAM, first get the * Record Mark to find out how much more there is to get. We must * lock the socket against other receivers until we have an entire * rpc request/reply. @@ -460,17 +460,17 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, //, struct rpc_call *call) { struct socket *so; + ssize_t nbytes; #ifdef CONFIG_NFS_TCPIP uint32_t len; int sotype; #endif - int ret = 0; int rcvflg; - -#ifdef CONFIG_NFS_TCPIP + int error = 0; int errval; - /* Set up arguments for soreceive() */ +#ifdef CONFIG_NFS_TCPIP + /* Set up arguments for psock_recvfrom() */ sotype = rep->r_rpcclnt->rc_sotype; @@ -542,14 +542,16 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, { socklen_t fromlen = sizeof(*rep->r_rpcclnt->rc_name) rcvflg = MSG_WAITALL; - error = psock_recvfrom(so, reply, sizeof(*reply), - &rcvflg, rep->r_rpcclnt->rc_name, - &fromlen); - if (error < 0) + nbytes = psock_recvfrom(so, reply, len, + &rcvflg, rep->r_rpcclnt->rc_name, + &fromlen); + if (nbytes < 0) { errval = errno; + fdbg("ERROR: psock_recvfrom returned %d\n", errval); + if (errval == EWOULDBLOCK && rep && - (rep->r_flags & TASK_SOFTTERM)) + (rep->r_flags & TASK_SOFTTERM) != 0) { return EINTR; } @@ -557,13 +559,24 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, } while (errval == EWOULDBLOCK); - if (error == 0) + if (nbytes < 0) + { + error = errval; + } + else if (nbytes < len) { fdbg("ERROR: Short receive from rpc server %s\n", rep->r_rpcclnt->rc_prog->prog_name); + fvdbg(" Expected %d bytes, received %d bytes\n", + len, nbytes); error = EPIPE; } + else + { + error = 0; + } +#warning "What is len? This logic is not right!" len = ntohl(len) & ~0x80000000; /* This is SERIOUS! We are out of sync with the @@ -571,7 +584,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, * can do. */ - if (len > RPC_MAXPACKET) + else if (len > RPC_MAXPACKET) { fdbg("ERROR %s (%d) from rpc server %s\n", "impossible packet length", @@ -585,10 +598,10 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, { socklen_t fromlen = sizeof(*rep->r_rpcclnt->rc_name); rcvflg = MSG_WAITALL; - error = psock_recvfrom(so, reply, sizeof(*reply), - &rcvflg, rep->r_rpcclnt->rc_name, - &fromlen); - if (error < 0) + nbytes = psock_recvfrom(so, reply, sizeof(*reply), + &rcvflg, rep->r_rpcclnt->rc_name, + &fromlen); + if (nbytes < 0) { errval = errno; fdbg("ERROR: psock_recvfrom failed: %d\n", errval); @@ -596,22 +609,28 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, } while (errval == EWOULDBLOCK || errval == EINTR || errval == ERESTART); - if (error == 0) + if (nbytes < 0) + { + error = errval; + goto errout; + } + else if (nbytes < len) { fdbg("ERROR: Short receive from rpc server %s\n", rep->r_rpcclnt->rc_prog->prog_name); + fvdbg(" Expected %d bytes, received %d bytes\n", + len, nbytes); error = EPIPE; } - - if (error < 0) + else { - goto errout; + error = 0; } } else { /* NB: Since uio_resid is big, MSG_WAITALL is ignored - * and soreceive() will return when it has either a + * and psock_recvfrom() will return when it has either a * control msg or a data msg. We have no use for * control msg., but must grab them and then throw * them away so we know what is going on. @@ -622,29 +641,46 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, { socklen_t fromlen = sizeof(*rep->r_rpcclnt->rc_name); rcvflg = 0; - error = psock_recvfrom(so, reply, sizeof(*reply), &rcvflg, - rep->r_rpcclnt->rc_name, &fromlen); - if (error == EWOULDBLOCK && rep) + nbytes = psock_recvfrom(so, reply, sizeof(*reply), &rcvflg, + rep->r_rpcclnt->rc_name, &fromlen); + if (nbytes < 0) { errval = errno; fdbg("ERROR: psock_recvfrom failed: %d\n", errval); - if (rep->r_flags & TASK_SOFTTERM) + + if (errval == EWOULDBLOCK && rep) { - return EINTR; + if (rep->r_flags & TASK_SOFTTERM) + { + return EINTR; + } } } } - while (errval == EWOULDBLOCK || !error); + while (errval == EWOULDBLOCK || nbytes == 0); if ((rcvflg & MSG_EOR) == 0) { fdbg("Egad!!\n"); } - if (error == 0) + if (nbytes < 0) + { + error = errval; + goto errout; + } + else if (nbytes < len) { + fdbg("ERROR: Short receive from rpc server %s\n", + rep->r_rpcclnt->rc_prog->prog_name); + fvdbg(" Expected %d bytes, received %d bytes\n", + len, nbytes); error = EPIPE; } + else + { + error = 0; + } } errout: @@ -679,15 +715,17 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, socklen_t fromlen = sizeof(struct sockaddr); rcvflg = 0; - ret = psock_recvfrom(so, reply, len, rcvflg, aname, &fromlen); - if (ret < 0) + nbytes = psock_recvfrom(so, reply, len, rcvflg, aname, &fromlen); + if (nbytes < 0) { - fdbg("ERROR: psock_recvfrom failed: %d\n", errno); + errval = errno; + fdbg("ERROR: psock_recvfrom failed: %d\n", errval); + error = errval; } } - fvdbg("Returning %d\n", ret); - return ret; + fvdbg("Returning %d\n", error); + return error; } /* Implement receipt of reply on a socket. We must search through the list of @@ -695,7 +733,8 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname, * until ours is found. */ -static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, void *reply, size_t len) +static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, + void *reply, size_t len) { struct rpctask *rep; struct rpc_reply_header replyheader; @@ -780,8 +819,7 @@ static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, void *repl if (rpc->rc_cwnd <= rpc->rc_sent) { rpc->rc_cwnd += - (RPC_CWNDSCALE * RPC_CWNDSCALE + - (rpc->rc_cwnd >> 1)) / rpc->rc_cwnd; + (RPC_CWNDSCALE * RPC_CWNDSCALE + (rpc->rc_cwnd >> 1)) / rpc->rc_cwnd; if (rpc->rc_cwnd > RPC_MAXCWND) { @@ -1163,6 +1201,20 @@ int rpcclnt_connect(struct rpcclnt *rpc) goto bad; } + /* Initialize congestion variables */ + + rpc->rc_srtt[0] = (RPC_TIMEO << 3); + rpc->rc_srtt[1] = (RPC_TIMEO << 3); + rpc->rc_srtt[2] = (RPC_TIMEO << 3); + rpc->rc_srtt[3] = (RPC_TIMEO << 3); + rpc->rc_sdrtt[0] = 0; + rpc->rc_sdrtt[1] = 0; + rpc->rc_sdrtt[2] = 0; + rpc->rc_sdrtt[3] = 0; + rpc->rc_cwnd = RPC_MAXCWND / 2; /* Initial send window */ + rpc->rc_sent = 0; + rpc->rc_timeouts = 0; + /* Protocols that do not require connections may be optionally left * unconnected for servers that reply from a port other than * NFS_PORT. @@ -1281,14 +1333,6 @@ int rpcclnt_connect(struct rpcclnt *rpc) } } - /* Initialize other non-zero congestion variables */ - - rpc->rc_srtt[0] = rpc->rc_srtt[1] = rpc->rc_srtt[2] = rpc->rc_srtt[3] = (RPC_TIMEO << 3); - rpc->rc_sdrtt[0] = rpc->rc_sdrtt[1] = rpc->rc_sdrtt[2] = rpc->rc_sdrtt[3] = 0; - rpc->rc_cwnd = RPC_MAXCWND / 2; /* Initial send window */ - rpc->rc_sent = 0; - rpc->rc_timeouts = 0; - fvdbg("Succeeded\n"); return 0; |