changeset 2260:32d66e0b0050

* src/ramfs.c (find_direntry): Don't search off the end of the directory node into hyperspace. * src/ramfs.c (ramfs_getinfo): Support for block usage call. * tests/ramfs1.c (main): Add file system block usage test.
author asl
date Fri, 04 Aug 2006 09:18:01 +0000
parents f2a958322096
children 04c9eb8c07e9
files packages/fs/ram/current/ChangeLog packages/fs/ram/current/src/ramfs.c packages/fs/ram/current/tests/ramfs1.c
diffstat 3 files changed, 64 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/packages/fs/ram/current/ChangeLog
+++ b/packages/fs/ram/current/ChangeLog
@@ -1,3 +1,10 @@
+2006-06-25  Andrew Lunn  <lunn@laptop.lunn.ch>
+
+	* src/ramfs.c (find_direntry): Don't search off the end of the
+	directory node into hyperspace.
+	* src/ramfs.c (ramfs_getinfo): Support for block usage call.
+	* tests/ramfs1.c (main): Add file system block usage test. 
+
 2006-05-17  Andy Jackson  <andy@grapevinetech.co.uk>
 
 	* tests/ramfs1.c (createfile): Fix compile warnings.
--- a/packages/fs/ram/current/src/ramfs.c
+++ b/packages/fs/ram/current/src/ramfs.c
@@ -1210,11 +1210,11 @@ static ramfs_dirent *find_direntry( ramf
         ramfs_dirent *d;
         cyg_uint8 *buf;
         size_t size;
-        
+
         // look for a first name fragment
         for(;;)
         {
-            err = findbuffer_node( dir, pos, &buf, &size, false );
+	  err = findbuffer_node( dir, pos, &buf, &size, false );
             if( err != ENOERR || size == 0)
                 return NULL;
 
@@ -1223,7 +1223,10 @@ static ramfs_dirent *find_direntry( ramf
             if( size < sizeof(ramfs_dirent) || !d->inuse || !d->first )
             {
                 pos += sizeof(ramfs_dirent);
-                continue;
+		if ( pos < dir->size )
+		  continue;
+		// End if directory, didn't find it.
+		return NULL;
             }
 
             break;
@@ -1248,17 +1251,17 @@ static ramfs_dirent *find_direntry( ramf
                     fraglen = d->fraglen;
 
                 // compare strings, if different, look for another
-                if( memcmp( frag, d->name, fraglen ) != 0 )
-                    break;
-
+                if( memcmp( frag, d->name, fraglen ) != 0 ) {
+		  break;
+		}
                 frag        += fraglen;
             
                 // If we are at the last fragment, then the whole name string
                 // has matched and we have a successful search.
                 
-                if( d->last )
-                        return first;
-
+                if( d->last ) 
+		  return first;
+		
                 // Otherwise move on to next entry in chain
                 err = findbuffer_node( dir, d->next, &buf, &size, false );
                 if( err != ENOERR )
@@ -1977,7 +1980,7 @@ static int ramfs_stat     ( cyg_mtab_ent
 
 // -------------------------------------------------------------------------
 // ramfs_getinfo()
-// Getinfo. Currently only support pathconf().
+// Getinfo. Currently only support pathconf() and filesystem usage.
 
 static int ramfs_getinfo  ( cyg_mtab_entry *mte, cyg_dir dir, const char *name,
                              int key, void *buf, int len )
@@ -1996,7 +1999,26 @@ static int ramfs_getinfo  ( cyg_mtab_ent
     case FS_INFO_CONF:
         err = ramfs_pathconf( ds.node, (struct cyg_pathconf_info *)buf );
         break;
-        
+#if defined(CYGSEM_FILEIO_BLOCK_USAGE) && defined(CYGPKG_FS_RAM_BLOCKS_ARRAY)
+	// When using malloc for storage this does not make much
+	// sense, so only implement this when using pre-allocated
+	// blocks
+    case FS_INFO_BLOCK_USAGE: {
+      struct cyg_fs_block_usage *usage = (struct cyg_fs_block_usage *) buf;
+      ramfs_block *b;
+      
+      usage->total_blocks = CYGNUM_FS_RAM_BLOCKS_ARRAY_SIZE;
+      usage->free_blocks = 0;
+      // Iterate over the free list to count its size
+      b = block_free_list;
+      while(b) {
+	usage->free_blocks++;
+	b=*(ramfs_block **)b;
+      }
+      usage->block_size = CYGNUM_RAMFS_BLOCK_SIZE;
+      return ENOERR;
+    }
+#endif
     default:
         err = EINVAL;
     }
--- a/packages/fs/ram/current/tests/ramfs1.c
+++ b/packages/fs/ram/current/tests/ramfs1.c
@@ -61,6 +61,7 @@
 #include <pkgconf/hal.h>
 #include <pkgconf/kernel.h>
 #include <pkgconf/io_fileio.h>
+#include <pkgconf/fs_ram.h>
 
 #include <cyg/kernel/ktypes.h>         // base kernel types
 #include <cyg/infra/cyg_trac.h>        // tracing macros
@@ -415,6 +416,9 @@ int main( int argc, char **argv )
 {
     int err;
     int existingdirents=-1;
+#if defined(CYGSEM_FILEIO_BLOCK_USAGE) && defined(CYGPKG_FS_RAM_BLOCKS_ARRAY)
+    struct cyg_fs_block_usage usage;
+#endif
 
     CYG_TEST_INIT();
 
@@ -431,7 +435,16 @@ int main( int argc, char **argv )
     listdir( "/", true, -1, &existingdirents );
     if ( existingdirents < 2 )
         CYG_TEST_FAIL("Not enough dir entries\n");
-
+    // --------------------------------------------------------------
+#if defined(CYGSEM_FILEIO_BLOCK_USAGE) && defined(CYGPKG_FS_RAM_BLOCKS_ARRAY)
+    err = cyg_fs_getinfo("/", FS_INFO_BLOCK_USAGE, &usage, sizeof(usage));
+    if( err < 0 ) SHOW_RESULT( cyg_fs_getinfo, err );
+    diag_printf("<INFO>: total size: %6lld blocks, %10lld bytes\n",
+		usage.total_blocks, usage.total_blocks * usage.block_size); 
+    diag_printf("<INFO>: free size:  %6lld blocks, %10lld bytes\n",
+		usage.free_blocks, usage.free_blocks * usage.block_size); 
+    diag_printf("<INFO>: block size: %6u bytes\n", usage.block_size);
+#endif
     // --------------------------------------------------------------
 
     createfile( "/foo", 202 );
@@ -552,6 +565,16 @@ int main( int argc, char **argv )
     listdir( "..", true, existingdirents+3, NULL );
 
     // --------------------------------------------------------------
+#if defined(CYGSEM_FILEIO_BLOCK_USAGE) && defined(CYGPKG_FS_RAM_BLOCKS_ARRAY)
+    err = cyg_fs_getinfo("/", FS_INFO_BLOCK_USAGE, &usage, sizeof(usage));
+    if( err < 0 ) SHOW_RESULT( cyg_fs_getinfo, err );
+    diag_printf("<INFO>: total size: %6lld blocks, %10lld bytes\n",
+		usage.total_blocks, usage.total_blocks * usage.block_size); 
+    diag_printf("<INFO>: free size:  %6lld blocks, %10lld bytes\n",
+		usage.free_blocks, usage.free_blocks * usage.block_size); 
+    diag_printf("<INFO>: block size: %6u bytes\n", usage.block_size);
+#endif
+    // --------------------------------------------------------------
 
     diag_printf("<INFO>: unlink tinky\n");    
     err = unlink( "tinky" );