summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-06-09 00:08:18 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-06-09 00:08:18 +0000
commitcd9f8ddacbdfdcfa75938f9fb803a86a4e2bbea4 (patch)
tree84dbabc493adcee6494a68abcab2c2462627d6e9 /nuttx
parentc59c1efa5e7c9f89665a1e9a4d4792094684f5e9 (diff)
downloadpx4-nuttx-cd9f8ddacbdfdcfa75938f9fb803a86a4e2bbea4.tar.gz
px4-nuttx-cd9f8ddacbdfdcfa75938f9fb803a86a4e2bbea4.tar.bz2
px4-nuttx-cd9f8ddacbdfdcfa75938f9fb803a86a4e2bbea4.zip
NFS update
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4819 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/fs/nfs/nfs_proto.h35
-rw-r--r--nuttx/fs/nfs/nfs_socket.c4
-rw-r--r--nuttx/fs/nfs/nfs_vfsops.c368
-rw-r--r--nuttx/fs/nfs/rpc_clnt.c38
4 files changed, 321 insertions, 124 deletions
diff --git a/nuttx/fs/nfs/nfs_proto.h b/nuttx/fs/nfs/nfs_proto.h
index 2512a842e..78b584238 100644
--- a/nuttx/fs/nfs/nfs_proto.h
+++ b/nuttx/fs/nfs/nfs_proto.h
@@ -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 */
};
diff --git a/nuttx/fs/nfs/nfs_socket.c b/nuttx/fs/nfs/nfs_socket.c
index 3c6524d89..141196b01 100644
--- a/nuttx/fs/nfs/nfs_socket.c
+++ b/nuttx/fs/nfs/nfs_socket.c
@@ -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;
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
index 655d552d1..c78825fe8 100644
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ b/nuttx/fs/nfs/nfs_vfsops.c
@@ -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 for EOF */
-#if 0 /* This logic is NOT correct */
- if (*ptr != 0)
- {
- np->n_direofoffset = fxdr_hyper(&dir->u.nfs.cookie[0]);
+ /* Check if attributes follow, if 0 so Skip over the attributes */
- /* We signal the end of the directory by returning the
- * special error -ENOENT
+ 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.
*/
- fdbg("End of directory\n");
- error = ENOENT;
+ 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 */
+ }
}
-#endif
- /* Otherwise, there is an entry. Get the file ID and point to the length */
- /* Missing logic to get the file ID */
+ /* 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.
+ */
- ptr += 2;
+ if (more)
+ {
+ /* There is an entry. Get the file ID and point to the length */
+ /* Missing logic to get the file ID */
- /* Get the length and point to the name */
+ ptr += 2;
- length = *ptr++;
- name = (uint8_t*)ptr;
+ /* Get the length and point to the name */
- /* Increment the pointer past the name (allowing for padding). ptr now points to the cookie. */
+ tmp = *ptr++;
+ length = fxdr_unsigned(uint32_t, tmp);
+ name = (uint8_t*)ptr;
- ptr += (length + 3) >> 2;
+ /* Increment the pointer past the name (allowing for padding). ptr
+ * now points to the cookie.
+ */
- /* 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.
- */
+ 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"
- /* Save the cookie and increment the point to point to the next entry */
+ /* 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.
+ */
- dir->u.nfs.cookie[0] = *ptr++;
- dir->u.nfs.cookie[1] = *ptr++;
+#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;
- ptr++; /* Just skip over the nextentry for now */
+ /* Construct the full path to the file */
- /* 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.
- */
+ 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;
+ }
- dir->fd_dir.d_type = DTYPE_FILE;
-// dir->fd_dir.d_type = entry->fileid;
-#warning "This must match the type values in dirent.h"
+ /* 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.
+ */
- /* Return the name of the node to the caller */
+ if (eod)
+ {
+ /* We signal the end of the directory by returning the
+ * special error -ENOENT
+ */
- memcpy(dir->fd_dir.d_name, name, length > NAME_MAX ? NAME_MAX : length);
- dir->fd_dir.d_name[NAME_MAX] = '\0';
- error = 0;
+ fvdbg("End of directory\n");
+ error = ENOENT;
+ }
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;
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
index e278bc628..243bbb0f0 100644
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ b/nuttx/fs/nfs/rpc_clnt.c
@@ -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;