From 2812a9f1df22438f8ccd30dd5e5dc48dc3465b3f Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 30 Apr 2012 23:51:23 +0000 Subject: NFS update git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4680 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/fs/nfs/nfs_socket.c | 65 +++++++++++++++++++------------- nuttx/fs/nfs/nfs_vfsops.c | 9 ++--- nuttx/fs/nfs/rpc.h | 4 +- nuttx/fs/nfs/rpc_clnt.c | 95 ++++++++++++++++++++++++++++++++--------------- 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 #include #include +#include #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 #include #include +#include #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(); -- cgit v1.2.3