update NFSv3.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@727 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
f056176486
commit
9c7ed22d04
|
@ -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'
|
||||
|
|
|
@ -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')
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
cu->cu_total = *(struct timeval *) info;
|
||||
|
||||
/* set socket option */
|
||||
setsockopt(cu->cu_sock, SOL_SOCKET, SO_RCVTIMEO, &cu->cu_total, sizeof(cu->cu_total));
|
||||
{
|
||||
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, 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue