9
0
Fork 0

NFS update

git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4819 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
patacongo 2012-06-09 00:08:18 +00:00
parent bc80377bfe
commit f06204ab7b
4 changed files with 332 additions and 135 deletions

View File

@ -116,7 +116,7 @@
#define NFSX_UNSIGNED 4
/* specific to NFS Version 2 */
/* Specific to NFS Version 2 */
#define NFSX_V2FH 32
#define NFSX_V2FATTR 68
@ -124,7 +124,7 @@
#define NFSX_V2COOKIE 4
#define NFSX_V2STATFS 20
/* specific to NFS Version 3 */
/* Specific to NFS Version 3 */
#define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */
#define NFSX_V3FHMAX 64 /* max. allowed by protocol */
@ -285,6 +285,21 @@
#define NFS_MAXFHSIZE 64
/* Mode bit values */
#define NFSMMODE_IXOTH 0x00001 /* Execute permission for others on a file */
#define NFSMMODE_IWOTH 0x00002 /* Write permission for others */
#define NFSMMODE_IROTH 0x00004 /* Read permission for others */
#define NFSMMODE_IXGRP 0x00008 /* Execute permission for group on a file */
#define NFSMMODE_IWGRP 0x00010 /* Write permission for group */
#define NFSMMODE_IRGRP 0x00020 /* Read permission for group */
#define NFSMMODE_IXUSR 0x00040 /* Execute permission for owner on a file */
#define NFSMMODE_IWUSR 0x00080 /* Write permission for owner */
#define NFSMMODE_IRUSR 0x00100 /* Read permission for owner */
#define NFSMMODE_SAVETEXT 0x00200 /* Save swapped text */
#define NFSMMODE_ISGID 0x00400 /* Set group ID on execution */
#define NFSMMODE_ISUID 0x00800 /* Set user ID on execution */
/* File identifier */
#define MAXFIDSZ 16
@ -297,13 +312,13 @@
typedef enum
{
NFNON = 0,
NFREG = 1,
NFDIR = 2,
NFBLK = 3,
NFCHR = 4,
NFLNK = 5,
NFSOCK = 6,
NFNON = 0, /* Unknown type */
NFREG = 1, /* Regular file */
NFDIR = 2, /* Directory */
NFBLK = 3, /* Block special device file */
NFCHR = 4, /* Characgter special device file */
NFLNK = 5, /* Symbolic link */
NFSOCK = 6, /* Socket */
NFFIFO = 7
} nfstype;
@ -670,8 +685,10 @@ struct READDIR3args
struct READDIR3resok
{
uint32_t attributes_follow;
struct nfs_fattr dir_attributes;
uint8_t cookieverf[NFSX_V3COOKIEVERF];
uint32_t value_follows;
uint32_t reply[1]; /* Variable length reply begins here */
};

View File

@ -201,13 +201,13 @@ tryagain:
goto out;
}
bcopy(dataout, &replyh, sizeof(struct rpc_reply_header));
memcpy(&replyh, dataout, sizeof(struct rpc_reply_header));
if (replyh.rpc_verfi.authtype != 0)
{
error = fxdr_unsigned(int, replyh.rpc_verfi.authtype);
if ((nmp->nm_flag & NFSMNT_NFSV3) && error == NFSERR_TRYLATER)
if ((nmp->nm_flag & NFSMNT_NFSV3) && error == EAGAIN)
{
error = 0;
trylater_delay *= NFS_TIMEOUTMUL;

View File

@ -240,9 +240,9 @@ again:
memset(&create, 0, sizeof(struct CREATE3args));
memset(&resok, 0, sizeof(struct rpc_reply_create));
bcopy(&sp, &create.how, sizeof(struct nfsv3_sattr));
memcpy(&create.how, &sp, sizeof(struct nfsv3_sattr));
create.where.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &create.where.dir.handle, sizeof(nfsfh_t));
memcpy(&create.where.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
create.where.length = txdr_unsigned(64);
strncpy(create.where.name, relpath, 64);
@ -282,9 +282,9 @@ again:
}
np->n_open = true;
bcopy(&resok.create.fshandle.handle, &np->n_fhp, sizeof(nfsfh_t));
memcpy(&np->n_fhp, &resok.create.fshandle.handle, sizeof(nfsfh_t));
np->n_size = fxdr_hyper(&resok.create.attributes.fa3_size);
bcopy(&resok.create.attributes, &np->n_fattr, sizeof(struct nfs_fattr));
memcpy(&resok.create.attributes, &np->n_fattr, sizeof(struct nfs_fattr));
fxdr_nfsv3time(&resok.create.attributes.fa3_mtime, &np->n_mtime)
np->n_ctime = fxdr_hyper(&resok.create.attributes.fa3_ctime);
@ -304,7 +304,7 @@ again:
}
else
{
if (error == NFSERR_NOTSUPP)
if (error == EOPNOTSUPP)
{
goto again;
}
@ -577,12 +577,12 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen)
writesize = resok.write.count;
if (writesize == 0)
{
error = NFSERR_IO;
error = EIO;
goto errout_with_semaphore;
}
commit = resok.write.committed;
bcopy(&resok.write.file_wcc.after, &np->n_fattr, sizeof(struct nfs_fattr));
memcpy(&np->n_fattr, &resok.write.file_wcc.after, sizeof(struct nfs_fattr));
/* Return the lowest committment level obtained by any of the RPCs. */
@ -598,12 +598,12 @@ nfs_write(FAR struct file *filep, const char *buffer, size_t buflen)
if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
{
bcopy((void*) resok.write.verf, (void*) nmp->nm_verf, NFSX_V3WRITEVERF);
memcpy((void*) nmp->nm_verf, (void*) resok.write.verf, NFSX_V3WRITEVERF);
nmp->nm_flag |= NFSMNT_HASWRITEVERF;
}
else if (strncmp((char*) resok.write.verf, (char*) nmp->nm_verf, NFSX_V3WRITEVERF))
{
bcopy((void*) resok.write.verf, (void*) nmp->nm_verf, NFSX_V3WRITEVERF);
memcpy((void*) nmp->nm_verf, (void*) resok.write.verf, NFSX_V3WRITEVERF);
}
fxdr_nfsv3time(&np->n_fattr.fa3_mtime, &np->n_mtime)
@ -707,12 +707,14 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
{
/* This buffer needs to go into struct fs_dirent_s nuttx/dirent.h */
uint32_t buffer[64];
struct READDIR3args readdir;
struct READDIR3args rddir;
struct rpc_reply_readdir *resok;
struct entry3 *entry;
uint32_t tmp;
uint32_t *ptr; /* This goes in fs_dirent_s */
uint8_t *name;
int length;
unsigned int length;
bool more;
bool eod;
int error = 0;
/* Check in 'dir' if we are have directories entries?
@ -722,104 +724,222 @@ int nfs_readdirrpc(struct nfsmount *nmp, struct nfsnode *np,
* If we have returned entries then read more entries if:
* 3) EOF = 0
*/
more = false; /* Set 'more' to true if we have buffered entries to be processed */
eod = false; /* Set 'eod' if we are at the end of the directory */
/* if need to read data */
/* Loop while we need more data (!more) and we are not at the end of
* the directory (!eod)
*/
while (!more && !eod)
{
/* Request a block directory enries */
nfsstats.rpccnt[NFSPROC_READDIR]++;
memset(&readdir, 0, sizeof(struct READDIR3args));
readdir.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &readdir.dir.handle, sizeof(nfsfh_t));
readdir.count = nmp->nm_readdirsize;
memset(&rddir, 0, sizeof(struct READDIR3args));
rddir.dir.length = txdr_unsigned(np->n_fhsize);
memcpy(&rddir.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
rddir.count = txdr_unsigned(nmp->nm_readdirsize);
if (nfsstats.rpccnt[NFSPROC_READDIR] == 1)
{
readdir.cookie.nfsuquad[0] = 0;
readdir.cookie.nfsuquad[1] = 0;
memset(&readdir.cookieverf, 0, NFSX_V3COOKIEVERF);
rddir.cookie.nfsuquad[0] = 0;
rddir.cookie.nfsuquad[1] = 0;
memset(&rddir.cookieverf, 0, NFSX_V3COOKIEVERF);
}
else
{
readdir.cookie.nfsuquad[0] = dir->u.nfs.cookie[0];
readdir.cookie.nfsuquad[1] = dir->u.nfs.cookie[1];
bcopy(&np->n_cookieverf, readdir.cookieverf, NFSX_V3COOKIEVERF);
rddir.cookie.nfsuquad[0] = dir->u.nfs.cookie[0];
rddir.cookie.nfsuquad[1] = dir->u.nfs.cookie[1];
memcpy(&rddir.cookieverf, &np->n_cookieverf, NFSX_V3COOKIEVERF);
}
error = nfs_request(nmp, NFSPROC_READDIR, (FAR const void *)&readdir,
error = nfs_request(nmp, NFSPROC_READDIR, (FAR const void *)&rddir,
(FAR void *)buffer, sizeof(buffer));
if (error)
{
goto nfsmout;
}
/* Save the node attributes and cooking information */
/* A new group of entries was successfully read. Process the
* information contained in the response header. This information
* includes:
*
* 1) Attributes follow indication - 4 bytes
* 2) Directory attributes - sizeof(struct nfs_fattr)
* 3) Cookie verifier - NFSX_V3COOKIEVERF bytes
* 4) Values follows indication - 4 bytes
*/
resok = (struct rpc_reply_readdir *)buffer;
bcopy(&resok->readdir.dir_attributes, &np->n_fattr, sizeof(struct nfs_fattr));
bcopy(&resok->readdir.cookieverf, np->n_cookieverf, NFSX_V3WRITEVERF);
/* Start with the first entry */
ptr = resok->readdir.reply;
ptr = (uint32_t*)&resok->readdir;
/* Check if attributes follow, if 0 so Skip over the attributes */
if (resok->readdir.attributes_follow == 1)
{
/* Get attibutes */
memcpy(&np->n_fattr, &resok->readdir.dir_attributes,
sizeof(struct nfs_fattr));
}
#warning "Won't the structure format be wrong if there are no attributes -- this will need to be parsed too"
/* Save the verification cookie */
memcpy(&np->n_cookieverf, &resok->readdir.cookieverf, NFSX_V3WRITEVERF);
/* Get a point to the entries (if any) */
ptr = (uint32_t*)&resok->readdir.reply;
/* Check if values follow. If no values follow, then the EOF indication
* will appear next.
*/
if (resok->readdir.value_follows == 0)
{
/* No values follow, then the reply should consist only of a 4-byte
* end-of-directory indication.
*/
more = false; /* No entries follow */
eod = (*ptr != 0); /* We are (probably) at the end of the directory */
}
else
{
more = true; /* Assume that entries follow */
eod = false; /* Assume that we are not at the end of the directory */
}
}
/* Check for EOF */
#if 0 /* This logic is NOT correct */
if (*ptr != 0)
{
np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]);
/* If we are not at the end of the directory listing, then a set of entries
* will follow the header. Each entry is of the form:
*
* File ID (8 bytes)
* Name length (4 bytes)
* Name string (varaiable size but in multiples of 4 bytes)
* Cookie (8 bytes)
* next entry (4 bytes)
*
* If 'more' is true, then we have more directory entries to process.
*/
if (more)
{
/* There is an entry. Get the file ID and point to the length */
/* Missing logic to get the file ID */
ptr += 2;
/* Get the length and point to the name */
tmp = *ptr++;
length = fxdr_unsigned(uint32_t, tmp);
name = (uint8_t*)ptr;
/* Increment the pointer past the name (allowing for padding). ptr
* now points to the cookie.
*/
ptr += (length + 3) >> 2;
/* Save the cookie and increment the pointer to the next entry */
dir->u.nfs.cookie[0] = *ptr++;
dir->u.nfs.cookie[1] = *ptr++;
ptr++; /* Just skip over the nextentry for now */
/* Return the directory entry to the caller. On subsequent calls to
* readdir(), we will return the next entry. And so on until all of
* the entries have been returned. Then read the next next block
* of entries until EOF is reported.
*/
#warning "Not implemented"
/* Return the name of the node to the caller */
if (length > NAME_MAX)
{
length = NAME_MAX;
}
memcpy(dir->fd_dir.d_name, name, length);
dir->fd_dir.d_name[length] = '\0';
fvdbg("name: \"%s\"\n", dir->fd_dir.d_name);
/* 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
char *path;
/* Construct the full path to the file */
asprintf(&path, "%s/%s", relpath, dir->fd_dir.d_name);
if (path)
{
/* Then stat the file */
int ret = nfs_getfsinfo(nmp, path, &buf);
if (ret == OK)
{
if (S_ISREG(buf.st_mode))
{
dir->fd_dir.d_type = DTYPE_FILE;
}
else if (S_ISDIR(buf.st_mode))
{
dir->fd_dir.d_type = DTYPE_FILE;
}
else if (S_ISCHR(buf.st_mode) || S_ISFIFO(buf.st_mode))
{
dir->fd_dir.d_type = DTYPE_FILE;
}
else if (S_ISBLK(buf.st_mode))
{
dir->fd_dir.d_type = DTYPE_FILE;
}
else
{
#warning "Other types should be ignored ... go to the next entry"
}
}
/* Free the allocated string */
kfree(path);
}
}
#else
#warning "Missing logic"
dir->fd_dir.d_type = DTYPE_FILE;
#endif
error = 0;
}
/* We are at the end of the directory. If 'eod' is true then we all of the
* directory entries have been processed and we are at the end of the
* directory.
*/
if (eod)
{
/* We signal the end of the directory by returning the
* special error -ENOENT
*/
fdbg("End of directory\n");
fvdbg("End of directory\n");
error = ENOENT;
}
#endif
/* Otherwise, there is an entry. Get the file ID and point to the length */
/* Missing logic to get the file ID */
ptr += 2;
/* Get the length and point to the name */
length = *ptr++;
name = (uint8_t*)ptr;
/* Increment the pointer past the name (allowing for padding). ptr now points to the cookie. */
ptr += (length + 3) >> 2;
/* Return the first entry to the caller. On subsequent calls to readdir(),
* we will return the next entry. And so on until all of the entries have
* been returned. Then read the next next block of entries until EOF is
* report.
*/
#warning "Not implemented"
/* Save the cookie and increment the point to point to the next entry */
dir->u.nfs.cookie[0] = *ptr++;
dir->u.nfs.cookie[1] = *ptr++;
ptr++; /* Just skip over the nextentry for now */
/* Return the Type of the node to the caller */
/* MISSING LOGIC TO DETERMINE FILE TYPE -- Need to (1) get nfstype, and (2)
* map NFREG, NFDIR, etc. to values in dirent.h.
*/
dir->fd_dir.d_type = DTYPE_FILE;
// dir->fd_dir.d_type = entry->fileid;
#warning "This must match the type values in dirent.h"
/* Return the name of the node to the caller */
memcpy(dir->fd_dir.d_name, name, length > NAME_MAX ? NAME_MAX : length);
dir->fd_dir.d_name[NAME_MAX] = '\0';
error = 0;
nfsmout:
return error;
@ -889,19 +1009,13 @@ static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
(void)nfs_getfsinfo(nmp, NULL, NULL);
}
error = nfs_readdirrpc(nmp, np, dir);
/* Read and return one directory entry. */
if (error == NFSERR_BAD_COOKIE)
error = nfs_readdirrpc(nmp, np, dir);
if (error != 0)
{
error = EINVAL;
goto errout_with_semaphore;
}
#if 0
if (!error && eof)
{
nfsstats.direofcache_misses++;
}
#endif
success_with_semaphore:
error = 0;
@ -1238,9 +1352,9 @@ int mountnfs(struct nfs_args *argp, void **handle)
np->n_flag |= NMODIFIED;
nmp->nm_head = np;
nmp->nm_mounted = true;
bcopy(&nmp->nm_rpcclnt->rc_fh, &nmp->nm_fh, sizeof(nfsfh_t));
memcpy(&nmp->nm_fh, &nmp->nm_rpcclnt->rc_fh, sizeof(nfsfh_t));
nmp->nm_fhsize = NFSX_V2FH;
bcopy(&nmp->nm_fh, &nmp->nm_head->n_fhp, sizeof(nfsfh_t));
memcpy(&nmp->nm_head->n_fhp, &nmp->nm_fh, sizeof(nfsfh_t));
nmp->nm_head->n_fhsize = nmp->nm_fhsize;
nmp->nm_so = nmp->nm_rpcclnt->rc_so;
@ -1249,7 +1363,7 @@ int mountnfs(struct nfs_args *argp, void **handle)
memset(&getattr, 0, sizeof(struct FS3args));
memset(&resok, 0, sizeof(struct rpc_reply_getattr));
getattr.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
bcopy(&nmp->nm_fh, &getattr.fsroot.handle, sizeof(nfsfh_t));
memcpy(&getattr.fsroot.handle, &nmp->nm_fh, sizeof(nfsfh_t));
error = nfs_request(nmp, NFSPROC_GETATTR, (FAR const void *)&getattr,
(FAR void*)&resok, sizeof(struct rpc_reply_getattr));
@ -1321,7 +1435,7 @@ static int nfs_bind(struct inode *blkdriver, const void *data, void **handle)
struct nfs_args args;
int error;
bcopy(data, &args, sizeof(struct nfs_args));
memcpy(&args, data, sizeof(struct nfs_args));
if (args.version == NFS_ARGSVERSION)
{
args.flags &= ~(NFSMNT_INTERNAL | NFSMNT_NOAC);
@ -1520,7 +1634,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
memset(&remove, 0, sizeof(struct REMOVE3args));
memset(&resok, 0, sizeof(struct rpc_reply_remove));
remove.object.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &remove.object.dir.handle, sizeof(nfsfh_t));
memcpy(&remove.object.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
remove.object.length = txdr_unsigned(64);
strncpy(remove.object.name, relpath, 64);
@ -1543,7 +1657,7 @@ static int nfs_remove(struct inode *mountpt, const char *relpath)
goto errout_with_semaphore;
}
bcopy(&resok.remove.dir_wcc.after, &np->n_fattr, sizeof(struct nfs_fattr));
memcpy(&np->n_fattr, &resok.remove.dir_wcc.after, sizeof(struct nfs_fattr));
np->n_flag |= NMODIFIED;
}
@ -1596,7 +1710,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
memset(&mkir, 0, sizeof(struct MKDIR3args));
memset(&resok, 0, sizeof(struct rpc_reply_mkdir));
mkir.where.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &mkir.where.dir.handle, sizeof(nfsfh_t));
memcpy(&mkir.where.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
mkir.where.length = txdr_unsigned(64);
strncpy(mkir.where.name, relpath, 64);
@ -1611,7 +1725,7 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
//memset(&sp.sa_atime, 0, sizeof(nfstime3));
//memset(&sp.sa_mtime, 0, sizeof(nfstime3));
bcopy(&sp, &mkir.attributes, sizeof(struct nfsv3_sattr));
memcpy(&mkir.attributes, &sp, sizeof(struct nfsv3_sattr));
error = nfs_request(nmp, NFSPROC_MKDIR, (FAR const void *)&mkir,
(FAR void *)&resok, sizeof(struct rpc_reply_mkdir));
@ -1622,9 +1736,9 @@ static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
np->n_open = true;
np->nfsv3_type = fxdr_unsigned(uint32_t, resok.mkdir.obj_attributes.fa_type);
bcopy(&resok.mkdir.fshandle.handle, &np->n_fhp, sizeof(nfsfh_t));
memcpy(&np->n_fhp, &resok.mkdir.fshandle.handle, sizeof(nfsfh_t));
np->n_size = fxdr_hyper(&resok.mkdir.obj_attributes.fa3_size);
bcopy(&resok.mkdir.obj_attributes, &np->n_fattr, sizeof(struct nfs_fattr));
memcpy(&np->n_fattr, &resok.mkdir.obj_attributes, sizeof(struct nfs_fattr));
fxdr_nfsv3time(&resok.mkdir.obj_attributes.fa3_mtime, &np->n_mtime)
np->n_ctime = fxdr_hyper(&resok.mkdir.obj_attributes.fa3_ctime);
np->n_flag |= NMODIFIED;
@ -1684,7 +1798,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
memset(&rmdir, 0, sizeof(struct RMDIR3args));
memset(&resok, 0, sizeof(struct rpc_reply_rmdir));
rmdir.object.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &rmdir.object.dir.handle, sizeof(nfsfh_t));
memcpy(&rmdir.object.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
rmdir.object.length = txdr_unsigned(64);
strncpy(rmdir.object.name, relpath, 64);
@ -1700,7 +1814,7 @@ static int nfs_rmdir(struct inode *mountpt, const char *relpath)
goto errout_with_semaphore;
}
bcopy(&resok.rmdir.dir_wcc.after, &np->n_fattr, sizeof(struct nfs_fattr));
memcpy(&np->n_fattr, &resok.rmdir.dir_wcc.after, sizeof(struct nfs_fattr));
np->n_flag |= NMODIFIED;
}
@ -1760,11 +1874,11 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
memset(&rename, 0, sizeof(struct RENAME3args));
memset(&resok, 0, sizeof(struct rpc_reply_rename));
rename.from.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &rename.from.dir.handle, sizeof(nfsfh_t));
memcpy(&rename.from.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
rename.from.length = txdr_unsigned(64);
strncpy(rename.from.name, oldrelpath, 64);
rename.to.dir.length = txdr_unsigned(np->n_fhsize);
bcopy(&np->n_fhp, &rename.to.dir.handle, sizeof(nfsfh_t));
memcpy(&rename.to.dir.handle, &np->n_fhp, sizeof(nfsfh_t));
rename.to.length = txdr_unsigned(64);
strncpy(rename.to.name, newrelpath, 64);
@ -1783,7 +1897,7 @@ static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
goto errout_with_semaphore;
}
bcopy(&resok.rename.todir_wcc.after, &np->n_fattr, sizeof(struct nfs_fattr));
memcpy(&np->n_fattr, &resok.rename.todir_wcc.after, sizeof(struct nfs_fattr));
np->n_flag |= NMODIFIED;
NFS_INVALIDATE_ATTRCACHE(np);
@ -1846,7 +1960,9 @@ static int nfs_getfsinfo(struct nfsmount *nmp, const char *relpath,
{
nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize == 0)
nmp->nm_wsize = max;
{
nmp->nm_wsize = max;
}
}
pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtpref);
@ -1886,7 +2002,71 @@ static int nfs_getfsinfo(struct nfsmount *nmp, const char *relpath,
if (buf)
{
buf->st_mode = fxdr_unsigned(uint32_t, nmp->nm_fattr.fa_mode);
/* 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);
/* 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);
/* 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;

View File

@ -777,7 +777,7 @@ static int rpcclnt_reply(struct rpctask *myrep, int procid, int prog,
return error;
}
bcopy(reply, &replyheader, sizeof(struct rpc_reply_header));
memcpy(&replyheader, reply, sizeof(struct rpc_reply_header));
/* Get the xid and check that it is an rpc replysvr */
@ -1281,7 +1281,7 @@ int rpcclnt_connect(struct rpcclnt *rpc)
goto bad;
}
bcopy(&mdata.mount.fhandle, &rpc->rc_fh, sizeof(nfsfh_t));
memcpy(&rpc->rc_fh, &mdata.mount.fhandle, sizeof(nfsfh_t));
/* Do the RPC to get a dynamic bounding with the server using PMAP.
* NFS port in the socket.
@ -1614,8 +1614,8 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
if (error == 0 || error == EPIPE)
{
error = rpcclnt_reply(task, procnum, prog, dataout, len);
fvdbg("rpcclnt_reply returned: %d\n", error);
}
fvdbg("out for reply %d\n", error);
/* RPC done, unlink the request. */
@ -1637,7 +1637,7 @@ int rpcclnt_request(struct rpcclnt *rpc, int procnum, int prog, int version,
/* Break down the rpc header and check if ok */
memset(&replymgs, 0, sizeof(replymgs));
bcopy(dataout, &replyheader, sizeof(struct rpc_reply_header));
memcpy(&replyheader, dataout, sizeof(struct rpc_reply_header));
replymgs.type = fxdr_unsigned(uint32_t, replyheader.type);
if (replymgs.type == RPC_MSGDENIED)
{
@ -1877,7 +1877,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
if (procid == PMAPPROC_GETPORT)
{
struct rpc_call_pmap *callmsg = (struct rpc_call_pmap *)dataout;
bcopy(datain, &callmsg->pmap, sizeof(struct call_args_pmap));
memcpy(&callmsg->pmap, datain, sizeof(struct call_args_pmap));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
@ -1907,7 +1907,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
else if (procid == PMAPPROC_UNSET)
{
struct rpc_call_pmap *callmsg = (struct rpc_call_pmap *)dataout;;
bcopy(datain, &callmsg->pmap, sizeof(struct call_args_pmap));
memcpy(&callmsg->pmap, datain, sizeof(struct call_args_pmap));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -1939,7 +1939,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
if (procid == RPCMNT_UMOUNT)
{
struct rpc_call_mount *callmsg = (struct rpc_call_mount *)dataout;
bcopy(datain, &callmsg->mount, sizeof(struct call_args_mount));
memcpy(&callmsg->mount, datain, sizeof(struct call_args_mount));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -1968,7 +1968,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
else if (procid == RPCMNT_MOUNT)
{
struct rpc_call_mount *callmsg = (struct rpc_call_mount *)dataout;
bcopy(datain, &callmsg->mount, sizeof(struct call_args_mount));
memcpy(&callmsg->mount, datain, sizeof(struct call_args_mount));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2002,7 +2002,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_CREATE:
{
struct rpc_call_create *callmsg = (struct rpc_call_create *)dataout;
bcopy(datain, &callmsg->create, sizeof(struct CREATE3args));
memcpy(&callmsg->create, datain, sizeof(struct CREATE3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2032,7 +2032,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_READ:
{
struct rpc_call_read *callmsg = (struct rpc_call_read *)dataout;
bcopy(datain, &callmsg->read, sizeof(struct READ3args));
memcpy(&callmsg->read, datain, sizeof(struct READ3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2063,7 +2063,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_WRITE:
{
struct rpc_call_write *callmsg = (struct rpc_call_write *)dataout;
bcopy(datain, &callmsg->write, sizeof(struct WRITE3args));
memcpy(&callmsg->write, datain, sizeof(struct WRITE3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2094,7 +2094,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_READDIR:
{
struct rpc_call_readdir *callmsg = (struct rpc_call_readdir *)dataout;
bcopy(datain, &callmsg->readdir, sizeof(struct READDIR3args));
memcpy(&callmsg->readdir, datain, sizeof(struct READDIR3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2125,7 +2125,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_FSSTAT:
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
bcopy(datain, &callmsg->fs, sizeof(struct FS3args));
memcpy(&callmsg->fs, datain, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2156,7 +2156,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_REMOVE:
{
struct rpc_call_remove *callmsg = (struct rpc_call_remove *)dataout;
bcopy(datain, &callmsg->remove, sizeof(struct REMOVE3args));
memcpy(&callmsg->remove, datain, sizeof(struct REMOVE3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2187,7 +2187,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_GETATTR:
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
bcopy(datain, &callmsg->fs, sizeof(struct FS3args));
memcpy(&callmsg->fs, datain, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2218,7 +2218,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_MKDIR:
{
struct rpc_call_mkdir *callmsg = (struct rpc_call_mkdir *)dataout;
bcopy(datain, &callmsg->mkdir, sizeof(struct MKDIR3args));
memcpy(&callmsg->mkdir, datain, sizeof(struct MKDIR3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2249,7 +2249,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_RMDIR:
{
struct rpc_call_rmdir *callmsg = (struct rpc_call_rmdir *)dataout;
bcopy(datain, &callmsg->rmdir, sizeof(struct RMDIR3args));
memcpy(&callmsg->rmdir, datain, sizeof(struct RMDIR3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2280,7 +2280,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_RENAME:
{
struct rpc_call_rename *callmsg = (struct rpc_call_rename *)dataout;
bcopy(datain, &callmsg->rename, sizeof(struct RENAME3args));
memcpy(&callmsg->rename, datain, sizeof(struct RENAME3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;
@ -2311,7 +2311,7 @@ int rpcclnt_buildheader(struct rpcclnt *rpc, int procid, int prog, int vers,
case NFSPROC_FSINFO:
{
struct rpc_call_fs *callmsg = (struct rpc_call_fs *)dataout;
bcopy(datain, &callmsg->fs, sizeof(struct FS3args));
memcpy(&callmsg->fs, datain, sizeof(struct FS3args));
callmsg->ch.rp_xid = txdr_unsigned(rpcclnt_xid);
value->xid = callmsg->ch.rp_xid;
callmsg->ch.rp_direction = rpc_call;