[rtems commit] nfsclient: Return an error status in nfsInit()

Sebastian Huber sebh at rtems.org
Wed Jan 9 16:20:10 UTC 2013


Module:    rtems
Branch:    master
Commit:    f33a84b5553a67aaea9d19b02701689058297c3c
Changeset: http://git.rtems.org/rtems/commit/?id=f33a84b5553a67aaea9d19b02701689058297c3c

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jan  9 17:22:51 2013 +0100

nfsclient: Return an error status in nfsInit()

Avoid assert() and use proper cleanup if nfsInit() fails to allocate a
resource.

---

 cpukit/libfs/src/nfsclient/src/librtemsNfs.h |    7 +-
 cpukit/libfs/src/nfsclient/src/nfs.c         |  127 ++++++++++++++++----------
 2 files changed, 84 insertions(+), 50 deletions(-)

diff --git a/cpukit/libfs/src/nfsclient/src/librtemsNfs.h b/cpukit/libfs/src/nfsclient/src/librtemsNfs.h
index ddef9ee..f1b2b4f 100644
--- a/cpukit/libfs/src/nfsclient/src/librtemsNfs.h
+++ b/cpukit/libfs/src/nfsclient/src/librtemsNfs.h
@@ -135,8 +135,11 @@ rpcUdpCleanup(void);
  *
  * 			Supply zero values to have the
  * 			driver chose reasonable defaults.
+ *
+ * @retval 0 Successful operation.
+ * @retval -1 An error occurred.  The errno is set to indicate the error.
  */
-void
+int
 nfsInit(int smallPoolDepth, int bigPoolDepth);
 
 /**
@@ -201,4 +204,4 @@ nfsGetTimeout(void);
 #endif
 
 /** @} */
-#endif
\ No newline at end of file
+#endif
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index e4e9d88..99e34d5 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -679,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
@@ -691,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
@@ -997,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;
@@ -1005,7 +1005,7 @@ entry	dummy;
 rtems_status_code status;
 
 	if (initialised)
-		return;
+		return 0;
 
 	initialised = 1;
 
@@ -1018,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)
@@ -1039,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'),
@@ -1059,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,
@@ -1075,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
@@ -1082,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;
+	}
 
-	/* hold the lock while cleaning up... */
+	if (nfsGlob.bigPool != NULL) {
+		rpcUdpXactPoolDestroy(nfsGlob.bigPool);
+		nfsGlob.bigPool = NULL;
+	}
 
-	rpcUdpXactPoolDestroy(smallPool);
-	rpcUdpXactPoolDestroy(bigPool);
-	l = nfsGlob.llock;
-	rtems_io_unregister_driver(nfsGlob.nfs_major);
+	if (nfsGlob.nfs_major != 0xffffffff) {
+		rtems_io_unregister_driver(nfsGlob.nfs_major);
+		nfsGlob.nfs_major = 0xffffffff;
+	}
+
+	if (nfsGlob.llock != 0) {
+		rtems_semaphore_delete(nfsGlob.llock);
+		nfsGlob.llock = 0;
+	}
 
-	rtems_semaphore_delete(l);
-	nfsGlob.llock = 0;
 	return 0;
 }
 
@@ -1153,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);
@@ -1776,7 +1804,10 @@ char				*path     = mt_entry->dev;
     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);




More information about the vc mailing list