From f06204ab7b08145c79275c5a32b7e1ce1ecc3272 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 9 Jun 2012 00:08:18 +0000 Subject: [PATCH] NFS update git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4819 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/fs/nfs/nfs_proto.h | 35 +++- nuttx/fs/nfs/nfs_socket.c | 4 +- nuttx/fs/nfs/nfs_vfsops.c | 390 ++++++++++++++++++++++++++++---------- nuttx/fs/nfs/rpc_clnt.c | 38 ++-- 4 files changed, 332 insertions(+), 135 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 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; 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;