More NFS buffering improvements

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4842 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-06-14 15:45:38 +00:00
parent 1c2b2798b4
commit 75d7834082
5 changed files with 93 additions and 73 deletions

View File

@ -101,6 +101,7 @@ struct nfsmount
struct rpc_call_mkdir mkdir; struct rpc_call_mkdir mkdir;
struct rpc_call_rmdir rmdir; struct rpc_call_rmdir rmdir;
struct rpc_call_readdir readdir; struct rpc_call_readdir readdir;
struct rpc_call_fs fsstat;
struct rpc_call_fs fs; struct rpc_call_fs fs;
struct rpc_reply_write write; struct rpc_reply_write write;
} nm_msgbuffer; } nm_msgbuffer;

View File

@ -215,8 +215,6 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
FAR struct nfs_fattr *obj_attributes, FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes) FAR struct nfs_fattr *dir_attributes)
{ {
struct rpc_call_lookup request;
struct rpc_reply_lookup response;
FAR uint32_t *ptr; FAR uint32_t *ptr;
uint32_t value; uint32_t value;
int reqlen; int reqlen;
@ -236,7 +234,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
/* Initialize the request */ /* Initialize the request */
ptr = (FAR uint32_t*)&request.lookup; ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.lookup.lookup;
reqlen = 0; reqlen = 0;
/* Copy the variable length, directory file handle */ /* Copy the variable length, directory file handle */
@ -260,8 +258,9 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
nfs_statistics(NFSPROC_LOOKUP); nfs_statistics(NFSPROC_LOOKUP);
error = nfs_request(nmp, NFSPROC_LOOKUP, error = nfs_request(nmp, NFSPROC_LOOKUP,
(FAR void *)&request, reqlen, (FAR void *)&nmp->nm_msgbuffer.lookup, reqlen,
(FAR void *)&response, sizeof(struct rpc_reply_lookup)); (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
if (error) if (error)
{ {
fdbg("ERROR: nfs_request failed: %d\n", error); fdbg("ERROR: nfs_request failed: %d\n", error);
@ -273,7 +272,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
* may differ in size whereas struct rpc_reply_lookup uses a fixed size. * may differ in size whereas struct rpc_reply_lookup uses a fixed size.
*/ */
ptr = (FAR uint32_t*)&response.lookup; ptr = (FAR uint32_t *)&((FAR struct rpc_reply_lookup *)nmp->nm_iobuffer)->lookup;
/* Get the length of the file handle */ /* Get the length of the file handle */

View File

@ -194,7 +194,6 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
struct file_handle fhandle; struct file_handle fhandle;
struct nfs_fattr fattr; struct nfs_fattr fattr;
char filename[NAME_MAX + 1]; char filename[NAME_MAX + 1];
struct rpc_reply_create resok;
FAR uint32_t *ptr; FAR uint32_t *ptr;
uint32_t tmp; uint32_t tmp;
int namelen; int namelen;
@ -212,7 +211,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
/* Create the CREATE RPC call arguments */ /* Create the CREATE RPC call arguments */
ptr = (FAR uint32_t *)&((FAR struct rpc_call_create *)nmp->nm_iobuffer)->create; ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.create.create;
reqlen = 0; reqlen = 0;
/* Copy the variable length, directory file handle */ /* Copy the variable length, directory file handle */
@ -306,8 +305,8 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
{ {
nfs_statistics(NFSPROC_CREATE); nfs_statistics(NFSPROC_CREATE);
error = nfs_request(nmp, NFSPROC_CREATE, error = nfs_request(nmp, NFSPROC_CREATE,
(FAR void *)nmp->nm_iobuffer, reqlen, (FAR void *)&nmp->nm_msgbuffer.create, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_create)); (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
} }
#ifdef USE_GUARDED_CREATE #ifdef USE_GUARDED_CREATE
while (0); while (0);
@ -321,7 +320,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
{ {
/* Parse the returned data */ /* Parse the returned data */
ptr = (FAR uint32_t *)&resok.create; ptr = (FAR uint32_t *)nmp->nm_iobuffer;
/* Save the file handle in the file data structure */ /* Save the file handle in the file data structure */
@ -1779,11 +1778,11 @@ int nfs_fsinfo(FAR struct nfsmount *nmp)
* *
****************************************************************************/ ****************************************************************************/
static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) static int nfs_statfs(FAR struct inode *mountpt, FAR struct statfs *sbp)
{ {
struct rpc_call_fs fsstat; FAR struct nfsmount *nmp;
struct rpc_reply_fsstat sfp; FAR struct rpc_call_fs *fsstat;
struct nfsmount *nmp; FAR struct rpc_reply_fsstat *sfp;
int error = 0; int error = 0;
uint64_t tquad; uint64_t tquad;
@ -1811,28 +1810,30 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
(void)nfs_fsinfo(nmp); (void)nfs_fsinfo(nmp);
fsstat.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize); fsstat = &nmp->nm_msgbuffer.fsstat;
fsstat.fs.fsroot.handle = nmp->nm_fh; fsstat->fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
memcpy(&fsstat->fs.fsroot.handle, &nmp->nm_fh, sizeof(nfsfh_t));
nfs_statistics(NFSPROC_FSSTAT); nfs_statistics(NFSPROC_FSSTAT);
error = nfs_request(nmp, NFSPROC_FSSTAT, error = nfs_request(nmp, NFSPROC_FSSTAT,
(FAR void *)&fsstat, sizeof(struct FS3args), (FAR void *)fsstat, sizeof(struct FS3args),
(FAR void *) &sfp, sizeof(struct rpc_reply_fsstat)); (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
if (error) if (error)
{ {
goto errout_with_semaphore; goto errout_with_semaphore;
} }
sfp = (FAR struct rpc_reply_fsstat *)nmp->nm_iobuffer;
sbp->f_bsize = NFS_FABLKSIZE; sbp->f_bsize = NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.fsstat.sf_tbytes); tquad = fxdr_hyper(&sfp->fsstat.sf_tbytes);
sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE; sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.fsstat.sf_fbytes); tquad = fxdr_hyper(&sfp->fsstat.sf_fbytes);
sbp->f_bfree = tquad / (uint64_t) NFS_FABLKSIZE; sbp->f_bfree = tquad / (uint64_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.fsstat.sf_abytes); tquad = fxdr_hyper(&sfp->fsstat.sf_abytes);
sbp->f_bavail = tquad / (uint64_t) NFS_FABLKSIZE; sbp->f_bavail = tquad / (uint64_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.fsstat.sf_tfiles); tquad = fxdr_hyper(&sfp->fsstat.sf_tfiles);
sbp->f_files = tquad; sbp->f_files = tquad;
tquad = fxdr_hyper(&sfp.fsstat.sf_ffiles); tquad = fxdr_hyper(&sfp->fsstat.sf_ffiles);
sbp->f_ffree = tquad; sbp->f_ffree = tquad;
sbp->f_namelen = NAME_MAX; sbp->f_namelen = NAME_MAX;
@ -1858,7 +1859,6 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
struct file_handle fhandle; struct file_handle fhandle;
struct nfs_fattr fattr; struct nfs_fattr fattr;
char filename[NAME_MAX + 1]; char filename[NAME_MAX + 1];
struct rpc_reply_remove resok;
FAR uint32_t *ptr; FAR uint32_t *ptr;
int namelen; int namelen;
int reqlen; int reqlen;
@ -1920,7 +1920,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
nfs_statistics(NFSPROC_REMOVE); nfs_statistics(NFSPROC_REMOVE);
error = nfs_request(nmp, NFSPROC_REMOVE, error = nfs_request(nmp, NFSPROC_REMOVE,
(FAR void *)&nmp->nm_msgbuffer.removef, reqlen, (FAR void *)&nmp->nm_msgbuffer.removef, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_remove)); (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
errout_with_semaphore: errout_with_semaphore:
nfs_semgive(nmp); nfs_semgive(nmp);
@ -1944,7 +1944,6 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
struct file_handle fhandle; struct file_handle fhandle;
struct nfs_fattr fattr; struct nfs_fattr fattr;
char dirname[NAME_MAX + 1]; char dirname[NAME_MAX + 1];
struct rpc_reply_mkdir resok;
FAR uint32_t *ptr; FAR uint32_t *ptr;
uint32_t tmp; uint32_t tmp;
int namelen; int namelen;
@ -2044,7 +2043,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
nfs_statistics(NFSPROC_MKDIR); nfs_statistics(NFSPROC_MKDIR);
error = nfs_request(nmp, NFSPROC_MKDIR, error = nfs_request(nmp, NFSPROC_MKDIR,
(FAR void *)&nmp->nm_msgbuffer.mkdir, reqlen, (FAR void *)&nmp->nm_msgbuffer.mkdir, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_mkdir)); (FAR void *)&nmp->nm_iobuffer, nmp->nm_buflen);
if (error) if (error)
{ {
fdbg("ERROR: nfs_request failed: %d\n", error); fdbg("ERROR: nfs_request failed: %d\n", error);
@ -2072,7 +2071,6 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
struct file_handle fhandle; struct file_handle fhandle;
struct nfs_fattr fattr; struct nfs_fattr fattr;
char dirname[NAME_MAX + 1]; char dirname[NAME_MAX + 1];
struct rpc_reply_rmdir resok;
FAR uint32_t *ptr; FAR uint32_t *ptr;
int namelen; int namelen;
int reqlen; int reqlen;
@ -2134,7 +2132,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
nfs_statistics(NFSPROC_RMDIR); nfs_statistics(NFSPROC_RMDIR);
error = nfs_request(nmp, NFSPROC_RMDIR, error = nfs_request(nmp, NFSPROC_RMDIR,
(FAR void *)&nmp->nm_msgbuffer.rmdir, reqlen, (FAR void *)&nmp->nm_msgbuffer.rmdir, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_rmdir)); (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
errout_with_semaphore: errout_with_semaphore:
nfs_semgive(nmp); nfs_semgive(nmp);
@ -2161,7 +2159,6 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
char from_name[NAME_MAX+1]; char from_name[NAME_MAX+1];
char to_name[NAME_MAX+1]; char to_name[NAME_MAX+1];
struct nfs_fattr fattr; struct nfs_fattr fattr;
struct rpc_reply_rename resok;
FAR uint32_t *ptr; FAR uint32_t *ptr;
int namelen; int namelen;
int reqlen; int reqlen;
@ -2252,7 +2249,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
nfs_statistics(NFSPROC_RENAME); nfs_statistics(NFSPROC_RENAME);
error = nfs_request(nmp, NFSPROC_RENAME, error = nfs_request(nmp, NFSPROC_RENAME,
(FAR void *)&nmp->nm_msgbuffer.renamef, reqlen, (FAR void *)&nmp->nm_msgbuffer.renamef, reqlen,
(FAR void *)&resok, sizeof(struct rpc_reply_rename)); (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
errout_with_semaphore: errout_with_semaphore:
nfs_semgive(nmp); nfs_semgive(nmp);

View File

@ -237,6 +237,12 @@ struct call_args_mount
char rpath[90]; char rpath[90];
}; };
struct call_args_umount
{
uint32_t len;
char rpath[90];
};
struct call_result_mount struct call_result_mount
{ {
uint32_t status; uint32_t status;
@ -295,7 +301,7 @@ struct rpc_call_mount
struct rpc_call_umount struct rpc_call_umount
{ {
struct rpc_call_header ch; struct rpc_call_header ch;
struct call_args_mount mount; struct call_args_umount umount;
}; };
struct rpc_call_create struct rpc_call_create

View File

@ -364,10 +364,19 @@ int rpcclnt_connect(struct rpcclnt *rpc)
struct sockaddr *saddr; struct sockaddr *saddr;
struct sockaddr_in sin; struct sockaddr_in sin;
struct sockaddr_in *sa; struct sockaddr_in *sa;
struct rpc_call_pmap sdata;
struct rpc_call_mount mountd; union
struct rpc_reply_pmap rdata; {
struct rpc_reply_mount mdata; struct rpc_call_pmap sdata;
struct rpc_call_mount mountd;
} request;
union
{
struct rpc_reply_pmap rdata;
struct rpc_reply_mount mdata;
} response;
struct timeval tv; struct timeval tv;
uint16_t tport; uint16_t tport;
int errval; int errval;
@ -460,14 +469,14 @@ int rpcclnt_connect(struct rpcclnt *rpc)
* Get port number for MOUNTD. * Get port number for MOUNTD.
*/ */
sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT); request.sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT);
sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1); request.sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1);
sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
sdata.pmap.port = 0; request.sdata.pmap.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&sdata, sizeof(struct call_args_pmap), (FAR void *)&request.sdata, sizeof(struct call_args_pmap),
(FAR void *)&rdata, sizeof(struct rpc_reply_pmap)); (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
if (error != 0) if (error != 0)
{ {
fdbg("ERROR: rpcclnt_request failed: %d\n", error); fdbg("ERROR: rpcclnt_request failed: %d\n", error);
@ -475,7 +484,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
} }
sa = (FAR struct sockaddr_in *)saddr; sa = (FAR struct sockaddr_in *)saddr;
sa->sin_port = htons(fxdr_unsigned(uint32_t, rdata.pmap.port)); sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error < 0) if (error < 0)
@ -487,26 +496,26 @@ int rpcclnt_connect(struct rpcclnt *rpc)
/* Do RPC to mountd. */ /* Do RPC to mountd. */
strncpy(mountd.mount.rpath, rpc->rc_path, 90); strncpy(request.mountd.mount.rpath, rpc->rc_path, 90);
mountd.mount.len = txdr_unsigned(sizeof(mountd.mount.rpath)); request.mountd.mount.len = txdr_unsigned(sizeof(request.mountd.mount.rpath));
error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1, error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1,
(FAR void *)&mountd, sizeof(struct call_args_mount), (FAR void *)&request.mountd, sizeof(struct call_args_mount),
(FAR void *)&mdata, sizeof(struct rpc_reply_mount)); (FAR void *)&response.mdata, sizeof(struct rpc_reply_mount));
if (error != 0) if (error != 0)
{ {
fdbg("ERROR: rpcclnt_request failed: %d\n", error); fdbg("ERROR: rpcclnt_request failed: %d\n", error);
goto bad; goto bad;
} }
error = fxdr_unsigned(uint32_t, mdata.mount.status); error = fxdr_unsigned(uint32_t, response.mdata.mount.status);
if (error != 0) if (error != 0)
{ {
fdbg("ERROR: Bad mount status: %d\n", error); fdbg("ERROR: Bad mount status: %d\n", error);
goto bad; goto bad;
} }
memcpy(&rpc->rc_fh, &mdata.mount.fhandle, sizeof(nfsfh_t)); memcpy(&rpc->rc_fh, &response.mdata.mount.fhandle, sizeof(nfsfh_t));
/* Do the RPC to get a dynamic bounding with the server using PMAP. /* Do the RPC to get a dynamic bounding with the server using PMAP.
* NFS port in the socket. * NFS port in the socket.
@ -522,21 +531,21 @@ int rpcclnt_connect(struct rpcclnt *rpc)
goto bad; goto bad;
} }
sdata.pmap.prog = txdr_unsigned(NFS_PROG); request.sdata.pmap.prog = txdr_unsigned(NFS_PROG);
sdata.pmap.vers = txdr_unsigned(NFS_VER3); request.sdata.pmap.vers = txdr_unsigned(NFS_VER3);
sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
sdata.pmap.port = 0; request.sdata.pmap.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&sdata, sizeof(struct call_args_pmap), (FAR void *)&request.sdata, sizeof(struct call_args_pmap),
(FAR void *)&rdata, sizeof(struct rpc_reply_pmap)); (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
if (error != 0) if (error != 0)
{ {
fdbg("ERROR: rpcclnt_request failed: %d\n", error); fdbg("ERROR: rpcclnt_request failed: %d\n", error);
goto bad; goto bad;
} }
sa->sin_port = htons(fxdr_unsigned(uint32_t, rdata.pmap.port)); sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
@ -567,11 +576,19 @@ int rpcclnt_umount(struct rpcclnt *rpc)
{ {
struct sockaddr *saddr; struct sockaddr *saddr;
struct sockaddr_in *sa; struct sockaddr_in *sa;
struct rpc_call_pmap sdata;
struct rpc_reply_pmap rdata; union
struct rpc_call_umount mountd; {
struct rpc_reply_umount mdata; struct rpc_call_pmap sdata;
uint32_t tmp; struct rpc_call_umount mountd;
} request;
union
{
struct rpc_reply_pmap rdata;
struct rpc_reply_umount mdata;
} response;
int error; int error;
int ret; int ret;
@ -593,21 +610,21 @@ int rpcclnt_umount(struct rpcclnt *rpc)
goto bad; goto bad;
} }
sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT); request.sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT);
sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1); request.sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1);
sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
sdata.pmap.port = 0; request.sdata.pmap.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&sdata, sizeof(struct call_args_pmap), (FAR void *)&request.sdata, sizeof(struct call_args_pmap),
(FAR void *)&rdata, sizeof(struct rpc_reply_pmap)); (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
if (error != 0) if (error != 0)
{ {
fdbg("ERROR: rpcclnt_request failed: %d\n", error); fdbg("ERROR: rpcclnt_request failed: %d\n", error);
goto bad; goto bad;
} }
sa->sin_port = htons(fxdr_unsigned(uint32_t, rdata.pmap.port)); sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
ret = psock_connect(rpc->rc_so, saddr, sizeof(*saddr)); ret = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (ret < 0) if (ret < 0)
@ -620,12 +637,12 @@ int rpcclnt_umount(struct rpcclnt *rpc)
/* Do RPC to umountd. */ /* Do RPC to umountd. */
strncpy(mountd.mount.rpath, rpc->rc_path, 92); strncpy(request.mountd.umount.rpath, rpc->rc_path, 92);
mountd.mount.len = txdr_unsigned(sizeof(mountd.mount.rpath)); request.mountd.umount.len = txdr_unsigned(sizeof(request.mountd.umount.rpath));
error = rpcclnt_request(rpc, RPCMNT_UMOUNT, RPCPROG_MNT, RPCMNT_VER1, error = rpcclnt_request(rpc, RPCMNT_UMOUNT, RPCPROG_MNT, RPCMNT_VER1,
(FAR void *)&mountd, sizeof(struct call_args_mount), (FAR void *)&request.mountd, sizeof(struct call_args_umount),
(FAR void *)&mdata, sizeof(struct rpc_reply_mount)); (FAR void *)&response.mdata, sizeof(struct rpc_reply_umount));
if (error != 0) if (error != 0)
{ {
fdbg("ERROR: rpcclnt_request failed: %d\n", error); fdbg("ERROR: rpcclnt_request failed: %d\n", error);