NFS update

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4809 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-06-07 01:03:34 +00:00
parent f341d5abcf
commit ecd38c4f9d
6 changed files with 310 additions and 459 deletions

View File

@ -124,13 +124,13 @@ int nfs_connect(struct nfsmount *nmp)
rpc = (struct rpcclnt *)kzalloc(sizeof(struct rpcclnt));
if (!rpc)
{
fdbg("Failed to allocate rpc structure\n");
fdbg("ERROR: Failed to allocate rpc structure\n");
return -ENOMEM;
}
rpc->rc_prog = &nfs3_program;
fvdbg("nfs connect!\n");
fvdbg("Connecting\n");
/* translate nfsmnt flags -> rpcclnt flags */
@ -181,12 +181,12 @@ void nfs_safedisconnect(struct nfsmount *nmp)
#endif
int nfs_request(struct nfsmount *nmp, int procnum, FAR const void *datain,
FAR void *dataout)
FAR void *dataout, size_t len)
{
int error;
struct rpcclnt *clnt= nmp->nm_rpcclnt;
struct rpcclnt *clnt= nmp->nm_rpcclnt;
struct rpc_reply_header replyh;
int trylater_delay;
int error;
tryagain:
@ -194,13 +194,14 @@ tryagain:
error = rpcclnt_request(clnt, procnum, nmp->nm_rpcclnt->rc_prog->prog_id,
nmp->nm_rpcclnt->rc_prog->prog_version, dataout,
datain);
datain, len);
if (error != 0)
{
fdbg("ERROR: rpcclnt_request failed: %d\n", error);
goto out;
}
bcopy(dataout, &replyh, sizeof(replyh));
bcopy(dataout, &replyh, sizeof(struct rpc_reply_header));
if (replyh.rpc_verfi.authtype != 0)
{
@ -224,12 +225,12 @@ tryagain:
if (error == ESTALE)
{
fdbg("%s: ESTALE on mount from server \n",
fdbg("ERROR %s: ESTALE on mount from server\n",
nmp->nm_rpcclnt->rc_prog->prog_name);
}
else
{
fdbg("%s: unknown error %d from server \n",
fdbg("ERROR %s: unknown error %d from server\n",
nmp->nm_rpcclnt->rc_prog->prog_name, error);
}

View File

@ -61,7 +61,7 @@ EXTERN void nfs_disconnect(struct nfsmount *);
EXTERN int nfs_sigintr(struct nfsmount *, struct nfsreq *, cthread_t *);
EXTERN void nfs_safedisconnect(struct nfsmount *);
#endif
EXTERN int nfs_request(struct nfsmount *, int, FAR const void *, FAR void *);
EXTERN int nfs_request(struct nfsmount *, int, FAR const void *, FAR void *, size_t);
#undef COMP
#ifdef COMP
EXTERN int nfs_nmcancelreqs(struct nfsmount *);

View File

@ -185,7 +185,7 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
struct nfsmount *nmp;
struct nfsnode *np;
struct CREATE3args create;
struct CREATE3resok resok;
struct rpc_reply_create resok;
int error = 0;
/* Sanity checks */
@ -232,13 +232,15 @@ again:
//txdr_nfsv3time2(&vap.fa3_mtime, &sp.sa_mtime);
memset(&create, 0, sizeof(struct CREATE3args));
memset(&resok, 0, sizeof(struct rpc_reply_create));
create.how = sp;
create.where.dir.length = txdr_unsigned(np->n_fhsize);
create.where.dir.handle = np->n_fhp;
create.where.length = txdr_unsigned(64);
strncpy(create.where.name, relpath, 64);
error = nfs_request(nmp, NFSPROC_CREATE, (FAR const void *)&create, (void *)&resok);
error = nfs_request(nmp, NFSPROC_CREATE, (FAR const void *)&create,
(void *)&resok, sizeof(struct rpc_reply_create));
if (!error)
{
/* Create an instance of the file private data to describe the opened
@ -248,7 +250,7 @@ again:
np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
if (!np)
{
fdbg("Failed to allocate private data\n", error);
fdbg("ERROR: Failed to allocate private data\n");
error = -ENOMEM;
goto errout_with_semaphore;
}
@ -257,7 +259,7 @@ again:
* non-zero elements)
*/
np->nfsv3_type = fxdr_unsigned(uint32_t, resok.attributes.fa_type);
// np->nfsv3_type = fxdr_unsigned(uint32_t, resok.attributes.fa_type);
/* The full path exists -- but is the final component a file
* or a directory?
@ -268,16 +270,16 @@ again:
/* It is a directory */
error = EISDIR;
fdbg("'%s' is a directory\n", relpath);
fdbg("ERROR: '%s' is a directory\n", relpath);
goto errout_with_semaphore;
}
np->n_open = true;
np->n_fhp = resok.fshandle.handle;
np->n_size = fxdr_hyper(&resok.attributes.fa3_size);
np->n_fattr = resok.attributes;
fxdr_nfsv3time(&resok.attributes.fa3_mtime, &np->n_mtime)
np->n_ctime = fxdr_hyper(&resok.attributes.fa3_ctime);
bcopy(&resok.create.fshandle.handle, &np->n_fhp, sizeof(nfsfh_t));
np->n_size = fxdr_hyper(&resok.create.attributes.fa3_size);
bcopy(&resok.create.attributes, &np->n_fattr, sizeof(struct nfs_fattr));
fxdr_nfsv3time(&resok.create.attributes.fa3_mtime, &np->n_mtime)
np->n_ctime = fxdr_hyper(&resok.create.attributes.fa3_ctime);
/* Attach the private date to the struct file instance */
@ -307,7 +309,7 @@ again:
{
if (np->nfsv3_type != NFREG)
{
fdbg("open eacces typ=%d\n", np->nfsv3_type);
fdbg("ERROR: open eacces typ=%d\n", np->nfsv3_type);
return EACCES;
}
@ -378,7 +380,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
int bytesleft;
uint64_t offset;
struct READ3args read;
struct READ3resok resok;
struct rpc_reply_read resok;
uint8_t *userbuffer = (uint8_t*)buffer;
int error = 0;
int len;
@ -449,18 +451,19 @@ again:
read.count = txdr_unsigned(buflen);
read.offset = txdr_unsigned(offset);
error = nfs_request(nmp, NFSPROC_READ, (FAR const void *)&read, (void *)&resok);
error = nfs_request(nmp, NFSPROC_READ, (FAR const void *)&read,
(void *)&resok, sizeof(struct rpc_reply_read));
if (error)
{
goto errout_with_semaphore;
}
eof = resok.eof;
//eof = resok.eof;
if (eof == true)
{
readsize = fxdr_unsigned(uint32_t, resok.count);
np->n_fattr = resok.file_attributes;
memcpy(userbuffer, resok.data, readsize);
readsize = fxdr_unsigned(uint32_t, resok.read.count);
np->n_fattr = resok.read.file_attributes;//
memcpy(userbuffer, resok.read.data, readsize);
}
else
{
@ -487,7 +490,7 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen)
struct nfsnode *np;
unsigned int writesize;
struct WRITE3args write;
struct WRITE3resok resok;
struct rpc_reply_write resok;
uint8_t *userbuffer = (uint8_t*)buffer;
int error = 0;
uint64_t offset;
@ -543,21 +546,21 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen)
memcpy((void *)write.data, userbuffer, buflen);
error = nfs_request(nmp, NFSPROC_WRITE, (FAR const void *)&write,
(FAR void *)&resok);
(FAR void *)&resok, sizeof(struct rpc_reply_write));
if (error)
{
goto errout_with_semaphore;
}
writesize = resok.count;
//writesize = resok.count;
if (writesize == 0)
{
error = NFSERR_IO;
goto errout_with_semaphore;
}
commit = resok.committed;
np->n_fattr = resok.file_wcc.after;
//commit = resok.committed;
np->n_fattr = resok.write.file_wcc.after;
/* Return the lowest committment level obtained by any of the RPCs. */
@ -573,12 +576,12 @@ 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.write.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.write.verf, (char*) nmp->nm_verf, NFSX_V3WRITEVERF))
{
bcopy((void*) resok.verf, (void*) nmp->nm_verf, NFSX_V3WRITEVERF);
bcopy((void*) resok.write.verf, (void*) nmp->nm_verf, NFSX_V3WRITEVERF);
}
fxdr_nfsv3time(&np->n_fattr.fa3_mtime, &np->n_mtime)
@ -675,7 +678,7 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
{
int error = 0;
struct READDIR3args readir;
struct READDIR3resok resok;
struct rpc_reply_readdir resok;
/* Loop around doing readdir rpc's of size nm_readdirsize
* truncated to a multiple of NFS_READDIRBLKSIZ.
@ -706,26 +709,25 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
}
error = nfs_request(nmp, NFSPROC_READDIR, (FAR const void *)&readir,
(FAR void *)&resok);
(FAR void *)&resok, sizeof(struct rpc_reply_readdir));
if (error)
{
goto nfsmout;
}
np->n_fattr = resok.dir_attributes;
np->n_cookieverf.nfsuquad[0] = resok.cookieverf.nfsuquad[0];
np->n_cookieverf.nfsuquad[1] = resok.cookieverf.nfsuquad[1];
dir->fd_dir.d_type = resok.reply.entries->fileid;
memcpy(&dir->fd_dir.d_name[NAME_MAX], &resok.reply.entries->name, NAME_MAX);
//dir->fd_dir.d_name = resok->reply.entries->name;//
dir->u.nfs.cookie[0] = resok.reply.entries->cookie.nfsuquad[0];
dir->u.nfs.cookie[1] = resok.reply.entries->cookie.nfsuquad[1];
/*np->n_fattr = resok.readir.dir_attributes;
np->n_cookieverf.nfsuquad[0] = resok.readir.cookieverf.nfsuquad[0];
np->n_cookieverf.nfsuquad[1] = resok.readir.cookieverf.nfsuquad[1];
dir->fd_dir.d_type = resok.readir.reply.entries->fileid;
memcpy(&dir->fd_dir.d_name[NAME_MAX], &resok.readir.reply.entries->name, NAME_MAX);
dir->u.nfs.cookie[0] = resok.readir.reply.entries->cookie.nfsuquad[0];
dir->u.nfs.cookie[1] = resok.readir.reply.entries->cookie.nfsuquad[1];
if (resok.reply.eof == true)
if (resok.readir.reply.eof == true)
{
end_of_directory = true;
}
*/
//more_dirs = fxdr_unsigned(int, *dp);
/* loop thru the dir entries */
@ -748,14 +750,14 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
more_dirs = fxdr_unsigned(int, *ndp);
}
*/
}
*/
/* We are now either at the end of the directory */
if (resok.reply.entries == NULL)
/*
if (resok.readir.reply.entries == NULL)
{
np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]);
np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]);*/
/* We signal the end of the directory by returning the
* special error -ENOENT
@ -1082,18 +1084,18 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
int mountnfs(struct nfs_args *argp, void **handle)
{
struct nfsmount *nmp;
struct nfsnode *np;
FAR struct nfsmount *nmp;
struct nfsnode *np = NULL;
struct FS3args getattr;
struct rpc_reply_getattr resok;
int error = 0;
/* Create an instance of the mountpt state structure */
nmp = (struct nfsmount *)kzalloc(sizeof(struct nfsmount));
nmp = (FAR struct nfsmount *)kzalloc(sizeof(struct nfsmount));
if (!nmp)
{
fdbg("Failed to allocate mountpoint structure\n");
fdbg("ERROR: Failed to allocate mountpoint structure\n");
return -ENOMEM;
}
@ -1105,35 +1107,43 @@ int mountnfs(struct nfs_args *argp, void **handle)
sem_init(&nmp->nm_sem, 0, 0); /* Initialize the semaphore that controls access */
nfs_init();
nmp->nm_flag = argp->flags;
nmp->nm_timeo = NFS_TIMEO;
nmp->nm_retry = NFS_RETRANS;
nmp->nm_wsize = NFS_WSIZE;
nmp->nm_rsize = NFS_RSIZE;
nmp->nm_flag = argp->flags;
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 = NFSX_V3FHMAX;
nmp->nm_acregmin = NFS_MINATTRTIMO;
nmp->nm_acregmax = NFS_MAXATTRTIMO;
nmp->nm_acdirmin = NFS_MINATTRTIMO;
nmp->nm_acdirmax = NFS_MAXATTRTIMO;
nmp->nm_numgrps = NFS_MAXGRPS;
nmp->nm_readahead = NFS_DEFRAHEAD;
nmp->nm_fhsize = NFSX_V3FHMAX;
nmp->nm_acregmin = NFS_MINATTRTIMO;
nmp->nm_acregmax = NFS_MAXATTRTIMO;
nmp->nm_acdirmin = NFS_MINATTRTIMO;
nmp->nm_acdirmax = NFS_MAXATTRTIMO;
strncpy(nmp->nm_path, argp->path, 90);
nmp->nm_nam = argp->addr;
nmp->nm_nam = argp->addr;
nfs_decode_args(nmp, argp);
/* Set up the sockets and per-host congestion */
nmp->nm_sotype = argp->sotype;
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)))
if (nmp->nm_sotype == SOCK_DGRAM)
{
goto bad;
/* Connection-less... connect now */
error = nfs_connect(nmp);
if (error != 0)
{
fdbg("ERROR: nfs_connect failed: %d\n", error);
goto bad;
}
}
/* Create an instance of the file private data to describe the opened
@ -1143,20 +1153,23 @@ int mountnfs(struct nfs_args *argp, void **handle)
np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
if (!np)
{
fdbg("Failed to allocate private data\n");
return -ENOMEM;
fdbg("ERROR: Failed to allocate private data\n");
error = -ENOMEM;
goto bad;
}
np->nfsv3_type = NFDIR;
np->n_open = true;
np->n_flag |= NMODIFIED;
nmp->nm_head = np;
nmp->nm_mounted = true;
nmp->nm_fh = nmp->nm_rpcclnt->rc_fh;
nmp->nm_fhsize = NFSX_V2FH;
nmp->nm_head->n_fhp = nmp->nm_fh;
np->nfsv3_type = NFDIR;
np->n_open = true;
np->n_flag |= NMODIFIED;
nmp->nm_head = np;
nmp->nm_mounted = true;
nmp->nm_fh = nmp->nm_rpcclnt->rc_fh;
nmp->nm_fhsize = NFSX_V2FH;
nmp->nm_head->n_fhp = nmp->nm_fh;
nmp->nm_head->n_fhsize = nmp->nm_fhsize;
nmp->nm_so = nmp->nm_rpcclnt->rc_so;
nmp->nm_so = nmp->nm_rpcclnt->rc_so;
/* Get the file attributes */
memset(&getattr, 0, sizeof(struct FS3args));
memset(&resok, 0, sizeof(struct rpc_reply_getattr));
@ -1164,35 +1177,53 @@ int mountnfs(struct nfs_args *argp, void **handle)
getattr.fsroot.handle = nmp->nm_fh;
error = nfs_request(nmp, NFSPROC_GETATTR, (FAR const void *)&getattr,
(FAR void*)&resok);
(FAR void*)&resok, sizeof(struct rpc_reply_getattr));
if (error)
{
fdbg("ERROR: nfs_request failed: %d\n", error);
goto bad;
}
memcpy(&np->n_fattr, &resok, sizeof(struct rpc_reply_getattr));
memcpy(&nmp->nm_fattr, &resok, sizeof(struct rpc_reply_getattr));
/* Save the file attributes */
fvdbg("value %d \n", sizeof(struct rpc_reply_getattr));
/* fvdbg("type %d \n", fxdr_unsigned(uint32_t, resok.attr.fa_type));
fvdbg("mode %d \n", fxdr_unsigned(uint32_t, resok.attr.fa_mode));
fvdbg("Type %d \n", fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_type));
fvdbg("mode %d \n", fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode));*/
memcpy(&np->n_fattr, &resok.attr, sizeof(struct nfs_fattr));
memcpy(&nmp->nm_fattr, &resok.attr, sizeof(struct nfs_fattr));
/* Mounted! */
*handle = (void*)nmp;
nfs_semgive(nmp);
fvdbg("Successfully mounted\n");
return 0;
bad:
nfs_disconnect(nmp);
sem_destroy(&nmp->nm_sem);
kfree(nmp->nm_head);
kfree(nmp->nm_so);
kfree(nmp->nm_rpcclnt);
kfree(nmp);
/* Free all memory that was successfully allocated */
if (np)
{
kfree(np);
}
if (nmp)
{
/* Disconnect from the server */
nfs_disconnect(nmp);
/* Free connection-related resources */
sem_destroy(&nmp->nm_sem);
if (nmp->nm_so)
{
kfree(nmp->nm_so);
}
if (nmp->nm_rpcclnt)
{
kfree(nmp->nm_rpcclnt);
}
kfree(nmp);
}
return error;
}
@ -1283,7 +1314,7 @@ bad:
static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
{
struct nfs_statfs sfp;
struct rpc_reply_fsstat sfp;
struct nfsmount *nmp;
int error = 0;
uint64_t tquad;
@ -1319,26 +1350,28 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
nfsstats.rpccnt[NFSPROC_FSSTAT]++;
memset(&fsstat, 0, sizeof(struct FS3args));
memset(&sfp, 0, sizeof(struct rpc_reply_fsstat));
fsstat.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
fsstat.fsroot.handle = nmp->nm_fh;
error = nfs_request(nmp, NFSPROC_FSSTAT, (FAR const void *)&fsstat, (FAR void *) &sfp);
error = nfs_request(nmp, NFSPROC_FSSTAT, (FAR const void *)&fsstat,
(FAR void *) &sfp, sizeof(struct rpc_reply_fsstat));
if (error)
{
goto errout_with_semaphore;
}
nmp->nm_head->n_fattr = sfp.obj_attributes;
nmp->nm_head->n_fattr = sfp.fsstat.obj_attributes;
sbp->f_bsize = NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.sf_tbytes);
tquad = fxdr_hyper(&sfp.fsstat.sf_tbytes);
sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.sf_fbytes);
tquad = fxdr_hyper(&sfp.fsstat.sf_fbytes);
sbp->f_bfree = tquad / (uint64_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.sf_abytes);
tquad = fxdr_hyper(&sfp.fsstat.sf_abytes);
sbp->f_bavail = tquad / (uint64_t) NFS_FABLKSIZE;
tquad = fxdr_hyper(&sfp.sf_tfiles);
tquad = fxdr_hyper(&sfp.fsstat.sf_tfiles);
sbp->f_files = tquad;
tquad = fxdr_hyper(&sfp.sf_ffiles);
tquad = fxdr_hyper(&sfp.fsstat.sf_ffiles);
sbp->f_ffree = tquad;
sbp->f_namelen = NAME_MAX;
@ -1359,7 +1392,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
struct nfsmount *nmp;
struct nfsnode *np;
struct REMOVE3args remove;
struct REMOVE3resok resok;
struct rpc_reply_remove resok;
int error = 0;
/* Sanity checks */
@ -1394,13 +1427,14 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
nfsstats.rpccnt[NFSPROC_REMOVE]++;
memset(&remove, 0, sizeof(struct REMOVE3args));
memset(&resok, 0, sizeof(struct rpc_reply_remove));
remove.object.dir.length = txdr_unsigned(np->n_fhsize);
remove.object.dir.handle = np->n_fhp;
remove.object.length = txdr_unsigned(64);
strncpy(remove.object.name, relpath, 64);
error = nfs_request(nmp, NFSPROC_REMOVE, (FAR const void *)&remove,
(FAR void*)&resok);
(FAR void*)&resok, sizeof(struct rpc_reply_remove));
/* Kludge City: If the first reply to the remove rpc is lost..
* the reply to the retransmitted request will be ENOENT
@ -1418,7 +1452,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
goto errout_with_semaphore;
}
np->n_fattr = resok.dir_wcc.after;
//np->n_fattr = resok.dir_wcc.after;
np->n_flag |= NMODIFIED;
}
@ -1442,7 +1476,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
struct nfsmount *nmp;
struct nfsnode *np;
struct MKDIR3args mkir;
struct MKDIR3resok resok;
struct rpc_reply_mkdir resok;
int error = 0;
/* Sanity checks */
@ -1465,6 +1499,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
nfsstats.rpccnt[NFSPROC_MKDIR]++;
memset(&mkir, 0, sizeof(struct MKDIR3args));
memset(&resok, 0, sizeof(struct rpc_reply_mkdir));
mkir.where.dir.length = txdr_unsigned(np->n_fhsize);
mkir.where.dir.handle = np->n_fhp;
mkir.where.length = txdr_unsigned(64);
@ -1484,19 +1519,19 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
mkir.attributes = sp;
error = nfs_request(nmp, NFSPROC_MKDIR, (FAR const void *)&mkir,
(FAR void *)&resok);
(FAR void *)&resok, sizeof(struct rpc_reply_mkdir));
if (error)
{
goto errout_with_semaphore;
}
np->n_open = true;
np->nfsv3_type = fxdr_unsigned(uint32_t, resok.obj_attributes.fa_type);
/* np->nfsv3_type = fxdr_unsigned(uint32_t, resok.obj_attributes.fa_type);
np->n_fhp = resok.fshandle.handle;
np->n_size = fxdr_hyper(&resok.obj_attributes.fa3_size);
np->n_fattr = resok.obj_attributes;
fxdr_nfsv3time(&resok.obj_attributes.fa3_mtime, &np->n_mtime)
np->n_ctime = fxdr_hyper(&resok.obj_attributes.fa3_ctime);
np->n_ctime = fxdr_hyper(&resok.obj_attributes.fa3_ctime);*/
np->n_flag |= NMODIFIED;
NFS_INVALIDATE_ATTRCACHE(np);
@ -1518,7 +1553,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
struct nfsmount *nmp;
struct nfsnode *np;
struct RMDIR3args rmdir;
struct RMDIR3resok resok;
struct rpc_reply_rmdir resok;
int error = 0;
/* Sanity checks */
@ -1548,13 +1583,14 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
nfsstats.rpccnt[NFSPROC_RMDIR]++;
memset(&rmdir, 0, sizeof(struct RMDIR3args));
memset(&resok, 0, sizeof(struct rpc_reply_rmdir));
rmdir.object.dir.length = txdr_unsigned(np->n_fhsize);
rmdir.object.dir.handle = np->n_fhp;
rmdir.object.length = txdr_unsigned(64);
strncpy(rmdir.object.name, relpath, 64);
error = nfs_request(nmp, NFSPROC_RMDIR, (FAR const void *)&rmdir,
(FAR void *)&resok);
(FAR void *)&resok, sizeof(struct rpc_reply_rmdir));
if (error == ENOENT)
{
error = 0;
@ -1565,7 +1601,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
goto errout_with_semaphore;
}
np->n_fattr = resok.dir_wcc.after;
//np->n_fattr = resok.dir_wcc.after;
np->n_flag |= NMODIFIED;
}
@ -1589,7 +1625,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
struct nfsmount *nmp;
struct nfsnode *np;
struct RENAME3args rename;
struct RENAME3resok resok;
struct rpc_reply_rename resok;
int error = 0;
/* Sanity checks */
@ -1619,6 +1655,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
nfsstats.rpccnt[NFSPROC_RENAME]++;
memset(&rename, 0, sizeof(struct RENAME3args));
memset(&resok, 0, sizeof(struct rpc_reply_rename));
rename.from.dir.length = txdr_unsigned(np->n_fhsize);
rename.from.dir.handle = np->n_fhp;
rename.from.length = txdr_unsigned(64);
@ -1629,7 +1666,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
strncpy(rename.to.name, newrelpath, 64);
error = nfs_request(nmp, NFSPROC_RENAME, (FAR const void *)&rename,
(FAR void *)&resok);
(FAR void *)&resok, sizeof(struct rpc_reply_rename));
/* ENOENT => 0 assuming that it is a reply to a retry. */
@ -1643,7 +1680,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
goto errout_with_semaphore;
}
np->n_fattr = resok.todir_wcc.after;
//np->n_fattr = resok.todir_wcc.after;
np->n_flag |= NMODIFIED;
NFS_INVALIDATE_ATTRCACHE(np);
@ -1661,10 +1698,10 @@ errout_with_semaphore:
static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *buf)
{
struct nfsv3_fsinfo fsp;
struct rpc_reply_fsinfo fsp;
struct FS3args fsinfo;
struct nfsmount *nmp;
uint32_t pref, max;
//uint32_t pref, max;
int error = 0;
/* Sanity checks */
@ -1685,19 +1722,21 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b
}
memset(buf, 0, sizeof(struct stat));
memset(&fsinfo, 0, sizeof(struct FS3args));
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;
error = nfs_request(nmp, NFSPROC_FSINFO, (FAR const void *)&fsinfo,
(FAR void *)&fsp);
(FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo));
if (error)
{
goto errout_with_semaphore;
}
//nmp->nm_fattr = fsp.obj_attributes;
pref = fxdr_unsigned(uint32_t, fsp.fs_wtpref);
/* pref = fxdr_unsigned(uint32_t, fsp.fs_wtpref);
if (pref < nmp->nm_wsize)
{
nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
@ -1741,7 +1780,7 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath, struct stat *b
nmp->nm_readdirsize = max;
}
}
*/
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;

View File

@ -543,7 +543,7 @@ int rpcclnt_reconnect(struct rpctask *);
void rpcclnt_disconnect(struct rpcclnt *);
int rpcclnt_umount(struct rpcclnt *);
void rpcclnt_safedisconnect(struct rpcclnt *);
int rpcclnt_request(struct rpcclnt *, int, int, int, void *, FAR const void *);
int rpcclnt_request(struct rpcclnt *, int, int, int, void *, FAR const void *, size_t);
#undef COMP
#ifdef COMP
int rpcclnt_cancelreqs(struct rpcclnt *);

View File

@ -207,8 +207,8 @@ static dq_queue_t rpctask_q;
static int rpcclnt_send(struct socket *, struct sockaddr *, int, int, void *,
struct rpctask *);
static int rpcclnt_receive(struct rpctask *, struct sockaddr *, int, int,
void *);//, struct rpc_call *);
static int rpcclnt_reply(struct rpctask *, int, int, void *);
void *, size_t);//, struct rpc_call *);
static int rpcclnt_reply(struct rpctask *, int, int, void *, size_t);
#ifdef CONFIG_NFS_TCPIP
static int rpcclnt_sndlock(int *, struct rpctask *);
static void rpcclnt_sndunlock(int *);
@ -459,17 +459,20 @@ rpcclnt_send(struct socket *so, struct sockaddr *nam, int procid, int prog,
*/
static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
int proc, int program, void *reply)//, struct rpc_call *call)
int proc, int program, void *reply, size_t len)
//, struct rpc_call *call)
{
struct socket *so;
#ifdef CONFIG_NFS_TCPIP
uint32_t len;
int sotype;
#endif
int error = 0;
int ret = 0;
int rcvflg;
#ifdef CONFIG_NFS_TCPIP
int errval;
/* Set up arguments for soreceive() */
sotype = rep->r_rpcclnt->rc_sotype;
@ -486,6 +489,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep);
if (error != 0)
{
fdbg("ERROR: rpcclnt_sndlock failed: %d\n", error);
return error;
}
@ -536,6 +540,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
if (sotype == SOCK_STREAM)
{
errval = 0;
do
{
socklen_t fromlen = sizeof(*rep->r_rpcclnt->rc_name)
@ -543,16 +548,21 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
error = psock_recvfrom(so, reply, sizeof(*reply),
&rcvflg, rep->r_rpcclnt->rc_name,
&fromlen);
if (error == EWOULDBLOCK && rep && (rep->r_flags & TASK_SOFTTERM))
if (error < 0)
{
RPC_RETURN(EINTR);
errval = errno;
if (errval == EWOULDBLOCK && rep &&
(rep->r_flags & TASK_SOFTTERM))
{
RPC_RETURN(EINTR);
}
}
}
while (error == EWOULDBLOCK);
while (errval == EWOULDBLOCK);
if (error == 0)
{
fdbg("short receive from rpc server %s\n",
fdbg("ERROR: Short receive from rpc server %s\n",
rep->r_rpcclnt->rc_prog->prog_name);
error = EPIPE;
}
@ -566,12 +576,14 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
if (len > RPC_MAXPACKET)
{
fdbg("%s (%d) from rpc server %s\n",
fdbg("ERROR %s (%d) from rpc server %s\n",
"impossible packet length",
len, rep->r_rpcclnt->rc_prog->prog_name);
error = EFBIG;
goto errout;
}
errval = 0
do
{
socklen_t fromlen = sizeof(*rep->r_rpcclnt->rc_name);
@ -579,17 +591,22 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
error = psock_recvfrom(so, reply, sizeof(*reply),
&rcvflg, rep->r_rpcclnt->rc_name,
&fromlen);
if (error < 0)
{
errval = errno;
fdbg("ERROR: psock_recvfrom failed: %d\n", errval);
}
}
while (error == EWOULDBLOCK || error == EINTR || error == ERESTART);
while (errval == EWOULDBLOCK || errval == EINTR || errval == ERESTART);
if (error == 0)
{
fdbg("short receive from rpc server %s\n",
fdbg("ERROR: Short receive from rpc server %s\n",
rep->r_rpcclnt->rc_prog->prog_name);
error = EPIPE;
}
if (error != 0)
if (error < 0)
{
goto errout;
}
@ -603,6 +620,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
* them away so we know what is going on.
*/
errval = 0;
do
{
socklen_t fromlen = sizeof(*rep->r_rpcclnt->rc_name);
@ -611,13 +629,15 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
rep->r_rpcclnt->rc_name, &fromlen);
if (error == EWOULDBLOCK && rep)
{
errval = errno;
fdbg("ERROR: psock_recvfrom failed: %d\n", errval);
if (rep->r_flags & TASK_SOFTTERM)
{
return EINTR;
}
}
}
while (error == EWOULDBLOCK || (!error));
while (errval == EWOULDBLOCK || !error);
if ((rcvflg & MSG_EOR) == 0)
{
@ -635,7 +655,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
{
if (error != EPIPE)
{
fdbg("receive error %d from rpc server %s\n",
fdbg("ERROR: Receive error %d from rpc server %s\n",
error, rep->r_rpcclnt->rc_prog->prog_name);
}
@ -660,147 +680,17 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
RPC_RETURN(EACCES);
}
socklen_t fromlen = sizeof(*aname);
socklen_t fromlen = sizeof(struct sockaddr);
rcvflg = 0;
if (program == PMAPPROG)
ret = psock_recvfrom(so, reply, len, rcvflg, aname, &fromlen);
if (ret > 0)
{
if (proc == PMAPPROC_GETPORT)
{
struct rpc_reply_pmap *replymsg = (struct rpc_reply_pmap *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
else if (proc == PMAPPROC_UNSET)
{
struct rpc_reply_pmap *replymsg = (struct rpc_reply_pmap *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
}
else if (program == RPCPROG_MNT)
{
if (proc== RPCMNT_UMOUNT)
{
struct rpc_reply_mount *replymsg = (struct rpc_reply_mount *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
else if (proc == RPCMNT_MOUNT)
{
struct rpc_reply_mount *replymsg = (struct rpc_reply_mount *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
}
else if (program == NFS_PROG)
{
switch (proc)
{
case NFSPROC_CREATE:
{
struct rpc_reply_create *replymsg = (struct rpc_reply_create *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_READ:
{
struct rpc_reply_read *replymsg = (struct rpc_reply_read *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_WRITE:
{
struct rpc_reply_write *replymsg = (struct rpc_reply_write *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_READDIR:
{
struct rpc_reply_readdir *replymsg = (struct rpc_reply_readdir *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_FSSTAT:
{
struct rpc_reply_fsstat *replymsg = (struct rpc_reply_fsstat *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_GETATTR:
{
struct rpc_reply_getattr *replymsg = (struct rpc_reply_getattr *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_REMOVE:
{
struct rpc_reply_remove *replymsg = (struct rpc_reply_remove *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_MKDIR:
{
struct rpc_reply_mkdir *replymsg = (struct rpc_reply_mkdir *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_RMDIR:
{
struct rpc_reply_rmdir *replymsg = (struct rpc_reply_rmdir *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_RENAME:
{
struct rpc_reply_rename *replymsg = (struct rpc_reply_rename *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
case NFSPROC_FSINFO:
{
struct rpc_reply_fsinfo *replymsg = (struct rpc_reply_fsinfo *)reply;
error = psock_recvfrom(so, replymsg, sizeof(*replymsg), rcvflg,
aname, &fromlen);
}
break;
default:
break;
}
}
fvdbg("psock_recvfrom returns %d\n", error);
if (error > 0)
{
RPC_RETURN(0);
RPC_RETURN(ret);
}
}
RPC_RETURN(ENONET);
fvdbg("Returning %d\n", ret);
RPC_RETURN(ret);
}
/* Implement receipt of reply on a socket. We must search through the list of
@ -808,7 +698,7 @@ 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)
static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, void *reply, size_t len)
{
struct rpctask *rep;
struct rpc_reply_header replyheader;
@ -837,7 +727,7 @@ static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog, void *repl
#endif
/* Get the next Rpc reply off the socket */
error = rpcclnt_receive(myrep, rpc->rc_name, procid, prog, reply);
error = rpcclnt_receive(myrep, rpc->rc_name, procid, prog, reply, len);
#ifdef CONFIG_NFS_TCPIP
rpcclnt_rcvunlock(&rpc->rc_flag);
#endif
@ -1173,7 +1063,6 @@ void rpcclnt_init(void)
//rpcclnt_timer(NULL, callmgs);
fvdbg("rpc initialized\n");
return;
}
/*
@ -1202,6 +1091,9 @@ int rpcclnt_connect(struct rpcclnt *rpc)
struct rpc_reply_mount mdata;
struct timeval tv;
uint16_t tport;
int errval;
fvdbg("Connecting\n");
/* Create the socket */
@ -1213,32 +1105,35 @@ int rpcclnt_connect(struct rpcclnt *rpc)
so = (struct socket *)kzalloc(sizeof(struct socket));
if (!so)
{
fdbg("Failed to allocate socket structure\n");
fdbg("ERROR: Failed to allocate socket structure\n");
return -ENOMEM;
}
error = psock_socket(saddr->sa_family, rpc->rc_sotype, rpc->rc_soproto, so);
if (error != 0)
if (error < 0)
{
fdbg("error %d in psock_socket()", error);
errval = errno;
fdbg("ERROR: psock_socket failed: %d", errval);
RPC_RETURN(error);
}
so->s_crefs = 1;
rpc->rc_so = so;
so->s_crefs = 1;
rpc->rc_so = so;
rpc->rc_soflags = so->s_flags;
/* Always set receive timeout to detect server crash and reconnect.
* Otherwise, we can get stuck in psock_receive forever.
*/
tv.tv_sec = 1;
tv.tv_sec = 1;
tv.tv_usec = 0;
error = psock_setsockopt(rpc->rc_so, SOL_SOCKET, SO_RCVTIMEO,
(const void *)&tv, sizeof(tv));
if (error != 0)
if (error < 0)
{
errval = errno;
fdbg("ERROR: psock_setsockopt failed: %d\n", errval);
goto bad;
}
@ -1247,21 +1142,27 @@ int rpcclnt_connect(struct rpcclnt *rpc)
* filehandle disclosure through UDP port capture.
*/
sin.sin_family = AF_INET;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
tport = 1024;
tport = 1024;
errval = 0;
do
{
tport--;
sin.sin_port = htons(tport);
error = psock_bind(rpc->rc_so, (struct sockaddr *)&sin, sizeof(sin));
if (error < 0)
{
errval = errno;
fdbg("ERROR: psock_bind failed: %d\n", errval);
}
}
while (error == EADDRINUSE && tport > 1024 / 2);
while (errval == EADDRINUSE && tport > 1024 / 2);
if (error)
{
fdbg("bind failed\n");
fdbg("ERROR: psock_bind failed: %d\n", errval);
goto bad;
}
@ -1280,10 +1181,10 @@ int rpcclnt_connect(struct rpcclnt *rpc)
#endif
{
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error)
if (error < 0)
{
fdbg("psock_connect to PMAP port returns %d", error);
errval = errno;
fdbg("ERROR: psock_connect to PMAP port failed: %d", errval);
goto bad;
}
@ -1291,17 +1192,19 @@ int rpcclnt_connect(struct rpcclnt *rpc)
* Get port number for MOUNTD.
*/
memset(&sdata, 0, sizeof(sdata));
memset(&rdata, 0, sizeof(rdata));
memset(&sdata, 0, sizeof(struct call_args_pmap));
memset(&rdata, 0, sizeof(struct rpc_reply_pmap));
sdata.prog = txdr_unsigned(RPCPROG_MNT);
sdata.vers = txdr_unsigned(RPCMNT_VER1);
sdata.proc = txdr_unsigned(IPPROTO_UDP);
sdata.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&rdata, (FAR const void *)&sdata);
(FAR void *)&rdata, (FAR const void *)&sdata,
sizeof(struct rpc_reply_pmap));
if (error != 0)
{
fdbg("ERROR: rpcclnt_request failed: %d\n", error);
goto bad;
}
@ -1309,47 +1212,51 @@ int rpcclnt_connect(struct rpcclnt *rpc)
sa->sin_port = htons(fxdr_unsigned(uint32_t, rdata.pmap.port));
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error)
if (error < 0)
{
fdbg("psock_connect MOUNTD port returns %d\n", error);
errval = errno;
fdbg("ERROR: psock_connect MOUNTD port failed: %d\n", errval);
goto bad;
}
/* Do RPC to mountd. */
memset(&mountd, 0, sizeof(mountd));
memset(&mdata, 0, sizeof(mdata));
memset(&mountd, 0, sizeof(struct call_args_mount));
memset(&mdata, 0, sizeof(struct rpc_reply_mount));
strncpy(mountd.rpath, rpc->rc_path, 90);
mountd.len = txdr_unsigned(sizeof(mountd.rpath));
error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1,
(FAR void *)&mdata, (FAR const void *)&mountd);
(FAR void *)&mdata, (FAR const void *)&mountd,
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);
if (error != 0)
{
fdbg("error mounting with the server %d\n", error);
fdbg("ERROR: fxdr_unsigned failed: %d\n", error);
goto bad;
}
rpc->rc_fh = mdata.mount.fhandle;
bcopy(&mdata.mount.fhandle, &rpc->rc_fh, sizeof(nfsfh_t));
/* Do the RPC to get a dynamic bounding with the server using PMAP.
* NFS port in the socket.
*/
memset(&sdata, 0, sizeof(sdata));
memset(&rdata, 0, sizeof(rdata));
memset(&sdata, 0, sizeof(struct call_args_pmap));
memset(&rdata, 0, sizeof(struct rpc_reply_pmap));
sa->sin_port = htons(PMAPPORT);
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error)
if (error < 0)
{
fdbg("psock_connect PMAP port returns %d\n", error);
errval = errno;
fdbg("ERROR: psock_connect PMAP port failed: %d\n", errval);
goto bad;
}
@ -1359,9 +1266,11 @@ int rpcclnt_connect(struct rpcclnt *rpc)
sdata.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(FAR void *)&rdata, (FAR const void *)&sdata);
(FAR void *)&rdata, (FAR const void *)&sdata,
sizeof(struct rpc_reply_pmap));
if (error != 0)
{
fdbg("ERROR: rpcclnt_request failed: %d\n", error);
goto bad;
}
@ -1383,6 +1292,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
rpc->rc_sent = 0;
rpc->rc_timeouts = 0;
fvdbg("Succeeded\n");
RPC_RETURN(0);
bad:
@ -1405,13 +1315,19 @@ int rpcclnt_reconnect(struct rpctask *rep)
int error;
rpcclnt_disconnect(rpc);
while ((error = rpcclnt_connect(rpc)) != 0)
do
{
if (error == EINTR || error == ERESTART)
error = rpcclnt_connect(rpc);
if (error != 0)
{
return EINTR;
fdbg("ERROR: rpcclnt_connect failed: %d\n", error);
if (error == EINTR || error == ERESTART)
{
return EINTR;
}
}
}
while (error != 0)
/* Loop through outstanding request list and fix up all
* requests on old socket.
@ -1458,8 +1374,8 @@ int rpcclnt_umount(struct rpcclnt *rpc)
* Get port number for MOUNTD.
*/
memset(&sdata, 0, sizeof(sdata));
memset(&rdata, 0, sizeof(rdata));
memset(&sdata, 0, sizeof(struct call_args_pmap));
memset(&rdata, 0, sizeof(struct rpc_reply_pmap));
sa->sin_port = htons(PMAPPORT);
error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
@ -1475,7 +1391,8 @@ int rpcclnt_umount(struct rpcclnt *rpc)
sdata.port = 0;
error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
(void *)&rdata, (FAR const void *)&sdata);
(void *)&rdata, (FAR const void *)&sdata,
sizeof(struct rpc_reply_pmap));
if (error != 0)
{
goto bad;
@ -1492,14 +1409,15 @@ int rpcclnt_umount(struct rpcclnt *rpc)
/* Do RPC to umountd. */
memset(&mountd, 0, sizeof(mountd));
memset(&mdata, 0, sizeof(mdata));
memset(&mountd, 0, sizeof(struct call_args_mount));
memset(&mdata, 0, sizeof(struct rpc_reply_mount));
strncpy(mountd.rpath, rpc->rc_path, 92);
mountd.len = txdr_unsigned(sizeof(mountd.rpath));
error = rpcclnt_request(rpc, RPCMNT_UMOUNT, RPCPROG_MNT, RPCMNT_VER1,
(void *)&mdata, (FAR const void *)&mountd);
(void *)&mdata, (FAR const void *)&mountd,
sizeof(struct rpc_reply_mount));
if (error != 0)
{
goto bad;
@ -1542,155 +1460,48 @@ void rpcclnt_safedisconnect(struct rpcclnt *rpc)
*/
int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
void *dataout, FAR const void *datain)
void *dataout, FAR const void *datain, size_t len)
{
struct rpc_reply_header replymgs;
struct rpc_reply_header replyheader;
struct rpctask *task = NULL;
struct xidr value;
struct rpc_call_pmap pmap;
struct rpc_call_mount mountd;
struct rpc_call_create create;
struct rpc_call_write write;
struct rpc_call_read read;
struct rpc_call_remove removef;
struct rpc_call_rename renamef;
struct rpc_call_mkdir mkdir;
struct rpc_call_rmdir rmdir;
struct rpc_call_readdir readdir;
struct rpc_call_fs fs;
void *msgcall = NULL;
int error = 0;
/* Set aside memory on the stack to hold the largest call message */
if (prog == PMAPPROG)
{
if (procnum == PMAPPROC_GETPORT)
{
memset(&pmap, 0, sizeof(struct rpc_call_pmap));
msgcall = &pmap;
}
else if (procnum == PMAPPROC_UNSET)
{
memset(&pmap, 0, sizeof(struct rpc_call_pmap));
msgcall = &pmap;
}
}
else if (prog == RPCPROG_MNT)
{
if (procnum == RPCMNT_UMOUNT)
{
memset(&mountd, 0, sizeof(struct rpc_call_mount));
msgcall = &mountd;
}
else if (procnum == RPCMNT_MOUNT)
{
memset(&mountd, 0, sizeof(struct rpc_call_mount));
msgcall = &mountd;
}
}
else if (prog == NFS_PROG)
{
switch (procnum)
{
case NFSPROC_CREATE:
{
memset(&create, 0, sizeof(struct rpc_call_create));
msgcall = &create;
}
break;
union
{
struct rpc_call_pmap pmap;
struct rpc_call_mount mountd;
struct rpc_call_create create;
struct rpc_call_write write;
struct rpc_call_read read;
struct rpc_call_remove removef;
struct rpc_call_rename renamef;
struct rpc_call_mkdir mkdir;
struct rpc_call_rmdir rmdir;
struct rpc_call_readdir readdir;
struct rpc_call_fs fs;
} u;
case NFSPROC_READ:
{
memset(&read, 0, sizeof(struct rpc_call_read));
msgcall = &read;
}
break;
/* Clear the call message memory */
case NFSPROC_WRITE:
{
memset(&write, 0, sizeof(struct rpc_call_write));
msgcall = &write;
}
break;
case NFSPROC_RENAME:
{
memset(&renamef, 0, sizeof(struct rpc_call_rename));
msgcall = &renamef;
}
break;
case NFSPROC_REMOVE:
{
memset(&removef, 0, sizeof(struct rpc_call_remove));
msgcall = &removef;
}
break;
case NFSPROC_MKDIR:
{
memset(&mkdir, 0, sizeof(struct rpc_call_mkdir));
msgcall = &mkdir;
}
break;
case NFSPROC_RMDIR:
{
memset(&rmdir, 0, sizeof(struct rpc_call_rmdir));
msgcall = &rmdir;
}
break;
case NFSPROC_READDIR:
{
memset(&readdir, 0, sizeof(struct rpc_call_readdir));
msgcall = &readdir;
}
break;
case NFSPROC_FSSTAT:
{
memset(&fs, 0, sizeof(struct rpc_call_fs));
msgcall = &fs;
}
break;
case NFSPROC_GETATTR:
{
memset(&fs, 0, sizeof(struct rpc_call_fs));
msgcall = &fs;
}
break;
case NFSPROC_FSINFO:
{
memset(&fs, 0, sizeof(struct rpc_call_fs));
msgcall = &fs;
}
break;
default:
{
error = ESRCH;
goto rpcmout;
}
}
}
memset(&u, 0, sizeof(u));
/* Create an instance of the task state structure */
task = (struct rpctask *)kzalloc(sizeof(struct rpctask));
if (!task)
{
fdbg("Failed to allocate reply msg structure\n");
fdbg("ERROR: Failed to allocate reply msg structure\n");
return -ENOMEM;
}
error = rpcclnt_buildheader(rpc, procnum, prog, version, &value, datain, msgcall);
error = rpcclnt_buildheader(rpc, procnum, prog, version, &value, datain, (FAR void*)&u);
if (error)
{
fdbg("building call header error");
fdbg("ERROR: Building call header error");
goto rpcmout;
}
@ -1746,7 +1557,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
if (error == 0)
{
error = rpcclnt_send(rpc->rc_so, rpc->rc_name, procnum, prog,
msgcall, task);
(FAR void*)&u, task);
#ifdef CONFIG_NFS_TCPIP
if (rpc->rc_soflags & PR_CONNREQUIRED)
@ -1771,7 +1582,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
if (error == 0 || error == EPIPE)
{
error = rpcclnt_reply(task, procnum, prog, dataout);
error = rpcclnt_reply(task, procnum, prog, dataout, len);
}
fvdbg("out for reply %d\n", error);
@ -1961,7 +1772,7 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
sizeof(*rpc->rc_name));
}
if (!error)
if (error < 0)
{
/* Iff first send, start timing else turn
* timing off, backoff timer and divide

View File

@ -63,26 +63,26 @@
struct nfs_args
{
uint8_t version; /* args structure version number */
struct sockaddr addr; /* file server address */
uint8_t addrlen; /* length of address */
uint8_t version; /* Args structure version number */
uint8_t addrlen; /* Length of address */
uint8_t sotype; /* Socket type */
uint8_t proto; /* and Protocol */
int flags; /* flags */
int wsize; /* write size in bytes */
int rsize; /* read size in bytes */
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 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 *path; /* server's path of the directory being mount */
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 */
char *path; /* Server's path of the directory being mount */
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 */
struct sockaddr addr; /* File server address (requires 32-bit alignment) */
};
/****************************************************************************