NFS update

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4680 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo
2012-04-30 23:51:23 +00:00
parent a6a3f5f495
commit a7a543df52
4 changed files with 112 additions and 61 deletions
+40 -25
View File
@@ -45,6 +45,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <debug.h> #include <debug.h>
#include <nuttx/kmalloc.h>
#include "nfs.h" #include "nfs.h"
#include "rpc.h" #include "rpc.h"
@@ -112,50 +113,57 @@ void nfs_init(void)
int nfs_connect(struct nfsmount *nmp) int nfs_connect(struct nfsmount *nmp)
{ {
struct rpcclnt rpc; struct rpcclnt *rpc;
if (nmp == NULL) if (nmp == NULL)
{ {
return EFAULT; 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"); nvdbg("nfs connect!\n");
/* translate nfsmnt flags -> rpcclnt flags */ /* translate nfsmnt flags -> rpcclnt flags */
rpc.rc_flag = 0; rpc->rc_flag = 0;
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, SOFT); 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, INT);
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, NOCONN); nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, NOCONN);
nfsmnt_to_rpcclnt(nmp->nm_flag, rpc.rc_flag, DUMBTIMR); nfsmnt_to_rpcclnt(nmp->nm_flag, rpc->rc_flag, DUMBTIMR);
//rpc->rc_flag |= RPCCLNT_REDIRECT; /* Make this a mount option. */ //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_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_sotype = nmp->nm_sotype;
rpc.rc_soproto = nmp->nm_soproto; rpc->rc_soproto = nmp->nm_soproto;
rpc.rc_rsize = (nmp->nm_rsize > nmp->nm_readdirsize) ? rpc->rc_rsize = (nmp->nm_rsize > nmp->nm_readdirsize) ?
nmp->nm_rsize : nmp->nm_readdirsize; nmp->nm_rsize : nmp->nm_readdirsize;
rpc.rc_wsize = nmp->nm_wsize; rpc->rc_wsize = nmp->nm_wsize;
rpc.rc_deadthresh = nmp->nm_deadthresh; rpc->rc_deadthresh = nmp->nm_deadthresh;
rpc.rc_timeo = nmp->nm_timeo; rpc->rc_timeo = nmp->nm_timeo;
rpc.rc_retry = nmp->nm_retry; rpc->rc_retry = nmp->nm_retry;
/* v3 need to use this */ /* v3 need to use this */
rpc.rc_proctlen = 0; rpc->rc_proctlen = 0;
rpc.rc_proct = NULL; 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. */ /* 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 nfs_request(struct nfsmount *nmp, int procnum, void *datain, void *dataout)
{ {
int error; int error;
struct rpcclnt *clnt; struct rpcclnt *clnt= nmp->nm_rpcclnt;
struct rpc_reply *reply; struct rpc_reply *reply;
int trylater_delay; 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: tryagain:
memset(reply, 0, sizeof(struct rpc_reply));
if ((error = rpcclnt_request(clnt, procnum, reply, datain)) != 0) if ((error = rpcclnt_request(clnt, procnum, reply, datain)) != 0)
{ {
goto out; goto out;
@@ -204,6 +217,7 @@ tryagain:
{ {
trylater_delay = NFS_MAXTIMEO; trylater_delay = NFS_MAXTIMEO;
} }
goto tryagain; goto tryagain;
} }
@@ -224,6 +238,7 @@ tryagain:
goto out; goto out;
} }
return 0; return 0;
out: out:
+4 -5
View File
@@ -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; struct nfsmount *nmp;
int error; 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); //memmove(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
//bcopy(pth, nmp->nm_mntonname, 90); //bcopy(pth, nmp->nm_mntonname, 90);
//memmove(argp, &mp->mnt_stat.mount_info.nfs_args, sizeof(*argp)); //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); nfs_decode_args(nmp, argp);
/* Set up the sockets and per-host congestion */ /* 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; int error;
struct nfs_args args; struct nfs_args args;
struct sockaddr *nam;
bcopy(data, &args, sizeof(struct nfs_args)); bcopy(data, &args, sizeof(struct nfs_args));
if (args.version == NFS_ARGSVERSION) if (args.version == NFS_ARGSVERSION)
@@ -1091,8 +1090,7 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle)
return -EINVAL; return -EINVAL;
} }
nam = args.addr; error = mountnfs(&args, handle);
error = mountnfs(&args, nam, handle);
return error; 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_fattr = resok->dir_wcc.after;
np->n_flag |= NMODIFIED; np->n_flag |= NMODIFIED;
} }
NFS_INVALIDATE_ATTRCACHE(np); NFS_INVALIDATE_ATTRCACHE(np);
errout_with_semaphore: errout_with_semaphore:
+2 -2
View File
@@ -101,7 +101,7 @@ struct rpc_program
{ {
uint32_t prog_id; uint32_t prog_id;
uint32_t prog_version; uint32_t prog_version;
char * prog_name; char *prog_name;
}; };
struct rpctask struct rpctask
@@ -221,7 +221,7 @@ struct rpcclnt
#endif #endif
void *rc_auth; void *rc_auth;
struct rpc_program *rc_prog; struct rpc_program *rc_prog;
//char *rc_servername; //char *rc_servername;
+66 -29
View File
@@ -90,6 +90,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <debug.h> #include <debug.h>
#include <nuttx/kmalloc.h>
#include "xdr_subs.h" #include "xdr_subs.h"
#include "nfs_proto.h" #include "nfs_proto.h"
@@ -531,7 +532,8 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
else else
{ {
#endif #endif
if ((so = rep->r_rpcclnt->rc_so) == NULL) so = rep->r_rpcclnt->rc_so;
if (so == NULL)
{ {
RPC_RETURN(EACCES); RPC_RETURN(EACCES);
} }
@@ -541,7 +543,7 @@ static int rpcclnt_receive(struct rpctask *rep, struct sockaddr *aname,
rcvflg = 0; rcvflg = 0;
error = error =
psock_recvfrom(so, reply, sizeof(*reply), rcvflg, aname, psock_recvfrom(so, reply, sizeof(*reply), rcvflg, aname,
(socklen_t *) sizeof(*aname)); sizeof(aname));
dbg("psock_recvfrom returns %d", error); dbg("psock_recvfrom returns %d", error);
if (error == EWOULDBLOCK && (rep->r_flags & TASK_SOFTTERM)) 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 rpctask *rep;
struct rpcclnt *rpc = myrep->r_rpcclnt; struct rpcclnt *rpc = myrep->r_rpcclnt;
int32_t t1; int32_t t1;
struct sockaddr *nam;
uint32_t rxid; uint32_t rxid;
int error; int error;
@@ -590,10 +591,9 @@ rpcclnt_reply(struct rpctask *myrep, struct rpc_call *call,
return error; return error;
} }
#endif #endif
/* /* Get the next Rpc reply off the socket */
* Get the next Rpc reply off the socket
*/ error = rpcclnt_receive(myrep, rpc->rc_name, reply, call);
error = rpcclnt_receive(myrep, nam, reply, call);
#ifdef CONFIG_NFS_TCPIP #ifdef CONFIG_NFS_TCPIP
rpcclnt_rcvunlock(&rpc->rc_flag); rpcclnt_rcvunlock(&rpc->rc_flag);
@@ -954,8 +954,17 @@ int rpcclnt_connect(struct rpcclnt *rpc)
saddr = rpc->rc_name; 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 = 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) if (error != 0)
{ {
@@ -963,7 +972,8 @@ int rpcclnt_connect(struct rpcclnt *rpc)
RPC_RETURN(error); RPC_RETURN(error);
} }
so = rpc->rc_so; so->s_crefs = 1;
rpc->rc_so = so;
rpc->rc_soflags = so->s_flags; rpc->rc_soflags = so->s_flags;
/* Some servers require that the client port be a reserved port /* Some servers require that the client port be a reserved port
@@ -979,7 +989,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
{ {
tport--; tport--;
sin.sin_port = htons(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); while (error == EADDRINUSE && tport > 1024 / 2);
@@ -1003,7 +1013,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
else else
{ {
#endif #endif
error = psock_connect(so, saddr, sizeof(*saddr)); error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
if (error) if (error)
{ {
@@ -1022,7 +1032,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
tv.tv_usec = 0; tv.tv_usec = 0;
if ((error = 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)))) sizeof(tv))))
{ {
goto bad; goto bad;
@@ -1078,6 +1088,7 @@ int rpcclnt_reconnect(struct rpctask *rep)
rp->r_flags |= TASK_MUSTRESEND; rp->r_flags |= TASK_MUSTRESEND;
} }
} }
return 0; return 0;
} }
#endif #endif
@@ -1117,7 +1128,6 @@ void rpcclnt_safedisconnect(struct rpcclnt *rpc)
* *
* always frees the request header, but NEVER frees 'mrest' * always frees the request header, but NEVER frees 'mrest'
* *
*
* note that reply->result_* are invalid unless reply->type == * note that reply->result_* are invalid unless reply->type ==
* RPC_MSGACCEPTED and reply->status == RPC_SUCCESS and that reply->verf_* * RPC_MSGACCEPTED and reply->status == RPC_SUCCESS and that reply->verf_*
* are invalid unless reply->type == RPC_MSGACCEPTED * 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) int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, void *datain)
{ {
struct rpc_call callhost; struct rpc_call *callhost;
struct rpc_reply replysvr; struct rpc_reply *replysvr;
struct rpctask *task, _task; struct rpctask *task;
int error = 0; int error = 0;
int xid = 0; int xid = 0;
task = &_task; /* Create an instance of the call state structure */
task->r_rpcclnt = rpc; callhost = (struct rpc_call *)kzalloc(sizeof(struct rpc_call));
task->r_procnum = procnum; if (!callhost)
{
fdbg("Failed to allocate call msg structure\n");
return -ENOMEM;
}
error = rpcclnt_buildheader(rpc, procnum, xid, datain, &callhost); /* 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 */
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) if (error)
{ {
ndbg("building call header error"); ndbg("building call header error");
goto rpcmout; goto rpcmout;
} }
task->r_rpcclnt = rpc;
task->r_xid = fxdr_unsigned(uint32_t,xid); task->r_xid = fxdr_unsigned(uint32_t,xid);
task->r_procnum = procnum;
if (rpc->rc_flag & RPCCLNT_SOFT) 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) 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 #ifdef CONFIG_NFS_TCPIP
if (rpc->rc_soflags & PR_CONNREQUIRED) if (rpc->rc_soflags & PR_CONNREQUIRED)
@@ -1202,6 +1236,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, struct rpc_reply *reply, v
} }
#endif #endif
} }
if (error == 0 && (task->r_flags & TASK_MUSTRESEND) == 0) if (error == 0 && (task->r_flags & TASK_MUSTRESEND) == 0)
{ {
rpc->rc_sent += RPC_CWNDSCALE; 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) if (error == 0 || error == EPIPE)
{ {
error = rpcclnt_reply(task, &callhost, replysvr); error = rpcclnt_reply(task, callhost, replysvr);
} }
/* RPC done, unlink the request. */ /* 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) if (reply->stat.status == RPC_SUCCESS)
{ {
nvdbg("RPC_SUCCESS"); nvdbg("RPC_SUCCESS");
reply->stat.where = replysvr->stat.where; reply->stat.where = replysvr->stat.where;
} }
else if (reply->stat.status == RPC_PROGMISMATCH) 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. */ /* 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) int xidp, void *datain, struct rpc_call *call)
{ {
struct timeval *tv; struct timeval tv;
srand(time(NULL)); srand(time(NULL));
/* The RPC header.*/ /* The RPC header.*/
@@ -1464,14 +1500,15 @@ int rpcclnt_buildheader(struct rpcclnt *rc, int procid,
xidp = rand(); xidp = rand();
} }
while ((xidp % 256) == 0); while ((xidp % 256) == 0);
rpcclnt_xid += xidp; rpcclnt_xid += xidp;
} }
call->rp_xid = xidp = txdr_unsigned(rpcclnt_xid); call->rp_xid = xidp = txdr_unsigned(rpcclnt_xid);
call->rp_direction = rpc_call; call->rp_direction = rpc_call;
call->rp_rpcvers = rpc_vers; call->rp_rpcvers = rpc_vers;
call->rp_prog = txdr_unsigned(rc->rc_prog->prog_id); call->rp_prog = txdr_unsigned(rpc->rc_prog->prog_id);
call->rp_vers = txdr_unsigned(rc->rc_prog->prog_version); call->rp_vers = txdr_unsigned(rpc->rc_prog->prog_version);
call->rp_proc = txdr_unsigned(procid); call->rp_proc = txdr_unsigned(procid);
call->data = datain; 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.authtype = rpc_auth_null;
call->rpc_auth.authlen = txdr_unsigned(sizeof(NULL)); call->rpc_auth.authlen = txdr_unsigned(sizeof(NULL));
tv->tv_sec = 1; tv.tv_sec = 1;
tv->tv_usec = 0; tv.tv_usec = 0;
#ifdef CONFIG_NFS_UNIX_AUTH #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_hostname = 0;
call->rpc_unix.ua_uid = geteuid(); call->rpc_unix.ua_uid = geteuid();
call->rpc_unix.ua_gid = getegid(); call->rpc_unix.ua_gid = getegid();