NFS update

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4821 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-06-09 19:29:49 +00:00
parent fd5446a23b
commit 3581588fde
6 changed files with 483 additions and 224 deletions

View File

@ -192,6 +192,16 @@
#define ND_NFSV3 0x08
#define NFSD_CHECKSLP 0x01
/****************************************************************************
* Public Data
****************************************************************************/
extern uint32_t nfs_true;
extern uint32_t nfs_false;
extern uint32_t nfs_xdrneg1;
extern struct nfsstats nfsstats;
extern int nfs_ticks;
/****************************************************************************
* Public Types
****************************************************************************/
@ -352,6 +362,11 @@ extern "C" {
EXTERN void nfs_semtake(struct nfsmount *nmp);
EXTERN void nfs_semgive(struct nfsmount *nmp);
EXTERN int nfs_checkmount(struct nfsmount *nmp);
EXTERN int nfs_fsinfo(struct nfsmount *nmp);
EXTERN int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes);
#undef EXTERN
#if defined(__cplusplus)

View File

@ -584,6 +584,24 @@ struct CREATE3resok
struct wcc_data dir_wcc;
};
struct LOOKUP3args
{
struct file_handle dirhandle;
uint32_t namelen;
uint32_t name[1]; /* Actual size determined by namelen */
};
#define SIZEOF_LOOKUP3args(n) \
(sizeof(struct LOOKUP3args) + ((((n)+3) >> 2) - 1)*sizeof(uint32_t))
struct LOOKUP3resok
{
struct file_handle fshandle;
uint32_t obj_attributes_follow;
struct nfs_fattr obj_attributes;
uint32_t dir_attributes_follow;
struct nfs_fattr dir_attributes;
};
struct READ3args
{
nfstype file;
@ -698,3 +716,4 @@ struct FS3args
};
#endif /* __FS_NFS_NFS_PROTO_H */

247
nuttx/fs/nfs/nfs_util.c Executable file → Normal file
View File

@ -53,9 +53,13 @@
#include <nuttx/fs/dirent.h>
#include "rpc.h"
#include "nfs.h"
#include "nfs_proto.h"
#include "nfs_mount.h"
#include "nfs_node.h"
#include "nfs_socket.h"
#include "xdr_subs.h"
/****************************************************************************
* Private Types
@ -77,6 +81,56 @@
* Private Functions
****************************************************************************/
static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer,
FAR char *terminator)
{
FAR const char *src = *path;
FAR char *dest = buffer;
int nbytes = 0;
char ch;
/* Loop until the name is successfully parsed or an error occurs */
for (;;)
{
/* Get the next byte from the path */
ch = *src++;
/* Check if this the last byte in this segment name */
if (ch == '\0' || ch == '/')
{
/* This logic just suppors "//" sequences in the path name */
if (ch == '\0' || nbytes > 0 )
{
/* NULL terminate the parsed path segment */
*dest = '\0';
/* Return next path and the terminating character */
*terminator = ch;
*path = src;
return OK;
}
/* Just skip over any leading '/' characters */
}
else if (nbytes >= NAME_MAX)
{
fdbg("File name segment is too long: %d\n", *path);
return EFBIG;
}
else
{
/* Save next character in the accumulated name */
*dest++ = ch;
}
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -141,3 +195,196 @@ int nfs_checkmount(struct nfsmount *nmp)
return 0;
}
/****************************************************************************
* Name: nfs_fsinfo
*
* Description:
* Return information about root directory.
*
* Returned Value:
* 0 on success; positive errno value on failure
*
* Assumptions:
* The caller has exclusive access to the NFS mount structure
*
****************************************************************************/
int nfs_fsinfo(FAR struct nfsmount *nmp)
{
struct rpc_reply_fsinfo fsp;
struct FS3args fsinfo;
uint32_t pref;
uint32_t max;
int error = 0;
memset(&fsinfo, 0, sizeof(struct FS3args));
memset(&fsp, 0, sizeof(struct rpc_reply_fsinfo));
nfsstats.rpccnt[NFSPROC_FSINFO]++;
fsinfo.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
fsinfo.fsroot.handle = nmp->nm_fh;
/* Request FSINFO from the server */
error = nfs_request(nmp, NFSPROC_FSINFO, (FAR const void *)&fsinfo,
(FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo));
if (error)
{
return error;
}
/* Save the root file system attributes */
#if 0
memcpy(&nmp->nm_fattr. &fsp.obj_attributes, sizeof(struct nfs_fattr));
#endif
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtpref);
if (pref < nmp->nm_wsize)
{
nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
}
max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtmax);
if (max < nmp->nm_wsize)
{
nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize == 0)
{
nmp->nm_wsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtpref);
if (pref < nmp->nm_rsize)
{
nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
}
max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtmax);
if (max < nmp->nm_rsize)
{
nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize == 0)
{
nmp->nm_rsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_dtpref);
if (pref < nmp->nm_readdirsize)
{
nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & ~(NFS_DIRBLKSIZ - 1);
}
if (max < nmp->nm_readdirsize)
{
nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize == 0)
{
nmp->nm_readdirsize = max;
}
}
nmp->nm_flag |= NFSMNT_GOTFSINFO;
return 0;
}
/****************************************************************************
* Name: nfs_findnode
*
* Desciption:
* Given a path to something that may or may not be in the file system,
* return the handle of the directory entry of the requested item object.
*
* Return Value:
* Zero on success; a positive errno value on failure.
*
****************************************************************************/
int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
FAR struct file_handle *fhandle, FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes)
{
FAR const char *path = relpath;
char buffer[NAME_MAX+1];
char terminator;
int error;
/* Start with the file handle and attributes of the root directory */
fhandle->length = nmp->nm_fhsize;
memcpy(&fhandle->handle, &nmp->nm_fh, sizeof(nfsfh_t));
#warning "Where do we get the attributes of the root file system?"
memset(obj_attributes, 0, sizeof(struct nfs_fattr));
memset(dir_attributes, 0, sizeof(struct nfs_fattr));
/* If no path was provided, then the root directory must be exactly what
* the caller is looking for.
*/
if (*path == '\0' || strlen(path) == 0)
{
return OK;
}
/* This is not the root directory. Loop until the directory entry corresponding
* to the path is found.
*/
for (;;)
{
/* Extract the next path segment name. */
error = nfs_pathsegment(&path, buffer, &terminator);
if (error != 0)
{
/* The filename segment contains is too long. */
fdbg("nfs_pathsegment of \"%s\" failed after \"%s\": %d\n",
relpath, buffer, error);
return error;
}
/* Look-up this path segment */
nfsstats.rpccnt[NFSPROC_LOOKUP]++;
error = rpcclnt_lookup(nmp->nm_rpcclnt, buffer, fhandle,
obj_attributes, dir_attributes);
if (error != 0)
{
fdbg("rpcclnt_lookup of \"%s\" failed at \"%s\": %d\n",
relpath, buffer, error);
return error;
}
/* If the terminator character in the path was the end of the string
* then we have successfully found the directory entry that describes
* the path.
*/
if (!terminator)
{
/* Return success meaning that the description the matching
* directory entry is in fhandle, obj_attributes, and dir_attributes.
*/
return OK;
}
/* No.. then we have found one of the intermediate directories on
* the way to the final path target. In this case, make sure
* the thing that we found is, indeed, a directory.
*/
if (obj_attributes->fa_type != NFDIR)
{
/* Ooops.. we found something else */
fdbg("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
buffer, path);
return ENOTDIR;
}
}
}

View File

@ -53,6 +53,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <queue.h>
#include <string.h>
@ -119,21 +120,11 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath,
static int nfs_rmdir(struct inode *mountpt, const char *relpath);
static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
const char *newrelpath);
static int nfs_getfsinfo(struct nfsmount *nmp, const char *relpath,
static int nfs_getstat(struct nfsmount *nmp, const char *relpath,
struct stat *buf);
static int nfs_fsinfo(struct inode *mountpt, const char *relpath,
static int nfs_stat(struct inode *mountpt, const char *relpath,
struct stat *buf);
/****************************************************************************
* External Public Data (this belong in a header file)
****************************************************************************/
extern uint32_t nfs_true;
extern uint32_t nfs_false;
extern uint32_t nfs_xdrneg1;
extern struct nfsstats nfsstats;
extern int nfs_ticks;
/****************************************************************************
* Public Data
****************************************************************************/
@ -162,7 +153,7 @@ const struct mountpt_operations nfs_operations =
nfs_mkdir, /* mkdir */
nfs_rmdir, /* rmdir */
nfs_rename, /* rename */
nfs_fsinfo /* stat */
nfs_stat /* stat */
};
/****************************************************************************
@ -173,7 +164,7 @@ const struct mountpt_operations nfs_operations =
* Public Functions
****************************************************************************/
/****************************************************************************
/****************************************************************************
* Name: nfs_create
*
* Description:
@ -295,7 +286,7 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
/* First check if the file already exists */
error = nfs_getfsinfo(nmp, relpath, &buf);
error = nfs_getstat(nmp, relpath, &buf);
if (error == 0)
{
/* Check if the file is a directory */
@ -362,31 +353,37 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
/* Fall through to finish the file open operation */
}
/* An error occurred while getting the file status */
/* An error occurred while getting the file status. Check if the stat failed
* because the file does not exist. That is not necessarily an error; that
* may only mean that we have to create the file.
*/
else if (error != ENOENT)
{
fdbg("ERROR: nfs_getstat failed: %d\n", error);
goto errout_with_semaphore;
}
/* The file does not exist. Check if we were asked to create the file. If
* the O_CREAT bit is set in the oflags then we should create the file if it
* does not exist.
*/
else if ((oflags & O_CREAT) == 0)
{
/* Return ENOENT if the file does not exist and we were not asked
* to create it.
*/
fdbg("ERROR: File does not exist\n");
error = ENOENT;
goto errout_with_semaphore;
}
/* Create the file */
else
{
/* Check if the stat failed because the file does not exist. */
#warning "Missing logic"
/* If the file does not exist then check if we were asked to create
* the file. If the O_CREAT bit is set in the oflags then we should
* create the file if it does not exist.
*/
if ((oflags & O_CREAT) == 0)
{
/* Return ENOENT if the file does not exist and we were not asked
* to create it.
*/
fdbg("ERROR: File does not exist\n");
error = ENOENT;
goto errout_with_semaphore;
}
/* Create the file */
error = nfs_create(nmp, np, relpath, mode);
if (error != 0)
{
@ -522,7 +519,7 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3)
{
(void)nfs_getfsinfo(nmp, NULL, NULL);
(void)nfs_fsinfo(nmp);
}
/* Get the number of bytes left in the file */
@ -962,11 +959,10 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
/* Get the file attributes associated with this name and return
* the file type.
*/
#if 0 /* There is no point in enabling until nfs_getfsinfo handles the relative path */
if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3)
{
struct stat buf
struct stat buf;
char *path;
/* Construct the full path to the file */
@ -976,7 +972,7 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
{
/* Then stat the file */
int ret = nfs_getfsinfo(nmp, path, &buf);
int ret = nfs_getstat(nmp, path, &buf);
if (ret == OK)
{
if (S_ISREG(buf.st_mode))
@ -1006,9 +1002,6 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
kfree(path);
}
}
#else
#warning "Missing logic"
dir->fd_dir.d_type = DTYPE_FILE;
#endif
error = 0;
}
@ -1093,7 +1086,7 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
if ((nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_GOTFSINFO)) == NFSMNT_NFSV3)
{
(void)nfs_getfsinfo(nmp, NULL, NULL);
(void)nfs_fsinfo(nmp);
}
/* Read and return one directory entry. */
@ -1633,7 +1626,7 @@ static int nfs_statfs(struct inode *mountpt, struct statfs *sbp)
if ((nmp->nm_flag & NFSMNT_GOTFSINFO) == 0)
{
(void)nfs_getfsinfo(nmp, NULL, NULL);
(void)nfs_fsinfo(nmp);
}
nfsstats.rpccnt[NFSPROC_FSSTAT]++;
@ -1994,11 +1987,11 @@ errout_with_semaphore:
}
/****************************************************************************
* Name: nfs_getfsinfo
* Name: nfs_getstat
*
* Description:
* Return information about root directory. This is an internal version
* used only within this file.
* Return information about the object at the specified path. This is an
* internal version of stat() used only within this file.
*
* Returned Value:
* 0 on success; positive errno value on failure
@ -2008,178 +2001,116 @@ errout_with_semaphore:
*
****************************************************************************/
static int nfs_getfsinfo(struct nfsmount *nmp, const char *relpath,
struct stat *buf)
static int nfs_getstat(struct nfsmount *nmp, const char *relpath,
struct stat *buf)
{
struct rpc_reply_fsinfo fsp;
struct FS3args fsinfo;
uint32_t pref;
uint32_t max;
int error = 0;
struct file_handle fhandle;
struct nfs_fattr obj_attributes;
struct nfs_fattr dir_attributes;
uint32_t tmp;
uint32_t mode;
int error = 0;
#warning "relpath is not used! Additional logic will be required!"
DEBUGASSERT(nmp && buf);
memset(&fsinfo, 0, sizeof(struct FS3args));
memset(&fsp, 0, sizeof(struct rpc_reply_fsinfo));
/* Get the attributes of the requested node */
nfsstats.rpccnt[NFSPROC_FSINFO]++;
fsinfo.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
fsinfo.fsroot.handle = nmp->nm_fh;
/* Request FSINFO from the server */
error = nfs_request(nmp, NFSPROC_FSINFO, (FAR const void *)&fsinfo,
(FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo));
if (error)
error = nfs_findnode(nmp, relpath, &fhandle, &obj_attributes,
&dir_attributes);
if (error != 0)
{
fdbg("ERROR: nfs_findnode failed: %d\n", error);
return error;
}
//nmp->nm_fattr = fsp.obj_attributes;
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtpref);
if (pref < nmp->nm_wsize)
{
nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
}
max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtmax);
if (max < nmp->nm_wsize)
{
nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize == 0)
{
nmp->nm_wsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtpref);
if (pref < nmp->nm_rsize)
{
nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
}
max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtmax);
if (max < nmp->nm_rsize)
{
nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize == 0)
{
nmp->nm_rsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_dtpref);
if (pref < nmp->nm_readdirsize)
{
nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & ~(NFS_DIRBLKSIZ - 1);
}
if (max < nmp->nm_readdirsize)
{
nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize == 0)
{
nmp->nm_readdirsize = max;
}
}
/* Verify that the caller has provided a non-NULL location to return the
* FSINFO data.
/* Construct the file mode. This is a 32-bit, encoded value containing
* both the access mode and the file type.
*/
if (buf)
{
/* Construct the file mode. This is a 32-bit, encoded value containing
* both the access mode and the file type.
*/
uint32_t tmp = fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode);
tmp = fxdr_unsigned(uint32_t, obj_attributes.fa_mode);
/* Here we exploit the fact that most mode bits are the same in NuttX
* as in the NFSv3 spec.
*/
/* Here we exploit the fact that most mode bits are the same in NuttX
* as in the NFSv3 spec.
*/
uint32_t mode = tmp & (NFSMMODE_IXOTH|NFSMMODE_IWOTH|NFSMMODE_IROTH|
NFSMMODE_IXGRP|NFSMMODE_IWGRP|NFSMMODE_IRGRP|
NFSMMODE_IXUSR|NFSMMODE_IWUSR|NFSMMODE_IRUSR);
mode = tmp & (NFSMMODE_IXOTH|NFSMMODE_IWOTH|NFSMMODE_IROTH|
NFSMMODE_IXGRP|NFSMMODE_IWGRP|NFSMMODE_IRGRP|
NFSMMODE_IXUSR|NFSMMODE_IWUSR|NFSMMODE_IRUSR);
/* Handle the cases that are not the same */
/* Handle the cases that are not the same */
if ((mode & NFSMMODE_ISGID) != 0)
{
mode |= S_ISGID;
}
if ((mode & NFSMMODE_ISUID) != 0)
{
mode |= S_ISUID;
}
/* Now OR in the file type */
tmp = fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_type);
switch (tmp)
{
default:
case NFNON: /* Unknown type */
break;
case NFREG: /* Regular file */
mode |= S_IFREG;
break;
case NFDIR: /* Directory */
mode |= S_IFDIR;
break;
case NFBLK: /* Block special device file */
mode |= S_IFBLK;
break;
case NFCHR: /* Character special device file */
mode |= S_IFCHR;
break;
case NFLNK: /* Symbolic link */
mode |= S_IFLNK;
break;
case NFSOCK: /* Socket */
mode |= S_IFSOCK;
break;
case NFFIFO: /* Named pipe */
mode |= S_IFMT;
break;
};
buf->st_mode = mode;
buf->st_size = fxdr_hyper(&nmp->nm_fattr.fa3_size);
buf->st_blksize = 0;
buf->st_blocks = 0;
buf->st_mtime = fxdr_hyper(&nmp->nm_fattr.fa3_mtime);
buf->st_atime = fxdr_hyper(&nmp->nm_fattr.fa3_atime);
buf->st_ctime = fxdr_hyper(&nmp->nm_fattr.fa3_ctime);
if ((mode & NFSMMODE_ISGID) != 0)
{
mode |= S_ISGID;
}
nmp->nm_flag |= NFSMNT_GOTFSINFO;
if ((mode & NFSMMODE_ISUID) != 0)
{
mode |= S_ISUID;
}
return 0;
/* Now OR in the file type */
tmp = fxdr_unsigned(uint32_t, obj_attributes.fa_type);
switch (tmp)
{
default:
case NFNON: /* Unknown type */
break;
case NFREG: /* Regular file */
mode |= S_IFREG;
break;
case NFDIR: /* Directory */
mode |= S_IFDIR;
break;
case NFBLK: /* Block special device file */
mode |= S_IFBLK;
break;
case NFCHR: /* Character special device file */
mode |= S_IFCHR;
break;
case NFLNK: /* Symbolic link */
mode |= S_IFLNK;
break;
case NFSOCK: /* Socket */
mode |= S_IFSOCK;
break;
case NFFIFO: /* Named pipe */
mode |= S_IFMT;
break;
}
buf->st_mode = mode;
buf->st_size = fxdr_hyper(&obj_attributes.fa3_size);
buf->st_blksize = 0;
buf->st_blocks = 0;
buf->st_mtime = fxdr_hyper(&obj_attributes.fa3_mtime);
buf->st_atime = fxdr_hyper(&obj_attributes.fa3_atime);
buf->st_ctime = fxdr_hyper(&obj_attributes.fa3_ctime);
return OK;
}
/****************************************************************************
* Name: nfs_fsinfo
* Name: nfs_stat
*
* Description:
* Return information about root directory
* Return information about the file system object at 'relpath'
*
* Returned Value:
* 0 on success; a negated errno value on failure.
*
****************************************************************************/
static int nfs_fsinfo(struct inode *mountpt, const char *relpath,
struct stat *buf)
static int nfs_stat(struct inode *mountpt, const char *relpath,
struct stat *buf)
{
struct nfsmount *nmp;
int error;
@ -2200,7 +2131,7 @@ static int nfs_fsinfo(struct inode *mountpt, const char *relpath,
{
/* Get the requested FSINFO */
error = nfs_getfsinfo(nmp, relpath, buf);
error = nfs_getstat(nmp, relpath, buf);
}
nfs_semgive(nmp);

View File

@ -240,6 +240,7 @@ struct rpcstats
};
/* PMAP headers */
struct call_args_pmap
{
uint32_t prog;
@ -325,6 +326,12 @@ struct rpc_call_create
struct CREATE3args create;
};
struct rpc_call_lookup
{
struct rpc_call_header ch;
struct LOOKUP3args lookup;
};
struct rpc_call_read
{
struct rpc_call_header ch;
@ -377,8 +384,8 @@ struct rpc_call_fs
struct rpc_reply_header
{
uint32_t rp_xid; /* request transaction id */
uint32_t rp_direction; /* call direction (1) */
uint32_t rp_xid; /* Request transaction id */
uint32_t rp_direction; /* Call direction (1) */
uint32_t type;
struct rpc_auth_info rpc_verfi;
uint32_t status;
@ -553,7 +560,13 @@ int rpcclnt_reconnect(struct rpctask *);
void rpcclnt_disconnect(struct rpcclnt *);
int rpcclnt_umount(struct rpcclnt *);
void rpcclnt_safedisconnect(struct rpcclnt *);
int rpcclnt_request(struct rpcclnt *, int, int, int, void *, FAR const void *, size_t);
int rpcclnt_request(FAR struct rpcclnt *, int, int, int, void *,
FAR const void *, size_t);
int rpcclnt_lookup(FAR struct rpcclnt *rpc, FAR const char *relpath,
FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes);
#undef COMP
#ifdef COMP
int rpcclnt_cancelreqs(struct rpcclnt *);

View File

@ -186,8 +186,6 @@ static uint32_t rpc_msgaccepted;
static uint32_t rpc_autherr;
static uint32_t rpc_auth_null;
static uint32_t rpcclnt_xid = 0;
static uint32_t rpcclnt_xid_touched = 0;
int rpcclnt_ticks;
struct rpcstats rpcstats;
//struct rpc_call *callmgs;
@ -1505,7 +1503,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
}
task->r_rpcclnt = rpc;
task->r_xid = value.xid;
task->r_xid = value.xid;
task->r_procnum = procnum;
if (rpc->rc_flag & RPCCLNT_SOFT)
@ -1809,19 +1807,15 @@ void rpcclnt_timer(void *arg, struct rpc_call *call)
}
#endif
/* Build the RPC header and fill in the authorization info. */
/* Get a new (non-zero) xid */
int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
struct xidr *value, FAR const void *datain,
void *dataout)
uint32_t rpcclnt_newxid(void)
{
srand(time(NULL));
static uint32_t rpcclnt_xid = 0;
static uint32_t rpcclnt_xid_touched = 0;
int xidp = 0;
/* The RPC header.*/
/* Get a new (non-zero) xid */
srand(time(NULL));
if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0))
{
rpcclnt_xid = rand();
@ -1838,6 +1832,23 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
rpcclnt_xid += xidp;
}
return rpcclnt_xid;
}
/* Build the RPC header and fill in the authorization info. */
int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
struct xidr *value, FAR const void *datain,
void *dataout)
{
uint32_t xid;
/* The RPC header.*/
/* Get a new (non-zero) xid */
xid = rpcclnt_newxid();
/* Perform the binding depending on the protocol type */
if (prog == PMAPPROG)
@ -1847,7 +1858,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
struct rpc_call_pmap *callmsg = (struct rpc_call_pmap *)dataout;
memcpy(&callmsg->pmap, datain, sizeof(struct call_args_pmap));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -1876,7 +1887,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_pmap *callmsg = (struct rpc_call_pmap *)dataout;;
memcpy(&callmsg->pmap, datain, sizeof(struct call_args_pmap));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -1908,7 +1919,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_mount *callmsg = (struct rpc_call_mount *)dataout;
memcpy(&callmsg->mount, datain, sizeof(struct call_args_mount));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -1937,7 +1948,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_mount *callmsg = (struct rpc_call_mount *)dataout;
memcpy(&callmsg->mount, datain, sizeof(struct call_args_mount));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -1971,7 +1982,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_create *callmsg = (struct rpc_call_create *)dataout;
memcpy(&callmsg->create, datain, sizeof(struct CREATE3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2001,7 +2012,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_read *callmsg = (struct rpc_call_read *)dataout;
memcpy(&callmsg->read, datain, sizeof(struct READ3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2032,7 +2043,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_write *callmsg = (struct rpc_call_write *)dataout;
memcpy(&callmsg->write, datain, sizeof(struct WRITE3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2063,7 +2074,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_readdir *callmsg = (struct rpc_call_readdir *)dataout;
memcpy(&callmsg->readdir, datain, sizeof(struct READDIR3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2094,7 +2105,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
memcpy(&callmsg->fs, datain, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2125,7 +2136,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_remove *callmsg = (struct rpc_call_remove *)dataout;
memcpy(&callmsg->remove, datain, sizeof(struct REMOVE3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2156,7 +2167,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
memcpy(&callmsg->fs, datain, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2187,7 +2198,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_mkdir *callmsg = (struct rpc_call_mkdir *)dataout;
memcpy(&callmsg->mkdir, datain, sizeof(struct MKDIR3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2218,7 +2229,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_rmdir *callmsg = (struct rpc_call_rmdir *)dataout;
memcpy(&callmsg->rmdir, datain, sizeof(struct RMDIR3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2249,7 +2260,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_rename *callmsg = (struct rpc_call_rename *)dataout;
memcpy(&callmsg->rename, datain, sizeof(struct RENAME3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2280,7 +2291,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
memcpy(&callmsg->fs, datain, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
callmsg->ch.rp_xid = txdr_unsigned(xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
callmsg->ch.rp_rpcvers = rpc_vers;
@ -2315,6 +2326,29 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
return ESRCH;
}
/****************************************************************************
* Name: rpcclnt_lookup
*
* Desciption:
* Given a directory file handle, and the path to file in the directory,
* return the file handle of the path and attributes of both the file and
* the directory containing the file.
*
* NOTE: The LOOKUP call differs from other RPC messages in that the
* call message is variable length, depending upon the size of the path
* name.
*
****************************************************************************/
int rpcclnt_lookup(FAR struct rpcclnt *rpc, FAR const char *relpath,
FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes)
{
#warning "Missing logic"
return ENOSYS;
}
#ifdef COMP
int rpcclnt_cancelreqs(struct rpcclnt *rpc)
{