NFS bug fix and improvement (#412)

* fs/nfs: Remove all nfs_checkmount call.  The check just waste cpu cycle since nobody will set nm_mounted to false, and remove the unused fields(nm_mounted and n_flags) and related flags too
* fs/nfs: Fix the definition not confirm to RFC 1813 and other minor issue(unused, typo, duplication, alignment...)
* fs/nfs: Always represent error with negative number and remove the unused arguments from function
* fs/nfs: Set socket receive timeout with nfs_args->timeo and fix warning:

nfs/nfs.h:59:28: warning: large integer implicitly truncated to unsigned type [-Woverflow]
 #define NFS_TIMEO          (1 * NFS_HZ)   /* Default timeout = 1 second */
                            ^
nfs/nfs_vfsops.c:1857:23: note: in expansion of macro 'NFS_TIMEO'
   nprmt.timeo       = NFS_TIMEO;
                            ^
                       ^~~~~~~~~

* fs/nfs: Update the file attribute correctly in nfs_filetruncate and simplify the attrbitue conversion between NFSv3 and NuttX
* fs/nfs: Remove the unfinished and buggy EXCLUSIVE creation mode
* fs/nfs: Call nfs_fsinfo in nfs_bind instead of nfs_statfs since we should update the buffer size before transfer happen, and handle the attribute existence variance correctly.
* fs/nfs: Shouldn't insert node into list again in nfs_dup and fix other typo issue
* fs/nfs: Should skip . and .. in nfs_readdir
* fs/nfs: Remove the unnecessary dynamic allocation and the duplicated root handle storage
This commit is contained in:
Xiang Xiao
2020-03-02 04:53:45 +08:00
committed by Gregory Nutt
parent 350adb236f
commit 915f094a74
9 changed files with 524 additions and 906 deletions
+4 -15
View File
@@ -54,18 +54,14 @@
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define NFS_TICKS 1 /* Number of system ticks */ #define NFS_TIMEO 10 /* Default timeout = 1 second */
#define NFS_HZ CLOCKS_PER_SEC /* Ticks/sec */ #define NFS_MINTIMEO 10 /* Min timeout to use */
#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */ #define NFS_MAXTIMEO 255 /* Max timeout to backoff to */
#define NFS_MINTIMEO (1 * NFS_HZ) /* Min timeout to use */
#define NFS_MAXTIMEO (60 * NFS_HZ) /* Max timeout to backoff to */
#define NFS_TIMEOUTMUL 2 /* Timeout/Delay multiplier */
#define NFS_MAXREXMIT 100 /* Stop counting after this many */ #define NFS_MAXREXMIT 100 /* Stop counting after this many */
#define NFS_RETRANS 10 /* Num of retrans for soft mounts */ #define NFS_RETRANS 10 /* Num of retrans for soft mounts */
#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */ #define NFS_WSIZE 8192 /* Def. write data size <= 8192 */
#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */ #define NFS_RSIZE 8192 /* Def. read data size <= 8192 */
#define NFS_READDIRSIZE 8192 /* Def. readdir size */ #define NFS_READDIRSIZE 8192 /* Def. readdir size */
#define NFS_NPROCS 23
/* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with /* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with
* broken NFS/ethernet drivers that won't work with anything bigger (Linux..) * broken NFS/ethernet drivers that won't work with anything bigger (Linux..)
@@ -85,9 +81,6 @@
* Public Data * Public Data
****************************************************************************/ ****************************************************************************/
extern uint32_t nfs_true;
extern uint32_t nfs_false;
extern uint32_t nfs_xdrneg1;
#ifdef CONFIG_NFS_STATISTICS #ifdef CONFIG_NFS_STATISTICS
extern struct nfsstats nfsstats; extern struct nfsstats nfsstats;
#endif #endif
@@ -115,11 +108,7 @@ extern "C" {
#define EXTERN extern #define EXTERN extern
#endif #endif
EXTERN void nfs_semtake(FAR struct nfsmount *nmp); EXTERN int nfs_request(FAR struct nfsmount *nmp, int procnum,
EXTERN void nfs_semgive(FAR struct nfsmount *nmp);
EXTERN int nfs_checkmount(FAR struct nfsmount *nmp);
EXTERN int nfs_fsinfo(FAR struct nfsmount *nmp);
EXTERN int nfs_request(struct nfsmount *nmp, int procnum,
FAR void *request, size_t reqlen, FAR void *request, size_t reqlen,
FAR void *response, size_t resplen); FAR void *response, size_t resplen);
EXTERN int nfs_lookup(FAR struct nfsmount *nmp, FAR const char *filename, EXTERN int nfs_lookup(FAR struct nfsmount *nmp, FAR const char *filename,
+15 -20
View File
@@ -67,23 +67,18 @@
struct nfsmount struct nfsmount
{ {
struct nfsnode *nm_head; /* A list of all files opened on this mountpoint */ FAR struct nfsnode *nm_head; /* A list of all files opened on this mountpoint */
sem_t nm_sem; /* Used to assure thread-safe access */ sem_t nm_sem; /* Used to assure thread-safe access */
nfsfh_t nm_fh; /* File handle of root dir */ nfsfh_t *nm_fh; /* File handle of root dir */
char nm_path[90]; /* server's path of the directory being mounted */ char nm_path[90]; /* server's path of the directory being mounted */
struct nfs_fattr nm_fattr; /* nfs file attribute cache */ struct nfs_fattr nm_fattr; /* nfs file attribute cache */
struct rpcclnt *nm_rpcclnt; /* RPC state */ FAR struct rpcclnt *nm_rpcclnt; /* RPC state */
struct socket *nm_so; /* RPC socket */ struct sockaddr nm_nam; /* Addr of server */
struct sockaddr nm_nam; /* Addr of server */ uint8_t nm_fhsize; /* Size of root file handle (host order) */
bool nm_mounted; /* true: The file system is ready */ uint16_t nm_rsize; /* Max size of read RPC */
uint8_t nm_fhsize; /* Size of root file handle (host order) */ uint16_t nm_wsize; /* Max size of write RPC */
uint8_t nm_sotype; /* Type of socket */ uint16_t nm_readdirsize; /* Size of a readdir RPC */
uint8_t nm_retry; /* Max retries */ uint16_t nm_buflen; /* Size of I/O buffer */
uint16_t nm_timeo; /* Timeout value (in system clock ticks) */
uint16_t nm_rsize; /* Max size of read RPC */
uint16_t nm_wsize; /* Max size of write RPC */
uint16_t nm_readdirsize; /* Size of a readdir RPC */
uint16_t nm_buflen; /* Size of I/O buffer */
/* Set aside memory on the stack to hold the largest call message. NOTE /* Set aside memory on the stack to hold the largest call message. NOTE
* that for the case of the write call message, it is the reply message that * that for the case of the write call message, it is the reply message that
@@ -104,7 +99,7 @@ struct nfsmount
struct rpc_call_readdir readdir; struct rpc_call_readdir readdir;
struct rpc_call_fs fsstat; struct rpc_call_fs fsstat;
struct rpc_call_setattr setattr; struct rpc_call_setattr setattr;
struct rpc_call_fs fs; struct rpc_call_fs fsinfo;
struct rpc_reply_write write; struct rpc_reply_write write;
} nm_msgbuffer; } nm_msgbuffer;
@@ -116,10 +111,10 @@ struct nfsmount
* possible WRITE call message or READ response message. * possible WRITE call message or READ response message.
*/ */
uint32_t nm_iobuffer[1]; /* Actual size is given by nm_buflen */ uint32_t nm_iobuffer[1]; /* Actual size is given by nm_buflen */
}; };
/* The size of the nfsmount structure will debug on the size of the allocated I/O /* The size of the nfsmount structure will depend on the size of the allocated I/O
* buffer. * buffer.
*/ */
+10 -19
View File
@@ -50,15 +50,6 @@
#include "nfs_proto.h" #include "nfs_proto.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Flags for struct nfsnode n_flag */
#define NFSNODE_OPEN (1 << 0) /* File is still open */
#define NFSNODE_MODIFIED (1 << 1) /* Might have a modified buffer */
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
@@ -69,16 +60,16 @@
struct nfsnode struct nfsnode
{ {
struct nfsnode *n_next; /* Retained in a singly linked list. */ FAR struct nfsnode *n_next; /* Retained in a singly linked list. */
uint8_t n_crefs; /* Reference count (for nfs_dup) */ uint8_t n_crefs; /* Reference count (for nfs_dup) */
uint8_t n_type; /* File type */ uint8_t n_type; /* File type */
uint8_t n_fhsize; /* Size in bytes of the file handle */ uint8_t n_fhsize; /* Size in bytes of the file handle */
uint8_t n_flags; /* Node flags */ uint16_t n_mode; /* File mode for fstat() */
uint16_t n_mode; /* File mode for fstat() */ time_t n_atime; /* File access time */
time_t n_mtime; /* File modification time */ time_t n_mtime; /* File modification time */
time_t n_ctime; /* File creation time */ time_t n_ctime; /* File creation time */
nfsfh_t n_fhandle; /* NFS File Handle */ nfsfh_t n_fhandle; /* NFS File Handle */
uint64_t n_size; /* Current size of file */ uint64_t n_size; /* Current size of file */
}; };
#endif /* __FS_NFS_NFS_NODE_H */ #endif /* __FS_NFS_NFS_NODE_H */
+20 -35
View File
@@ -118,13 +118,13 @@
/* Specific to NFS Version 3 */ /* Specific to NFS Version 3 */
#define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */ #define NFSX_V3FH (sizeof(struct fhandle)) /* size this server uses */
#define NFSX_V3FHMAX 64 /* max. allowed by protocol */ #define NFSX_V3FHMAX 64 /* max. allowed by protocol */
#define NFSX_V3FATTR 84 #define NFSX_V3FATTR 84
#define NFSX_V3SATTR 60 /* max. all fields filled in */ #define NFSX_V3SATTR 60 /* max. all fields filled in */
#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr)) #define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr))
#define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED) #define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED)
#define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED) #define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 7 * NFSX_UNSIGNED)
#define NFSX_V3COOKIEVERF 8 #define NFSX_V3COOKIEVERF 8
#define NFSX_V3WRITEVERF 8 #define NFSX_V3WRITEVERF 8
#define NFSX_V3CREATEVERF 8 #define NFSX_V3CREATEVERF 8
@@ -185,13 +185,6 @@
#define NFSV3FSINFO_HOMOGENEOUS 0x08 #define NFSV3FSINFO_HOMOGENEOUS 0x08
#define NFSV3FSINFO_CANSETTIME 0x10 #define NFSV3FSINFO_CANSETTIME 0x10
/* Conversion macros */
#define vtonfsv3_mode(m) txdr_unsigned((m) & 07777)
#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777)
#define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))])
#define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(uint32_t,(a))&0x7]
/* Mode bit values */ /* Mode bit values */
#define NFSMODE_IXOTH (1 << 0) /* Execute permission for others on a file */ #define NFSMODE_IXOTH (1 << 0) /* Execute permission for others on a file */
@@ -230,7 +223,7 @@ typedef enum
} nfstype; } nfstype;
/* File Handle variable is up to 64 bytes for version 3. This structures a /* File Handle variable is up to 64 bytes for version 3. This structures a
* ariable sized and are provided only for setting aside maximum memory * variable sized and are provided only for setting aside maximum memory
* allocations for a file handle. * allocations for a file handle.
*/ */
@@ -305,7 +298,7 @@ struct nfsv3_sattr
uint32_t sa_gidfollows; /* TRUE: Mode value follows */ uint32_t sa_gidfollows; /* TRUE: Mode value follows */
uint32_t sa_gid; /* Mode value */ uint32_t sa_gid; /* Mode value */
uint32_t sa_sizefollows; /* TRUE: Size value follows */ uint32_t sa_sizefollows; /* TRUE: Size value follows */
uint32_t sa_size; /* Size value */ nfsuint64 sa_size; /* Size value */
uint32_t sa_atimetype; /* Don't change, use server timer, or use client time */ uint32_t sa_atimetype; /* Don't change, use server timer, or use client time */
nfstime3 sa_atime; /* Client time */ nfstime3 sa_atime; /* Client time */
uint32_t sa_mtimetype; /* Don't change, use server timer, or use client time */ uint32_t sa_mtimetype; /* Don't change, use server timer, or use client time */
@@ -314,6 +307,7 @@ struct nfsv3_sattr
struct nfs_statfs struct nfs_statfs
{ {
uint32_t obj_attributes_follow;
struct nfs_fattr obj_attributes; struct nfs_fattr obj_attributes;
nfsuint64 sf_tbytes; nfsuint64 sf_tbytes;
nfsuint64 sf_fbytes; nfsuint64 sf_fbytes;
@@ -324,16 +318,10 @@ struct nfs_statfs
uint32_t sf_invarsec; uint32_t sf_invarsec;
}; };
struct post_attr
{
uint32_t obj_attributesfalse;
struct nfs_fattr attributes;
};
struct nfsv3_fsinfo struct nfsv3_fsinfo
{ {
//struct post_attr obj_attributes; uint32_t obj_attributes_follow;
uint32_t obj_attributesfalse; struct nfs_fattr obj_attributes;
uint32_t fs_rtmax; uint32_t fs_rtmax;
uint32_t fs_rtpref; uint32_t fs_rtpref;
uint32_t fs_rtmult; uint32_t fs_rtmult;
@@ -393,6 +381,18 @@ struct CREATE3resok
struct wcc_data dir_wcc; struct wcc_data dir_wcc;
}; };
struct SETATTR3args
{
struct file_handle fhandle; /* Variable length */
struct nfsv3_sattr new_attributes; /* Variable length */
uint32_t guard; /* Guard value */
};
struct SETATTR3resok
{
struct wcc_data wcc_data;
};
/* The actual size of the lookup argument is variable. These structures are, therefore, /* The actual size of the lookup argument is variable. These structures are, therefore,
* only useful in setting aside maximum memory usage for the LOOKUP arguments. * only useful in setting aside maximum memory usage for the LOOKUP arguments.
*/ */
@@ -409,18 +409,6 @@ struct LOOKUP3args
struct LOOKUP3filename name; /* Variable length */ struct LOOKUP3filename name; /* Variable length */
}; };
struct SETATTR3args
{
struct file_handle fhandle; /* Variable length */
struct nfsv3_sattr new_attributes; /* Variable length */
uint32_t guard; /* Guard value */
};
struct SETATTR3resok
{
struct wcc_data wcc_data;
};
/* Actual size of LOOKUP3args */ /* Actual size of LOOKUP3args */
#define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b)+3) & ~3)) #define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b)+3) & ~3))
@@ -464,6 +452,7 @@ struct nfs_wrhdr_s
uint64_t offset; uint64_t offset;
uint32_t count; uint32_t count;
uint32_t stable; uint32_t stable;
uint32_t length;
}; };
struct WRITE3args struct WRITE3args
@@ -528,10 +517,6 @@ struct RMDIR3resok
struct wcc_data dir_wcc; struct wcc_data dir_wcc;
}; };
/* The actual size of the lookup argument is variable. This structures is, therefore,
* only useful in setting aside maximum memory usage for the LOOKUP arguments.
*/
struct READDIR3args struct READDIR3args
{ {
struct file_handle dir; /* Variable length */ struct file_handle dir; /* Variable length */
+32 -93
View File
@@ -42,18 +42,14 @@
#include <sys/time.h> #include <sys/time.h>
#include <stdint.h> #include <stdint.h>
#include <queue.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <assert.h>
#include <debug.h> #include <debug.h>
#include <nuttx/fs/dirent.h>
#include "rpc.h" #include "rpc.h"
#include "nfs.h" #include "nfs.h"
#include "nfs_proto.h" #include "nfs_proto.h"
@@ -105,7 +101,7 @@ static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer,
else if (nbytes >= NAME_MAX) else if (nbytes >= NAME_MAX)
{ {
ferr("ERROR: File name segment is too long: %d\n", *path); ferr("ERROR: File name segment is too long: %d\n", *path);
return EFBIG; return -EFBIG;
} }
else else
{ {
@@ -121,78 +117,26 @@ static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer,
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Name: nfs_semtake
****************************************************************************/
void nfs_semtake(struct nfsmount *nmp)
{
nxsem_wait_uninterruptible(&nmp->nm_sem);
}
/****************************************************************************
* Name: nfs_semgive
****************************************************************************/
void nfs_semgive(struct nfsmount *nmp)
{
nxsem_post(&nmp->nm_sem);
}
/****************************************************************************
* Name: nfs_checkmount
*
* Description: Check if the mountpoint is still valid.
*
* The caller should hold the mountpoint semaphore
*
****************************************************************************/
int nfs_checkmount(struct nfsmount *nmp)
{
struct nfsnode *file;
/* If the nm_mounted flag is false, then we have already handled the loss
* of the mount.
*/
DEBUGASSERT(nmp);
if (!nmp->nm_mounted)
{
/* Make sure that this is flagged in every opened file */
for (file = nmp->nm_head; file; file = file->n_next)
{
file->n_flags &= ~NFSNODE_OPEN;
}
return -ENODEV;
}
return 0;
}
/**************************************************************************** /****************************************************************************
* Name: nfs_request * Name: nfs_request
* *
* Description: * Description:
* Perform the NFS request. On successful receipt, it verifies the NFS level of the * Perform the NFS request. On successful receipt, it verifies the NFS level
* returned values. * of the returned values.
* *
* Returned Value: * Returned Value:
* Zero on success; a positive errno value on failure. * Zero on success; a negative errno value on failure.
* *
****************************************************************************/ ****************************************************************************/
int nfs_request(struct nfsmount *nmp, int procnum, int nfs_request(FAR struct nfsmount *nmp, int procnum,
FAR void *request, size_t reqlen, FAR void *request, size_t reqlen,
FAR void *response, size_t resplen) FAR void *response, size_t resplen)
{ {
struct rpcclnt *clnt = nmp->nm_rpcclnt; FAR struct rpcclnt *clnt = nmp->nm_rpcclnt;
struct nfs_reply_header replyh; struct nfs_reply_header replyh;
int error; int error;
tryagain:
error = rpcclnt_request(clnt, procnum, NFS_PROG, NFS_VER3, error = rpcclnt_request(clnt, procnum, NFS_PROG, NFS_VER3,
request, reqlen, response, resplen); request, reqlen, response, resplen);
if (error != 0) if (error != 0)
@@ -207,29 +151,23 @@ tryagain:
{ {
if (fxdr_unsigned(uint32_t, replyh.nfs_status) > 32) if (fxdr_unsigned(uint32_t, replyh.nfs_status) > 32)
{ {
error = EOPNOTSUPP; error = -EOPNOTSUPP;
} }
else else
{ {
/* NFS_ERRORS are the same as NuttX errno values */ /* NFS_ERRORS are the same as NuttX errno values */
error = fxdr_unsigned(uint32_t, replyh.nfs_status); error = -fxdr_unsigned(uint32_t, replyh.nfs_status);
} }
return error; return error;
} }
if (replyh.rpc_verfi.authtype != 0) if (replyh.rh.rpc_verfi.authtype != 0)
{ {
error = fxdr_unsigned(int, replyh.rpc_verfi.authtype); error = -EOPNOTSUPP;
ferr("ERROR: NFS authtype %d from server\n",
if (error == EAGAIN) fxdr_unsigned(int, replyh.rpc_verfi.authtype));
{
error = 0;
goto tryagain;
}
ferr("ERROR: NFS error %d from server\n", error);
return error; return error;
} }
@@ -251,7 +189,7 @@ tryagain:
* *
****************************************************************************/ ****************************************************************************/
int nfs_lookup(struct nfsmount *nmp, FAR const char *filename, int nfs_lookup(FAR struct nfsmount *nmp, FAR const char *filename,
FAR struct file_handle *fhandle, FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes, FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes) FAR struct nfs_fattr *dir_attributes)
@@ -270,7 +208,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
if (namelen > NAME_MAX) if (namelen > NAME_MAX)
{ {
ferr("ERROR: Length of the string is too long: %d\n", namelen); ferr("ERROR: Length of the string is too long: %d\n", namelen);
return E2BIG; return -E2BIG;
} }
/* Initialize the request */ /* Initialize the request */
@@ -284,7 +222,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
reqlen += sizeof(uint32_t); reqlen += sizeof(uint32_t);
memcpy(ptr, &fhandle->handle, fhandle->length); memcpy(ptr, &fhandle->handle, fhandle->length);
reqlen += fhandle->length; reqlen += uint32_alignup(fhandle->length);
ptr += uint32_increment(fhandle->length); ptr += uint32_increment(fhandle->length);
/* Copy the variable-length file name */ /* Copy the variable-length file name */
@@ -322,7 +260,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
if (value > NFSX_V3FHMAX) if (value > NFSX_V3FHMAX)
{ {
ferr("ERROR: Bad file handle length: %d\n", value); ferr("ERROR: Bad file handle length: %d\n", value);
return EIO; return -EIO;
} }
/* Return the file handle */ /* Return the file handle */
@@ -367,11 +305,11 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
* return the handle of the directory entry of the requested object. * return the handle of the directory entry of the requested object.
* *
* Returned Value: * Returned Value:
* Zero on success; a positive errno value on failure. * Zero on success; a negative errno value on failure.
* *
****************************************************************************/ ****************************************************************************/
int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath, int nfs_findnode(FAR struct nfsmount *nmp, FAR const char *relpath,
FAR struct file_handle *fhandle, FAR struct file_handle *fhandle,
FAR struct nfs_fattr *obj_attributes, FAR struct nfs_fattr *obj_attributes,
FAR struct nfs_fattr *dir_attributes) FAR struct nfs_fattr *dir_attributes)
@@ -385,13 +323,13 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
/* Start with the file handle of the root directory. */ /* Start with the file handle of the root directory. */
fhandle->length = nmp->nm_fhsize; fhandle->length = nmp->nm_fhsize;
memcpy(&fhandle->handle, &nmp->nm_fh, nmp->nm_fhsize); memcpy(&fhandle->handle, nmp->nm_fh, nmp->nm_fhsize);
/* If no path was provided, then the root directory must be exactly what /* If no path was provided, then the root directory must be exactly what
* the caller is looking for. * the caller is looking for.
*/ */
if (*path == '\0' || strlen(path) == 0) if (*path == '\0')
{ {
/* Return the root directory attributes */ /* Return the root directory attributes */
@@ -461,8 +399,8 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
/* Ooops.. we found something else */ /* Ooops.. we found something else */
ferr("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n", ferr("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
buffer, path); buffer, relpath);
return ENOTDIR; return -ENOTDIR;
} }
} }
} }
@@ -476,11 +414,11 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
* object. * object.
* *
* Returned Value: * Returned Value:
* Zero on success; a positive errno value on failure. * Zero on success; a negative errno value on failure.
* *
****************************************************************************/ ****************************************************************************/
int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath, int nfs_finddir(FAR struct nfsmount *nmp, FAR const char *relpath,
FAR struct file_handle *fhandle, FAR struct file_handle *fhandle,
FAR struct nfs_fattr *attributes, FAR char *filename) FAR struct nfs_fattr *attributes, FAR char *filename)
{ {
@@ -491,17 +429,15 @@ int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
/* Verify that a path was provided */ /* Verify that a path was provided */
if (*path == '\0' || strlen(path) == 0) if (*path == '\0')
{ {
/* Return the root directory attributes */ return -ENOENT;
return ENOENT;
} }
/* Start with the file handle of the root directory. */ /* Start with the file handle of the root directory. */
fhandle->length = nmp->nm_fhsize; fhandle->length = nmp->nm_fhsize;
memcpy(&fhandle->handle, &nmp->nm_fh, nmp->nm_fhsize); memcpy(&fhandle->handle, nmp->nm_fh, nmp->nm_fhsize);
memcpy(attributes, &nmp->nm_fattr, sizeof(struct nfs_fattr)); memcpy(attributes, &nmp->nm_fattr, sizeof(struct nfs_fattr));
/* Loop until the directory entry containing the path is found. */ /* Loop until the directory entry containing the path is found. */
@@ -552,8 +488,8 @@ int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
/* Ooops.. we found something else */ /* Ooops.. we found something else */
ferr("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n", ferr("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
filename, path); filename, relpath);
return ENOTDIR; return -ENOTDIR;
} }
} }
} }
@@ -579,6 +515,9 @@ void nfs_attrupdate(FAR struct nfsnode *np, FAR struct nfs_fattr *attributes)
np->n_mode = fxdr_unsigned(uint16_t, attributes->fa_mode); np->n_mode = fxdr_unsigned(uint16_t, attributes->fa_mode);
np->n_size = fxdr_hyper(&attributes->fa_size); np->n_size = fxdr_hyper(&attributes->fa_size);
fxdr_nfsv3time(&attributes->fa_atime, &ts);
np->n_atime = ts.tv_sec;
fxdr_nfsv3time(&attributes->fa_mtime, &ts); fxdr_nfsv3time(&attributes->fa_mtime, &ts);
np->n_mtime = ts.tv_sec; np->n_mtime = ts.tv_sec;
+313 -489
View File
File diff suppressed because it is too large Load Diff
+36 -67
View File
@@ -75,6 +75,8 @@
****************************************************************************/ ****************************************************************************/
#include <sys/types.h> #include <sys/types.h>
#include <nuttx/net/net.h>
#include "nfs_proto.h" #include "nfs_proto.h"
/**************************************************************************** /****************************************************************************
@@ -161,25 +163,13 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* Global RPC statistics */
#ifdef CONFIG_NFS_STATISTICS
struct rpcstats
{
int rpcretries;
int rpcrequests;
int rpctimeouts;
int rpcinvalid;
};
#endif
/* PMAP headers */ /* PMAP headers */
struct call_args_pmap struct call_args_pmap
{ {
uint32_t prog; uint32_t prog;
uint32_t vers; uint32_t vers;
uint32_t proc; uint32_t prot;
uint32_t port; uint32_t port;
}; };
@@ -218,7 +208,7 @@ struct call_result_mount
uint32_t status; uint32_t status;
struct file_handle fhandle; struct file_handle fhandle;
uint32_t authlen; uint32_t authlen;
uint32_t autolist[AUTH_MAX]; uint32_t authlist[AUTH_MAX];
}; };
/* Generic RPC call headers */ /* Generic RPC call headers */
@@ -231,11 +221,11 @@ struct rpc_auth_info
struct auth_unix struct auth_unix
{ {
int32_t stamp; uint32_t stamp;
uint8_t hostname; /* null */ uint32_t hostname; /* null */
int32_t uid; uint32_t uid;
int32_t gid; uint32_t gid;
int32_t gidlist; /* null */ uint32_t gidlist; /* null */
}; };
struct rpc_call_header struct rpc_call_header
@@ -349,11 +339,7 @@ struct rpc_reply_header
struct nfs_reply_header struct nfs_reply_header
{ {
uint32_t rp_xid; /* Request transaction id */ struct rpc_reply_header rh;
uint32_t rp_direction; /* Call direction (1) */
uint32_t type;
struct rpc_auth_info rpc_verfi;
uint32_t status;
uint32_t nfs_status; uint32_t nfs_status;
}; };
@@ -376,115 +362,100 @@ struct rpc_reply_umount
struct rpc_reply_create struct rpc_reply_create
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct CREATE3resok create; struct CREATE3resok create;
}; };
struct rpc_reply_lookup struct rpc_reply_lookup
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct LOOKUP3resok lookup; struct LOOKUP3resok lookup;
}; };
struct rpc_reply_write struct rpc_reply_write
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct WRITE3resok write; /* Variable length */ struct WRITE3resok write; /* Variable length */
}; };
struct rpc_reply_read struct rpc_reply_read
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct READ3resok read; /* Variable length */ struct READ3resok read; /* Variable length */
}; };
#define SIZEOF_rpc_reply_read(n) \ #define SIZEOF_rpc_reply_read(n) \
(sizeof(struct rpc_reply_header) + sizeof(uint32_t) + \ (sizeof(struct nfs_reply_header) + SIZEOF_READ3resok(n))
SIZEOF_READ3resok(n))
struct rpc_reply_remove struct rpc_reply_remove
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct REMOVE3resok remove; struct REMOVE3resok remove;
}; };
struct rpc_reply_rename struct rpc_reply_rename
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct RENAME3resok rename; struct RENAME3resok rename;
}; };
struct rpc_reply_mkdir struct rpc_reply_mkdir
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct MKDIR3resok mkdir; struct MKDIR3resok mkdir;
}; };
struct rpc_reply_rmdir struct rpc_reply_rmdir
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct RMDIR3resok rmdir; struct RMDIR3resok rmdir;
}; };
struct rpc_reply_readdir struct rpc_reply_readdir
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct READDIR3resok readdir; struct READDIR3resok readdir;
}; };
#define SIZEOF_rpc_reply_readdir(n) \ #define SIZEOF_rpc_reply_readdir(n) \
(sizeof(struct rpc_reply_header) + sizeof(uint32_t) + \ (sizeof(struct nfs_reply_header) + SIZEOF_READDIR3resok(n))
SIZEOF_READDIR3resok(n))
struct rpc_reply_fsinfo struct rpc_reply_fsinfo
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct nfsv3_fsinfo fsinfo; struct nfsv3_fsinfo fsinfo;
}; };
struct rpc_reply_fsstat struct rpc_reply_fsstat
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct nfs_statfs fsstat; struct nfs_statfs fsstat;
}; };
struct rpc_reply_getattr struct rpc_reply_getattr
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct nfs_fattr attr; struct nfs_fattr attr;
}; };
struct rpc_reply_setattr struct rpc_reply_setattr
{ {
struct rpc_reply_header rh; struct nfs_reply_header rh;
uint32_t status;
struct SETATTR3resok setattr; struct SETATTR3resok setattr;
}; };
struct rpcclnt struct rpcclnt
{ {
nfsfh_t rc_fh; /* File handle of the root directory */ nfsfh_t rc_fh; /* File handle of the root directory */
uint8_t rc_fhsize; /* File size of the root directory */ uint8_t rc_fhsize; /* File size of the root directory */
char *rc_path; /* Server's path of the mounted directory */ FAR char *rc_path; /* Server's path of the mounted directory */
struct sockaddr *rc_name; FAR struct sockaddr *rc_name;
struct socket *rc_so; /* RPC socket */ struct socket rc_so; /* RPC socket */
bool rc_timeout; /* Receipt of reply timed out */ uint8_t rc_sotype; /* Type of socket */
uint8_t rc_sotype; /* Type of socket */ uint8_t rc_timeo; /* Timeout value (in deciseconds) */
uint8_t rc_retry; /* Max retries */ uint8_t rc_retry; /* Max retries */
}; };
/**************************************************************************** /****************************************************************************
@@ -493,12 +464,10 @@ struct rpcclnt
void rpcclnt_init(void); void rpcclnt_init(void);
int rpcclnt_connect(FAR struct rpcclnt *rpc); int rpcclnt_connect(FAR struct rpcclnt *rpc);
int rpcclnt_reconnect(FAR struct rpcclnt *rpc);
void rpcclnt_disconnect(FAR struct rpcclnt *rpc); void rpcclnt_disconnect(FAR struct rpcclnt *rpc);
int rpcclnt_umount(FAR struct rpcclnt *rpc); int rpcclnt_umount(FAR struct rpcclnt *rpc);
void rpcclnt_safedisconnect(FAR struct rpcclnt *rpc); int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog, int version, int version, FAR void *request, size_t reqlen,
FAR void *request, size_t reqlen,
FAR void *response, size_t resplen); FAR void *response, size_t resplen);
#endif /* __FS_NFS_RPC_H */ #endif /* __FS_NFS_RPC_H */
+94 -139
View File
File diff suppressed because it is too large Load Diff
-29
View File
@@ -68,47 +68,18 @@
#define fxdr_unsigned(t, v) ((t)ntohl(v)) #define fxdr_unsigned(t, v) ((t)ntohl(v))
#define txdr_unsigned(v) (htonl(v)) #define txdr_unsigned(v) (htonl(v))
#define fxdr_nfsv2time(f, t) \
{ \
(t)->tv_sec = ntohl(((struct nfsv2_time *)(f))->nfsv2_sec); \
if (((struct nfsv2_time *)(f))->nfsv2_usec != 0xffffffff) \
(t)->tv_nsec = 1000 * ntohl(((struct nfsv2_time *)(f))->nfsv2_usec); \
else \
(t)->tv_nsec = 0; \
}
#define txdr_nfsv2time(f, t) \
{ \
((struct nfsv2_time *)(t))->nfsv2_sec = htonl((f)->tv_sec); \
if ((f)->tv_nsec != -1) \
((struct nfsv2_time *)(t))->nfsv2_usec = htonl((f)->tv_nsec / 1000); \
else \
((struct nfsv2_time *)(t))->nfsv2_usec = 0xffffffff; \
}
#define fxdr_nfsv3time(f, t) \ #define fxdr_nfsv3time(f, t) \
{ \ { \
(t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \ (t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
(t)->tv_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \ (t)->tv_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \
} }
#define fxdr_nfsv3time2(f, t) { \
(t)->nfsv3_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
(t)->nfsv3_nsec = ntohl(((struct nfsv3_time *)(f))->nfsv3_nsec); \
}
#define txdr_nfsv3time(f, t) \ #define txdr_nfsv3time(f, t) \
{ \ { \
((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \ ((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \
((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \ ((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->tv_nsec); \
} }
#define txdr_nfsv3time2(f, t) \
{ \
((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->nfsv3_sec); \
((struct nfsv3_time *)(t))->nfsv3_nsec = htonl((f)->nfsv3_nsec); \
}
#define fxdr_hyper(f) \ #define fxdr_hyper(f) \
((((uint64_t)ntohl(((uint32_t *)(f))[0])) << 32) | \ ((((uint64_t)ntohl(((uint32_t *)(f))[0])) << 32) | \
(uint64_t)(ntohl(((uint32_t *)(f))[1]))) (uint64_t)(ntohl(((uint32_t *)(f))[1])))