From b1ca44e80e071794da0f50432058353ba32c064b Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 14 Jun 2012 15:45:38 +0000 Subject: [PATCH] More NFS buffering improvements git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4842 42af7a65-404d-4744-a932-0658087f49c3 --- fs/nfs/nfs_mount.h | 1 + fs/nfs/nfs_util.c | 11 +++-- fs/nfs/nfs_vfsops.c | 49 +++++++++++------------ fs/nfs/rpc.h | 8 +++- fs/nfs/rpc_clnt.c | 97 ++++++++++++++++++++++++++------------------- 5 files changed, 93 insertions(+), 73 deletions(-) diff --git a/fs/nfs/nfs_mount.h b/fs/nfs/nfs_mount.h index cfae14e37c..302cd9370c 100644 --- a/fs/nfs/nfs_mount.h +++ b/fs/nfs/nfs_mount.h @@ -101,6 +101,7 @@ struct nfsmount struct rpc_call_mkdir mkdir; struct rpc_call_rmdir rmdir; struct rpc_call_readdir readdir; + struct rpc_call_fs fsstat; struct rpc_call_fs fs; struct rpc_reply_write write; } nm_msgbuffer; diff --git a/fs/nfs/nfs_util.c b/fs/nfs/nfs_util.c index 643117e22a..8ab3e974e6 100644 --- a/fs/nfs/nfs_util.c +++ b/fs/nfs/nfs_util.c @@ -215,8 +215,6 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename, FAR struct nfs_fattr *obj_attributes, FAR struct nfs_fattr *dir_attributes) { - struct rpc_call_lookup request; - struct rpc_reply_lookup response; FAR uint32_t *ptr; uint32_t value; int reqlen; @@ -236,7 +234,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename, /* Initialize the request */ - ptr = (FAR uint32_t*)&request.lookup; + ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.lookup.lookup; reqlen = 0; /* 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); error = nfs_request(nmp, NFSPROC_LOOKUP, - (FAR void *)&request, reqlen, - (FAR void *)&response, sizeof(struct rpc_reply_lookup)); + (FAR void *)&nmp->nm_msgbuffer.lookup, reqlen, + (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen); + if (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. */ - 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 */ diff --git a/fs/nfs/nfs_vfsops.c b/fs/nfs/nfs_vfsops.c index a8477823ce..dc62943683 100644 --- a/fs/nfs/nfs_vfsops.c +++ b/fs/nfs/nfs_vfsops.c @@ -194,7 +194,6 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np, struct file_handle fhandle; struct nfs_fattr fattr; char filename[NAME_MAX + 1]; - struct rpc_reply_create resok; FAR uint32_t *ptr; uint32_t tmp; int namelen; @@ -212,7 +211,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np, /* 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; /* 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); error = nfs_request(nmp, NFSPROC_CREATE, - (FAR void *)nmp->nm_iobuffer, reqlen, - (FAR void *)&resok, sizeof(struct rpc_reply_create)); + (FAR void *)&nmp->nm_msgbuffer.create, reqlen, + (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen); } #ifdef USE_GUARDED_CREATE while (0); @@ -321,7 +320,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np, { /* 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 */ @@ -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; - struct rpc_reply_fsstat sfp; - struct nfsmount *nmp; + FAR struct nfsmount *nmp; + FAR struct rpc_call_fs *fsstat; + FAR struct rpc_reply_fsstat *sfp; int error = 0; uint64_t tquad; @@ -1811,28 +1810,30 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp) (void)nfs_fsinfo(nmp); - fsstat.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize); - fsstat.fs.fsroot.handle = nmp->nm_fh; + fsstat = &nmp->nm_msgbuffer.fsstat; + fsstat->fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize); + memcpy(&fsstat->fs.fsroot.handle, &nmp->nm_fh, sizeof(nfsfh_t)); nfs_statistics(NFSPROC_FSSTAT); error = nfs_request(nmp, NFSPROC_FSSTAT, - (FAR void *)&fsstat, sizeof(struct FS3args), - (FAR void *) &sfp, sizeof(struct rpc_reply_fsstat)); + (FAR void *)fsstat, sizeof(struct FS3args), + (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen); if (error) { goto errout_with_semaphore; } + sfp = (FAR struct rpc_reply_fsstat *)nmp->nm_iobuffer; 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; - tquad = fxdr_hyper(&sfp.fsstat.sf_fbytes); + tquad = fxdr_hyper(&sfp->fsstat.sf_fbytes); 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; - tquad = fxdr_hyper(&sfp.fsstat.sf_tfiles); + tquad = fxdr_hyper(&sfp->fsstat.sf_tfiles); sbp->f_files = tquad; - tquad = fxdr_hyper(&sfp.fsstat.sf_ffiles); + tquad = fxdr_hyper(&sfp->fsstat.sf_ffiles); sbp->f_ffree = tquad; sbp->f_namelen = NAME_MAX; @@ -1858,7 +1859,6 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) struct file_handle fhandle; struct nfs_fattr fattr; char filename[NAME_MAX + 1]; - struct rpc_reply_remove resok; FAR uint32_t *ptr; int namelen; int reqlen; @@ -1920,7 +1920,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath) nfs_statistics(NFSPROC_REMOVE); error = nfs_request(nmp, NFSPROC_REMOVE, (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: 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 nfs_fattr fattr; char dirname[NAME_MAX + 1]; - struct rpc_reply_mkdir resok; FAR uint32_t *ptr; uint32_t tmp; int namelen; @@ -2044,7 +2043,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode) nfs_statistics(NFSPROC_MKDIR); error = nfs_request(nmp, NFSPROC_MKDIR, (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) { 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 nfs_fattr fattr; char dirname[NAME_MAX + 1]; - struct rpc_reply_rmdir resok; FAR uint32_t *ptr; int namelen; int reqlen; @@ -2134,7 +2132,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath) nfs_statistics(NFSPROC_RMDIR); error = nfs_request(nmp, NFSPROC_RMDIR, (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: nfs_semgive(nmp); @@ -2161,7 +2159,6 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, char from_name[NAME_MAX+1]; char to_name[NAME_MAX+1]; struct nfs_fattr fattr; - struct rpc_reply_rename resok; FAR uint32_t *ptr; int namelen; int reqlen; @@ -2252,7 +2249,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath, nfs_statistics(NFSPROC_RENAME); error = nfs_request(nmp, NFSPROC_RENAME, (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: nfs_semgive(nmp); diff --git a/fs/nfs/rpc.h b/fs/nfs/rpc.h index 4a95d6bc2e..15b340ee4f 100644 --- a/fs/nfs/rpc.h +++ b/fs/nfs/rpc.h @@ -237,6 +237,12 @@ struct call_args_mount char rpath[90]; }; +struct call_args_umount +{ + uint32_t len; + char rpath[90]; +}; + struct call_result_mount { uint32_t status; @@ -295,7 +301,7 @@ struct rpc_call_mount struct rpc_call_umount { struct rpc_call_header ch; - struct call_args_mount mount; + struct call_args_umount umount; }; struct rpc_call_create diff --git a/fs/nfs/rpc_clnt.c b/fs/nfs/rpc_clnt.c index e6a3f7daff..c20a04cd9f 100644 --- a/fs/nfs/rpc_clnt.c +++ b/fs/nfs/rpc_clnt.c @@ -364,10 +364,19 @@ int rpcclnt_connect(struct rpcclnt *rpc) struct sockaddr *saddr; struct sockaddr_in sin; struct sockaddr_in *sa; - struct rpc_call_pmap sdata; - struct rpc_call_mount mountd; - struct rpc_reply_pmap rdata; - struct rpc_reply_mount mdata; + + union + { + 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; uint16_t tport; int errval; @@ -460,14 +469,14 @@ int rpcclnt_connect(struct rpcclnt *rpc) * Get port number for MOUNTD. */ - sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT); - sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1); - sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); - sdata.pmap.port = 0; + request.sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT); + request.sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1); + request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); + request.sdata.pmap.port = 0; error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, - (FAR void *)&sdata, sizeof(struct call_args_pmap), - (FAR void *)&rdata, sizeof(struct rpc_reply_pmap)); + (FAR void *)&request.sdata, sizeof(struct call_args_pmap), + (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap)); if (error != 0) { 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->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)); if (error < 0) @@ -487,26 +496,26 @@ int rpcclnt_connect(struct rpcclnt *rpc) /* Do RPC to mountd. */ - strncpy(mountd.mount.rpath, rpc->rc_path, 90); - mountd.mount.len = txdr_unsigned(sizeof(mountd.mount.rpath)); + strncpy(request.mountd.mount.rpath, rpc->rc_path, 90); + request.mountd.mount.len = txdr_unsigned(sizeof(request.mountd.mount.rpath)); error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1, - (FAR void *)&mountd, sizeof(struct call_args_mount), - (FAR void *)&mdata, sizeof(struct rpc_reply_mount)); + (FAR void *)&request.mountd, sizeof(struct call_args_mount), + (FAR void *)&response.mdata, sizeof(struct rpc_reply_mount)); if (error != 0) { fdbg("ERROR: rpcclnt_request failed: %d\n", error); goto bad; } - error = fxdr_unsigned(uint32_t, mdata.mount.status); + error = fxdr_unsigned(uint32_t, response.mdata.mount.status); if (error != 0) { fdbg("ERROR: Bad mount status: %d\n", error); 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. * NFS port in the socket. @@ -522,21 +531,21 @@ int rpcclnt_connect(struct rpcclnt *rpc) goto bad; } - sdata.pmap.prog = txdr_unsigned(NFS_PROG); - sdata.pmap.vers = txdr_unsigned(NFS_VER3); - sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); - sdata.pmap.port = 0; + request.sdata.pmap.prog = txdr_unsigned(NFS_PROG); + request.sdata.pmap.vers = txdr_unsigned(NFS_VER3); + request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); + request.sdata.pmap.port = 0; error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, - (FAR void *)&sdata, sizeof(struct call_args_pmap), - (FAR void *)&rdata, sizeof(struct rpc_reply_pmap)); + (FAR void *)&request.sdata, sizeof(struct call_args_pmap), + (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap)); if (error != 0) { fdbg("ERROR: rpcclnt_request failed: %d\n", error); 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)); if (error) @@ -567,11 +576,19 @@ int rpcclnt_umount(struct rpcclnt *rpc) { struct sockaddr *saddr; struct sockaddr_in *sa; - struct rpc_call_pmap sdata; - struct rpc_reply_pmap rdata; - struct rpc_call_umount mountd; - struct rpc_reply_umount mdata; - uint32_t tmp; + + union + { + struct rpc_call_pmap sdata; + struct rpc_call_umount mountd; + } request; + + union + { + struct rpc_reply_pmap rdata; + struct rpc_reply_umount mdata; + } response; + int error; int ret; @@ -593,21 +610,21 @@ int rpcclnt_umount(struct rpcclnt *rpc) goto bad; } - sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT); - sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1); - sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); - sdata.pmap.port = 0; + request.sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT); + request.sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1); + request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP); + request.sdata.pmap.port = 0; error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS, - (FAR void *)&sdata, sizeof(struct call_args_pmap), - (FAR void *)&rdata, sizeof(struct rpc_reply_pmap)); + (FAR void *)&request.sdata, sizeof(struct call_args_pmap), + (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap)); if (error != 0) { fdbg("ERROR: rpcclnt_request failed: %d\n", error); 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)); if (ret < 0) @@ -620,12 +637,12 @@ int rpcclnt_umount(struct rpcclnt *rpc) /* Do RPC to umountd. */ - strncpy(mountd.mount.rpath, rpc->rc_path, 92); - mountd.mount.len = txdr_unsigned(sizeof(mountd.mount.rpath)); + strncpy(request.mountd.umount.rpath, rpc->rc_path, 92); + request.mountd.umount.len = txdr_unsigned(sizeof(request.mountd.umount.rpath)); error = rpcclnt_request(rpc, RPCMNT_UMOUNT, RPCPROG_MNT, RPCMNT_VER1, - (FAR void *)&mountd, sizeof(struct call_args_mount), - (FAR void *)&mdata, sizeof(struct rpc_reply_mount)); + (FAR void *)&request.mountd, sizeof(struct call_args_umount), + (FAR void *)&response.mdata, sizeof(struct rpc_reply_umount)); if (error != 0) { fdbg("ERROR: rpcclnt_request failed: %d\n", error);