aboutsummaryrefslogtreecommitdiff
path: root/nuttx/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/fs/nfs')
-rw-r--r--nuttx/fs/nfs/Kconfig24
-rw-r--r--nuttx/fs/nfs/Make.defs53
-rw-r--r--nuttx/fs/nfs/nfs.h149
-rw-r--r--nuttx/fs/nfs/nfs_mount.h140
-rw-r--r--nuttx/fs/nfs/nfs_node.h83
-rw-r--r--nuttx/fs/nfs/nfs_proto.h571
-rw-r--r--nuttx/fs/nfs/nfs_util.c601
-rw-r--r--nuttx/fs/nfs/nfs_vfsops.c2622
-rw-r--r--nuttx/fs/nfs/rpc.h491
-rw-r--r--nuttx/fs/nfs/rpc_clnt.c805
-rw-r--r--nuttx/fs/nfs/xdr_subs.h128
11 files changed, 0 insertions, 5667 deletions
diff --git a/nuttx/fs/nfs/Kconfig b/nuttx/fs/nfs/Kconfig
deleted file mode 100644
index 3838efffa..000000000
--- a/nuttx/fs/nfs/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config NFS
- bool "NFS client file system"
- default n
- depends on NET && !DISABLE_MOUNTPOINT
- ---help---
- Enable network file system (NFS) client file system
-
-#if NFS
-
-config NFS_STATISTICS
- bool "NFS Stastics"
- default n
- depends on NFS
- ---help---
- Collect support for NFS statistics. There is no user interface to
- obtain these statistics, however. So they would only be of value
- if you add debug instrumentation or use a debugger.
-
-#endif
diff --git a/nuttx/fs/nfs/Make.defs b/nuttx/fs/nfs/Make.defs
deleted file mode 100644
index ec2177fcf..000000000
--- a/nuttx/fs/nfs/Make.defs
+++ /dev/null
@@ -1,53 +0,0 @@
-############################################################################
-# Make.defs
-#
-# Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-# 3. Neither the name Nuttx nor the names of its contributors may be
-# used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-#
-############################################################################
-
-ifeq ($(CONFIG_NFS),y)
-# Files required for NFS file system support
-
-ASRCS +=
-CSRCS +=
-
-# Files required for NFS RPC
-
-ASRCS +=
-CSRCS += rpc_clnt.c nfs_util.c nfs_vfsops.c
-
-# Include NFS build support
-
-DEPPATH += --dep-path nfs
-VPATH += :nfs
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)fs$(DELIM)nfs}
-
-endif
diff --git a/nuttx/fs/nfs/nfs.h b/nuttx/fs/nfs/nfs.h
deleted file mode 100644
index af24357a4..000000000
--- a/nuttx/fs/nfs/nfs.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/****************************************************************************
- * fs/nfs/nfs.h
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 1989, 1993, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __FS_NFS_NFS_H
-#define __FS_NFS_NFS_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include "nfs_mount.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define NFS_TICKINTVL MSEC_PER_TICK /* Smallest that we can get */
-#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_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..)
- */
-
-#define NFS_DIRBLKSIZ 1024 /* Must be a multiple of DIRBLKSIZ */
-
-/* Increment NFS statistics */
-
-#ifdef CONFIG_NFS_STATISTICS
-# define nfs_statistics(n) do { nfsstats.rpccnt[n]++; } while (0)
-#else
-# define nfs_statistics(n)
-#endif
-
-/****************************************************************************
- * 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
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/* NFS statistics structure */
-
-struct nfsstats
-{
- uint64_t rpccnt[NFS_NPROCS];
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#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,
- FAR void *request, size_t reqlen,
- FAR void *response, size_t resplen);
-EXTERN 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);
-EXTERN 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);
-EXTERN int nfs_finddir(FAR struct nfsmount *nmp, FAR const char *relpath,
- FAR struct file_handle *fhandle,
- FAR struct nfs_fattr *attributes, FAR char *filename);
-EXTERN void nfs_attrupdate(FAR struct nfsnode *np,
- FAR struct nfs_fattr *attributes);
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _NFS_NFS_H */
diff --git a/nuttx/fs/nfs/nfs_mount.h b/nuttx/fs/nfs/nfs_mount.h
deleted file mode 100644
index 8f1f7be53..000000000
--- a/nuttx/fs/nfs/nfs_mount.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
- * fs/nfs/nfs_mount.h
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __FS_NFS_NFS_MOUNT_H
-#define __FS_NFS_NFS_MOUNT_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <sys/socket.h>
-
-#include "rpc.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/* Mount structure. One mount structure is allocated for each NFS mount. This
- * structure holds NFS specific information for mount.
- */
-
-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 */
-
- /* 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
- * is in this union.
- */
-
- union
- {
- struct rpc_call_pmap pmap;
- struct rpc_call_mount mountd;
- struct rpc_call_create create;
- struct rpc_call_lookup lookup;
- struct rpc_call_read read;
- struct rpc_call_remove removef;
- struct rpc_call_rename renamef;
- struct rpc_call_mkdir mkdir;
- struct rpc_call_rmdir rmdir;
- struct rpc_call_readdir readdir;
- struct rpc_call_fs fsstat;
- struct rpc_call_setattr setattr;
- struct rpc_call_fs fs;
- struct rpc_reply_write write;
- } nm_msgbuffer;
-
- /* I/O buffer (must be a aligned to 32-bit boundaries). This buffer used for all
- * reply messages EXCEPT for the WRITE RPC. In that case it is used for the WRITE
- * call message that contains the data to be written. This buffer must be
- * dynamically sized based on the characteristics of the server and upon the
- * configuration of the NuttX network. It must be sized to hold the largest
- * possible WRITE call message or READ response message.
- */
-
- 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
- * buffer.
- */
-
-#define SIZEOF_nfsmount(n) (sizeof(struct nfsmount) + ((n + 3) & ~3) - sizeof(uint32_t))
-
-/* Mount parameters structure. This structure is use in nfs_decode_args funtion before one
- * mount structure is allocated in each NFS mount.
- */
-
-struct nfs_mount_parameters
-{
- uint8_t timeo; /* Timeout value (in deciseconds) */
- uint8_t retry; /* Max retries */
- uint16_t rsize; /* Max size of read RPC */
- uint16_t wsize; /* Max size of write RPC */
- uint16_t readdirsize; /* Size of a readdir RPC */
-};
-
-#endif
diff --git a/nuttx/fs/nfs/nfs_node.h b/nuttx/fs/nfs/nfs_node.h
deleted file mode 100644
index 408bd1993..000000000
--- a/nuttx/fs/nfs/nfs_node.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
- * fs/nfs/nfs_node.h
- *
- * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __FS_NFS_NFS_NODE_H
-#define __FS_NFS_NFS_NODE_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#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
- ****************************************************************************/
-
-/* There is a unique nfsnode allocated for each active file. An nfsnode is
- * 'named' by its file handle.
- */
-
-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 */
- struct timespec n_mtime; /* File modification time (see NOTE) */
- time_t n_ctime; /* File creation time (see NOTE) */
- nfsfh_t n_fhandle; /* NFS File Handle */
- uint64_t n_size; /* Current size of file (see NOTE) */
-};
-
-#endif /* __FS_NFS_NFS_NODE_H */
diff --git a/nuttx/fs/nfs/nfs_proto.h b/nuttx/fs/nfs/nfs_proto.h
deleted file mode 100644
index 676ee6232..000000000
--- a/nuttx/fs/nfs/nfs_proto.h
+++ /dev/null
@@ -1,571 +0,0 @@
-/****************************************************************************
- * fs/nfs/nfs_proto.h
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __FS_NFS_NFS_PROTO_H
-#define __FS_NFS_NFS_PROTO_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Constants as defined in the Sun NFS Version 2 and 3 specs.
- * "NFS: Network File System Protocol Specification" RFC1094
- * and in the "NFS: Network File System Version 3 Protocol
- * Specification"
- */
-
-#define NFS_PORT 2049
-#define NFS_PROG 100003
-#define NFS_VER2 2
-#define NFS_VER3 3
-#define NFS_VER4 4
-#define NFS_MAXDGRAMDATA 32768
-#define MAXBSIZE 64000
-#define NFS_MAXDATA MAXBSIZE
-#define NFS_MAXPATHLEN 1024
-#define NFS_MAXNAMLEN 255
-#define NFS_MAXPKTHDR 404
-#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA)
-#define NFS_MINPACKET 20
-#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
-
-/* Stat numbers for rpc returns (version 2 and 3) */
-
-#define NFS_OK 0
-#define NFSERR_PERM 1
-#define NFSERR_NOENT 2
-#define NFSERR_IO 5
-#define NFSERR_NXIO 6
-#define NFSERR_ACCES 13
-#define NFSERR_EXIST 17
-#define NFSERR_XDEV 18 /* Version 3 only */
-#define NFSERR_NODEV 19
-#define NFSERR_NOTDIR 20
-#define NFSERR_ISDIR 21
-#define NFSERR_INVAL 22 /* Version 3 only */
-#define NFSERR_FBIG 27
-#define NFSERR_NOSPC 28
-#define NFSERR_ROFS 30
-#define NFSERR_MLINK 31 /* Version 3 only */
-#define NFSERR_NAMETOL 63
-#define NFSERR_NOTEMPTY 66
-#define NFSERR_DQUOT 69
-#define NFSERR_STALE 70
-#define NFSERR_REMOTE 71 /* Version 3 only */
-#define NFSERR_WFLUSH 99 /* Version 2 only */
-#define NFSERR_BADHANDLE 10001 /* The rest Version 3 only */
-#define NFSERR_NOT_SYNC 10002
-#define NFSERR_BAD_COOKIE 10003
-#define NFSERR_NOTSUPP 10004
-#define NFSERR_TOOSMALL 10005
-#define NFSERR_SERVERFAULT 10006
-#define NFSERR_BADTYPE 10007
-#define NFSERR_JUKEBOX 10008
-#define NFSERR_TRYLATER NFSERR_JUKEBOX
-#define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */
-
-#define NFSERR_RETVOID 0x20000000 /* Return void, not error */
-#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */
-#define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */
-
-/* Sizes in bytes of various nfs rpc components */
-
-#define NFSX_UNSIGNED 4
-
-/* Specific to NFS Version 3 */
-
-#define NFSX_V3FH (sizeof (fhandle_t)) /* 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_V3COOKIEVERF 8
-#define NFSX_V3WRITEVERF 8
-#define NFSX_V3CREATEVERF 8
-#define NFSX_V3STATFS 52
-#define NFSX_V3FSINFO 48
-#define NFSX_V3PATHCONF 24
-
-/* NFS RPC procedure numbers (before version mapping) */
-
-#define NFSPROC_NULL 0
-#define NFSPROC_GETATTR 1
-#define NFSPROC_SETATTR 2
-#define NFSPROC_LOOKUP 3
-#define NFSPROC_ACCESS 4
-#define NFSPROC_READLINK 5
-#define NFSPROC_READ 6
-#define NFSPROC_WRITE 7
-#define NFSPROC_CREATE 8
-#define NFSPROC_MKDIR 9
-#define NFSPROC_SYMLINK 10
-#define NFSPROC_MKNOD 11
-#define NFSPROC_REMOVE 12
-#define NFSPROC_RMDIR 13
-#define NFSPROC_RENAME 14
-#define NFSPROC_LINK 15
-#define NFSPROC_READDIR 16
-#define NFSPROC_READDIRPLUS 17
-#define NFSPROC_FSSTAT 18
-#define NFSPROC_FSINFO 19
-#define NFSPROC_PATHCONF 20
-#define NFSPROC_COMMIT 21
-#define NFSPROC_NOOP 22
-#define NFS_NPROCS 23
-
-
-/* Constants used by the Version 3 protocol for various RPCs */
-
-#define NFSV3SATTRTIME_DONTCHANGE 0
-#define NFSV3SATTRTIME_TOSERVER 1
-#define NFSV3SATTRTIME_TOCLIENT 2
-
-#define NFSV3ACCESS_READ 0x01
-#define NFSV3ACCESS_LOOKUP 0x02
-#define NFSV3ACCESS_MODIFY 0x04
-#define NFSV3ACCESS_EXTEND 0x08
-#define NFSV3ACCESS_DELETE 0x10
-#define NFSV3ACCESS_EXECUTE 0x20
-
-#define NFSV3WRITE_UNSTABLE 0
-#define NFSV3WRITE_DATASYNC 1
-#define NFSV3WRITE_FILESYNC 2
-
-#define NFSV3CREATE_UNCHECKED 0
-#define NFSV3CREATE_GUARDED 1
-#define NFSV3CREATE_EXCLUSIVE 2
-
-#define NFSV3FSINFO_LINK 0x01
-#define NFSV3FSINFO_SYMLINK 0x02
-#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 */
-#define NFSMODE_IWOTH (1 << 1) /* Write permission for others */
-#define NFSMODE_IROTH (1 << 2) /* Read permission for others */
-#define NFSMODE_IXGRP (1 << 3) /* Execute permission for group on a file */
-#define NFSMODE_IWGRP (1 << 4) /* Write permission for group */
-#define NFSMODE_IRGRP (1 << 5) /* Read permission for group */
-#define NFSMODE_IXUSR (1 << 6) /* Execute permission for owner on a file */
-#define NFSMODE_IWUSR (1 << 7) /* Write permission for owner */
-#define NFSMODE_IRUSR (1 << 8) /* Read permission for owner */
-#define NFSMODE_SAVETEXT (1 << 9) /* Save swapped text */
-#define NFSMODE_ISGID (1 << 10) /* Set group ID on execution */
-#define NFSMODE_ISUID (1 << 11) /* Set user ID on execution */
-
-/* File identifier */
-
-#define MAXFIDSZ 16
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/* File types */
-
-typedef enum
-{
- NFNON = 0, /* Unknown type */
- NFREG = 1, /* Regular file */
- NFDIR = 2, /* Directory */
- NFBLK = 3, /* Block special device file */
- NFCHR = 4, /* Character special device file */
- NFLNK = 5, /* Symbolic link */
- NFSOCK = 6, /* Socket */
- NFFIFO = 7 /* Named FIFO */
-} 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
- * allocations for a file handle.
- */
-
-struct nfsfh
-{
- uint8_t fh_bytes[NFSX_V3FHMAX];
-};
-typedef struct nfsfh nfsfh_t;
-#define SIZEOF_nfsfh_t(n) (n)
-
-struct nfsv3_time
-{
- uint32_t nfsv3_sec;
- uint32_t nfsv3_nsec;
-};
-typedef struct nfsv3_time nfstime3;
-
-/* Quads are defined as arrays of 2 longs to ensure dense packing for the
- * protocol and to facilitate xdr conversion.
- */
-
-struct nfs_uquad
-{
- uint32_t nfsuquad[2];
-};
-typedef struct nfs_uquad nfsuint64;
-
-/* NFS Version 3 special file number. */
-
-struct nfsv3_spec
-{
- uint32_t specdata1;
- uint32_t specdata2;
-};
-typedef struct nfsv3_spec nfsv3spec;
-
-/* File attributes and setable attributes. These structures cover both
- * NFS version 2 and the version 3 protocol. Note that the union is only
- * used so that one pointer can refer to both variants. These structures
- * go out on the wire and must be densely packed, so no quad data types
- * are used. (all fields are longs or u_longs or structures of same)
- */
-
-struct nfs_fattr
-{
- uint32_t fa_type;
- uint32_t fa_mode;
- uint32_t fa_nlink;
- uint32_t fa_uid;
- uint32_t fa_gid;
- nfsuint64 fa_size;
- nfsuint64 fa_used;
- nfsv3spec fa_rdev;
- nfsuint64 fa_fsid;
- nfsuint64 fa_fileid;
- nfstime3 fa_atime;
- nfstime3 fa_mtime;
- nfstime3 fa_ctime;
-};
-
-/* NFS Version 3 sattr structure for the new node creation case. This is the
- * maximum size of the attributes; the actual size may vary if values are not
- * include.
- */
-
-struct nfsv3_sattr
-{
- uint32_t sa_modefollows; /* TRUE: Mode value follows */
- uint32_t sa_mode; /* Mode value */
- uint32_t sa_uidfollows; /* TRUE: Uid value follows */
- uint32_t sa_uid; /* Uid value */
- 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 */
- 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 */
- nfstime3 sa_mtime; /* Client time */
-};
-
-struct nfs_statfs
-{
- struct nfs_fattr obj_attributes;
- nfsuint64 sf_tbytes;
- nfsuint64 sf_fbytes;
- nfsuint64 sf_abytes;
- nfsuint64 sf_tfiles;
- nfsuint64 sf_ffiles;
- nfsuint64 sf_afiles;
- 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 fs_rtmax;
- uint32_t fs_rtpref;
- uint32_t fs_rtmult;
- uint32_t fs_wtmax;
- uint32_t fs_wtpref;
- uint32_t fs_wtmult;
- uint32_t fs_dtpref;
- nfsuint64 fs_maxfilesize;
- nfstime3 fs_timedelta;
- uint32_t fs_properties;
-};
-
-/* NFS procedures args */
-
-struct wcc_attr
-{
- nfsuint64 size;
- nfstime3 mtime;
- nfstime3 ctime;
-};
-
-struct wcc_data
-{
- uint32_t wcc_attr_follows; /* True if data follows */
- struct wcc_attr before;
- uint32_t nfs_attr_follow; /* True if attributes present */
- struct nfs_fattr after;
-};
-
-struct file_handle
-{
- uint32_t length;
- nfsfh_t handle;
-};
-#define SIZEOF_file_handle(n) (sizeof(uint32_t) + SIZEOF_nfsfh_t(n))
-
-struct diropargs3
-{
- struct file_handle fhandle; /* Variable length */
- uint32_t length; /* Size of name[] */
- uint32_t name[(NAME_MAX+3) >> 2]; /* Variable length */
-};
-
-struct CREATE3args
-{
- struct diropargs3 where;
- uint32_t create_mode;
- struct nfsv3_sattr how;
-};
-
-struct CREATE3resok
-{
- uint32_t handle_follows; /* True, handle follows */
- struct file_handle fhandle; /* Variable length */
- uint32_t attributes_follows; /* True, attributes follows */
- struct nfs_fattr attributes; /* File attributes */
- struct wcc_data dir_wcc;
-};
-
-/* 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.
- */
-
-struct LOOKUP3filename
-{
- uint32_t namelen; /* Size of name[] */
- uint32_t name[(NAME_MAX+3) >> 2]; /* Variable length */
-};
-
-struct LOOKUP3args
-{
- struct file_handle dirhandle; /* 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 */
-
-#define SIZEOF_LOOKUP3filename(b) (sizeof(uint32_t) + (((b)+3) & ~3))
-#define SIZEOF_LOOKUP3args(a,b) (SIZEOF_file_handle(a) + SIZEOF_LOOKUP3filename(b))
-
-struct LOOKUP3resok
-{
- struct file_handle fhandle;
- uint32_t obj_attributes_follow;
- struct nfs_fattr obj_attributes;
- uint32_t dir_attributes_follow;
- struct nfs_fattr dir_attributes;
-};
-
-struct READ3args
-{
- struct file_handle fhandle; /* Variable length */
- uint64_t offset;
- uint32_t count;
-};
-
-struct nfs_rdhdr_s
-{
- uint32_t attributes_follow;
- struct nfs_fattr attributes; /* Will not be present if attributes_follow == 0 */
- uint32_t count; /* Number of bytes read */
- uint32_t eof; /* Non-zero if at the end of file */
- uint32_t length; /* Length of data (same as count?) */
-};
-
-struct READ3resok
-{
- struct nfs_rdhdr_s hdr;
- uint8_t data[1]; /* Actual data size depends on count */
-};
-#define SIZEOF_READ3resok(n) (sizeof(struct nfs_rdhdr_s) + (n))
-
-struct nfs_wrhdr_s
-{
- struct file_handle fhandle; /* Variable length */
- uint64_t offset;
- uint32_t count;
- uint32_t stable;
-};
-
-struct WRITE3args
-{
- struct nfs_wrhdr_s hdr;
- uint8_t data[1]; /* Actual data size depends on count */
-};
-#define SIZEOF_WRITE3args(n) (sizeof(struct nfs_wrhdr_s) + (n))
-
-struct WRITE3resok
-{
- struct wcc_data file_wcc;
- uint32_t count;
- uint32_t committed;
- uint8_t verf[NFSX_V3WRITEVERF];
-};
-
-struct REMOVE3args
-{
- struct diropargs3 object;
-};
-
-struct REMOVE3resok
-{
- struct wcc_data dir_wcc;
-};
-
-struct RENAME3args
-{
- struct diropargs3 from;
- struct diropargs3 to;
-};
-
-struct RENAME3resok
-{
- struct wcc_data fromdir_wcc;
- struct wcc_data todir_wcc;
-};
-
-struct MKDIR3args
-{
- struct diropargs3 where;
- struct nfsv3_sattr how;
-};
-
-struct MKDIR3resok
-{
- uint32_t handle_follows; /* True, handle follows */
- struct file_handle fhandle; /* Variable length */
- uint32_t attributes_follows; /* True, attributes follows */
- struct nfs_fattr attributes; /* Directory attributes */
- struct wcc_data dir_wcc;
-};
-
-struct RMDIR3args
-{
- struct diropargs3 object;
-};
-
-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 */
- nfsuint64 cookie;
- uint8_t cookieverf[NFSX_V3COOKIEVERF];
- uint32_t count;
-};
-
-/* The READDIR reply is variable length and consists of multiple entries, each
- * of form:
- *
- * EOF - OR -
- *
- * 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)
- */
-
-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 */
-};
-
-struct FS3args
-{
- struct file_handle fsroot;
-};
-
-#endif /* __FS_NFS_NFS_PROTO_H */
-
diff --git a/nuttx/fs/nfs/nfs_util.c b/nuttx/fs/nfs/nfs_util.c
deleted file mode 100644
index e7d28b3d7..000000000
--- a/nuttx/fs/nfs/nfs_util.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/****************************************************************************
- * fs/nfs/nfs_util.c
- *
- * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <stdint.h>
-#include <queue.h>
-#include <stdbool.h>
-#include <stdlib.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"
-#include "nfs_mount.h"
-#include "nfs_node.h"
-#include "xdr_subs.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static inline int nfs_pathsegment(FAR const char **path, FAR char *buffer,
- FAR char *terminator)
-{
- FAR const char *src = *path;
- FAR char *dest = buffer;
- int nbytes = 0;
- char ch;
-
- /* Loop until the name is successfully parsed or an error occurs */
-
- for (;;)
- {
- /* Get the next byte from the path */
-
- ch = *src++;
-
- /* Check if this the last byte in this segment name */
-
- if (ch == '\0' || ch == '/')
- {
- /* This logic just suppors "//" sequences in the path name */
-
- if (ch == '\0' || nbytes > 0 )
- {
- /* NULL terminate the parsed path segment */
-
- *dest = '\0';
-
- /* Return next path and the terminating character */
-
- *terminator = ch;
- *path = src;
- return OK;
- }
-
- /* Just skip over any leading '/' characters */
- }
- else if (nbytes >= NAME_MAX)
- {
- fdbg("File name segment is too long: %d\n", *path);
- return EFBIG;
- }
- else
- {
- /* Save next character in the accumulated name */
-
- *dest++ = ch;
- nbytes++;
- }
- }
-}
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nfs_semtake
- ****************************************************************************/
-
-void nfs_semtake(struct nfsmount *nmp)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&nmp->nm_sem) != 0)
- {
- /* The only case that an error should occur here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(*get_errno_ptr() == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: nfs_semgive
- ****************************************************************************/
-
-void nfs_semgive(struct nfsmount *nmp)
-{
- sem_post(&nmp->nm_sem);
-}
-
-/****************************************************************************
- * Name: nfs_checkmount
- *
- * Desciption: 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
- *
- * Desciption:
- * Perform the NFS request. On successful receipt, it verifies the NFS level of the
- * returned values.
- *
- * Return Value:
- * Zero on success; a positive errno value on failure.
- *
- ****************************************************************************/
-
-int nfs_request(struct nfsmount *nmp, int procnum,
- FAR void *request, size_t reqlen,
- FAR void *response, size_t resplen)
-{
- 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)
- {
- fdbg("ERROR: rpcclnt_request failed: %d\n", error);
- return error;
- }
-
- memcpy(&replyh, response, sizeof(struct nfs_reply_header));
-
- if (replyh.nfs_status != 0)
- {
- if (fxdr_unsigned(uint32_t, replyh.nfs_status) > 32)
- {
- error = EOPNOTSUPP;
- }
- else
- {
- /* NFS_ERRORS are the same as NuttX errno values */
-
- error = fxdr_unsigned(uint32_t, replyh.nfs_status);
- }
-
- return error;
- }
-
- if (replyh.rpc_verfi.authtype != 0)
- {
- error = fxdr_unsigned(int, replyh.rpc_verfi.authtype);
-
- if (error == EAGAIN)
- {
- error = 0;
- goto tryagain;
- }
-
- fdbg("ERROR: NFS error %d from server\n", error);
- return error;
- }
-
- fvdbg("NFS_SUCCESS\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_lookup
- *
- * Desciption:
- * Given a directory file handle, and the path to file in the directory,
- * return the file handle of the path and attributes of both the file and
- * the directory containing the file.
- *
- * NOTE: The LOOKUP call differs from other RPC messages in that the
- * call message is variable length, depending upon the size of the path
- * name.
- *
- ****************************************************************************/
-
-int nfs_lookup(struct nfsmount *nmp, FAR const char *filename,
- FAR struct file_handle *fhandle,
- FAR struct nfs_fattr *obj_attributes,
- FAR struct nfs_fattr *dir_attributes)
-{
- FAR uint32_t *ptr;
- uint32_t value;
- int reqlen;
- int namelen;
- int error = 0;
-
- DEBUGASSERT(nmp && filename && fhandle);
-
- /* Get the length of the string to be sent */
-
- namelen = strlen(filename);
- if (namelen > NAME_MAX)
- {
- fdbg("Length of the string is too big: %d\n", namelen);
- return E2BIG;
- }
-
- /* Initialize the request */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.lookup.lookup;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned(fhandle->length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &fhandle->handle, fhandle->length);
- reqlen += fhandle->length;
- ptr += uint32_increment(fhandle->length);
-
- /* Copy the variable-length file name */
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, filename, namelen);
- reqlen += uint32_alignup(namelen);
-
- /* Request LOOKUP from the server */
-
- nfs_statistics(NFSPROC_LOOKUP);
- error = nfs_request(nmp, NFSPROC_LOOKUP,
- (FAR void *)&nmp->nm_msgbuffer.lookup, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
-
- if (error)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- return error;
- }
-
- /* Return the data to the caller's buffers. NOTE: Here we ignore the
- * the exact layout of the rpc_reply_lookup structure. File handles
- * may differ in size whereas struct rpc_reply_lookup uses a fixed size.
- */
-
- ptr = (FAR uint32_t *)&((FAR struct rpc_reply_lookup *)nmp->nm_iobuffer)->lookup;
-
- /* Get the length of the file handle */
-
- value = *ptr++;
- value = fxdr_unsigned(uint32_t, value);
- if (value > NFSX_V3FHMAX)
- {
- fdbg("ERROR: Bad file handle length: %d\n", value);
- return EIO;
- }
-
- /* Return the file handle */
-
- fhandle->length = value;
- memcpy(&fhandle->handle, ptr, value);
- ptr += uint32_increment(value);
-
- /* Check if there are object attributes and, if so, copy them to the user
- * buffer
- */
-
- value = *ptr++;
- if (value)
- {
- if (obj_attributes)
- {
- memcpy(obj_attributes, ptr, sizeof(struct nfs_fattr));
- }
- ptr += uint32_increment(sizeof(struct nfs_fattr));
- }
-
- /* Check if there are directory attributes and, if so, copy them to the
- * user buffer
- */
-
- value = *ptr++;
- if (value && dir_attributes)
- {
- memcpy(dir_attributes, ptr, sizeof(struct nfs_fattr));
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_findnode
- *
- * Desciption:
- * Given a path to something that may or may not be in the file system,
- * return the handle of the directory entry of the requested object.
- *
- * Return Value:
- * Zero on success; a positive errno value on failure.
- *
- ****************************************************************************/
-
-int nfs_findnode(struct nfsmount *nmp, FAR const char *relpath,
- FAR struct file_handle *fhandle, FAR struct nfs_fattr *obj_attributes,
- FAR struct nfs_fattr *dir_attributes)
-{
- FAR const char *path = relpath;
- char buffer[NAME_MAX+1];
- char terminator;
- uint32_t tmp;
- int error;
-
- /* Start with the file handle of the root directory. */
-
- fhandle->length = 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)
- {
- /* Return the root directory attributes */
-
- if (obj_attributes)
- {
- memcpy(obj_attributes, &nmp->nm_fattr, sizeof(struct nfs_fattr));
- }
-
- if (dir_attributes)
- {
- memcpy(dir_attributes, &nmp->nm_fattr, sizeof(struct nfs_fattr));
- }
-
- return OK;
- }
-
- /* This is not the root directory. Loop until the directory entry corresponding
- * to the path is found.
- */
-
- for (;;)
- {
- /* Extract the next path segment name. */
-
- error = nfs_pathsegment(&path, buffer, &terminator);
- if (error != OK)
- {
- /* The filename segment contains is too long. */
-
- fdbg("nfs_pathsegment of \"%s\" failed after \"%s\": %d\n",
- relpath, buffer, error);
- return error;
- }
-
- /* Look-up this path segment */
-
- error = nfs_lookup(nmp, buffer, fhandle, obj_attributes, dir_attributes);
- if (error != OK)
- {
- fdbg("nfs_lookup of \"%s\" failed at \"%s\": %d\n",
- relpath, buffer, error);
- return error;
- }
-
- /* If the terminator character in the path was the end of the string
- * then we have successfully found the directory entry that describes
- * the path.
- */
-
- if (!terminator)
- {
- /* Return success meaning that the description the matching
- * directory entry is in fhandle, obj_attributes, and dir_attributes.
- */
-
- return OK;
- }
-
- /* No.. then we have found one of the intermediate directories on
- * the way to the final path target. In this case, make sure
- * the thing that we found is, indeed, a directory.
- */
-
- tmp = fxdr_unsigned(uint32_t, obj_attributes->fa_type);
- if (tmp != NFDIR)
- {
- /* Ooops.. we found something else */
-
- fdbg("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
- buffer, path);
- return ENOTDIR;
- }
- }
-}
-
-/****************************************************************************
- * Name: nfs_finddir
- *
- * Desciption:
- * Given a path to something that may or may not be in the file system,
- * return the handle of the entry of the directory containing the requested
-* object.
- *
- * Return Value:
- * Zero on success; a positive errno value on failure.
- *
- ****************************************************************************/
-
-int nfs_finddir(struct nfsmount *nmp, FAR const char *relpath,
- FAR struct file_handle *fhandle,
- FAR struct nfs_fattr *attributes, FAR char *filename)
-{
- FAR const char *path = relpath;
- uint32_t tmp;
- char terminator;
- int error;
-
- /* Verify that a path was provided */
-
- if (*path == '\0' || strlen(path) == 0)
- {
- /* Return the root directory attributes */
-
- 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(attributes, &nmp->nm_fattr, sizeof(struct nfs_fattr));
-
- /* Loop until the directory entry containing the path is found. */
-
- for (;;)
- {
- /* Extract the next path segment name. */
-
- error = nfs_pathsegment(&path, filename, &terminator);
- if (error != OK)
- {
- /* The filename segment contains is too long. */
-
- fdbg("nfs_pathsegment of \"%s\" failed after \"%s\": %d\n",
- relpath, filename, error);
- return error;
- }
-
- /* If the terminator character in the path was the end of the string
- * then we have successfully found the directory that contains the name
- * of interest.
- */
-
- if (!terminator)
- {
- /* Return success meaning that the description of the directory
- * containing the object is in fhandle and attributes.
- */
-
- return OK;
- }
-
- /* Look-up the next path segment */
-
- error = nfs_lookup(nmp, filename, fhandle, attributes, NULL);
- if (error != OK)
- {
- fdbg("nfs_lookup of \"%s\" failed at \"%s\": %d\n",
- relpath, filename, error);
- return error;
- }
-
- /* Make sure the thing that we found is, indeed, a directory. */
-
- tmp = fxdr_unsigned(uint32_t, attributes->fa_type);
- if (tmp != NFDIR)
- {
- /* Ooops.. we found something else */
-
- fdbg("ERROR: Intermediate segment \"%s\" of \'%s\" is not a directory\n",
- filename, path);
- return ENOTDIR;
- }
- }
-}
-
-/****************************************************************************
- * Name: nfs_attrupdate
- *
- * Desciption:
- * Update file attributes on write or after the file is modified.
- *
- * Return Value:
- * None.
- *
- ****************************************************************************/
-
-void nfs_attrupdate(FAR struct nfsnode *np, FAR struct nfs_fattr *attributes)
-{
- /* Save a few of the files attribute values in file structur (host order) */
-
- np->n_type = fxdr_unsigned(uint32_t, attributes->fa_type);
- np->n_size = fxdr_hyper(&attributes->fa_size);
- fxdr_nfsv3time(&attributes->fa_mtime, &np->n_mtime)
- np->n_ctime = fxdr_hyper(&attributes->fa_ctime);
-}
diff --git a/nuttx/fs/nfs/nfs_vfsops.c b/nuttx/fs/nfs/nfs_vfsops.c
deleted file mode 100644
index 2ff4ff9d3..000000000
--- a/nuttx/fs/nfs/nfs_vfsops.c
+++ /dev/null
@@ -1,2622 +0,0 @@
-/****************************************************************************
- * fs/nfs/nfs_vfsops.c
- *
- * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 1989, 1993, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/socket.h>
-#include <sys/statfs.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <queue.h>
-#include <string.h>
-#include <fcntl.h>
-#include <time.h>
-#include <semaphore.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/dirent.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/nfs.h>
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-udp.h>
-#include <nuttx/net/uip/uipopt.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-
-#include "nfs.h"
-#include "rpc.h"
-#include "nfs_proto.h"
-#include "nfs_node.h"
-#include "nfs_mount.h"
-#include "xdr_subs.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* The V3 EXCLUSIVE file creation logic is not fully supported. */
-
-#define USE_GUARDED_CREATE 1
-
-/* include/nuttx/fs/dirent.h has its own version of these lengths. They must
- * match the NFS versions.
- */
-
-#if NFSX_V3FHMAX != DIRENT_NFS_MAXHANDLE
-# error "Length of file handle in fs_dirent_s is incorrect"
-#endif
-
-#if NFSX_V3COOKIEVERF != DIRENT_NFS_VERFLEN
-# error "Length of cookie verify in fs_dirent_s is incorrect"
-#endif
-
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
-
-uint32_t nfs_true;
-uint32_t nfs_false;
-uint32_t nfs_xdrneg1;
-
-#ifdef CONFIG_NFS_STATISTICS
-struct nfsstats nfsstats;
-#endif
-
-/****************************************************************************
- * Private Type Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
- FAR const char *relpath, mode_t mode);
-static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np);
-static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
- FAR const char *relpath, int oflags, mode_t mode);
-static int nfs_open(FAR struct file *filep, const char *relpath,
- int oflags, mode_t mode);
-static int nfs_close(FAR struct file *filep);
-static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen);
-static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
- size_t buflen);
-static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp);
-static int nfs_opendir(struct inode *mountpt, const char *relpath,
- struct fs_dirent_s *dir);
-static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir);
-static int nfs_rewinddir(FAR struct inode *mountpt,
- FAR struct fs_dirent_s *dir);
-static void nfs_decode_args(FAR struct nfs_mount_parameters *nprmt,
- FAR struct nfs_args *argp);
-static int nfs_bind(FAR struct inode *blkdriver, const void *data,
- void **handle);
-static int nfs_unbind(void *handle, FAR struct inode **blkdriver);
-static int nfs_statfs(struct inode *mountpt, struct statfs *buf);
-static int nfs_remove(struct inode *mountpt, const char *relpath);
-static int nfs_mkdir(struct inode *mountpt, const char *relpath,
- mode_t mode);
-static int nfs_rmdir(struct inode *mountpt, const char *relpath);
-static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
- const char *newrelpath);
-static int nfs_stat(struct inode *mountpt, const char *relpath,
- struct stat *buf);
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-/* nfs vfs operations. */
-
-const struct mountpt_operations nfs_operations =
-{
- nfs_open, /* open */
- nfs_close, /* close */
- nfs_read, /* read */
- nfs_write, /* write */
- NULL, /* seek */
- NULL, /* ioctl */
-
- NULL, /* sync */
- nfs_dup, /* dup */
-
- nfs_opendir, /* opendir */
- NULL, /* closedir */
- nfs_readdir, /* readdir */
- nfs_rewinddir, /* rewinddir */
-
- nfs_bind, /* bind */
- nfs_unbind, /* unbind */
- nfs_statfs, /* statfs */
-
- nfs_remove, /* unlink */
- nfs_mkdir, /* mkdir */
- nfs_rmdir, /* rmdir */
- nfs_rename, /* rename */
- nfs_stat /* stat */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: nfs_filecreate
- *
- * Description:
- * Create a file. This is part of the file open logic that is executed if
- * the user asks to create a file.
- *
- * Returned Value:
- * 0 on success; a positive errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
- FAR const char *relpath, mode_t mode)
-{
- struct file_handle fhandle;
- struct nfs_fattr fattr;
- char filename[NAME_MAX + 1];
- FAR uint32_t *ptr;
- uint32_t tmp;
- int namelen;
- int reqlen;
- int error;
-
- /* Find the NFS node of the directory containing the file to be created */
-
- error = nfs_finddir(nmp, relpath, &fhandle, &fattr, filename);
- if (error != OK)
- {
- fdbg("ERROR: nfs_finddir returned: %d\n", error);
- return error;
- }
-
- /* Create the CREATE RPC call arguments */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.create.create;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned(fhandle.length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &fhandle.handle, fhandle.length);
- reqlen += (int)fhandle.length;
- ptr += uint32_increment(fhandle.length);
-
- /* Copy the variable-length file name */
-
- namelen = strlen(filename);
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, filename, namelen);
- ptr += uint32_increment(namelen);
- reqlen += uint32_alignup(namelen);
-
- /* Set the creation mode */
-
- if ((mode & O_CREAT) != 0)
- {
-#ifdef USE_GUARDED_CREATE
- *ptr++ = HTONL(NFSV3CREATE_GUARDED);
-#else
- *ptr++ = HTONL(NFSV3CREATE_EXCLUSIVE);
-#endif
- }
- else
- {
- *ptr++ = HTONL(NFSV3CREATE_UNCHECKED);
- }
- reqlen += sizeof(uint32_t);
-
- /* Mode information is not provided if EXCLUSIVE creation is used.
- * in this case, we must call SETATTR after successfully creating
- * the file.
- */
-
-#ifndef USE_GUARDED_CREATE
- if ((mode & O_CREAT) == 0)
-#endif
- {
- /* Set the mode. NOTE: Here we depend on the fact that the NuttX and NFS
- * bit settings are the same (at least for the bits of interest).
- */
-
- *ptr++ = nfs_true; /* True: mode value follows */
- reqlen += sizeof(uint32_t);
-
- tmp = mode & (NFSMODE_IWOTH | NFSMODE_IROTH | NFSMODE_IWGRP |
- NFSMODE_IRGRP | NFSMODE_IWUSR | NFSMODE_IRUSR);
- *ptr++ = txdr_unsigned(tmp);
- reqlen += sizeof(uint32_t);
-
- /* Set the user ID to zero */
-
- *ptr++ = nfs_true; /* True: Uid value follows */
- *ptr++ = 0; /* UID = 0 (nobody) */
- reqlen += 2*sizeof(uint32_t);
-
- /* Set the group ID to one */
-
- *ptr++ = nfs_true; /* True: Gid value follows */
- *ptr++ = HTONL(1); /* GID = 1 (nogroup) */
- reqlen += 2*sizeof(uint32_t);
-
- /* Set the size to zero */
-
- *ptr++ = nfs_true; /* True: Size value follows */
- *ptr++ = 0; /* Size = 0 */
- *ptr++ = 0;
- reqlen += 3*sizeof(uint32_t);
-
- /* Don't change times */
-
- *ptr++ = HTONL(NFSV3SATTRTIME_DONTCHANGE); /* Don't change atime */
- *ptr++ = HTONL(NFSV3SATTRTIME_DONTCHANGE); /* Don't change mtime */
- reqlen += 2*sizeof(uint32_t);
- }
-
- /* Send the NFS request. Note there is special logic here to handle version 3
- * exclusive open semantics.
- */
-
- do
- {
- nfs_statistics(NFSPROC_CREATE);
- error = nfs_request(nmp, NFSPROC_CREATE,
- (FAR void *)&nmp->nm_msgbuffer.create, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
- }
-#ifdef USE_GUARDED_CREATE
- while (0);
-#else
- while (((mode & O_CREAT) != 0) && error == EOPNOTSUPP);
-#endif
-
- /* Check for success */
-
- if (error == OK)
- {
- /* Parse the returned data */
-
- ptr = (FAR uint32_t *)&((FAR struct rpc_reply_create *)nmp->nm_iobuffer)->create;
-
- /* Save the file handle in the file data structure */
-
- tmp = *ptr++; /* handle_follows */
- if (!tmp)
- {
- fdbg("ERROR: no file handle follows\n");
- return EINVAL;
- }
-
- tmp = *ptr++;
- tmp = fxdr_unsigned(uint32_t, tmp);
- DEBUGASSERT(tmp <= NFSX_V3FHMAX);
-
- np->n_fhsize = (uint8_t)tmp;
- memcpy(&np->n_fhandle, ptr, tmp);
- ptr += uint32_increment(tmp);
-
- /* Save the attributes in the file data structure */
-
- tmp = *ptr; /* handle_follows */
- if (!tmp)
- {
- fdbg("WARNING: no file attributes\n");
- }
- else
- {
- /* Initialize the file attributes */
-
- nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
- }
-
- /* Any following dir_wcc data is ignored for now */
- }
-
- return error;
-}
-
-/****************************************************************************
- * Name: nfs_fileopen
- *
- * Description:
- * Truncate an open file to zero length. This is part of the file open
- * logic.
- *
- * Returned Value:
- * 0 on success; a positive errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
-{
- FAR uint32_t *ptr;
- int reqlen;
- int error;
-
- fvdbg("Truncating file\n");
-
- /* Create the SETATTR RPC call arguments */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.setattr.setattr;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned(np->n_fhsize);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &np->n_fhandle, np->n_fhsize);
- reqlen += (int)np->n_fhsize;
- ptr += uint32_increment(np->n_fhsize);
-
- /* Copy the variable-length attributes */
-
- *ptr++ = nfs_false; /* Don't change mode */
- *ptr++ = nfs_false; /* Don't change uid */
- *ptr++ = nfs_false; /* Don't change gid */
- *ptr++ = nfs_true; /* Use the following size */
- *ptr++ = 0; /* Truncate to zero length */
- *ptr++ = 0;
- *ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
- *ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
- *ptr++ = nfs_false; /* No guard value */
- reqlen += 9 * sizeof(uint32_t);
-
- /* Perform the SETATTR RPC */
-
- nfs_statistics(NFSPROC_SETATTR);
- error = nfs_request(nmp, NFSPROC_SETATTR,
- (FAR void *)&nmp->nm_msgbuffer.setattr, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
- if (error != OK)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- return error;
- }
-
- /* Indicate that the file now has zero length */
-
- np->n_size = 0;
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_fileopen
- *
- * Description:
- * Open a file. This is part of the file open logic that attempts to open
- * an existing file.
- *
- * Returned Value:
- * 0 on success; a positive errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
- FAR const char *relpath, int oflags, mode_t mode)
-{
- struct file_handle fhandle;
- struct nfs_fattr fattr;
- uint32_t tmp;
- int error = 0;
-
- /* Find the NFS node associate with the path */
-
- error = nfs_findnode(nmp, relpath, &fhandle, &fattr, NULL);
- if (error != OK)
- {
- fdbg("ERROR: nfs_findnode returned: %d\n", error);
- return error;
- }
-
- /* Check if the object is a directory */
-
- tmp = fxdr_unsigned(uint32_t, fattr.fa_type);
- if (tmp == NFDIR)
- {
- /* Exit with EISDIR if we attempt to open a directory */
-
- fdbg("ERROR: Path is a directory\n");
- return EISDIR;
- }
-
- /* Check if the caller has sufficient privileges to open the file */
-
- if ((oflags & O_WRONLY) != 0)
- {
- /* Check if anyone has priveleges to write to the file -- owner,
- * group, or other (we are probably "other" and may still not be
- * able to write).
- */
-
- tmp = fxdr_unsigned(uint32_t, fattr.fa_mode);
- if ((tmp & (NFSMODE_IWOTH|NFSMODE_IWGRP|NFSMODE_IWUSR)) == 0)
- {
- fdbg("ERROR: File is read-only: %08x\n", tmp);
- return EACCES;
- }
- }
-
- /* It would be an error if we are asked to create the file exclusively */
-
- if ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
- {
- /* Already exists -- can't create it exclusively */
-
- fdbg("ERROR: File exists\n");
- return EEXIST;
- }
-
- /* Initialize the file private data */
- /* Copy the file handle */
-
- np->n_fhsize = (uint8_t)fhandle.length;
- memcpy(&np->n_fhandle, &fhandle.handle, fhandle.length);
-
- /* Save the file attributes */
-
- nfs_attrupdate(np, &fattr);
-
- /* If O_TRUNC is specified and the file is opened for writing,
- * then truncate the file. This operation requires that the file is
- * writable, but we have already checked that. O_TRUNC without write
- * access is ignored.
- */
-
- if ((oflags & (O_TRUNC|O_WRONLY)) == (O_TRUNC|O_WRONLY))
- {
- /* Truncate the file to zero length. I think we can do this with
- * the SETATTR call by setting the length to zero.
- */
-
- return nfs_filetruncate(nmp, np);
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_open
- *
- * Description:
- * If oflags == O_CREAT it creates a file, if not it check to see if the
- * type is ok and that deletion is not in progress.
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_open(FAR struct file *filep, FAR const char *relpath,
- int oflags, mode_t mode)
-{
- struct nfsmount *nmp;
- struct nfsnode *np;
- int error;
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_inode != NULL);
-
- /* Get the mountpoint inode reference from the file structure and the
- * mountpoint private data from the inode structure
- */
-
- nmp = (struct nfsmount*)filep->f_inode->i_private;
- DEBUGASSERT(nmp != NULL);
-
- /* Pre-allocate the file private data to describe the opened file. */
-
- np = (struct nfsnode *)kzalloc(sizeof(struct nfsnode));
- if (!np)
- {
- fdbg("ERROR: Failed to allocate private data\n");
- return -ENOMEM;
- }
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Try to open an existing file at that path */
-
- error = nfs_fileopen(nmp, np, relpath, oflags, mode);
- if (error != OK)
- {
- /* An error occurred while trying to open the existing file. Check if
- * the open failed because the file does not exist. That is not
- * necessarily an error; that may only mean that we have to create the
- * file.
- */
-
- if (error != ENOENT)
- {
- fdbg("ERROR: nfs_findnode failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* The file does not exist. Check if we were asked to create the file. If
- * the O_CREAT bit is set in the oflags then we should create the file if it
- * does not exist.
- */
-
- if ((oflags & O_CREAT) == 0)
- {
- /* Return ENOENT if the file does not exist and we were not asked
- * to create it.
- */
-
- fdbg("ERROR: File does not exist\n");
- error = ENOENT;
- goto errout_with_semaphore;
- }
-
- /* Create the file */
-
- error = nfs_filecreate(nmp, np, relpath, mode);
- if (error != OK)
- {
- fdbg("ERROR: nfs_filecreate failed: %d\n", error);
- goto errout_with_semaphore;
- }
- }
-
- /* Initialize the file private data (only need to initialize
- * non-zero elements)
- */
-
- np->n_crefs = 1;
-
- /* Attach the private data to the struct file instance */
-
- filep->f_priv = np;
-
- /* Then insert the new instance at the head of the list in the mountpoint
- * tructure. It needs to be there (1) to handle error conditions that effect
- * all files, and (2) to inform the umount logic that we are busy. We
- * cannot unmount the file system if this list is not empty!
- */
-
- np->n_next = nmp->nm_head;
- nmp->nm_head = np;
-
- np->n_flags |= (NFSNODE_OPEN | NFSNODE_MODIFIED);
- nfs_semgive(nmp);
- return OK;
-
-errout_with_semaphore:
- if (np)
- {
- kfree(np);
- }
-
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_close
- *
- * Description:
- * Close a file.
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_close(FAR struct file *filep)
-{
- FAR struct nfsmount *nmp;
- FAR struct nfsnode *np;
- FAR struct nfsnode *prev;
- FAR struct nfsnode *curr;
- int ret;
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover our private data from the struct file instance */
-
- nmp = (struct nfsmount*) filep->f_inode->i_private;
- np = (struct nfsnode*) filep->f_priv;
-
- DEBUGASSERT(nmp != NULL);
-
- /* Get exclusive access to the mount structure. */
-
- nfs_semtake(nmp);
-
- /* Decrement the reference count. If the reference count would not
- * decrement to zero, then that is all we have to do.
- */
-
- if (np->n_crefs > 1)
- {
- np->n_crefs--;
- ret = OK;
- }
-
- /* There are no more references to the file structure. Now we need to
- * free up all resources associated with the open file.
- *
- * First, find our file structure in the list of file structures
- * containted in the mount structure.
- */
-
- else
- {
- /* Assume file structure will not be found. This should never happen. */
-
- ret = -EINVAL;
-
- for (prev = NULL, curr = nmp->nm_head;
- curr;
- prev = curr, curr = curr->n_next)
- {
- /* Check if this node is ours */
-
- if (np == curr)
- {
- /* Yes.. remove it from the list of file structures */
-
- if (prev)
- {
- /* Remove from mid-list */
-
- prev->n_next = np->n_next;
- }
- else
- {
- /* Remove from the head of the list */
-
- nmp->nm_head = np->n_next;
- }
-
- /* Then deallocate the file structure and return success */
-
- kfree(np);
- ret = OK;
- break;
- }
- }
- }
-
- filep->f_priv = NULL;
- nfs_semgive(nmp);
- return ret;
-}
-
-/****************************************************************************
- * Name: nfs_read
- *
- * Returned Value:
- * The (non-negative) number of bytes read on success; a negated errno
- * value on failure.
- *
- ****************************************************************************/
-
-static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
-{
- FAR struct nfsmount *nmp;
- FAR struct nfsnode *np;
- ssize_t readsize;
- ssize_t tmp;
- ssize_t bytesread;
- size_t reqlen;
- FAR uint32_t *ptr;
- int error = 0;
-
- fvdbg("Read %d bytes from offset %d\n", buflen, filep->f_pos);
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover our private data from the struct file instance */
-
- nmp = (struct nfsmount*)filep->f_inode->i_private;
- np = (struct nfsnode*)filep->f_priv;
-
- DEBUGASSERT(nmp != NULL);
-
- /* Make sure that the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Get the number of bytes left in the file and truncate read count so that
- * it does not exceed the number of bytes left in the file.
- */
-
- tmp = np->n_size - filep->f_pos;
- if (buflen > tmp)
- {
- buflen = tmp;
- fvdbg("Read size truncated to %d\n", buflen);
- }
-
- /* Now loop until we fill the user buffer (or hit the end of the file) */
-
- for (bytesread = 0; bytesread < buflen; )
- {
- /* Make sure that the attempted read size does not exceed the RPC maximum */
-
- readsize = buflen;
- if (readsize > nmp->nm_rsize)
- {
- readsize = nmp->nm_rsize;
- }
-
- /* Make sure that the attempted read size does not exceed the IO buffer size */
-
- tmp = SIZEOF_rpc_reply_read(readsize);
- if (tmp > nmp->nm_buflen)
- {
- readsize -= (tmp - nmp->nm_buflen);
- }
-
- /* Initialize the request */
-
- ptr = (FAR uint32_t*)&nmp->nm_msgbuffer.read.read;
- reqlen = 0;
-
- /* Copy the variable length, file handle */
-
- *ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &np->n_fhandle, np->n_fhsize);
- reqlen += (int)np->n_fhsize;
- ptr += uint32_increment((int)np->n_fhsize);
-
- /* Copy the file offset */
-
- txdr_hyper((uint64_t)filep->f_pos, ptr);
- ptr += 2;
- reqlen += 2*sizeof(uint32_t);
-
- /* Set the readsize */
-
- *ptr = txdr_unsigned(readsize);
- reqlen += sizeof(uint32_t);
-
- /* Perform the read */
-
- fvdbg("Reading %d bytes\n", readsize);
- nfs_statistics(NFSPROC_READ);
- error = nfs_request(nmp, NFSPROC_READ,
- (FAR void *)&nmp->nm_msgbuffer.read, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
- if (error)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* The read was successful. Get a pointer to the beginning of the NFS
- * response data.
- */
-
- ptr = (FAR uint32_t *)&((FAR struct rpc_reply_read *)nmp->nm_iobuffer)->read;
-
- /* Check if attributes are included in the responses */
-
- tmp = *ptr++;
- if (*ptr != 0)
- {
- /* Yes... just skip over the attributes for now */
-
- ptr += uint32_increment(sizeof(struct nfs_fattr));
- }
-
- /* This is followed by the count of data read. Isn't this
- * the same as the length that is included in the read data?
- *
- * Just skip over if for now.
- */
-
- ptr++;
-
- /* Next comes an EOF indication. Save that in tmp for now. */
-
- tmp = *ptr++;
-
- /* Then the length of the read data followed by the read data itself */
-
- readsize = fxdr_unsigned(uint32_t, *ptr);
- ptr++;
-
- /* Copy the read data into the user buffer */
-
- memcpy(buffer, ptr, readsize);
-
- /* Update the read state data */
-
- filep->f_pos += readsize;
- bytesread += readsize;
- buffer += readsize;
-
- /* Check if we hit the end of file */
-
- if (tmp != 0)
- {
- break;
- }
- }
-
- fvdbg("Read %d bytes\n", bytesread);
- nfs_semgive(nmp);
- return bytesread;
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_write
- *
- * Returned Value:
- * The (non-negative) number of bytes written on success; a negated errno
- * value on failure.
- *
- ****************************************************************************/
-
-static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
- size_t buflen)
-{
- struct nfsmount *nmp;
- struct nfsnode *np;
- ssize_t writesize;
- ssize_t bufsize;
- ssize_t byteswritten;
- size_t reqlen;
- FAR uint32_t *ptr;
- uint32_t tmp;
- int commit = 0;
- int committed = NFSV3WRITE_FILESYNC;
- int error;
-
- fvdbg("Write %d bytes to offset %d\n", buflen, filep->f_pos);
-
- /* Sanity checks */
-
- DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
-
- /* Recover our private data from the struct file instance */
-
- nmp = (struct nfsmount*)filep->f_inode->i_private;
- np = (struct nfsnode*)filep->f_priv;
-
- DEBUGASSERT(nmp != NULL);
-
- /* Make sure that the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Check if the file size would exceed the range of off_t */
-
- if (np->n_size + buflen < np->n_size)
- {
- error = EFBIG;
- goto errout_with_semaphore;
- }
-
- /* Now loop until we send the entire user buffer */
-
- writesize = 0;
- for (byteswritten = 0; byteswritten < buflen; )
- {
- /* Make sure that the attempted write size does not exceed the RPC maximum */
-
- writesize = buflen;
- if (writesize > nmp->nm_wsize)
- {
- writesize = nmp->nm_wsize;
- }
-
- /* Make sure that the attempted read size does not exceed the IO buffer size */
-
- bufsize = SIZEOF_rpc_call_write(writesize);
- if (bufsize > nmp->nm_buflen)
- {
- writesize -= (bufsize - nmp->nm_buflen);
- }
-
- /* Initialize the request. Here we need an offset pointer to the write
- * arguments, skipping over the RPC header. Write is unique among the
- * RPC calls in that the entry RPC calls messasge lies in the I/O buffer
- */
-
- ptr = (FAR uint32_t *)&((FAR struct rpc_call_write *)nmp->nm_iobuffer)->write;
- reqlen = 0;
-
- /* Copy the variable length, file handle */
-
- *ptr++ = txdr_unsigned((uint32_t)np->n_fhsize);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &np->n_fhandle, np->n_fhsize);
- reqlen += (int)np->n_fhsize;
- ptr += uint32_increment((int)np->n_fhsize);
-
- /* Copy the file offset */
-
- txdr_hyper((uint64_t)filep->f_pos, ptr);
- ptr += 2;
- reqlen += 2*sizeof(uint32_t);
-
- /* Copy the count and stable values */
-
- *ptr++ = txdr_unsigned(buflen);
- *ptr++ = txdr_unsigned(committed);
- reqlen += 2*sizeof(uint32_t);
-
- /* Copy a chunk of the user data into the I/O buffer */
-
- *ptr++ = txdr_unsigned(buflen);
- reqlen += sizeof(uint32_t);
- memcpy(ptr, buffer, writesize);
- reqlen += uint32_alignup(writesize);
-
- /* Perform the write */
-
- nfs_statistics(NFSPROC_WRITE);
- error = nfs_request(nmp, NFSPROC_WRITE,
- (FAR void *)nmp->nm_iobuffer, reqlen,
- (FAR void *)&nmp->nm_msgbuffer.write, sizeof(struct rpc_reply_write));
- if (error)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Get a pointer to the WRITE reply data */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.write.write;
-
- /* Parse file_wcc. First, check if WCC attributes follow. */
-
- tmp = *ptr++;
- if (tmp != 0)
- {
- /* Yes.. WCC attributes follow. But we just skip over them. */
-
- ptr += uint32_increment(sizeof(struct wcc_attr));
- }
-
- /* Check if normal file attributes follow */
-
- tmp = *ptr++;
- if (tmp != 0)
- {
- /* Yes.. Update the cached file status in the file structure. */
-
- nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
- ptr += uint32_increment(sizeof(struct nfs_fattr));
- }
-
- /* Get the count of bytes actually written */
-
- tmp = fxdr_unsigned(uint32_t, *ptr);
- ptr++;
-
- if (tmp < 1 || tmp > writesize)
- {
- error = EIO;
- goto errout_with_semaphore;
- }
-
- writesize = tmp;
-
- /* Determine the lowest committment level obtained by any of the RPCs. */
-
- commit = *ptr++;
- if (committed == NFSV3WRITE_FILESYNC)
- {
- committed = commit;
- }
- else if (committed == NFSV3WRITE_DATASYNC &&
- commit == NFSV3WRITE_UNSTABLE)
- {
- committed = commit;
- }
-
- /* Update the read state data */
-
- filep->f_pos += writesize;
- byteswritten += writesize;
- buffer += writesize;
- }
-
- nfs_semgive(nmp);
- return writesize;
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: binfs_dup
- *
- * Description:
- * Duplicate open file data in the new file structure.
- *
- ****************************************************************************/
-
-static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp)
-{
- struct nfsmount *nmp;
- FAR struct nfsnode *np;
- int error;
-
- fvdbg("Dup %p->%p\n", oldp, newp);
-
- /* Sanity checks */
-
- DEBUGASSERT(oldp->f_priv != NULL && oldp->f_inode != NULL);
-
- /* Recover our private data from the struct file instance */
-
- nmp = (struct nfsmount*)oldp->f_inode->i_private;
- np = (struct nfsnode*)oldp->f_priv;
-
- DEBUGASSERT(nmp != NULL);
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- nfs_semgive(nmp);
- return -error;
- }
-
- /* Increment the reference count on the NFS node structure */
-
- DEBUGASSERT(np->n_crefs < 0xff);
- np->n_crefs++;
-
- /* And save this as the file data for the new node */
-
- newp->f_priv = np;
-
- /* Then insert the new instance at the head of the list in the mountpoint
- * tructure. It needs to be there (1) to handle error conditions that effect
- * all files, and (2) to inform the umount logic that we are busy. We
- * cannot unmount the file system if this list is not empty!
- */
-
- np->n_next = nmp->nm_head;
- nmp->nm_head = np;
-
- nfs_semgive(nmp);
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_opendir
- *
- * Description:
- * Open a directory for read access
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_opendir(struct inode *mountpt, const char *relpath,
- struct fs_dirent_s *dir)
-{
- struct nfsmount *nmp;
- struct file_handle fhandle;
- struct nfs_fattr obj_attributes;
- uint32_t objtype;
- int error;
-
- fvdbg("relpath: \"%s\"\n", relpath ? relpath : "NULL");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL && dir);
-
- /* Recover our private data from the inode instance */
-
- nmp = mountpt->i_private;
-
- /* Initialize the NFS-specific portions of dirent structure to zero */
-
- memset(&dir->u.nfs, 0, sizeof(struct nfsdir_s));
-
- /* Make sure that the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Find the NFS node associate with the path */
-
- error = nfs_findnode(nmp, relpath, &fhandle, &obj_attributes, NULL);
- if (error != OK)
- {
- fdbg("ERROR: nfs_findnode failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* The entry is a directory */
-
- objtype = fxdr_unsigned(uint32_t, obj_attributes.fa_type);
- if (objtype != NFDIR)
- {
- fdbg("ERROR: Not a directory, type=%d\n", objtype);
- error = ENOTDIR;
- goto errout_with_semaphore;
- }
-
- /* Save the directory information in struct fs_dirent_s so that it can be
- * used later when readdir() is called.
- */
-
- dir->u.nfs.nfs_fhsize = (uint8_t)fhandle.length;
- DEBUGASSERT(fhandle.length <= DIRENT_NFS_MAXHANDLE);
-
- memcpy(dir->u.nfs.nfs_fhandle, &fhandle.handle, DIRENT_NFS_MAXHANDLE);
- error = OK;
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_readdir
- *
- * Description: Read from directory
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
-{
- struct nfsmount *nmp;
- struct file_handle fhandle;
- struct nfs_fattr obj_attributes;
- uint32_t tmp;
- uint32_t *ptr;
- uint8_t *name;
- unsigned int length;
- int reqlen;
- int error = 0;
-
- fvdbg("Entry\n");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);
-
- /* Recover our private data from the inode instance */
-
- nmp = mountpt->i_private;
-
- /* Make sure that the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Request a block directory entries, copying directory information from
- * the dirent structure.
- */
-
- ptr = (FAR uint32_t*)&nmp->nm_msgbuffer.readdir.readdir;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned((uint32_t)dir->u.nfs.nfs_fhsize);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, dir->u.nfs.nfs_fhandle, dir->u.nfs.nfs_fhsize);
- reqlen += (int)dir->u.nfs.nfs_fhsize;
- ptr += uint32_increment((int)dir->u.nfs.nfs_fhsize);
-
- /* Cookie and cookie verifier */
-
- ptr[0] = dir->u.nfs.nfs_cookie[0];
- ptr[1] = dir->u.nfs.nfs_cookie[1];
- ptr += 2;
- reqlen += 2*sizeof(uint32_t);
-
- memcpy(ptr, dir->u.nfs.nfs_verifier, DIRENT_NFS_VERFLEN);
- ptr += uint32_increment(DIRENT_NFS_VERFLEN);
- reqlen += DIRENT_NFS_VERFLEN;
-
- /* Number of directory entries (We currently only process one entry at a time) */
-
- *ptr = txdr_unsigned(nmp->nm_readdirsize);
- reqlen += sizeof(uint32_t);
-
- /* And read the directory */
-
- nfs_statistics(NFSPROC_READDIR);
- error = nfs_request(nmp, NFSPROC_READDIR,
- (FAR void *)&nmp->nm_msgbuffer.readdir, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
- if (error != OK)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* 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
- */
-
- ptr = (uint32_t *)&((FAR struct rpc_reply_readdir *)nmp->nm_iobuffer)->readdir;
-
- /* Check if attributes follow, if 0 so Skip over the attributes */
-
- tmp = *ptr++;
- if (tmp != 0)
- {
- /* Attributes are not currently used */
-
- ptr += uint32_increment(sizeof(struct nfs_fattr));
- }
-
- /* Save the verification cookie */
-
- memcpy(dir->u.nfs.nfs_verifier, ptr, DIRENT_NFS_VERFLEN);
- ptr += uint32_increment(DIRENT_NFS_VERFLEN);
-
- /* Check if values follow. If no values follow, then the EOF indication
- * will appear next.
- */
-
- tmp = *ptr++;
- if (tmp == 0)
- {
- /* No values follow, then the reply should consist only of a 4-byte
- * end-of-directory indication.
- */
-
- tmp = *ptr++;
- if (tmp != 0)
- {
- fvdbg("End of directory\n");
- error = ENOENT;
- }
-
- /* What would it mean if there were not data and we not at the end of
- * file?
- */
-
- else
- {
- fvdbg("No data but not end of directory???\n");
- error = EAGAIN;
- }
-
- goto errout_with_semaphore;
- }
-
- /* 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)
- */
-
- /* There is an entry. Skip over the file ID and point to the length */
-
- 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 += uint32_increment(length);
-
- /* Save the cookie and increment the pointer to the next entry */
-
- dir->u.nfs.nfs_cookie[0] = *ptr++;
- dir->u.nfs.nfs_cookie[1] = *ptr++;
-
- ptr++; /* Just skip over the nextentry for now */
-
- /* 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.
- */
-
- fhandle.length = (uint32_t)dir->u.nfs.nfs_fhsize;
- memcpy(&fhandle.handle, dir->u.nfs.nfs_fhandle, DIRENT_NFS_MAXHANDLE);
-
- error = nfs_lookup(nmp, dir->fd_dir.d_name, &fhandle, &obj_attributes, NULL);
- if (error != OK)
- {
- fdbg("nfs_lookup failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Set the dirent file type */
-
- tmp = fxdr_unsigned(uint32_t, obj_attributes.fa_type);
- switch (tmp)
- {
- default:
- case NFNON: /* Unknown type */
- case NFSOCK: /* Socket */
- case NFLNK: /* Symbolic link */
- break;
-
- case NFREG: /* Regular file */
- dir->fd_dir.d_type = DTYPE_FILE;
- break;
-
- case NFDIR: /* Directory */
- dir->fd_dir.d_type = DTYPE_DIRECTORY;
- break;
-
- case NFBLK: /* Block special device file */
- dir->fd_dir.d_type = DTYPE_BLK;
- break;
-
- case NFFIFO: /* Named FIFO */
- case NFCHR: /* Character special device file */
- dir->fd_dir.d_type = DTYPE_CHR;
- break;
- }
- fvdbg("type: %d->%d\n", (int)tmp, dir->fd_dir.d_type);
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_rewinddir
- *
- * Description:
- * Reset the directory traveral logic to the first entry in the open
- * directory.
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir)
-{
- fvdbg("Entry\n");
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt != NULL && dir != NULL);
-
- /* Reset the NFS-specific portions of dirent structure, retaining only the
- * file handle.
- */
-
- memset(&dir->u.nfs.nfs_verifier, 0, DIRENT_NFS_VERFLEN);
- dir->u.nfs.nfs_cookie[0] = 0;
- dir->u.nfs.nfs_cookie[1] = 0;
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_decode_args
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-static void nfs_decode_args(FAR struct nfs_mount_parameters *nprmt,
- FAR struct nfs_args *argp)
-{
- int maxio;
-
- /* Get the selected timeout value */
-
- if ((argp->flags & NFSMNT_TIMEO) != 0 && argp->timeo > 0)
- {
- uint32_t tmp = ((uint32_t)argp->timeo * NFS_HZ + 5) / 10;
- if (tmp < NFS_MINTIMEO)
- {
- tmp = NFS_MINTIMEO;
- }
- else if (tmp > NFS_MAXTIMEO)
- {
- tmp = NFS_MAXTIMEO;
- }
- nprmt->timeo = tmp;
- }
-
- /* Get the selected retransmission count */
-
- if ((argp->flags & NFSMNT_RETRANS) != 0 && argp->retrans > 1)
- {
- if (argp->retrans < NFS_MAXREXMIT)
- {
- nprmt->retry = argp->retrans;
- }
- else
- {
- nprmt->retry = NFS_MAXREXMIT;
- }
- }
-
- if ((argp->flags & NFSMNT_SOFT) == 0)
- {
- nprmt->retry = NFS_MAXREXMIT + 1; /* Past clip limit */
- }
-
- /* Get the maximum amount of data that can be transferred in one packet */
-
- if ((argp->sotype == SOCK_DGRAM) != 0)
- {
- maxio = NFS_MAXDGRAMDATA;
- }
- else
- {
- fdbg("ERROR: Only SOCK_DRAM is supported\n");
- maxio = NFS_MAXDATA;
- }
-
- /* Get the maximum amount of data that can be transferred in one write transfer */
-
- if ((argp->flags & NFSMNT_WSIZE) != 0 && argp->wsize > 0)
- {
- nprmt->wsize = argp->wsize;
-
- /* Round down to multiple of blocksize */
-
- nprmt->wsize &= ~(NFS_FABLKSIZE - 1);
- if (nprmt->wsize <= 0)
- {
- nprmt->wsize = NFS_FABLKSIZE;
- }
- }
-
- if (nprmt->wsize > maxio)
- {
- nprmt->wsize = maxio;
- }
-
- if (nprmt->wsize > MAXBSIZE)
- {
- nprmt->wsize = MAXBSIZE;
- }
-
- /* Get the maximum amount of data that can be transferred in one read transfer */
-
- if ((argp->flags & NFSMNT_RSIZE) != 0 && argp->rsize > 0)
- {
- nprmt->rsize = argp->rsize;
-
- /* Round down to multiple of blocksize */
-
- nprmt->rsize &= ~(NFS_FABLKSIZE - 1);
- if (nprmt->rsize <= 0)
- {
- nprmt->rsize = NFS_FABLKSIZE;
- }
- }
-
- if (nprmt->rsize > maxio)
- {
- nprmt->rsize = maxio;
- }
-
- if (nprmt->rsize > MAXBSIZE)
- {
- nprmt->rsize = MAXBSIZE;
- }
-
- /* Get the maximum amount of data that can be transferred in directory transfer */
-
- if ((argp->flags & NFSMNT_READDIRSIZE) != 0 && argp->readdirsize > 0)
- {
- nprmt->readdirsize = argp->readdirsize;
-
- /* Round down to multiple of blocksize */
-
- nprmt->readdirsize &= ~(NFS_DIRBLKSIZ - 1);
- if (nprmt->readdirsize < NFS_DIRBLKSIZ)
- {
- nprmt->readdirsize = NFS_DIRBLKSIZ;
- }
- }
- else if (argp->flags & NFSMNT_RSIZE)
- {
- nprmt->readdirsize = nprmt->rsize;
- }
-
- if (nprmt->readdirsize > maxio)
- {
- nprmt->readdirsize = maxio;
- }
-}
-
-/****************************************************************************
- * Name: nfs_bind
- *
- * Description:
- * This implements a portion of the mount operation. This function allocates
- * and initializes the mountpoint private data and gets mount information
- * from the NFS server. The final binding of the private data (containing
- * NFS server mount information) to the mountpoint is performed by mount().
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_bind(FAR struct inode *blkdriver, FAR const void *data,
- FAR void **handle)
-{
- FAR struct nfs_args *argp = (FAR struct nfs_args *)data;
- FAR struct nfsmount *nmp;
- struct rpcclnt *rpc;
- struct rpc_call_fs getattr;
- struct rpc_reply_getattr resok;
- struct nfs_mount_parameters nprmt;
- uint32_t buflen;
- uint32_t tmp;
- int error = 0;
-
- DEBUGASSERT(data && handle);
-
- /* Set default values of the parameters. These may be overridden by
- * settings in the argp->flags.
- */
-
- nprmt.timeo = NFS_TIMEO;
- nprmt.retry = NFS_RETRANS;
- nprmt.wsize = NFS_WSIZE;
- nprmt.rsize = NFS_RSIZE;
- nprmt.readdirsize = NFS_READDIRSIZE;
-
- nfs_decode_args(&nprmt, argp);
-
- /* Determine the size of a buffer that will hold one RPC data transfer.
- * First, get the maximum size of a read and a write transfer */
-
- buflen = SIZEOF_rpc_call_write(nprmt.wsize);
- tmp = SIZEOF_rpc_reply_read(nprmt.rsize);
-
- /* The buffer size will be the maximum of those two sizes */
-
- if (tmp > buflen)
- {
- buflen = tmp;
- }
-
- /* But don't let the buffer size exceed the MSS of the socket type */
-
- if (buflen > UIP_UDP_MSS)
- {
- buflen = UIP_UDP_MSS;
- }
-
- /* Create an instance of the mountpt state structure */
-
- nmp = (FAR struct nfsmount *)kzalloc(SIZEOF_nfsmount(buflen));
- if (!nmp)
- {
- fdbg("ERROR: Failed to allocate mountpoint structure\n");
- return ENOMEM;
- }
-
- /* Save the allocated I/O buffer size */
-
- nmp->nm_buflen = (uint16_t)buflen;
-
- /* Initialize the allocated mountpt state structure. */
-
- /* Initialize the semaphore that controls access. The initial count
- * is zero, but nfs_semgive() is called at the completion of initialization,
- * incrementing the count to one.
- */
-
- sem_init(&nmp->nm_sem, 0, 0); /* Initialize the semaphore that controls access */
-
- /* Initialize NFS */
-
- nfs_true = txdr_unsigned(TRUE);
- nfs_false = txdr_unsigned(FALSE);
- nfs_xdrneg1 = txdr_unsigned(-1);
-
- rpcclnt_init();
-
- /* Set initial values of other fields */
-
- nmp->nm_timeo = nprmt.timeo;
- nmp->nm_retry = nprmt.retry;
- nmp->nm_wsize = nprmt.wsize;
- nmp->nm_rsize = nprmt.rsize;
- nmp->nm_readdirsize = nprmt.readdirsize;
- nmp->nm_fhsize = NFSX_V3FHMAX;
-
- strncpy(nmp->nm_path, argp->path, 90);
- memcpy(&nmp->nm_nam, &argp->addr, argp->addrlen);
-
- /* Set up the sockets and per-host congestion */
-
- nmp->nm_sotype = argp->sotype;
-
- if (nmp->nm_sotype == SOCK_DGRAM)
- {
- /* Connection-less... connect now */
-
- /* Create an instance of the rpc state structure */
-
- rpc = (struct rpcclnt *)kzalloc(sizeof(struct rpcclnt));
- if (!rpc)
- {
- fdbg("ERROR: Failed to allocate rpc structure\n");
- return ENOMEM;
- }
-
- fvdbg("Connecting\n");
-
- /* Translate nfsmnt flags -> rpcclnt flags */
-
- rpc->rc_path = nmp->nm_path;
- rpc->rc_name = &nmp->nm_nam;
- rpc->rc_sotype = nmp->nm_sotype;
- rpc->rc_retry = nmp->nm_retry;
-
- nmp->nm_rpcclnt = rpc;
-
- error = rpcclnt_connect(nmp->nm_rpcclnt);
- if (error != OK)
- {
- fdbg("ERROR: nfs_connect failed: %d\n", error);
- goto bad;
- }
- }
-
- nmp->nm_mounted = true;
- nmp->nm_so = nmp->nm_rpcclnt->rc_so;
- memcpy(&nmp->nm_fh, &nmp->nm_rpcclnt->rc_fh, sizeof(nfsfh_t));
-
- /* Get the file attributes */
-
- getattr.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
- memcpy(&getattr.fs.fsroot.handle, &nmp->nm_fh, sizeof(nfsfh_t));
-
- error = nfs_request(nmp, NFSPROC_GETATTR,
- (FAR void *)&getattr, sizeof(struct FS3args),
- (FAR void*)&resok, sizeof(struct rpc_reply_getattr));
- if (error)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- goto bad;
- }
-
- /* Save the file attributes */
-
- memcpy(&nmp->nm_fattr, &resok.attr, sizeof(struct nfs_fattr));
-
- /* Mounted! */
-
- *handle = (void*)nmp;
- nfs_semgive(nmp);
-
- fvdbg("Successfully mounted\n");
- return OK;
-
-bad:
- if (nmp)
- {
- /* Disconnect from the server */
-
- rpcclnt_disconnect(nmp->nm_rpcclnt);
-
- /* Free connection-related resources */
-
- sem_destroy(&nmp->nm_sem);
- if (nmp->nm_so)
- {
- kfree(nmp->nm_so);
- }
-
- if (nmp->nm_rpcclnt)
- {
- kfree(nmp->nm_rpcclnt);
- }
-
- kfree(nmp);
- }
-
- return error;
-}
-
-/****************************************************************************
- * Name: nfs_unbind
- *
- * Description: This implements the filesystem portion of the umount
- * operation.
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int nfs_unbind(FAR void *handle, FAR struct inode **blkdriver)
-{
- FAR struct nfsmount *nmp = (FAR struct nfsmount *)handle;
- int error;
-
- fvdbg("Entry\n");
- DEBUGASSERT(nmp);
-
- /* Get exclusive access to the mount structure */
-
- nfs_semtake(nmp);
-
- /* Are there any open files? We can tell if there are open files by looking
- * at the list of file structures in the mount structure. If this list
- * not empty, then there are open files and we cannot unmount now (or a
- * crash is sure to follow).
- */
-
- if (nmp->nm_head != NULL)
- {
- fdbg("ERROR; There are open files: %p\n", nmp->nm_head);
- error = EBUSY;
- goto errout_with_semaphore;
- }
-
- /* No open file... Umount the file system. */
-
- error = rpcclnt_umount(nmp->nm_rpcclnt);
- if (error)
- {
- fdbg("ERROR: rpcclnt_umount failed: %d\n", error);
- }
-
- /* Disconnect from the server */
-
- rpcclnt_disconnect(nmp->nm_rpcclnt);
-
- /* And free any allocated resources */
-
- sem_destroy(&nmp->nm_sem);
- kfree(nmp->nm_so);
- kfree(nmp->nm_rpcclnt);
- kfree(nmp);
-
- return -error;
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_fsinfo
- *
- * Description:
- * Return information about root directory.
- *
- * Returned Value:
- * 0 on success; positive errno value on failure
- *
- * Assumptions:
- * The caller has exclusive access to the NFS mount structure
- *
- ****************************************************************************/
-
-int nfs_fsinfo(FAR struct nfsmount *nmp)
-{
- struct rpc_call_fs fsinfo;
- struct rpc_reply_fsinfo fsp;
- uint32_t pref;
- uint32_t max;
- int error = 0;
-
- fsinfo.fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
- fsinfo.fs.fsroot.handle = nmp->nm_fh;
-
- /* Request FSINFO from the server */
-
- nfs_statistics(NFSPROC_FSINFO);
- error = nfs_request(nmp, NFSPROC_FSINFO,
- (FAR void *)&fsinfo, sizeof(struct FS3args),
- (FAR void *)&fsp, sizeof(struct rpc_reply_fsinfo));
- if (error)
- {
- return error;
- }
-
- /* Save the root file system attributes */
-
-//memcpy(&nmp->nm_fattr. &fsp.obj_attributes, sizeof(struct nfs_fattr));
-
- pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtpref);
- if (pref < nmp->nm_wsize)
- {
- nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
- }
-
- max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_wtmax);
- if (max < nmp->nm_wsize)
- {
- nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_wsize == 0)
- {
- nmp->nm_wsize = max;
- }
- }
-
- pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtpref);
- if (pref < nmp->nm_rsize)
- {
- nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & ~(NFS_FABLKSIZE - 1);
- }
-
- max = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_rtmax);
- if (max < nmp->nm_rsize)
- {
- nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_rsize == 0)
- {
- nmp->nm_rsize = max;
- }
- }
-
- pref = fxdr_unsigned(uint32_t, fsp.fsinfo.fs_dtpref);
- if (pref < nmp->nm_readdirsize)
- {
- nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & ~(NFS_DIRBLKSIZ - 1);
- }
-
- if (max < nmp->nm_readdirsize)
- {
- nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
- if (nmp->nm_readdirsize == 0)
- {
- nmp->nm_readdirsize = max;
- }
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: nfs_statfs
- *
- * Description:
- * Return filesystem statistics
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_statfs(FAR struct inode *mountpt, FAR struct statfs *sbp)
-{
- FAR struct nfsmount *nmp;
- FAR struct rpc_call_fs *fsstat;
- FAR struct rpc_reply_fsstat *sfp;
- int error = 0;
- uint64_t tquad;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- nmp = (struct nfsmount*)mountpt->i_private;
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Fill in the statfs info */
-
- sbp->f_type = NFS_SUPER_MAGIC;
-
- (void)nfs_fsinfo(nmp);
-
- fsstat = &nmp->nm_msgbuffer.fsstat;
- fsstat->fs.fsroot.length = txdr_unsigned(nmp->nm_fhsize);
- memcpy(&fsstat->fs.fsroot.handle, &nmp->nm_fh, sizeof(nfsfh_t));
-
- nfs_statistics(NFSPROC_FSSTAT);
- error = nfs_request(nmp, NFSPROC_FSSTAT,
- (FAR void *)fsstat, sizeof(struct FS3args),
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
- if (error)
- {
- goto errout_with_semaphore;
- }
-
- sfp = (FAR struct rpc_reply_fsstat *)nmp->nm_iobuffer;
- sbp->f_bsize = NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->fsstat.sf_tbytes);
- sbp->f_blocks = tquad / (uint64_t) NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->fsstat.sf_fbytes);
- sbp->f_bfree = tquad / (uint64_t) NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->fsstat.sf_abytes);
- sbp->f_bavail = tquad / (uint64_t) NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->fsstat.sf_tfiles);
- sbp->f_files = tquad;
- tquad = fxdr_hyper(&sfp->fsstat.sf_ffiles);
- sbp->f_ffree = tquad;
- sbp->f_namelen = NAME_MAX;
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_remove
- *
- * Description:
- * Remove a file
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_remove(struct inode *mountpt, const char *relpath)
-{
- FAR struct nfsmount *nmp;
- struct file_handle fhandle;
- struct nfs_fattr fattr;
- char filename[NAME_MAX + 1];
- FAR uint32_t *ptr;
- int namelen;
- int reqlen;
- int error;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- nmp = (struct nfsmount*)mountpt->i_private;
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Find the NFS node of the directory containing the file to be deleted */
-
- error = nfs_finddir(nmp, relpath, &fhandle, &fattr, filename);
- if (error != OK)
- {
- fdbg("ERROR: nfs_finddir returned: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Create the REMOVE RPC call arguments */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.removef.remove;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned(fhandle.length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &fhandle.handle, fhandle.length);
- reqlen += (int)fhandle.length;
- ptr += uint32_increment(fhandle.length);
-
- /* Copy the variable-length file name */
-
- namelen = strlen(filename);
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, filename, namelen);
- reqlen += uint32_alignup(namelen);
-
- /* Perform the REMOVE RPC call */
-
- nfs_statistics(NFSPROC_REMOVE);
- error = nfs_request(nmp, NFSPROC_REMOVE,
- (FAR void *)&nmp->nm_msgbuffer.removef, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_mkdir
- *
- * Description:
- * Create a directory
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_mkdir(struct inode *mountpt, const char *relpath, mode_t mode)
-{
- struct nfsmount *nmp;
- struct file_handle fhandle;
- struct nfs_fattr fattr;
- char dirname[NAME_MAX + 1];
- FAR uint32_t *ptr;
- uint32_t tmp;
- int namelen;
- int reqlen;
- int error;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- nmp = (struct nfsmount*) mountpt->i_private;
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Find the NFS node of the directory containing the directory to be created */
-
- error = nfs_finddir(nmp, relpath, &fhandle, &fattr, dirname);
- if (error != OK)
- {
- fdbg("ERROR: nfs_finddir returned: %d\n", error);
- return error;
- }
-
- /* Format the MKDIR call message arguments */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.mkdir.mkdir;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned(fhandle.length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &fhandle.handle, fhandle.length);
- ptr += uint32_increment(fhandle.length);
- reqlen += (int)fhandle.length;
-
- /* Copy the variable-length directory name */
-
- namelen = strlen(dirname);
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, dirname, namelen);
- ptr += uint32_increment(namelen);
- reqlen += uint32_alignup(namelen);
-
- /* Set the mode. NOTE: Here we depend on the fact that the NuttX and NFS
- * bit settings are the same (at least for the bits of interest).
- */
-
- *ptr++ = nfs_true; /* True: mode value follows */
- reqlen += sizeof(uint32_t);
-
- tmp = mode & (NFSMODE_IXOTH | NFSMODE_IWOTH | NFSMODE_IROTH |
- NFSMODE_IXGRP | NFSMODE_IWGRP | NFSMODE_IRGRP |
- NFSMODE_IXUSR | NFSMODE_IWUSR | NFSMODE_IRUSR);
- *ptr++ = txdr_unsigned(tmp);
- reqlen += sizeof(uint32_t);
-
- /* Set the user ID to zero */
-
- *ptr++ = nfs_true; /* True: Uid value follows */
- *ptr++ = 0; /* UID = 0 (nobody) */
- reqlen += 2*sizeof(uint32_t);
-
- /* Set the group ID to one */
-
- *ptr++ = nfs_true; /* True: Gid value follows */
- *ptr++ = HTONL(1); /* GID = 1 (nogroup) */
- reqlen += 2*sizeof(uint32_t);
-
- /* No size */
-
- *ptr++ = nfs_false; /* False: No size value follows */
- reqlen += sizeof(uint32_t);
-
- /* Don't change times */
-
- *ptr++ = HTONL(NFSV3SATTRTIME_DONTCHANGE); /* Don't change atime */
- *ptr++ = HTONL(NFSV3SATTRTIME_DONTCHANGE); /* Don't change mtime */
- reqlen += 2*sizeof(uint32_t);
-
- /* Perform the MKDIR RPC */
-
- nfs_statistics(NFSPROC_MKDIR);
- error = nfs_request(nmp, NFSPROC_MKDIR,
- (FAR void *)&nmp->nm_msgbuffer.mkdir, reqlen,
- (FAR void *)&nmp->nm_iobuffer, nmp->nm_buflen);
- if (error)
- {
- fdbg("ERROR: nfs_request failed: %d\n", error);
- }
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_rmdir
- *
- * Description:
- * Remove a directory
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_rmdir(struct inode *mountpt, const char *relpath)
-{
- struct nfsmount *nmp;
- struct file_handle fhandle;
- struct nfs_fattr fattr;
- char dirname[NAME_MAX + 1];
- FAR uint32_t *ptr;
- int namelen;
- int reqlen;
- int error;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- nmp = (struct nfsmount *)mountpt->i_private;
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Find the NFS node of the directory containing the directory to be removed */
-
- error = nfs_finddir(nmp, relpath, &fhandle, &fattr, dirname);
- if (error != OK)
- {
- fdbg("ERROR: nfs_finddir returned: %d\n", error);
- return error;
- }
-
- /* Set up the RMDIR call message arguments */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.rmdir.rmdir;
- reqlen = 0;
-
- /* Copy the variable length, directory file handle */
-
- *ptr++ = txdr_unsigned(fhandle.length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &fhandle.handle, fhandle.length);
- reqlen += (int)fhandle.length;
- ptr += uint32_increment(fhandle.length);
-
- /* Copy the variable-length directory name */
-
- namelen = strlen(dirname);
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, dirname, namelen);
- reqlen += uint32_alignup(namelen);
-
- /* Perform the RMDIR RPC */
-
- nfs_statistics(NFSPROC_RMDIR);
- error = nfs_request(nmp, NFSPROC_RMDIR,
- (FAR void *)&nmp->nm_msgbuffer.rmdir, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_rename
- *
- * Description:
- * Rename a file or directory
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_rename(struct inode *mountpt, const char *oldrelpath,
- const char *newrelpath)
-{
- struct nfsmount *nmp;
- struct file_handle from_handle;
- struct file_handle to_handle;
- char from_name[NAME_MAX+1];
- char to_name[NAME_MAX+1];
- struct nfs_fattr fattr;
- FAR uint32_t *ptr;
- int namelen;
- int reqlen;
- int error;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- nmp = (struct nfsmount *)mountpt->i_private;
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount returned: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Find the NFS node of the directory containing the 'from' object */
-
- error = nfs_finddir(nmp, oldrelpath, &from_handle, &fattr, from_name);
- if (error != OK)
- {
- fdbg("ERROR: nfs_finddir returned: %d\n", error);
- return error;
- }
-
- /* Find the NFS node of the directory containing the 'from' object */
-
- error = nfs_finddir(nmp, newrelpath, &to_handle, &fattr, to_name);
- if (error != OK)
- {
- fdbg("ERROR: nfs_finddir returned: %d\n", error);
- return error;
- }
-
- /* Format the RENAME RPC arguments */
-
- ptr = (FAR uint32_t *)&nmp->nm_msgbuffer.renamef.rename;
- reqlen = 0;
-
- /* Copy the variable length, 'from' directory file handle */
-
- *ptr++ = txdr_unsigned(from_handle.length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &from_handle.handle, from_handle.length);
- reqlen += (int)from_handle.length;
- ptr += uint32_increment(from_handle.length);
-
- /* Copy the variable-length 'from' object name */
-
- namelen = strlen(from_name);
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, from_name, namelen);
- reqlen += uint32_alignup(namelen);
- ptr += uint32_increment(namelen);
-
- /* Copy the variable length, 'to' directory file handle */
-
- *ptr++ = txdr_unsigned(to_handle.length);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, &to_handle.handle, to_handle.length);
- ptr += uint32_increment(to_handle.length);
- reqlen += (int)to_handle.length;
-
- /* Copy the variable-length 'to' object name */
-
- namelen = strlen(to_name);
-
- *ptr++ = txdr_unsigned(namelen);
- reqlen += sizeof(uint32_t);
-
- memcpy(ptr, to_name, namelen);
- reqlen += uint32_alignup(namelen);
-
- /* Perform the RENAME RPC */
-
- nfs_statistics(NFSPROC_RENAME);
- error = nfs_request(nmp, NFSPROC_RENAME,
- (FAR void *)&nmp->nm_msgbuffer.renamef, reqlen,
- (FAR void *)nmp->nm_iobuffer, nmp->nm_buflen);
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
-
-/****************************************************************************
- * Name: nfs_stat
- *
- * Description:
- * Return information about the file system object at 'relpath'
- *
- * Returned Value:
- * 0 on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-static int nfs_stat(struct inode *mountpt, const char *relpath,
- struct stat *buf)
-{
- struct nfsmount *nmp;
- struct file_handle fhandle;
- struct nfs_fattr obj_attributes;
- uint32_t tmp;
- uint32_t mode;
- int error;
-
- /* Sanity checks */
-
- DEBUGASSERT(mountpt && mountpt->i_private);
-
- /* Get the mountpoint private data from the inode structure */
-
- nmp = (struct nfsmount*)mountpt->i_private;
- DEBUGASSERT(nmp && buf);
-
- /* Check if the mount is still healthy */
-
- nfs_semtake(nmp);
- error = nfs_checkmount(nmp);
- if (error != OK)
- {
- fdbg("ERROR: nfs_checkmount failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Get the file handle attributes of the requested node */
-
- error = nfs_findnode(nmp, relpath, &fhandle, &obj_attributes, NULL);
- if (error != OK)
- {
- fdbg("ERROR: nfs_findnode failed: %d\n", error);
- goto errout_with_semaphore;
- }
-
- /* Construct the file mode. This is a 32-bit, encoded value containing
- * both the access mode and the file type.
- */
-
- tmp = fxdr_unsigned(uint32_t, obj_attributes.fa_mode);
-
- /* Here we exploit the fact that most mode bits are the same in NuttX
- * as in the NFSv3 spec.
- */
-
- mode = tmp & (NFSMODE_IXOTH|NFSMODE_IWOTH|NFSMODE_IROTH|
- NFSMODE_IXGRP|NFSMODE_IWGRP|NFSMODE_IRGRP|
- NFSMODE_IXUSR|NFSMODE_IWUSR|NFSMODE_IRUSR);
-
- /* Handle the cases that are not the same */
-
- if ((mode & NFSMODE_ISGID) != 0)
- {
- mode |= S_ISGID;
- }
-
- if ((mode & NFSMODE_ISUID) != 0)
- {
- mode |= S_ISUID;
- }
-
- /* Now OR in the file type */
-
- tmp = fxdr_unsigned(uint32_t, obj_attributes.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(&obj_attributes.fa_size);
- buf->st_blksize = 0;
- buf->st_blocks = 0;
- buf->st_mtime = fxdr_hyper(&obj_attributes.fa_mtime);
- buf->st_atime = fxdr_hyper(&obj_attributes.fa_atime);
- buf->st_ctime = fxdr_hyper(&obj_attributes.fa_ctime);
-
-errout_with_semaphore:
- nfs_semgive(nmp);
- return -error;
-}
diff --git a/nuttx/fs/nfs/rpc.h b/nuttx/fs/nfs/rpc.h
deleted file mode 100644
index 27366557d..000000000
--- a/nuttx/fs/nfs/rpc.h
+++ /dev/null
@@ -1,491 +0,0 @@
-/****************************************************************************
- * fs/nfs/rpc.h
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * copyright (c) 2003
- * the regents of the university of michigan
- * all rights reserved
- *
- * permission is granted to use, copy, create derivative works and redistribute
- * this software and such derivative works for any purpose, so long as the name
- * of the university of michigan is not used in any advertising or publicity
- * pertaining to the use or distribution of this software without specific,
- * written prior authorization. if the above copyright notice or any other
- * identification of the university of michigan is included in any copy of any
- * portion of this software, then the disclaimer below must also be included.
- *
- * this software is provided as is, without representation from the university
- * of michigan as to its fitness for any purpose, and without warranty by the
- * university of michigan of any kind, either express or implied, including
- * without limitation the implied warranties of merchantability and fitness for
- * a particular purpose. the regents of the university of michigan shall not be
- * liable for any damages, including special, indirect, incidental, or
- * consequential damages, with respect to any claim arising out of or in
- * connection with the use of the software, even if it has been or is hereafter
- * advised of the possibility of such damages.
- *
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __FS_NFS_RPC_H
-#define __FS_NFS_RPC_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <sys/types.h>
-#include "nfs_proto.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Version # */
-
-#define RPC_VER2 2
-
-/* Authentication */
-
-#define RPCAUTH_NULL 0
-#define RPCAUTH_UNIX 1
-#define RPCAUTH_SHORT 2
-#define RPCAUTH_KERB4 4
-#define RPCAUTH_MAXSIZ 400
-#define RPCVERF_MAXSIZ 12
- /* For Kerb, can actually be 400 */
-#define RPCAUTH_UNIXGIDS 16
-
-/* Constants associated with authentication flavours. */
-
-#define RPCAKN_FULLNAME 0
-#define RPCAKN_NICKNAME 1
-
-/* RPC Constants */
-
-#define RPC_CALL 0
-#define RPC_REPLY 1
-#define RPC_MSGACCEPTED 0
-#define RPC_MSGDENIED 1
-#define RPC_PROGUNAVAIL 1
-#define RPC_PROGMISMATCH 2
-#define RPC_PROCUNAVAIL 3
-#define RPC_GARBAGE 4
-
-#define RPC_MISMATCH 0
-#define RPC_AUTHERR 1
-
-/* Authentication failures */
-
-#define AUTH_BADCRED 1
-#define AUTH_REJECTCRED 2
-#define AUTH_BADVERF 3
-#define AUTH_REJECTVERF 4
-#define AUTH_TOOWEAK 5
-
-/* Sizes of RPC header parts */
-
-#define RPC_SIZ 24
-#define RPC_REPLYSIZ 28
-
-/* RPC Prog definitions */
-
-#define RPCPROG_MNT 100005
-#define RPCMNT_VER1 1
-#define RPCMNT_VER3 3
-#define RPCMNT_MOUNT 1
-#define RPCMNT_DUMP 2
-#define RPCMNT_UMOUNT 3
-#define RPCMNT_UMNTALL 4
-#define RPCMNT_EXPORT 5
-#define RPCMNT_NAMELEN 255
-#define RPCMNT_PATHLEN 1024
-#define RPCPROG_NFS 100003
-
-/* RPC definitions for the portmapper. */
-
-#define PMAPPORT 111
-#define PMAPPROG 100000
-#define PMAPVERS 2
-
-#define PMAPPROC_NULL 0
-#define PMAPPROC_SET 1
-#define PMAPPROC_UNSET 2
-#define PMAPPROC_GETPORT 3
-#define PMAPPROC_DUMP 4
-#define PMAPPROC_CALLIT 5
-
-#define RPC_SUCCESS 0
-
-/****************************************************************************
- * 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 port;
-};
-
-struct call_result_pmap
-{
- uint32_t port;
-};
-
-/* MOUNTD headers */
-
-struct call_args_mount
-{
- uint32_t len;
- char rpath[90];
-};
-
-struct call_args_umount
-{
- uint32_t len;
- char rpath[90];
-};
-
-struct call_result_mount
-{
- uint32_t status;
- nfsfh_t fhandle;
-};
-
-/* Generic RPC call headers */
-
-enum auth_flavor
-{
- AUTH_NONE = 0,
- AUTH_SYS = 1,
- AUTH_SHORT = 2
- /* and more to be defined */
-};
-
-struct rpc_auth_info
-{
- uint32_t authtype; /* auth type */
- uint32_t authlen; /* auth length */
-};
-
-struct auth_unix
-{
- int32_t stamp;
- uint8_t hostname; /* null */
- int32_t uid;
- int32_t gid;
- int32_t gidlist; /* null */
-};
-
-struct rpc_call_header
-{
- uint32_t rp_xid; /* request transaction id */
- int32_t rp_direction; /* call direction (0) */
- uint32_t rp_rpcvers; /* RPC version (2) */
- uint32_t rp_prog; /* program */
- uint32_t rp_vers; /* version */
- uint32_t rp_proc; /* procedure */
- struct rpc_auth_info rpc_auth;
- struct rpc_auth_info rpc_verf;
-};
-
-struct rpc_call_pmap
-{
- struct rpc_call_header ch;
- struct call_args_pmap pmap;
-};
-
-struct rpc_call_mount
-{
- struct rpc_call_header ch;
- struct call_args_mount mount;
-};
-
-struct rpc_call_umount
-{
- struct rpc_call_header ch;
- struct call_args_umount umount;
-};
-
-struct rpc_call_create
-{
- struct rpc_call_header ch;
- struct CREATE3args create;
-};
-
-struct rpc_call_lookup
-{
- struct rpc_call_header ch;
- struct LOOKUP3args lookup;
-};
-#define SIZEOF_rpc_call_lookup(n) (sizeof(struct rpc_call_header) + SIZEOF_LOOKUP3args(n))
-
-struct rpc_call_read
-{
- struct rpc_call_header ch;
- struct READ3args read;
-};
-
-struct rpc_call_write
-{
- struct rpc_call_header ch;
- struct WRITE3args write; /* Variable length */
-};
-#define SIZEOF_rpc_call_write(n) (sizeof(struct rpc_call_header) + SIZEOF_WRITE3args(n))
-
-struct rpc_call_remove
-{
- struct rpc_call_header ch;
- struct REMOVE3args remove;
-};
-
-struct rpc_call_rename
-{
- struct rpc_call_header ch;
- struct RENAME3args rename;
-};
-
-struct rpc_call_mkdir
-{
- struct rpc_call_header ch;
- struct MKDIR3args mkdir;
-};
-
-struct rpc_call_rmdir
-{
- struct rpc_call_header ch;
- struct RMDIR3args rmdir;
-};
-
-struct rpc_call_readdir
-{
- struct rpc_call_header ch;
- struct READDIR3args readdir;
-};
-
-struct rpc_call_setattr
-{
- struct rpc_call_header ch;
- struct SETATTR3args setattr;
-};
-
-struct rpc_call_fs
-{
- struct rpc_call_header ch;
- struct FS3args fs;
-};
-
-/* Generic RPC reply headers */
-
-struct rpc_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 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;
- uint32_t nfs_status;
-};
-
-struct rpc_reply_pmap
-{
- struct rpc_reply_header rh;
- struct call_result_pmap pmap;
-};
-
-struct rpc_reply_mount
-{
- struct rpc_reply_header rh;
- struct call_result_mount mount;
-};
-
-struct rpc_reply_umount
-{
- struct rpc_reply_header rh;
-};
-
-struct rpc_reply_create
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct CREATE3resok create;
-};
-
-struct rpc_reply_lookup
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct LOOKUP3resok lookup;
-};
-
-struct rpc_reply_write
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct WRITE3resok write; /* Variable length */
-};
-
-struct rpc_reply_read
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct READ3resok read; /* Variable length */
-};
-#define SIZEOF_rpc_reply_read(n) (sizeof(struct rpc_reply_header) + sizeof(uint32_t) + SIZEOF_READ3resok(n))
-
-struct rpc_reply_remove
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct REMOVE3resok remove;
-};
-
-struct rpc_reply_rename
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct RENAME3resok rename;
-};
-
-struct rpc_reply_mkdir
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct MKDIR3resok mkdir;
-};
-
-struct rpc_reply_rmdir
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct RMDIR3resok rmdir;
-};
-
-struct rpc_reply_readdir
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct READDIR3resok readdir;
-};
-
-struct rpc_reply_fsinfo
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct nfsv3_fsinfo fsinfo;
-};
-
-struct rpc_reply_fsstat
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct nfs_statfs fsstat;
-};
-
-struct rpc_reply_getattr
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct nfs_fattr attr;
-};
-
-struct rpc_reply_setattr
-{
- struct rpc_reply_header rh;
- uint32_t status;
- struct SETATTR3resok setattr;
-};
-
-struct rpcclnt
-{
- nfsfh_t rc_fh; /* File handle of the root directory */
- char *rc_path; /* Server's path of the mounted directory */
-
- 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 */
-};
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-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,
- FAR void *response, size_t resplen);
-
-#endif /* __FS_NFS_RPC_H */
diff --git a/nuttx/fs/nfs/rpc_clnt.c b/nuttx/fs/nfs/rpc_clnt.c
deleted file mode 100644
index 9c2ada4f2..000000000
--- a/nuttx/fs/nfs/rpc_clnt.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/****************************************************************************
- * fs/nfs/rpc_clnt.c
- *
- * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 2004 The Regents of the University of Michigan.
- * All rights reserved.
- *
- * Copyright (c) 2004 Weston Andros Adamson <muzzle@umich.edu>.
- * Copyright (c) 2004 Marius Aamodt Eriksen <marius@umich.edu>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Copyright (c) 1989, 1991, 1993, 1995 The Regents of the University of
- * California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by Rick Macklem at
- * The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer. 2.
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution. 3. All advertising
- * materials mentioning features or use of this software must display the
- * following acknowledgement: This product includes software developed by the
- * University of California, Berkeley and its contributors. 4. Neither the
- * name of the University nor the names of its contributors may be used to
- * endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <sys/socket.h>
-#include <queue.h>
-#include <time.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <debug.h>
-#include <nuttx/kmalloc.h>
-
-#include "xdr_subs.h"
-#include "nfs_proto.h"
-#include "rpc.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Increment RPC statistics */
-
-#ifdef CONFIG_NFS_STATISTICS
-# define rpc_statistics(n) do { rpcstats.(n)++; } while (0)
-#else
-# define rpc_statistics(n)
-#endif
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* Static data, mostly RPC constants in XDR form */
-
-static uint32_t rpc_reply;
-static uint32_t rpc_call;
-static uint32_t rpc_vers;
-static uint32_t rpc_msgdenied;
-static uint32_t rpc_mismatch;
-static uint32_t rpc_auth_unix;
-static uint32_t rpc_msgaccepted;
-static uint32_t rpc_autherr;
-static uint32_t rpc_auth_null;
-
-/* Global statics for all client instances. Cleared by NuttX on boot-up. */
-
-#ifdef CONFIG_NFS_STATISTICS
-static struct rpcstats rpcstats;
-#endif
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int rpcclnt_send(FAR struct rpcclnt *rpc, int procid, int prog,
- FAR void *call, int reqlen);
-static int rpcclnt_receive(FAR struct rpcclnt *rpc, struct sockaddr *aname,
- int proc, int program, void *reply, size_t resplen);
-static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
- void *reply, size_t resplen);
-static uint32_t rpcclnt_newxid(void);
-static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
- uint32_t xid, int procid, int prog, int vers);
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rpcclnt_send
- *
- * Description:
- * This is the nfs send routine.
- *
- * Returned Value:
- * Returns zero on success or a (positive) errno value on failure.
- *
- ****************************************************************************/
-
-static int rpcclnt_send(FAR struct rpcclnt *rpc, int procid, int prog,
- FAR void *call, int reqlen)
-{
- ssize_t nbytes;
- int error = OK;
-
- /* Send the call message
- *
- * On success, psock_sendto returns the number of bytes sent;
- * On failure, it returns -1 with the specific error in errno.
- */
-
- nbytes = psock_sendto(rpc->rc_so, call, reqlen, 0,
- rpc->rc_name, sizeof(struct sockaddr));
- if (nbytes < 0)
- {
- /* psock_sendto failed */
-
- error = errno;
- fdbg("ERROR: psock_sendto failed: %d\n", error);
- }
-
- return error;
-}
-
-/****************************************************************************
- * Name: rpcclnt_receive
- *
- * Description:
- * Receive a Sun RPC Request/Reply. For SOCK_DGRAM, the work is all done
- * by psock_recvfrom().
- *
- ****************************************************************************/
-
-static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
- int proc, int program, FAR void *reply,
- size_t resplen)
-{
- ssize_t nbytes;
- int error = 0;
-
- socklen_t fromlen = sizeof(struct sockaddr);
- nbytes = psock_recvfrom(rpc->rc_so, reply, resplen, 0, aname, &fromlen);
- if (nbytes < 0)
- {
- error = errno;
- fdbg("ERROR: psock_recvfrom failed: %d\n", error);
- }
-
- return error;
-}
-
-/****************************************************************************
- * Name: rpcclnt_reply
- *
- * Description:
- * Received the RPC reply on the socket.
- *
- ****************************************************************************/
-
-static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
- FAR void *reply, size_t resplen)
-{
- int error;
-
- /* Get the next RPC reply from the socket */
-
- error = rpcclnt_receive(rpc, rpc->rc_name, procid, prog, reply, resplen);
- if (error != 0)
- {
- fdbg("ERROR: rpcclnt_receive returned: %d\n", error);
-
- /* If we failed because of a timeout, then try sending the CALL
- * message again.
- */
-
- if (error == EAGAIN || error == ETIMEDOUT)
- {
- rpc->rc_timeout = true;
- }
- }
-
- /* Get the xid and check that it is an RPC replysvr */
-
- else
- {
- FAR struct rpc_reply_header *replyheader =
- (FAR struct rpc_reply_header *)reply;
-
- if (replyheader->rp_direction != rpc_reply)
- {
- fdbg("ERROR: Different RPC REPLY returned\n");
- rpc_statistics(rpcinvalid);
- error = EPROTO;
- }
- }
-
- return error;
-}
-
-/****************************************************************************
- * Name: rpcclnt_newxid
- *
- * Description:
- * Get a new (non-zero) xid
- *
- ****************************************************************************/
-
-static uint32_t rpcclnt_newxid(void)
-{
- static uint32_t rpcclnt_xid = 0;
- static uint32_t rpcclnt_xid_touched = 0;
-
- srand(time(NULL));
- if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0))
- {
- rpcclnt_xid = rand();
- rpcclnt_xid_touched = 1;
- }
- else
- {
- int xidp = 0;
- do
- {
- xidp = rand();
- }
- while ((xidp % 256) == 0);
-
- rpcclnt_xid += xidp;
- }
-
- return rpcclnt_xid;
-}
-
-/****************************************************************************
- * Name: rpcclnt_fmtheader
- *
- * Description:
- * Format the common part of the call header
- *
- ****************************************************************************/
-
-static void rpcclnt_fmtheader(FAR struct rpc_call_header *ch,
- uint32_t xid, int prog, int vers, int procid)
-{
- /* Format the call header */
-
- ch->rp_xid = txdr_unsigned(xid);
- ch->rp_direction = rpc_call;
- ch->rp_rpcvers = rpc_vers;
- ch->rp_prog = txdr_unsigned(prog);
- ch->rp_vers = txdr_unsigned(vers);
- ch->rp_proc = txdr_unsigned(procid);
-
- /* rpc_auth part (auth_null) */
-
- ch->rpc_auth.authtype = rpc_auth_null;
- ch->rpc_auth.authlen = 0;
-
- /* rpc_verf part (auth_null) */
-
- ch->rpc_verf.authtype = rpc_auth_null;
- ch->rpc_verf.authlen = 0;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rpcclnt_init
- *
- * Description:
- * Initialize the RPC client
- *
- ****************************************************************************/
-
-void rpcclnt_init(void)
-{
- /* RPC constants how about actually using more than one of these! */
-
- rpc_reply = txdr_unsigned(RPC_REPLY);
- rpc_vers = txdr_unsigned(RPC_VER2);
- rpc_call = txdr_unsigned(RPC_CALL);
- rpc_msgdenied = txdr_unsigned(RPC_MSGDENIED);
- rpc_msgaccepted = txdr_unsigned(RPC_MSGACCEPTED);
- rpc_mismatch = txdr_unsigned(RPC_MISMATCH);
- rpc_autherr = txdr_unsigned(RPC_AUTHERR);
- rpc_auth_unix = txdr_unsigned(RPCAUTH_UNIX);
- rpc_auth_null = txdr_unsigned(RPCAUTH_NULL);
-
- fvdbg("RPC initialized\n");
-}
-
-/****************************************************************************
- * Name: rpcclnt_connect
- *
- * Description:
- * Initialize sockets for a new RPC connection. We do not free the
- * sockaddr if an error occurs.
- *
- ****************************************************************************/
-
-int rpcclnt_connect(struct rpcclnt *rpc)
-{
- struct socket *so;
- int error;
- struct sockaddr *saddr;
- struct sockaddr_in sin;
- struct sockaddr_in *sa;
-
- union
- {
- struct rpc_call_pmap sdata;
- struct rpc_call_mount mountd;
- } request;
-
- union
- {
- struct rpc_reply_pmap rdata;
- struct rpc_reply_mount mdata;
- } response;
-
- struct timeval tv;
- uint16_t tport;
- int errval;
-
- fvdbg("Connecting\n");
-
- /* Create the socket */
-
- saddr = rpc->rc_name;
-
- /* Create an instance of the socket state structure */
-
- so = (struct socket *)kzalloc(sizeof(struct socket));
- if (!so)
- {
- fdbg("ERROR: Failed to allocate socket structure\n");
- return ENOMEM;
- }
-
- error = psock_socket(saddr->sa_family, rpc->rc_sotype, IPPROTO_UDP, so);
- if (error < 0)
- {
- errval = errno;
- fdbg("ERROR: psock_socket failed: %d", errval);
- return error;
- }
-
- so->s_crefs = 1;
- rpc->rc_so = so;
-
- /* Always set receive timeout to detect server crash and reconnect.
- * Otherwise, we can get stuck in psock_receive forever.
- */
-
- tv.tv_sec = 1;
- tv.tv_usec = 0;
-
- error = psock_setsockopt(rpc->rc_so, SOL_SOCKET, SO_RCVTIMEO,
- (const void *)&tv, sizeof(tv));
- if (error < 0)
- {
- errval = errno;
- fdbg("ERROR: psock_setsockopt failed: %d\n", errval);
- goto bad;
- }
-
- /* Some servers require that the client port be a reserved port
- * number. We always allocate a reserved port, as this prevents
- * filehandle disclosure through UDP port capture.
- */
-
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- tport = 1024;
-
- errval = 0;
- do
- {
- tport--;
- sin.sin_port = htons(tport);
- error = psock_bind(rpc->rc_so, (struct sockaddr *)&sin, sizeof(sin));
- if (error < 0)
- {
- errval = errno;
- fdbg("ERROR: psock_bind failed: %d\n", errval);
- }
- }
- while (errval == EADDRINUSE && tport > 1024 / 2);
-
- if (error)
- {
- fdbg("ERROR: psock_bind failed: %d\n", errval);
- goto bad;
- }
-
- /* Protocols that do not require connections may be optionally left
- * unconnected for servers that reply from a port other than
- * NFS_PORT.
- */
-
- error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
- if (error < 0)
- {
- errval = errno;
- fdbg("ERROR: psock_connect to PMAP port failed: %d", errval);
- goto bad;
- }
-
- /* Do the RPC to get a dynamic bounding with the server using ppmap.
- * Get port number for MOUNTD.
- */
-
- request.sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT);
- request.sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1);
- request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
- request.sdata.pmap.port = 0;
-
- error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
- (FAR void *)&request.sdata, sizeof(struct call_args_pmap),
- (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
- if (error != 0)
- {
- fdbg("ERROR: rpcclnt_request failed: %d\n", error);
- goto bad;
- }
-
- sa = (FAR struct sockaddr_in *)saddr;
- sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
-
- error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
- if (error < 0)
- {
- errval = errno;
- fdbg("ERROR: psock_connect MOUNTD port failed: %d\n", errval);
- goto bad;
- }
-
- /* Do RPC to mountd. */
-
- strncpy(request.mountd.mount.rpath, rpc->rc_path, 90);
- request.mountd.mount.len = txdr_unsigned(sizeof(request.mountd.mount.rpath));
-
- error = rpcclnt_request(rpc, RPCMNT_MOUNT, RPCPROG_MNT, RPCMNT_VER1,
- (FAR void *)&request.mountd, sizeof(struct call_args_mount),
- (FAR void *)&response.mdata, sizeof(struct rpc_reply_mount));
- if (error != 0)
- {
- fdbg("ERROR: rpcclnt_request failed: %d\n", error);
- goto bad;
- }
-
- error = fxdr_unsigned(uint32_t, response.mdata.mount.status);
- if (error != 0)
- {
- fdbg("ERROR: Bad mount status: %d\n", error);
- goto bad;
- }
-
- memcpy(&rpc->rc_fh, &response.mdata.mount.fhandle, sizeof(nfsfh_t));
-
- /* Do the RPC to get a dynamic bounding with the server using PMAP.
- * NFS port in the socket.
- */
-
- sa->sin_port = htons(PMAPPORT);
-
- error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
- if (error < 0)
- {
- errval = errno;
- fdbg("ERROR: psock_connect PMAP port failed: %d\n", errval);
- goto bad;
- }
-
- request.sdata.pmap.prog = txdr_unsigned(NFS_PROG);
- request.sdata.pmap.vers = txdr_unsigned(NFS_VER3);
- request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
- request.sdata.pmap.port = 0;
-
- error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
- (FAR void *)&request.sdata, sizeof(struct call_args_pmap),
- (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
- if (error != 0)
- {
- fdbg("ERROR: rpcclnt_request failed: %d\n", error);
- goto bad;
- }
-
- sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
-
- error = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
- if (error)
- {
- fdbg("psock_connect NFS port returns %d\n", error);
- goto bad;
- }
-
- return OK;
-
-bad:
- rpcclnt_disconnect(rpc);
- return error;
-}
-
-/****************************************************************************
- * Name: rpcclnt_disconnect
- *
- * Description:
- * Disconnect from the NFS server.
- *
- ****************************************************************************/
-
-void rpcclnt_disconnect(struct rpcclnt *rpc)
-{
- if (rpc->rc_so != NULL)
- {
- (void)psock_close(rpc->rc_so);
- }
-}
-
-/****************************************************************************
- * Name: rpcclnt_umount
- *
- * Description:
- * Un-mount the NFS file system.
- *
- ****************************************************************************/
-
-int rpcclnt_umount(struct rpcclnt *rpc)
-{
- struct sockaddr *saddr;
- struct sockaddr_in *sa;
-
- union
- {
- struct rpc_call_pmap sdata;
- struct rpc_call_umount mountd;
- } request;
-
- union
- {
- struct rpc_reply_pmap rdata;
- struct rpc_reply_umount mdata;
- } response;
-
- int error;
- int ret;
-
- saddr = rpc->rc_name;
- sa = (FAR struct sockaddr_in *)saddr;
-
- /* Do the RPC to get a dynamic bounding with the server using ppmap.
- * Get port number for MOUNTD.
- */
-
- sa->sin_port = htons(PMAPPORT);
-
- ret = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
- if (ret < 0)
- {
- error = errno;
- fdbg("ERROR: psock_connect failed [port=%d]: %d\n",
- ntohs(sa->sin_port), error);
- goto bad;
- }
-
- request.sdata.pmap.prog = txdr_unsigned(RPCPROG_MNT);
- request.sdata.pmap.vers = txdr_unsigned(RPCMNT_VER1);
- request.sdata.pmap.proc = txdr_unsigned(IPPROTO_UDP);
- request.sdata.pmap.port = 0;
-
- error = rpcclnt_request(rpc, PMAPPROC_GETPORT, PMAPPROG, PMAPVERS,
- (FAR void *)&request.sdata, sizeof(struct call_args_pmap),
- (FAR void *)&response.rdata, sizeof(struct rpc_reply_pmap));
- if (error != 0)
- {
- fdbg("ERROR: rpcclnt_request failed: %d\n", error);
- goto bad;
- }
-
- sa->sin_port = htons(fxdr_unsigned(uint32_t, response.rdata.pmap.port));
-
- ret = psock_connect(rpc->rc_so, saddr, sizeof(*saddr));
- if (ret < 0)
- {
- error = errno;
- fdbg("ERROR: psock_connect failed [port=%d]: %d\n",
- ntohs(sa->sin_port), error);
- goto bad;
- }
-
- /* Do RPC to umountd. */
-
- strncpy(request.mountd.umount.rpath, rpc->rc_path, 92);
- request.mountd.umount.len = txdr_unsigned(sizeof(request.mountd.umount.rpath));
-
- error = rpcclnt_request(rpc, RPCMNT_UMOUNT, RPCPROG_MNT, RPCMNT_VER1,
- (FAR void *)&request.mountd, sizeof(struct call_args_umount),
- (FAR void *)&response.mdata, sizeof(struct rpc_reply_umount));
- if (error != 0)
- {
- fdbg("ERROR: rpcclnt_request failed: %d\n", error);
- goto bad;
- }
-
- return OK;
-
-bad:
- rpcclnt_disconnect(rpc);
- return error;
-}
-
-/****************************************************************************
- * Name: rpcclnt_request
- *
- * Description:
- * Perform the RPC request. Logic formats the RPC CALL message and calls
- * rpcclnt_send to send the RPC CALL message. It then calls rpcclnt_reply()
- * to get the response. It may attempt to re-send the CALL message on
- * certain errors.
- *
- * On successful receipt, it verifies the RPC level of the returned values.
- * (There may still be be NFS layer errors that will be deted by calling
- * logic).
- *
- ****************************************************************************/
-
-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)
-{
- struct rpc_reply_header *replymsg;
- uint32_t tmp;
- uint32_t xid;
- int retries;
- int error = 0;
-
- /* Get a new (non-zero) xid */
-
- xid = rpcclnt_newxid();
-
- /* Initialize the RPC header fields */
-
- rpcclnt_fmtheader((FAR struct rpc_call_header *)request,
- xid, prog, version, procnum);
-
- /* Get the full size of the message (the size of variable data plus the size of
- * the messages header).
- */
-
- reqlen += sizeof(struct rpc_call_header);
-
- /* Send the RPC call messsages and receive the RPC response. A limited
- * number of re-tries will be attempted, but only for the case of response
- * timeouts.
- */
-
- retries = 0;
- do
- {
- /* Do the client side RPC. */
-
- rpc_statistics(rpcrequests);
- rpc->rc_timeout = false;
-
- /* Send the RPC CALL message */
-
- error = rpcclnt_send(rpc, procnum, prog, request, reqlen);
- if (error != OK)
- {
- fvdbg("ERROR rpcclnt_send failed: %d\n", error);
- }
-
- /* Wait for the reply from our send */
-
- else
- {
- error = rpcclnt_reply(rpc, procnum, prog, response, resplen);
- if (error != OK)
- {
- fvdbg("ERROR rpcclnt_reply failed: %d\n", error);
- }
- }
-
- retries++;
- }
- while (rpc->rc_timeout && retries <= rpc->rc_retry);
-
- if (error != OK)
- {
- fdbg("ERROR: RPC failed: %d\n", error);
- return error;
- }
-
- /* Break down the RPC header and check if it is OK */
-
- replymsg = (FAR struct rpc_reply_header *)response;
-
- tmp = fxdr_unsigned(uint32_t, replymsg->type);
- if (tmp == RPC_MSGDENIED)
- {
- tmp = fxdr_unsigned(uint32_t, replymsg->status);
- switch (tmp)
- {
- case RPC_MISMATCH:
- fdbg("RPC_MSGDENIED: RPC_MISMATCH error\n");
- return EOPNOTSUPP;
-
- case RPC_AUTHERR:
- fdbg("RPC_MSGDENIED: RPC_AUTHERR error\n");
- return EACCES;
-
- default:
- return EOPNOTSUPP;
- }
- }
- else if (tmp != RPC_MSGACCEPTED)
- {
- return EOPNOTSUPP;
- }
-
- tmp = fxdr_unsigned(uint32_t, replymsg->status);
- if (tmp == RPC_SUCCESS)
- {
- fvdbg("RPC_SUCCESS\n");
- }
- else if (tmp == RPC_PROGMISMATCH)
- {
- fdbg("RPC_MSGACCEPTED: RPC_PROGMISMATCH error\n");
- return EOPNOTSUPP;
- }
- else if (tmp > 5)
- {
- fdbg("ERROR: Other RPC type: %d\n", tmp);
- return EOPNOTSUPP;
- }
-
- return OK;
-}
diff --git a/nuttx/fs/nfs/xdr_subs.h b/nuttx/fs/nfs/xdr_subs.h
deleted file mode 100644
index 891af004c..000000000
--- a/nuttx/fs/nfs/xdr_subs.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/****************************************************************************
- * fs/nfs/xdr_subs.h
- * Definitions for Sun RPC Version 2, from
- * "RPC: Remote Procedure Call Protocol Specification" RFC1057
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
- * Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * Leveraged from OpenBSD:
- *
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __FS_NFS_XDR_SUBS_H
-#define __FS_NFS_XDR_SUBS_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <arpa/inet.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Macros used for conversion to/from xdr representation by nfs...
- * These use the MACHINE DEPENDENT routines ntohl, htonl
- * As defined by "XDR: External Data Representation Standard" RFC1014
- *
- * To simplify the implementation, we use ntohl/htonl even on big-endian
- * machines, and count on them being `#define'd away. Some of these
- * might be slightly more efficient as int64_t copies on a big-endian,
- * but we cannot count on their alignment anyway.
- */
-
-#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])))
-
-#define txdr_hyper(f, t) \
-{ \
- ((uint32_t *)(t))[0] = htonl((uint32_t)((f) >> 32)); \
- ((uint32_t *)(t))[1] = htonl((uint32_t)((f) & 0xffffffff)); \
-}
-
-/* Macros for dealing with byte data saved in uint32_t aligned memory */
-
-#define uint32_aligndown(b) ((b) & ~3)
-#define uint32_alignup(b) (((b) + 3) & ~3)
-#define uint32_increment(b) (((b) + 3) >> 2)
-
-#endif /* __FS_NFS_XDR_SUBS_H */