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

View File

@ -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:

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;
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:

View File

@ -101,7 +101,7 @@ struct rpc_program
{
uint32_t prog_id;
uint32_t prog_version;
char * prog_name;
char *prog_name;
};
struct rpctask

View File

@ -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);
@ -954,8 +954,17 @@ int rpcclnt_connect(struct rpcclnt *rpc)
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;
}
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)
{
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();