From e618b202159d383779ad9d2fc1865266fd7c5952 Mon Sep 17 00:00:00 2001 From: Bhavya Shah Date: Wed, 11 Jun 2025 01:41:09 +0530 Subject: [PATCH] imfs/imfs_statvfs: Added the statvfs functionality to IMFS module - Modified the psximfs01 test to validate the functionality - Modified the IMFS_fs_info_t keeping the jnode counter - Added imfs_statvfs.c which sets the statvfs struct fields for imfs --- cpukit/include/rtems/confdefs/libio.h | 2 +- cpukit/include/rtems/imfs.h | 41 +++++++++++---- cpukit/libfs/src/imfs/imfs_init.c | 2 +- cpukit/libfs/src/imfs/imfs_initsupp.c | 1 + cpukit/libfs/src/imfs/imfs_mknod.c | 3 +- cpukit/libfs/src/imfs/imfs_rmnod.c | 2 + cpukit/libfs/src/imfs/imfs_statvfs.c | 57 +++++++++++++++++++++ spec/build/cpukit/librtemscpu.yml | 1 + testsuites/psxtests/psximfs01/init.c | 18 ++++++- testsuites/psxtests/psximfs01/psximfs01.doc | 3 ++ testsuites/psxtests/psximfs01/psximfs01.scn | 1 + 11 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 cpukit/libfs/src/imfs/imfs_statvfs.c diff --git a/cpukit/include/rtems/confdefs/libio.h b/cpukit/include/rtems/confdefs/libio.h index 289f2e26c6..d59da704d1 100644 --- a/cpukit/include/rtems/confdefs/libio.h +++ b/cpukit/include/rtems/confdefs/libio.h @@ -260,7 +260,7 @@ static const rtems_filesystem_operations_table IMFS_root_ops = { #else IMFS_rename, #endif - rtems_filesystem_default_statvfs + IMFS_statvfs }; static const IMFS_mknod_controls IMFS_root_mknod_controls = { diff --git a/cpukit/include/rtems/imfs.h b/cpukit/include/rtems/imfs.h index cb41bd198a..013fa7d131 100644 --- a/cpukit/include/rtems/imfs.h +++ b/cpukit/include/rtems/imfs.h @@ -35,6 +35,7 @@ #define _RTEMS_IMFS_H #include +#include #include #include @@ -381,6 +382,7 @@ typedef struct { typedef struct { IMFS_directory_t Root_directory; const IMFS_mknod_controls *mknod_controls; + int jnode_count; } IMFS_fs_info_t; typedef struct { @@ -528,9 +530,9 @@ extern void IMFS_eval_path_devfs( /** * @brief Create a new IMFS link node. * - * The following rouine creates a new link node under parent with the - * name given in name. The link node is set to point to the node at - * to_loc. + * The following routine creates a new link node under parent with the + * name given in @a name. The link node is set to point to the node at + * @a targetloc. */ extern int IMFS_link( const rtems_filesystem_location_info_t *parentloc, @@ -953,8 +955,8 @@ extern int IMFS_fchmod( /** * @brief Create a new IMFS symbolic link node. * - * The following rouine creates a new symbolic link node under parent - * with the name given in name. The node is set to point to the node at + * The following routine creates a new symbolic link node under parent + * with the name given in @a name. The node is set to point to the node at * to_loc. */ extern int IMFS_symlink( @@ -964,11 +966,32 @@ extern int IMFS_symlink( const char *target ); +/** + * @brief Sets @a buf with the IMFS statistics. + * + * The following routine sets the @a buf which has attributes + * f_bsize - Filesystem block size + * f_frsize - Fragment size + * f_blocks - Size of fs in f_frsize units + * f_frsize - Fragment size: + * f_bfree - Number of free blocks + * f_files - Number of inodes + * f_fsid - Filesystem ID + * f_flag - Mount flags + * f_namemax - Maximum filename Length + * @retval 0 Successful operation. + * @retval -1 An error occurred. The @c errno indicates the error. + */ +extern int IMFS_statvfs( + const rtems_filesystem_location_info_t *loc, + struct statvfs *buf +); + /** * @brief Put IMFS symbolic link into buffer. * - * The following rouine puts the symbolic links destination name into - * buff. + * The following routine puts the symbolic links destination name into + * @a buf. * */ extern ssize_t IMFS_readlink( @@ -980,8 +1003,8 @@ extern ssize_t IMFS_readlink( /** * @brief Rename the IMFS. * - * The following rouine creates a new link node under parent with the - * name given in name and removes the old. + * The following routine creates a new link node under parent with the + * name given in @a name and removes the old. */ extern int IMFS_rename( const rtems_filesystem_location_info_t *oldparentloc, diff --git a/cpukit/libfs/src/imfs/imfs_init.c b/cpukit/libfs/src/imfs/imfs_init.c index 8685caae68..87fcd8b2d3 100644 --- a/cpukit/libfs/src/imfs/imfs_init.c +++ b/cpukit/libfs/src/imfs/imfs_init.c @@ -62,7 +62,7 @@ static const rtems_filesystem_operations_table IMFS_ops = { .symlink_h = IMFS_symlink, .readlink_h = IMFS_readlink, .rename_h = IMFS_rename, - .statvfs_h = rtems_filesystem_default_statvfs + .statvfs_h = IMFS_statvfs }; static const IMFS_mknod_controls IMFS_default_mknod_controls = { diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c index b3dccf37e0..000767f7d8 100644 --- a/cpukit/libfs/src/imfs/imfs_initsupp.c +++ b/cpukit/libfs/src/imfs/imfs_initsupp.c @@ -56,6 +56,7 @@ int IMFS_initialize_support( fs_info = mount_data->fs_info; fs_info->mknod_controls = mount_data->mknod_controls; + fs_info->jnode_count = 0; node_control = &mount_data->mknod_controls->directory->node_control; root_node = &fs_info->Root_directory.Node; diff --git a/cpukit/libfs/src/imfs/imfs_mknod.c b/cpukit/libfs/src/imfs/imfs_mknod.c index 7c708f9fa8..d60f327cb6 100644 --- a/cpukit/libfs/src/imfs/imfs_mknod.c +++ b/cpukit/libfs/src/imfs/imfs_mknod.c @@ -69,7 +69,7 @@ int IMFS_mknod( ) { int rv = 0; - const IMFS_fs_info_t *fs_info = parentloc->mt_entry->fs_info; + IMFS_fs_info_t *fs_info = parentloc->mt_entry->fs_info; const IMFS_mknod_control *mknod_control = get_control( fs_info->mknod_controls, mode ); IMFS_jnode_t *new_node; @@ -90,6 +90,7 @@ int IMFS_mknod( } else { rv = -1; } + fs_info->jnode_count++; return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_rmnod.c b/cpukit/libfs/src/imfs/imfs_rmnod.c index ed60baeff3..1c0d59c475 100644 --- a/cpukit/libfs/src/imfs/imfs_rmnod.c +++ b/cpukit/libfs/src/imfs/imfs_rmnod.c @@ -50,6 +50,7 @@ int IMFS_rmnod( { int rv = 0; IMFS_jnode_t *node = loc->node_access; + IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info; node = (*node->control->node_remove)( node ); if ( node != NULL ) { @@ -61,6 +62,7 @@ int IMFS_rmnod( } else { rv = -1; } + fs_info->jnode_count--; return rv; } diff --git a/cpukit/libfs/src/imfs/imfs_statvfs.c b/cpukit/libfs/src/imfs/imfs_statvfs.c new file mode 100644 index 0000000000..65787da277 --- /dev/null +++ b/cpukit/libfs/src/imfs/imfs_statvfs.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup IMFS + * + * @brief FIFO Support + */ + +/* + * Copyright (c) 2025 On-Line Application Research Corporation (OAR) + * Copyright (c) 2025 Bhavya Shah + * + * 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. + * + * 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. + */ + +#include +#include +#include + +int IMFS_statvfs( + const rtems_filesystem_location_info_t *loc, + struct statvfs *buf +) +{ + IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info; + buf->f_bsize = IMFS_MEMFILE_BYTES_PER_BLOCK; + buf->f_frsize = IMFS_MEMFILE_BYTES_PER_BLOCK; + buf->f_blocks = UINT_MAX / IMFS_MEMFILE_BYTES_PER_BLOCK; + buf->f_bfree = malloc_free_space() / IMFS_MEMFILE_BYTES_PER_BLOCK; + buf->f_bavail = malloc_free_space() / IMFS_MEMFILE_BYTES_PER_BLOCK; + buf->f_files = fs_info->jnode_count; + buf->f_fsid = 1; + buf->f_flag = loc->mt_entry->writeable; + buf->f_namemax = IMFS_NAME_MAX; + return 0; +} diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 1752fba772..cfcc5aedd0 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -891,6 +891,7 @@ source: - cpukit/libfs/src/imfs/imfs_rename.c - cpukit/libfs/src/imfs/imfs_rmnod.c - cpukit/libfs/src/imfs/imfs_stat.c +- cpukit/libfs/src/imfs/imfs_statvfs.c - cpukit/libfs/src/imfs/imfs_stat_file.c - cpukit/libfs/src/imfs/imfs_symlink.c - cpukit/libfs/src/imfs/imfs_unmount.c diff --git a/testsuites/psxtests/psximfs01/init.c b/testsuites/psxtests/psximfs01/init.c index 324baa5723..0aca334c7b 100644 --- a/testsuites/psxtests/psximfs01/init.c +++ b/testsuites/psxtests/psximfs01/init.c @@ -36,10 +36,12 @@ #include #include #include +#include #include #include #include +#define BLOCK_SIZE 16 const char rtems_test_name[] = "PSXIMFS 1"; /* forward declarations to avoid warnings */ @@ -51,6 +53,7 @@ void truncate_helper(void); void extend_helper(int eno); void close_it(void); void unlink_it(void); +void statvfs_helper(void); int TestFd; uint8_t Buffer[256]; @@ -228,6 +231,16 @@ void unlink_it(void) rtems_test_assert( rc == 0 ); } +void statvfs_helper(void) +{ + struct statvfs imfs_statvfs; + puts( "statvfs(" FILE_NAME ") - OK " ); + int rc = statvfs(FILE_NAME, &imfs_statvfs); + rtems_test_assert(rc == 0); + rtems_test_assert(imfs_statvfs.f_bsize == BLOCK_SIZE); + rtems_test_assert(imfs_statvfs.f_files == 2); +} + rtems_task Init( rtems_task_argument argument ) @@ -245,6 +258,9 @@ rtems_task Init( Buffer[i] = (uint8_t) i; open_it(false, true); + + statvfs_helper(); + write_helper(); close_it(); @@ -292,7 +308,7 @@ rtems_task Init( #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_MAXIMUM_TASKS 1 -#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK 16 +#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK BLOCK_SIZE #define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 4 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION diff --git a/testsuites/psxtests/psximfs01/psximfs01.doc b/testsuites/psxtests/psximfs01/psximfs01.doc index 0471605e56..bb1e2a8d8a 100644 --- a/testsuites/psxtests/psximfs01/psximfs01.doc +++ b/testsuites/psxtests/psximfs01/psximfs01.doc @@ -38,12 +38,15 @@ directives: + lseek + ftruncate + unlink + + statvfs concepts: + Create an IMFS instance with the smallest possible block size. This ensures the maximum file size is relatively small. ++ Ensures the IMFS block size is correctly configured. + + Create, write, and read a file of maximum size. + Use ftruncate to shorten the file from the maximum size to 0. diff --git a/testsuites/psxtests/psximfs01/psximfs01.scn b/testsuites/psxtests/psximfs01/psximfs01.scn index 5ae790a56d..36c10afc76 100644 --- a/testsuites/psxtests/psximfs01/psximfs01.scn +++ b/testsuites/psxtests/psximfs01/psximfs01.scn @@ -1,5 +1,6 @@ *** TEST IMFS 01 *** open(biggie) - OK +statvfs(biggie) - OK write(biggie) - OK Total written = 1280 close(biggie) - OK