summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/nfsclient/src/nfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs/src/nfsclient/src/nfs.c')
-rw-r--r--cpukit/libfs/src/nfsclient/src/nfs.c150
1 files changed, 93 insertions, 57 deletions
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index 2627726dc0..99e34d5ac7 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -1,15 +1,20 @@
-/* NFS client implementation for RTEMS; hooks into the RTEMS filesystem */
-
-/* Author: Till Straumann <strauman@slac.stanford.edu> 2002 */
+/**
+ * @file
+ *
+ * @brief NFS Client Implementation for RTEMS
+ * @ingroup libfs
+ *
+ * Hooks Into the RTEMS NFS Filesystem
+ */
/*
+ * Author: Till Straumann <strauman@slac.stanford.edu>, 2002
+ *
* Hacked on by others.
*
* Modifications to support reference counting in the file system are
* Copyright (c) 2012 embedded brains GmbH.
- */
-
-/*
+ *
* Authorship
* ----------
* This software (NFS-2 client implementation for RTEMS) was created by
@@ -674,7 +679,19 @@ static struct nfsstats {
* during the system lifetime
*/
u_short fs_ids;
-} nfsGlob = {0, 0, 0, 0, 0, 0};
+
+ /* Two pools of RPC transactions;
+ * One with small send buffers
+ * the other with a big one.
+ * The actual size of the small
+ * buffer is configurable (see top).
+ *
+ * Note: The RX buffers are always
+ * big
+ */
+ RpcUdpXactPool smallPool;
+ RpcUdpXactPool bigPool;
+} nfsGlob = {0, 0, 0xffffffff, 0, 0, 0, NULL, NULL};
/*
* Global variable to tune the 'st_blksize' (stat(2)) value this nfs
@@ -686,18 +703,6 @@ static struct nfsstats {
#endif
int nfsStBlksize = DEFAULT_NFS_ST_BLKSIZE;
-/* Two pools of RPC transactions;
- * One with small send buffers
- * the other with a big one.
- * The actual size of the small
- * buffer is configurable (see top).
- *
- * Note: The RX buffers are always
- * big
- */
-static RpcUdpXactPool smallPool = 0;
-static RpcUdpXactPool bigPool = 0;
-
/*****************************************
Implementation
@@ -992,7 +997,7 @@ NfsNode rval = nfsNodeCreate(node->nfs, 0);
* they are created and destroyed
* on the fly).
*/
-void
+int
nfsInit(int smallPoolDepth, int bigPoolDepth)
{
static int initialised = 0;
@@ -1000,7 +1005,7 @@ entry dummy;
rtems_status_code status;
if (initialised)
- return;
+ return 0;
initialised = 1;
@@ -1013,7 +1018,8 @@ rtems_status_code status;
if (RTEMS_SUCCESSFUL != rtems_io_register_driver(0, &drvNfs, &nfsGlob.nfs_major)) {
fprintf(stderr,"Registering NFS driver failed - %s\n", strerror(errno));
- return;
+ errno = ENOMEM;
+ return -1;
}
if (0==smallPoolDepth)
@@ -1034,19 +1040,23 @@ rtems_status_code status;
dummy.name = "somename"; /* guess average length of a filename */
dirres_entry_size = xdr_sizeof((xdrproc_t)xdr_entry, &dummy);
- smallPool = rpcUdpXactPoolCreate(
+ nfsGlob.smallPool = rpcUdpXactPoolCreate(
NFS_PROGRAM,
NFS_VERSION_2,
CONFIG_NFS_SMALL_XACT_SIZE,
smallPoolDepth);
- assert( smallPool );
+ if (nfsGlob.smallPool == NULL) {
+ goto cleanup;
+ }
- bigPool = rpcUdpXactPoolCreate(
+ nfsGlob.bigPool = rpcUdpXactPoolCreate(
NFS_PROGRAM,
NFS_VERSION_2,
CONFIG_NFS_BIG_XACT_SIZE,
bigPoolDepth);
- assert( bigPool );
+ if (nfsGlob.bigPool == NULL) {
+ goto cleanup;
+ }
status = rtems_semaphore_create(
rtems_build_name('N','F','S','l'),
@@ -1054,14 +1064,19 @@ rtems_status_code status;
MUTEX_ATTRIBUTES,
0,
&nfsGlob.llock);
- assert( status == RTEMS_SUCCESSFUL );
+ if (status != RTEMS_SUCCESSFUL) {
+ goto cleanup;
+ }
+
status = rtems_semaphore_create(
rtems_build_name('N','F','S','m'),
1,
MUTEX_ATTRIBUTES,
0,
&nfsGlob.lock);
- assert( status == RTEMS_SUCCESSFUL );
+ if (status != RTEMS_SUCCESSFUL) {
+ goto cleanup;
+ }
if (sizeof(ino_t) < sizeof(u_int)) {
fprintf(stderr,
@@ -1070,6 +1085,15 @@ rtems_status_code status;
"you should fix newlib's sys/stat.h - for now I'll enable a hack...\n");
}
+
+ return 0;
+
+cleanup:
+
+ nfsCleanup();
+ initialised = 0;
+
+ return -1;
}
/* Driver cleanup code
@@ -1077,38 +1101,47 @@ rtems_status_code status;
int
nfsCleanup(void)
{
-rtems_id l;
int refuse;
- if (!nfsGlob.llock) {
- /* registering the driver failed - let them still cleanup */
- return 0;
+ if (nfsGlob.llock != 0) {
+ LOCK(nfsGlob.llock);
+ if ( (refuse = nfsGlob.num_mounted_fs) ) {
+ fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n",
+ refuse);
+ nfsMountsShow(stderr);
+ /* yes, printing is slow - but since you try to unload the driver,
+ * you assume nobody is using NFS, so what if they have to wait?
+ */
+ UNLOCK(nfsGlob.llock);
+ return -1;
+ }
}
- LOCK(nfsGlob.llock);
- if ( (refuse = nfsGlob.num_mounted_fs) ) {
- fprintf(stderr,"Refuse to unload NFS; %i filesystems still mounted.\n",
- refuse);
- nfsMountsShow(stderr);
- /* yes, printing is slow - but since you try to unload the driver,
- * you assume nobody is using NFS, so what if they have to wait?
- */
- UNLOCK(nfsGlob.llock);
- return -1;
+ if (nfsGlob.lock != 0) {
+ rtems_semaphore_delete(nfsGlob.lock);
+ nfsGlob.lock = 0;
}
- rtems_semaphore_delete(nfsGlob.lock);
- nfsGlob.lock = 0;
+ if (nfsGlob.smallPool != NULL) {
+ rpcUdpXactPoolDestroy(nfsGlob.smallPool);
+ nfsGlob.smallPool = NULL;
+ }
+
+ if (nfsGlob.bigPool != NULL) {
+ rpcUdpXactPoolDestroy(nfsGlob.bigPool);
+ nfsGlob.bigPool = NULL;
+ }
- /* hold the lock while cleaning up... */
+ if (nfsGlob.nfs_major != 0xffffffff) {
+ rtems_io_unregister_driver(nfsGlob.nfs_major);
+ nfsGlob.nfs_major = 0xffffffff;
+ }
- rpcUdpXactPoolDestroy(smallPool);
- rpcUdpXactPoolDestroy(bigPool);
- l = nfsGlob.llock;
- rtems_io_unregister_driver(nfsGlob.nfs_major);
+ if (nfsGlob.llock != 0) {
+ rtems_semaphore_delete(nfsGlob.llock);
+ nfsGlob.llock = 0;
+ }
- rtems_semaphore_delete(l);
- nfsGlob.llock = 0;
return 0;
}
@@ -1148,8 +1181,8 @@ int rval = -1;
switch (proc) {
case NFSPROC_SYMLINK:
case NFSPROC_WRITE:
- pool = bigPool; break;
- default: pool = smallPool; break;
+ pool = nfsGlob.bigPool; break;
+ default: pool = nfsGlob.smallPool; break;
}
xact = rpcUdpXactPoolGet(pool, XactGetCreate);
@@ -1313,7 +1346,7 @@ int len;
}
memcpy(&psa->sin_addr, h->h_addr, sizeof (struct in_addr));
-
+
/* END OF NON-THREAD SAFE REGION */
psa->sin_family = AF_INET;
@@ -1770,13 +1803,16 @@ char *path = mt_entry->dev;
fprintf (stderr, "error: initialising RPC\n");
return -1;
}
-
- nfsInit(0, 0);
+
+ if (nfsInit(0, 0) != 0) {
+ fprintf (stderr, "error: initialising NFS\n");
+ return -1;
+ };
#if 0
printf("Trying to mount %s on %s\n",path,mntpoint);
#endif
-
+
if ( buildIpAddr(&uid, &gid, &host, &saddr, &path) )
return -1;