mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
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:
+4
-15
@@ -54,18 +54,14 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NFS_TICKS 1 /* Number of system ticks */
|
||||
#define NFS_HZ CLOCKS_PER_SEC /* Ticks/sec */
|
||||
#define NFS_TIMEO (1 * NFS_HZ) /* Default timeout = 1 second */
|
||||
#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_TIMEO 10 /* Default timeout = 1 second */
|
||||
#define NFS_MINTIMEO 10 /* Min timeout to use */
|
||||
#define NFS_MAXTIMEO 255 /* Max timeout to backoff to */
|
||||
#define NFS_MAXREXMIT 100 /* Stop counting after this many */
|
||||
#define NFS_RETRANS 10 /* Num of retrans for soft mounts */
|
||||
#define NFS_WSIZE 8192 /* Def. write data size <= 8192 */
|
||||
#define NFS_RSIZE 8192 /* Def. read data size <= 8192 */
|
||||
#define NFS_READDIRSIZE 8192 /* Def. readdir size */
|
||||
#define NFS_NPROCS 23
|
||||
|
||||
/* Ideally, NFS_DIRBLKSIZ should be bigger, but I've seen servers with
|
||||
* broken NFS/ethernet drivers that won't work with anything bigger (Linux..)
|
||||
@@ -85,9 +81,6 @@
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern uint32_t nfs_true;
|
||||
extern uint32_t nfs_false;
|
||||
extern uint32_t nfs_xdrneg1;
|
||||
#ifdef CONFIG_NFS_STATISTICS
|
||||
extern struct nfsstats nfsstats;
|
||||
#endif
|
||||
@@ -115,11 +108,7 @@ extern "C" {
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
EXTERN void nfs_semtake(FAR struct nfsmount *nmp);
|
||||
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,
|
||||
EXTERN int nfs_request(FAR struct nfsmount *nmp, int procnum,
|
||||
FAR void *request, size_t reqlen,
|
||||
FAR void *response, size_t resplen);
|
||||
EXTERN int nfs_lookup(FAR struct nfsmount *nmp, FAR const char *filename,
|
||||
|
||||
+15
-20
@@ -67,23 +67,18 @@
|
||||
|
||||
struct nfsmount
|
||||
{
|
||||
struct nfsnode *nm_head; /* A list of all files opened on this mountpoint */
|
||||
sem_t nm_sem; /* Used to assure thread-safe access */
|
||||
nfsfh_t nm_fh; /* File handle of root dir */
|
||||
char nm_path[90]; /* server's path of the directory being mounted */
|
||||
struct nfs_fattr nm_fattr; /* nfs file attribute cache */
|
||||
struct rpcclnt *nm_rpcclnt; /* RPC state */
|
||||
struct socket *nm_so; /* RPC socket */
|
||||
struct sockaddr nm_nam; /* Addr of server */
|
||||
bool nm_mounted; /* true: The file system is ready */
|
||||
uint8_t nm_fhsize; /* Size of root file handle (host order) */
|
||||
uint8_t nm_sotype; /* Type of socket */
|
||||
uint8_t nm_retry; /* Max retries */
|
||||
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 */
|
||||
FAR struct nfsnode *nm_head; /* A list of all files opened on this mountpoint */
|
||||
sem_t nm_sem; /* Used to assure thread-safe access */
|
||||
nfsfh_t *nm_fh; /* File handle of root dir */
|
||||
char nm_path[90]; /* server's path of the directory being mounted */
|
||||
struct nfs_fattr nm_fattr; /* nfs file attribute cache */
|
||||
FAR struct rpcclnt *nm_rpcclnt; /* RPC state */
|
||||
struct sockaddr nm_nam; /* Addr of server */
|
||||
uint8_t nm_fhsize; /* Size of root file handle (host order) */
|
||||
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
|
||||
* 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_fs fsstat;
|
||||
struct rpc_call_setattr setattr;
|
||||
struct rpc_call_fs fs;
|
||||
struct rpc_call_fs fsinfo;
|
||||
struct rpc_reply_write write;
|
||||
} nm_msgbuffer;
|
||||
|
||||
@@ -116,10 +111,10 @@ struct nfsmount
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
+10
-19
@@ -50,15 +50,6 @@
|
||||
|
||||
#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
|
||||
****************************************************************************/
|
||||
@@ -69,16 +60,16 @@
|
||||
|
||||
struct nfsnode
|
||||
{
|
||||
struct nfsnode *n_next; /* Retained in a singly linked list. */
|
||||
uint8_t n_crefs; /* Reference count (for nfs_dup) */
|
||||
uint8_t n_type; /* File type */
|
||||
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() */
|
||||
time_t n_mtime; /* File modification time */
|
||||
time_t n_ctime; /* File creation time */
|
||||
nfsfh_t n_fhandle; /* NFS File Handle */
|
||||
uint64_t n_size; /* Current size of file */
|
||||
FAR struct nfsnode *n_next; /* Retained in a singly linked list. */
|
||||
uint8_t n_crefs; /* Reference count (for nfs_dup) */
|
||||
uint8_t n_type; /* File type */
|
||||
uint8_t n_fhsize; /* Size in bytes of the file handle */
|
||||
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_ctime; /* File creation time */
|
||||
nfsfh_t n_fhandle; /* NFS File Handle */
|
||||
uint64_t n_size; /* Current size of file */
|
||||
};
|
||||
|
||||
#endif /* __FS_NFS_NFS_NODE_H */
|
||||
|
||||
+20
-35
@@ -118,13 +118,13 @@
|
||||
|
||||
/* 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_V3FATTR 84
|
||||
#define NFSX_V3SATTR 60 /* max. all fields filled in */
|
||||
#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr))
|
||||
#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_V3WRITEVERF 8
|
||||
#define NFSX_V3CREATEVERF 8
|
||||
@@ -185,13 +185,6 @@
|
||||
#define NFSV3FSINFO_HOMOGENEOUS 0x08
|
||||
#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 */
|
||||
|
||||
#define NFSMODE_IXOTH (1 << 0) /* Execute permission for others on a file */
|
||||
@@ -230,7 +223,7 @@ typedef enum
|
||||
} nfstype;
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
@@ -305,7 +298,7 @@ struct nfsv3_sattr
|
||||
uint32_t sa_gidfollows; /* TRUE: Mode value follows */
|
||||
uint32_t sa_gid; /* Mode value */
|
||||
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 */
|
||||
nfstime3 sa_atime; /* 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
|
||||
{
|
||||
uint32_t obj_attributes_follow;
|
||||
struct nfs_fattr obj_attributes;
|
||||
nfsuint64 sf_tbytes;
|
||||
nfsuint64 sf_fbytes;
|
||||
@@ -324,16 +318,10 @@ struct nfs_statfs
|
||||
uint32_t sf_invarsec;
|
||||
};
|
||||
|
||||
struct post_attr
|
||||
{
|
||||
uint32_t obj_attributesfalse;
|
||||
struct nfs_fattr attributes;
|
||||
};
|
||||
|
||||
struct nfsv3_fsinfo
|
||||
{
|
||||
//struct post_attr obj_attributes;
|
||||
uint32_t obj_attributesfalse;
|
||||
uint32_t obj_attributes_follow;
|
||||
struct nfs_fattr obj_attributes;
|
||||
uint32_t fs_rtmax;
|
||||
uint32_t fs_rtpref;
|
||||
uint32_t fs_rtmult;
|
||||
@@ -393,6 +381,18 @@ struct CREATE3resok
|
||||
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,
|
||||
* only useful in setting aside maximum memory usage for the LOOKUP arguments.
|
||||
*/
|
||||
@@ -409,18 +409,6 @@ struct LOOKUP3args
|
||||
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 */
|
||||
|
||||
#define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b)+3) & ~3))
|
||||
@@ -464,6 +452,7 @@ struct nfs_wrhdr_s
|
||||
uint64_t offset;
|
||||
uint32_t count;
|
||||
uint32_t stable;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
struct WRITE3args
|
||||
@@ -528,10 +517,6 @@ struct RMDIR3resok
|
||||
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 file_handle dir; /* Variable length */
|
||||
|
||||
+32
-93
@@ -42,18 +42,14 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <queue.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/fs/dirent.h>
|
||||
|
||||
#include "rpc.h"
|
||||
#include "nfs.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)
|
||||
{
|
||||
ferr("ERROR: File name segment is too long: %d\n", *path);
|
||||
return EFBIG;
|
||||
return -EFBIG;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,78 +117,26 @@ static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer,
|
||||
* 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
|
||||
*
|
||||
* Description:
|
||||
* Perform the NFS request. On successful receipt, it verifies the NFS level of the
|
||||
* returned values.
|
||||
* Perform the NFS request. On successful receipt, it verifies the NFS level
|
||||
* of the returned values.
|
||||
*
|
||||
* 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 *response, size_t resplen)
|
||||
{
|
||||
struct rpcclnt *clnt = nmp->nm_rpcclnt;
|
||||
FAR struct rpcclnt *clnt = nmp->nm_rpcclnt;
|
||||
struct nfs_reply_header replyh;
|
||||
int error;
|
||||
|
||||
tryagain:
|
||||
error = rpcclnt_request(clnt, procnum, NFS_PROG, NFS_VER3,
|
||||
request, reqlen, response, resplen);
|
||||
if (error != 0)
|
||||
@@ -207,29 +151,23 @@ tryagain:
|
||||
{
|
||||
if (fxdr_unsigned(uint32_t, replyh.nfs_status) > 32)
|
||||
{
|
||||
error = EOPNOTSUPP;
|
||||
error = -EOPNOTSUPP;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (replyh.rpc_verfi.authtype != 0)
|
||||
if (replyh.rh.rpc_verfi.authtype != 0)
|
||||
{
|
||||
error = fxdr_unsigned(int, replyh.rpc_verfi.authtype);
|
||||
|
||||
if (error == EAGAIN)
|
||||
{
|
||||
error = 0;
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
ferr("ERROR: NFS error %d from server\n", error);
|
||||
error = -EOPNOTSUPP;
|
||||
ferr("ERROR: NFS authtype %d from server\n",
|
||||
fxdr_unsigned(int, replyh.rpc_verfi.authtype));
|
||||
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 nfs_fattr *obj_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)
|
||||
{
|
||||
ferr("ERROR: Length of the string is too long: %d\n", namelen);
|
||||
return E2BIG;
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
/* Initialize the request */
|
||||
@@ -284,7 +222,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
|
||||
reqlen += sizeof(uint32_t);
|
||||
|
||||
memcpy(ptr, &fhandle->handle, fhandle->length);
|
||||
reqlen += fhandle->length;
|
||||
reqlen += uint32_alignup(fhandle->length);
|
||||
ptr += uint32_increment(fhandle->length);
|
||||
|
||||
/* Copy the variable-length file name */
|
||||
@@ -322,7 +260,7 @@ int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
|
||||
if (value > NFSX_V3FHMAX)
|
||||
{
|
||||
ferr("ERROR: Bad file handle length: %d\n", value);
|
||||
return EIO;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* 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 nfs_fattr *obj_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. */
|
||||
|
||||
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
|
||||
* the caller is looking for.
|
||||
*/
|
||||
|
||||
if (*path == '\0' || strlen(path) == 0)
|
||||
if (*path == '\0')
|
||||
{
|
||||
/* Return the root directory attributes */
|
||||
|
||||
@@ -461,8 +399,8 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
|
||||
/* Ooops.. we found something else */
|
||||
|
||||
ferr("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
|
||||
buffer, path);
|
||||
return ENOTDIR;
|
||||
buffer, relpath);
|
||||
return -ENOTDIR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -476,11 +414,11 @@ int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
|
||||
* object.
|
||||
*
|
||||
* 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 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 */
|
||||
|
||||
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. */
|
||||
|
||||
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));
|
||||
|
||||
/* 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 */
|
||||
|
||||
ferr("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
|
||||
filename, path);
|
||||
return ENOTDIR;
|
||||
filename, relpath);
|
||||
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_size = fxdr_hyper(&attributes->fa_size);
|
||||
|
||||
fxdr_nfsv3time(&attributes->fa_atime, &ts);
|
||||
np->n_atime = ts.tv_sec;
|
||||
|
||||
fxdr_nfsv3time(&attributes->fa_mtime, &ts);
|
||||
np->n_mtime = ts.tv_sec;
|
||||
|
||||
|
||||
+313
-489
File diff suppressed because it is too large
Load Diff
+36
-67
@@ -75,6 +75,8 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "nfs_proto.h"
|
||||
|
||||
/****************************************************************************
|
||||
@@ -161,25 +163,13 @@
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Global RPC statistics */
|
||||
|
||||
#ifdef CONFIG_NFS_STATISTICS
|
||||
struct rpcstats
|
||||
{
|
||||
int rpcretries;
|
||||
int rpcrequests;
|
||||
int rpctimeouts;
|
||||
int rpcinvalid;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* PMAP headers */
|
||||
|
||||
struct call_args_pmap
|
||||
{
|
||||
uint32_t prog;
|
||||
uint32_t vers;
|
||||
uint32_t proc;
|
||||
uint32_t prot;
|
||||
uint32_t port;
|
||||
};
|
||||
|
||||
@@ -218,7 +208,7 @@ struct call_result_mount
|
||||
uint32_t status;
|
||||
struct file_handle fhandle;
|
||||
uint32_t authlen;
|
||||
uint32_t autolist[AUTH_MAX];
|
||||
uint32_t authlist[AUTH_MAX];
|
||||
};
|
||||
|
||||
/* Generic RPC call headers */
|
||||
@@ -231,11 +221,11 @@ struct rpc_auth_info
|
||||
|
||||
struct auth_unix
|
||||
{
|
||||
int32_t stamp;
|
||||
uint8_t hostname; /* null */
|
||||
int32_t uid;
|
||||
int32_t gid;
|
||||
int32_t gidlist; /* null */
|
||||
uint32_t stamp;
|
||||
uint32_t hostname; /* null */
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
uint32_t gidlist; /* null */
|
||||
};
|
||||
|
||||
struct rpc_call_header
|
||||
@@ -349,11 +339,7 @@ struct rpc_reply_header
|
||||
|
||||
struct nfs_reply_header
|
||||
{
|
||||
uint32_t rp_xid; /* Request transaction id */
|
||||
uint32_t rp_direction; /* Call direction (1) */
|
||||
uint32_t type;
|
||||
struct rpc_auth_info rpc_verfi;
|
||||
uint32_t status;
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t nfs_status;
|
||||
};
|
||||
|
||||
@@ -376,115 +362,100 @@ struct rpc_reply_umount
|
||||
|
||||
struct rpc_reply_create
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct CREATE3resok create;
|
||||
};
|
||||
|
||||
struct rpc_reply_lookup
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct LOOKUP3resok lookup;
|
||||
};
|
||||
|
||||
struct rpc_reply_write
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct WRITE3resok write; /* Variable length */
|
||||
};
|
||||
|
||||
struct rpc_reply_read
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct READ3resok read; /* Variable length */
|
||||
};
|
||||
|
||||
#define SIZEOF_rpc_reply_read(n) \
|
||||
(sizeof(struct rpc_reply_header) + sizeof(uint32_t) + \
|
||||
SIZEOF_READ3resok(n))
|
||||
(sizeof(struct nfs_reply_header) + SIZEOF_READ3resok(n))
|
||||
|
||||
struct rpc_reply_remove
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct REMOVE3resok remove;
|
||||
};
|
||||
|
||||
struct rpc_reply_rename
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct RENAME3resok rename;
|
||||
};
|
||||
|
||||
struct rpc_reply_mkdir
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct MKDIR3resok mkdir;
|
||||
};
|
||||
|
||||
struct rpc_reply_rmdir
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct RMDIR3resok rmdir;
|
||||
};
|
||||
|
||||
struct rpc_reply_readdir
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct READDIR3resok readdir;
|
||||
};
|
||||
|
||||
#define SIZEOF_rpc_reply_readdir(n) \
|
||||
(sizeof(struct rpc_reply_header) + sizeof(uint32_t) + \
|
||||
SIZEOF_READDIR3resok(n))
|
||||
(sizeof(struct nfs_reply_header) + SIZEOF_READDIR3resok(n))
|
||||
|
||||
struct rpc_reply_fsinfo
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct nfsv3_fsinfo fsinfo;
|
||||
};
|
||||
|
||||
struct rpc_reply_fsstat
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct nfs_statfs fsstat;
|
||||
};
|
||||
|
||||
struct rpc_reply_getattr
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct nfs_fattr attr;
|
||||
};
|
||||
|
||||
struct rpc_reply_setattr
|
||||
{
|
||||
struct rpc_reply_header rh;
|
||||
uint32_t status;
|
||||
struct nfs_reply_header rh;
|
||||
struct SETATTR3resok setattr;
|
||||
};
|
||||
|
||||
struct rpcclnt
|
||||
struct rpcclnt
|
||||
{
|
||||
nfsfh_t rc_fh; /* File handle of the root directory */
|
||||
uint8_t rc_fhsize; /* File size of the root directory */
|
||||
char *rc_path; /* Server's path of the mounted directory */
|
||||
nfsfh_t rc_fh; /* File handle of the root directory */
|
||||
uint8_t rc_fhsize; /* File size of the root directory */
|
||||
FAR char *rc_path; /* Server's path of the mounted directory */
|
||||
|
||||
struct sockaddr *rc_name;
|
||||
struct socket *rc_so; /* RPC socket */
|
||||
FAR struct sockaddr *rc_name;
|
||||
struct socket rc_so; /* RPC socket */
|
||||
|
||||
bool rc_timeout; /* Receipt of reply timed out */
|
||||
uint8_t rc_sotype; /* Type of socket */
|
||||
uint8_t rc_retry; /* Max retries */
|
||||
uint8_t rc_sotype; /* Type of socket */
|
||||
uint8_t rc_timeo; /* Timeout value (in deciseconds) */
|
||||
uint8_t rc_retry; /* Max retries */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -493,12 +464,10 @@ struct rpcclnt
|
||||
|
||||
void rpcclnt_init(void);
|
||||
int rpcclnt_connect(FAR struct rpcclnt *rpc);
|
||||
int rpcclnt_reconnect(FAR struct rpcclnt *rpc);
|
||||
void rpcclnt_disconnect(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 version,
|
||||
FAR void *request, size_t reqlen,
|
||||
int rpcclnt_request(FAR struct rpcclnt *rpc, int procnum, int prog,
|
||||
int version, FAR void *request, size_t reqlen,
|
||||
FAR void *response, size_t resplen);
|
||||
|
||||
#endif /* __FS_NFS_RPC_H */
|
||||
|
||||
+94
-139
File diff suppressed because it is too large
Load Diff
@@ -68,47 +68,18 @@
|
||||
#define fxdr_unsigned(t, v) ((t)ntohl(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) \
|
||||
{ \
|
||||
(t)->tv_sec = ntohl(((struct nfsv3_time *)(f))->nfsv3_sec); \
|
||||
(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) \
|
||||
{ \
|
||||
((struct nfsv3_time *)(t))->nfsv3_sec = htonl((f)->tv_sec); \
|
||||
((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) \
|
||||
((((uint64_t)ntohl(((uint32_t *)(f))[0])) << 32) | \
|
||||
(uint64_t)(ntohl(((uint32_t *)(f))[1])))
|
||||
|
||||
Reference in New Issue
Block a user