summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-30 23:51:23 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-04-30 23:51:23 +0000
commit2812a9f1df22438f8ccd30dd5e5dc48dc3465b3f (patch)
treeeabf923391d4e2e5bffcc2fb137dadae3d3d0283
parent1d3abc8d480110850480ca27560e6a9672052e0b (diff)
downloadnuttx-2812a9f1df22438f8ccd30dd5e5dc48dc3465b3f.tar.gz
nuttx-2812a9f1df22438f8ccd30dd5e5dc48dc3465b3f.tar.bz2
nuttx-2812a9f1df22438f8ccd30dd5e5dc48dc3465b3f.zip
NFS update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4680 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/fs/nfs/nfs_socket.c65
-rw-r--r--nuttx/fs/nfs/nfs_vfsops.c9
-rw-r--r--nuttx/fs/nfs/rpc.h4
-rw-r--r--nuttx/fs/nfs/rpc_clnt.c95
4 files changed, 112 insertions, 61 deletions
diff --git a/nuttx/fs/nfs/nfs_socket.c b/nuttx/fs/nfs/nfs_socket.c
index 5e130d3b5..d0f4e36b2 100644
--- a/nuttx/fs/nfs/nfs_socket.c
+++ b/nuttx/fs/nfs/nfs_socket.c
@@ -45,6 +45,7 @@
#include <stdlib.h>
#include <string.h>
#include <debug.h>
+#include <nuttx/kmalloc.h>
#include "nfs.h"
#include "rpc.h"
@@ -112,50 +113,57 @@ void nfs_init(void)
int nfs_connect(struct nfsmount *nmp)
{
- struct rpcclnt rpc;
+ struct rpcclnt *rpc;
if (nmp == NULL)
{
return EFAULT;
}
- //memset(rpc, 0, sizeof(*rpc));
+ /* Create an instance of the rpc state structure */
- rpc.rc_prog = &nfs3_program;
+ rpc = (struct rpcclnt *)kzalloc(sizeof(struct rpcclnt));
+ if (!rpc)
+ {
+ fdbg("Failed to allocate rpc structure\n");
+ return -ENOMEM;
+ }
+
+ rpc->rc_prog = &nfs3_program;
nvdbg("nfs connect!\n");
/* translate nfsmnt flags -> rpcclnt flags */
- rpc.rc_flag = 0;
- nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, SOFT);
- nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, INT);
- nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, NOCONN);
- nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, DUMBTIMR);
+ rpc->rc_flag = 0;
+ nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, SOFT);
+ nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, INT);
+ nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, NOCONN);
+ nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, DUMBTIMR);
//rpc->rc_flag |= RPCCLNT_REDIRECT; /* Make this a mount option. */
- rpc.rc_authtype = RPCAUTH_NULL; /* for now */
+ rpc->rc_authtype = RPCAUTH_NULL; /* for now */
//rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname;
- rpc.rc_name = nmp->nm_nam;
+ rpc->rc_name = nmp->nm_nam;
- rpc.rc_sotype = nmp->nm_sotype;
- rpc.rc_soproto = nmp->nm_soproto;
- rpc.rc_rsize = (nmp->nm_rsize > nmp->nm_readdirsize) ?
+ rpc->rc_sotype = nmp->nm_sotype;
+ rpc->rc_soproto = nmp->nm_soproto;
+ rpc->rc_rsize = (nmp->nm_rsize > nmp->nm_readdirsize) ?
nmp->nm_rsize : nmp->nm_readdirsize;
- rpc.rc_wsize = nmp->nm_wsize;
- rpc.rc_deadthresh = nmp->nm_deadthresh;
- rpc.rc_timeo = nmp->nm_timeo;
- rpc.rc_retry = nmp->nm_retry;
+ rpc->rc_wsize = nmp->nm_wsize;
+ rpc->rc_deadthresh = nmp->nm_deadthresh;
+ rpc->rc_timeo = nmp->nm_timeo;
+ rpc->rc_retry = nmp->nm_retry;
/* v3 need to use this */
- rpc.rc_proctlen = 0;
- rpc.rc_proct = NULL;
+ rpc->rc_proctlen = 0;
+ rpc->rc_proct = NULL;
- nmp->nm_rpcclnt = &rpc;
+ nmp->nm_rpcclnt = rpc;
- return rpcclnt_connect(&rpc);
+ return rpcclnt_connect(rpc);
}
/* NFS disconnect. Clean up and unlink. */
@@ -175,16 +183,21 @@ void nfs_safedisconnect(struct nfsmount *nmp)
int nfs_request(struct nfsmount *nmp, int procnum, void *datain, void *dataout)
{
int error;
- struct rpcclnt *clnt;
+ struct rpcclnt *clnt= nmp->nm_rpcclnt;
struct rpc_reply *reply;
int trylater_delay;
- clnt = nmp->nm_rpcclnt;
+ /* Create an instance of the reply state structure */
+ reply = (struct rpc_reply *)kzalloc(sizeof(struct rpc_reply));
+ if (!reply)
+ {
+ fdbg("Failed to allocate reply structure\n");
+ return -ENOMEM;
+ }
+
tryagain:
- memset(reply, 0, sizeof(struct rpc_reply));
-
if ((error = rpcclnt_request(clnt, procnum, reply, datain)) != 0)
{
goto out;
@@ -204,6 +217,7 @@ tryagain:
{
trylater_delay = NFS_MAXTIMEO;
}
+
goto tryagain;
}
@@ -224,6 +238,7 @@ tryagain:
goto out;
}
+
return 0;
out:
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
index 113df67b2..bdd388ec6 100644
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ b/nuttx/fs/nfs/nfs_vfsops.c
@@ -981,7 +981,7 @@ void nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
*
****************************************************************************/
-int mountnfs(struct nfs_args *argp, struct sockaddr *nam, void **handle)
+int mountnfs(struct nfs_args *argp, void **handle)
{
struct nfsmount *nmp;
int error;
@@ -1021,7 +1021,7 @@ int mountnfs(struct nfs_args *argp, struct sockaddr *nam, void **handle)
//memmove(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
//bcopy(pth, nmp->nm_mntonname, 90);
//memmove(argp, &mp->mnt_stat.mount_info.nfs_args, sizeof(*argp));
- nmp->nm_nam = nam;
+ nmp->nm_nam = argp->addr;
nfs_decode_args(nmp, argp);
/* Set up the sockets and per-host congestion */
@@ -1069,7 +1069,6 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle)
{
int error;
struct nfs_args args;
- struct sockaddr *nam;
bcopy(data, &args, sizeof(struct nfs_args));
if (args.version == NFS_ARGSVERSION)
@@ -1091,8 +1090,7 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle)
return -EINVAL;
}
- nam = args.addr;
- error = mountnfs(&args, nam, handle);
+ error = mountnfs(&args, handle);
return error;
}
@@ -1461,6 +1459,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
np->n_fattr = resok->dir_wcc.after;
np->n_flag |= NMODIFIED;
}
+
NFS_INVALIDATE_ATTRCACHE(np);
errout_with_semaphore:
diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h
index 29bebbf4d..00f2ef47b 100644
--- a/nuttx/fs/nfs/rpc.h
+++ b/nuttx/fs/nfs/rpc.h
@@ -101,7 +101,7 @@ struct rpc_program
{
uint32_t prog_id;
uint32_t prog_version;
- char * prog_name;
+ char *prog_name;
};
struct rpctask
@@ -221,7 +221,7 @@ struct rpcclnt
#endif
void *rc_auth;
- struct rpc_program *rc_prog;
+ struct rpc_program *rc_prog;
//char *rc_servername;
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
index 86ceab169..cbd1c8941 100644
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ b/nuttx/fs/nfs/rpc_clnt.c
@@ -90,6 +90,7 @@
#include <stdlib.h>
#include <string.h>
#include <debug.h>
+#include <nuttx/kmalloc.h>
#include "xdr_subs.h"
#include "nfs_proto.h"
@@ -531,7 +532,8 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
else
{
#endif
- if ((so = rep->r_rpcclnt->rc_so) == NULL)
+ so = rep->r_rpcclnt->rc_so;
+ if (so == NULL)
{
RPC_RETURN(EACCES);
}
@@ -541,7 +543,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
rcvflg = 0;
error =
psock_recvfrom(so, reply, sizeof(*reply), rcvflg, aname,
- (socklen_t *) sizeof(*aname));
+ sizeof(aname));
dbg("psock_recvfrom returns %d", error);
if (error == EWOULDBLOCK && (rep->r_flags & TASK_SOFTTERM))
{
@@ -569,7 +571,6 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
struct rpctask *rep;
struct rpcclnt *rpc = myrep->r_rpcclnt;
int32_t t1;
- struct sockaddr *nam;
uint32_t rxid;
int error;
@@ -590,10 +591,9 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
return error;
}
#endif
- /*
- * Get the next Rpc reply off the socket
- */
- error = rpcclnt_receive(myrep, nam, reply, call);
+ /* Get the next Rpc reply off the socket */
+
+ error = rpcclnt_receive(myrep, rpc->rc_name, reply, call);
#ifdef CONFIG_NFS_TCPIP
rpcclnt_rcvunlock(&rpc->rc_flag);
@@ -953,9 +953,18 @@ int rpcclnt_connect(struct rpcclnt *rpc)
/* Create the socket */
saddr = rpc->rc_name;
+
+ /* Create an instance of the socket state structure */
+ so = (struct socket *)kzalloc(sizeof(struct socket));
+ if (!so)
+ {
+ fdbg("Failed to allocate socket structure\n");
+ return -ENOMEM;
+ }
+
error =
- psock_socket(saddr->sa_family, rpc->rc_sotype, rpc->rc_soproto, rpc->rc_so);
+ psock_socket(saddr->sa_family, rpc->rc_sotype, rpc->rc_soproto, so);
if (error != 0)
{
@@ -963,7 +972,8 @@ int rpcclnt_connect(struct rpcclnt *rpc)
RPC_RETURN(error);
}
- so = rpc->rc_so;
+ so->s_crefs = 1;
+ rpc->rc_so = so;
rpc->rc_soflags = so->s_flags;
/* Some servers require that the client port be a reserved port
@@ -979,7 +989,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
{
tport--;
sin.sin_port = htons(tport);
- error = psock_bind(so, (struct sockaddr *)&sin, sizeof(sin));
+ error = psock_bind(rpc->rc_so, (struct sockaddr *)&sin, sizeof(sin));
}
while (error == EADDRINUSE && tport > 1024 / 2);
@@ -1003,7 +1013,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
else
{
#endif
- error = psock_connect(so, saddr, sizeof(*saddr));
+ error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error)
{
@@ -1022,7 +1032,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
tv.tv_usec = 0;
if ((error =
- psock_setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tv,
+ psock_setsockopt(rpc->rc_so, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tv,
sizeof(tv))))
{
goto bad;
@@ -1078,6 +1088,7 @@ int rpcclnt_reconnect(struct rpctask *rep)
rp->r_flags |= TASK_MUSTRESEND;
}
}
+
return 0;
}
#endif
@@ -1117,7 +1128,6 @@ void rpcclnt_safedisconnect(struct rpcclnt *rpc)
*
* always frees the request header, but NEVER frees 'mrest'
*
- *
* note that reply->result_* are invalid unless reply->type ==
* RPC_MSGACCEPTED and reply->status == RPC_SUCCESS and that reply->verf_*
* are invalid unless reply->type == RPC_MSGACCEPTED
@@ -1125,25 +1135,49 @@ void rpcclnt_safedisconnect(struct rpcclnt *rpc)
int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, void *datain)
{
- struct rpc_call callhost;
- struct rpc_reply replysvr;
- struct rpctask *task, _task;
+ struct rpc_call *callhost;
+ struct rpc_reply *replysvr;
+ struct rpctask *task;
int error = 0;
int xid = 0;
- task = &_task;
+ /* Create an instance of the call state structure */
- task->r_rpcclnt = rpc;
- task->r_procnum = procnum;
+ callhost = (struct rpc_call *)kzalloc(sizeof(struct rpc_call));
+ if (!callhost)
+ {
+ fdbg("Failed to allocate call msg structure\n");
+ return -ENOMEM;
+ }
+
+ /* Create an instance of the reply state structure */
+
+ replysvr = (struct rpc_reply *)kzalloc(sizeof(struct rpc_reply));
+ if (!replysvr)
+ {
+ fdbg("Failed to allocate reply msg structure\n");
+ return -ENOMEM;
+ }
+
+ /* Create an instance of the task state structure */
- error = rpcclnt_buildheader(rpc, procnum, xid, datain, &callhost);
+ task = (struct rpctask *)kzalloc(sizeof(struct rpctask));
+ if (!task)
+ {
+ fdbg("Failed to allocate reply msg structure\n");
+ return -ENOMEM;
+ }
+
+ error = rpcclnt_buildheader(rpc, procnum, xid, datain, callhost);
if (error)
{
ndbg("building call header error");
goto rpcmout;
}
+ task->r_rpcclnt = rpc;
task->r_xid = fxdr_unsigned(uint32_t,xid);
+ task->r_procnum = procnum;
if (rpc->rc_flag & RPCCLNT_SOFT)
{
@@ -1193,7 +1227,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, v
if (error == 0)
{
- error = rpcclnt_send(rpc->rc_so, rpc->rc_name, &callhost, task);
+ error = rpcclnt_send(rpc->rc_so, rpc->rc_name, callhost, task);
#ifdef CONFIG_NFS_TCPIP
if (rpc->rc_soflags & PR_CONNREQUIRED)
@@ -1202,6 +1236,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, v
}
#endif
}
+
if (error == 0 && (task->r_flags & TASK_MUSTRESEND) == 0)
{
rpc->rc_sent += RPC_CWNDSCALE;
@@ -1217,7 +1252,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, v
if (error == 0 || error == EPIPE)
{
- error = rpcclnt_reply(task, &callhost, replysvr);
+ error = rpcclnt_reply(task, callhost, replysvr);
}
/* RPC done, unlink the request. */
@@ -1282,6 +1317,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, v
if (reply->stat.status == RPC_SUCCESS)
{
nvdbg("RPC_SUCCESS");
+
reply->stat.where = replysvr->stat.where;
}
else if (reply->stat.status == RPC_PROGMISMATCH)
@@ -1442,10 +1478,10 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
/* Build the RPC header and fill in the authorization info. */
-int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
+int rpcclnt_buildheader(struct rpcclnt *rpc, int procid,
int xidp, void *datain, struct rpc_call *call)
{
- struct timeval *tv;
+ struct timeval tv;
srand(time(NULL));
/* The RPC header.*/
@@ -1464,14 +1500,15 @@ int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
xidp = rand();
}
while ((xidp % 256) == 0);
+
rpcclnt_xid += xidp;
}
call->rp_xid = xidp = txdr_unsigned(rpcclnt_xid);
call->rp_direction = rpc_call;
call->rp_rpcvers = rpc_vers;
- call->rp_prog = txdr_unsigned(rc->rc_prog->prog_id);
- call->rp_vers = txdr_unsigned(rc->rc_prog->prog_version);
+ call->rp_prog = txdr_unsigned(rpc->rc_prog->prog_id);
+ call->rp_vers = txdr_unsigned(rpc->rc_prog->prog_version);
call->rp_proc = txdr_unsigned(procid);
call->data = datain;
@@ -1480,10 +1517,10 @@ int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
call->rpc_auth.authtype = rpc_auth_null;
call->rpc_auth.authlen = txdr_unsigned(sizeof(NULL));
- tv->tv_sec = 1;
- tv->tv_usec = 0;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
#ifdef CONFIG_NFS_UNIX_AUTH
- call->rpc_unix.ua_time = txdr_unsigned(tv->tv_sec);
+ call->rpc_unix.ua_time = txdr_unsigned(&tv->tv_sec);
call->rpc_unix.ua_hostname = 0;
call->rpc_unix.ua_uid = geteuid();
call->rpc_unix.ua_gid = getegid();