update NFSv3.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@727 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong@gmail.com 2010-05-22 14:57:51 +00:00
parent f056176486
commit 9c7ed22d04
6 changed files with 186 additions and 136 deletions

View File

@ -48,6 +48,21 @@ filesystems/yaffs2/yaffs_checkptrw.c
filesystems/yaffs2/yaffs_qsort.c
""")
nfs = Split('''
filesystems/nfs/mount_clnt.c
filesystems/nfs/mount_xdr.c
filesystems/nfs/nfs_clnt.c
filesystems/nfs/nfs_xdr.c
filesystems/nfs/dfs_nfs.c
filesystems/nfs/rpc/auth_none.c
filesystems/nfs/rpc/clnt_generic.c
filesystems/nfs/rpc/clnt_udp.c
filesystems/nfs/rpc/rpc_prot.c
filesystems/nfs/rpc/pmap.c
filesystems/nfs/rpc/xdr.c
filesystems/nfs/rpc/xdr_mem.c
''')
src_local = dfs
# The set of source files associated with this SConscript file.
path = [RTT_ROOT + '/components/dfs', RTT_ROOT + '/components/dfs/include']
@ -62,6 +77,10 @@ if 'RT_DFS_ELM_USE_LFN' in dir(rtconfig) and rtconfig.RT_DFS_ELM_USE_LFN:
if 'RT_USING_DFS_ELMFAT' in dir(rtconfig) and rtconfig.RT_USING_DFS_ELMFAT:
src_local = src_local + elmfat
if 'RT_USING_DFS_NFS' in dir(rtconfig) and rtconfig.RT_USING_DFS_NFS:
src_local = src_local + nfs
path = path + [RTT_ROOT + '/components/dfs/filesystems/nfs']
# group definitions
group = {}
group['name'] = 'Filesystem'

View File

@ -1,40 +0,0 @@
Import('env')
Import('projects')
Import('RTT_ROOT')
Import('rtconfig')
src = Split('''
mount_clnt.c
mount_xdr.c
nfs_clnt.c
nfs_xdr.c
dfs_nfs.c
rpc/auth_none.c
rpc/clnt_generic.c
rpc/clnt_udp.c
rpc/rpc_prot.c
rpc/pmap.c
rpc/xdr.c
rpc/xdr_mem.c
''')
# group definitions
group = {}
group['name'] = 'nfsclient'
group['src'] = File(src) #Glob('*.c')
group['CCFLAGS'] = ''
group['CPPPATH'] = [RTT_ROOT + '/components/dfs/filesystems/nfs']
group['CPPDEFINES'] = ''
group['LINKFLAGS'] = ''
# add group to project list
projects.append(group)
env.Append(CCFLAGS = group['CCFLAGS'])
env.Append(CPPPATH = group['CPPPATH'])
env.Append(CPPDEFINES = group['CPPDEFINES'])
env.Append(LINKFLAGS = group['LINKFLAGS'])
objs = env.Object(group['src'])
Return('objs')

View File

@ -3,7 +3,6 @@
#include <dfs_fs.h>
#include <dfs_def.h>
#ifdef RT_USING_LWIP /* NFSv3 must use lwip as network protocol */
#include <rpc/rpc.h>
#include "mount.h"
@ -17,6 +16,7 @@ struct nfs_file
size_t offset; /* current offset */
size_t size; /* total size */
bool_t eof; /* end of file */
};
struct nfs_dir
@ -253,6 +253,43 @@ static size_t nfs_get_filesize(struct nfs_filesystem* nfs, nfs_fh3 *handle)
return size;
}
rt_bool_t nfs_is_directory(struct nfs_filesystem* nfs, const char* name)
{
GETATTR3args args;
GETATTR3res res;
fattr3 *info;
nfs_fh3 *handle;
rt_bool_t result;
result = RT_FALSE;
handle = get_handle(nfs, name);
if(handle == RT_NULL) return RT_FALSE;
args.object = *handle;
memset(&res, '\0', sizeof(res));
if (nfsproc3_getattr_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
{
rt_kprintf("GetAttr failed\n");
return RT_FALSE;
}
else if(res.status!=NFS3_OK)
{
rt_kprintf("Getattr failed: %d\n", res.status);
return RT_FALSE;
}
info=&res.GETATTR3res_u.resok.obj_attributes;
if (info->type == NFS3DIR) result = RT_TRUE;
xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res);
xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
return result;
}
int nfs_create(struct nfs_filesystem* nfs, const char *name, mode_t mode)
{
CREATE3args args;
@ -489,12 +526,15 @@ int nfs_read(struct dfs_fd* file, void *buf, rt_size_t count)
if(nfs->nfs_client==RT_NULL)
return -1;
/* end of file */
if (fd->eof == TRUE) return 0;
args.file=fd->handle;
args.offset=fd->offset;
args.count=count;
memset(&res, 0, sizeof(res));
if(nfsproc3_read_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
if(nfsproc3_read_3(args, &res, nfs->nfs_client) != RPC_SUCCESS)
{
rt_kprintf("Read failed\n");
bytes = 0;
@ -509,6 +549,7 @@ int nfs_read(struct dfs_fd* file, void *buf, rt_size_t count)
if(res.READ3res_u.resok.eof)
{
/* something should probably be here */
fd->eof = TRUE;
}
bytes=res.READ3res_u.resok.count;
fd->offset += bytes;
@ -659,6 +700,7 @@ int nfs_open(struct dfs_fd* file)
/* get size of file */
fp->size = nfs_get_filesize(nfs, handle);
fp->offset=0;
fp->eof = FALSE;
copy_handle(&fp->handle, handle);
xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
@ -706,7 +748,7 @@ int nfs_stat(struct dfs_filesystem* fs, const char *path, struct dfs_stat *st)
return -1;
}
info=&res.GETATTR3res_u.resok.obj_attributes;
info = &res.GETATTR3res_u.resok.obj_attributes;
st->st_dev = 0;
@ -804,82 +846,79 @@ char *nfs_readdir(struct nfs_filesystem* nfs, nfs_dir *dir)
int nfs_unlink(struct dfs_filesystem* fs, const char* path)
{
REMOVE3args args;
REMOVE3res res;
int ret=0;
nfs_fh3 *handle;
int ret = 0;
struct nfs_filesystem* nfs;
RT_ASSERT(fs != RT_NULL);
RT_ASSERT(fs->data != RT_NULL);
nfs = (struct nfs_filesystem *)fs->data;
if(nfs->nfs_client==RT_NULL)
return -1;
handle = get_dir_handle(nfs, path);
if(handle == RT_NULL)
return -1;
args.object.dir=*handle;
args.object.name=strrchr(path, '/');
if(args.object.name==RT_NULL)
if (nfs_is_directory(nfs, path) == RT_FALSE)
{
args.object.name=(char *)path;
/* remove file */
REMOVE3args args;
REMOVE3res res;
nfs_fh3 *handle;
handle = get_dir_handle(nfs, path);
if(handle == RT_NULL) return -1;
args.object.dir=*handle;
args.object.name=strrchr(path, '/');
if(args.object.name==RT_NULL)
{
args.object.name=(char *)path;
}
memset(&res, 0, sizeof(res));
if(nfsproc3_remove_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
{
rt_kprintf("Remove failed\n");
ret=-1;
}
else if(res.status!=NFS3_OK)
{
rt_kprintf("Remove failed: %d\n", res.status);
ret=-1;
}
xdr_free((xdrproc_t)xdr_REMOVE3res, (char *)&res);
xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
}
else
{
/* remove directory */
RMDIR3args args;
RMDIR3res res;
nfs_fh3 *handle;
handle=get_dir_handle(nfs, path);
if(handle==RT_NULL) return -1;
args.object.dir=*handle;
args.object.name=strrchr(path, '/');
if(args.object.name==RT_NULL)
{
args.object.name=(char *)path;
}
memset(&res, 0, sizeof(res));
if(nfsproc3_rmdir_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
{
rt_kprintf("Rmdir failed\n");
ret = -1;
}
else if(res.status!=NFS3_OK)
{
rt_kprintf("Rmdir failed: %d\n", res.status);
ret = -1;
}
xdr_free((xdrproc_t)xdr_RMDIR3res, (char *)&res);
xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
}
memset(&res, 0, sizeof(res));
if(nfsproc3_remove_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
{
rt_kprintf("Remove failed\n");
ret=-1;
}
else if(res.status!=NFS3_OK)
{
rt_kprintf("Remove failed: %d\n", res.status);
ret=-1;
}
xdr_free((xdrproc_t)xdr_REMOVE3res, (char *)&res);
xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
return ret;
}
int nfs_rmdir(struct nfs_filesystem* nfs, const char *name)
{
RMDIR3args args;
RMDIR3res res;
int ret=0;
nfs_fh3 *handle;
if(nfs->nfs_client==RT_NULL)
return -1;
handle=get_dir_handle(nfs, name);
if(handle==RT_NULL)
return -1;
args.object.dir=*handle;
args.object.name=strrchr(name, '/');
if(args.object.name==RT_NULL)
{
args.object.name=(char *)name;
}
memset(&res, 0, sizeof(res));
if(nfsproc3_rmdir_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS)
{
rt_kprintf("Rmdir failed\n");
ret = -1;
}
else if(res.status!=NFS3_OK)
{
rt_kprintf("Rmdir failed: %d\n", res.status);
ret = -1;
}
xdr_free((xdrproc_t)xdr_RMDIR3res, (char *)&res);
xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle);
return ret;
}
@ -938,7 +977,44 @@ int nfs_rename(struct dfs_filesystem* fs, const char *src, const char *dest)
int nfs_getdents(struct dfs_fd* file, struct dfs_dirent* dirp, rt_uint32_t count)
{
return 0;
nfs_dir *dir;
rt_uint32_t index;
struct dfs_dirent* d;
struct nfs_filesystem* nfs;
char *name;
dir = (nfs_dir *)(file->data);
RT_ASSERT(dir != RT_NULL);
RT_ASSERT(file->fs != RT_NULL);
RT_ASSERT(file->fs->data != RT_NULL);
nfs = (struct nfs_filesystem *)file->fs->data;
/* make integer count */
count = (count / sizeof(struct dfs_dirent)) * sizeof(struct dfs_dirent);
if ( count == 0 ) return -DFS_STATUS_EINVAL;
index = 0;
while (1)
{
char *fn;
d = dirp + index;
name = nfs_readdir(nfs, dir);
if (name == RT_NULL) break;
d->d_type &= DFS_DT_REG;
d->d_namlen = rt_strlen(name);
d->d_reclen = (rt_uint16_t)sizeof(struct dfs_dirent);
rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
index ++;
if ( index * sizeof(struct dfs_dirent) >= count )
break;
}
return index * sizeof(struct dfs_dirent);
}
static struct dfs_filesystem_operation _nfs;
@ -964,12 +1040,3 @@ int nfs_init(void)
return RT_EOK;
}
#include <finsh.h>
void nfs_test(char* host)
{
dfs_mount(RT_NULL, "/nfs", "nfs", 0, (void*)host);
}
FINSH_FUNCTION_EXPORT(nfs_test, test nfs mount);
#endif

View File

@ -200,8 +200,7 @@ CLIENT *clntudp_create(struct sockaddr_in *raddr,
UDPMSGSIZE, UDPMSGSIZE));
}
static enum clnt_stat
clntudp_call(CLIENT *cl, unsigned long proc,
static enum clnt_stat clntudp_call(CLIENT *cl, unsigned long proc,
xdrproc_t xargs, char* argsp,
xdrproc_t xresults, char* resultsp,
struct timeval utimeout)
@ -210,7 +209,6 @@ clntudp_call(CLIENT *cl, unsigned long proc,
register XDR *xdrs;
register int outlen;
register int inlen;
struct timeval singlewait;
socklen_t fromlen;
struct sockaddr_in from;
@ -223,10 +221,12 @@ call_again:
xdrs = &(cu->cu_outxdrs);
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, cu->cu_xdrpos);
/*
* the transaction is the first thing in the out buffer
*/
(*(uint32_t *) (cu->cu_outbuf))++;
(*(unsigned long *) (cu->cu_outbuf))++;
if ((!XDR_PUTLONG(xdrs, (long *) &proc)) ||
(!AUTH_MARSHALL(cl->cl_auth, xdrs)) || (!(*xargs) (xdrs, argsp)))
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
@ -258,9 +258,6 @@ send_again:
inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
(int) cu->cu_recvsz, 0,
(struct sockaddr *) &from, &fromlen);
if (inlen <= 0)
rt_kprintf("recv error: len %d, errno %d\n", inlen, lwip_get_error(cu->cu_sock));
}while (inlen < 0 && errno == EINTR);
if (inlen < 4)
@ -296,8 +293,7 @@ send_again:
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
{
xdrs->x_op = XDR_FREE;
(void) xdr_opaque_auth(xdrs,
&(reply_msg.acpted_rply.ar_verf));
(void) xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
}
} /* end successful completion */
else
@ -308,7 +304,7 @@ send_again:
nrefreshes--;
goto call_again;
}
} /* end of unsuccessful completion */
} /* end of unsuccessful completion */
} /* end of valid reply message */
else
{
@ -345,11 +341,16 @@ static bool_t clntudp_control(CLIENT *cl, int request, char *info)
switch (request)
{
case CLSET_TIMEOUT:
{
int mtimeout;
cu->cu_total = *(struct timeval *) info;
mtimeout = ((cu->cu_total.tv_sec * 1000) + ((cu->cu_total.tv_usec + 500)/1000));
/* set socket option */
setsockopt(cu->cu_sock, SOL_SOCKET, SO_RCVTIMEO, &cu->cu_total, sizeof(cu->cu_total));
/* set socket option, note: lwip only support msecond timeout */
setsockopt(cu->cu_sock, SOL_SOCKET, SO_RCVTIMEO,
&mtimeout, sizeof(mtimeout));
}
break;
case CLGET_TIMEOUT:
*(struct timeval *) info = cu->cu_total;

View File

@ -41,7 +41,6 @@
typedef unsigned int u_int;
typedef unsigned char u_char;
typedef unsigned long u_long;
typedef rt_int32_t ssize_t;
typedef rt_int8_t int8_t;
typedef rt_uint8_t uint8_t;
@ -56,8 +55,11 @@ typedef unsigned long long uint64_t;
typedef int bool_t;
typedef int enum_t;
#ifndef RT_USING_NEWLIB
typedef rt_int32_t ssize_t;
typedef unsigned long mode_t;
typedef unsigned long dev_t;
#endif
/* This needs to be changed to uint32_t in the future */
typedef unsigned long rpcprog_t;

View File

@ -378,7 +378,8 @@ int dfs_unmount(const char *specialfile)
}
/* close device, but do not check the status of device */
rt_device_close(fs->dev_id);
if (fs->dev_id != RT_NULL)
rt_device_close(fs->dev_id);
/* clear this filesystem table entry */
rt_memset(fs, 0, sizeof(struct dfs_filesystem));