From 56f2260008ad5425ec89bfacafe9146422c2c3a7 Mon Sep 17 00:00:00 2001 From: Andrei Mozzhuhin Date: Thu, 16 May 2013 11:23:46 +0200 Subject: dosfs: Add statvfs() support --- cpukit/libfs/Makefile.am | 2 +- cpukit/libfs/src/dosfs/msdos.h | 3 + cpukit/libfs/src/dosfs/msdos_init.c | 2 +- cpukit/libfs/src/dosfs/msdos_statvfs.c | 75 +++++++++++++++++++++ testsuites/fstests/Makefile.am | 1 + testsuites/fstests/configure.ac | 1 + testsuites/fstests/fsstatvfs/fsstatvfs.doc | 21 ++++++ testsuites/fstests/fsstatvfs/test.c | 88 +++++++++++++++++++++++++ testsuites/fstests/mdosfs_fsstatvfs/Makefile.am | 30 +++++++++ 9 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 cpukit/libfs/src/dosfs/msdos_statvfs.c create mode 100644 testsuites/fstests/fsstatvfs/fsstatvfs.doc create mode 100644 testsuites/fstests/fsstatvfs/test.c create mode 100644 testsuites/fstests/mdosfs_fsstatvfs/Makefile.am diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am index 7535b5a3a6..0828da8515 100644 --- a/cpukit/libfs/Makefile.am +++ b/cpukit/libfs/Makefile.am @@ -80,7 +80,7 @@ libdosfs_a_SOURCES += src/dosfs/msdos_create.c src/dosfs/msdos_dir.c \ src/dosfs/msdos_handlers_file.c src/dosfs/msdos_init.c \ src/dosfs/msdos_initsupp.c src/dosfs/msdos_misc.c \ src/dosfs/msdos_mknod.c src/dosfs/msdos_node_type.c \ - src/dosfs/msdos_rmnod.c \ + src/dosfs/msdos_rmnod.c src/dosfs/msdos_statvfs.c \ src/dosfs/msdos_conv.c src/dosfs/msdos.h src/dosfs/msdos_format.c \ src/dosfs/dosfs.h src/dosfs/msdos_rename.c endif diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h index 9465d268d7..78eda9b226 100644 --- a/cpukit/libfs/src/dosfs/msdos.h +++ b/cpukit/libfs/src/dosfs/msdos.h @@ -293,6 +293,9 @@ int msdos_rename( size_t new_namelen ); +int msdos_statvfs(const rtems_filesystem_location_info_t *root_loc, + struct statvfs *sb); + void msdos_lock(const rtems_filesystem_mount_table_entry_t *mt_entry); void msdos_unlock(const rtems_filesystem_mount_table_entry_t *mt_entry); diff --git a/cpukit/libfs/src/dosfs/msdos_init.c b/cpukit/libfs/src/dosfs/msdos_init.c index eb46141503..e82e3f52d2 100644 --- a/cpukit/libfs/src/dosfs/msdos_init.c +++ b/cpukit/libfs/src/dosfs/msdos_init.c @@ -53,7 +53,7 @@ const rtems_filesystem_operations_table msdos_ops = { .symlink_h = rtems_filesystem_default_symlink, .readlink_h = rtems_filesystem_default_readlink, .rename_h = msdos_rename, - .statvfs_h = rtems_filesystem_default_statvfs + .statvfs_h = msdos_statvfs }; void msdos_lock(const rtems_filesystem_mount_table_entry_t *mt_entry) diff --git a/cpukit/libfs/src/dosfs/msdos_statvfs.c b/cpukit/libfs/src/dosfs/msdos_statvfs.c new file mode 100644 index 0000000000..1a1d974fc3 --- /dev/null +++ b/cpukit/libfs/src/dosfs/msdos_statvfs.c @@ -0,0 +1,75 @@ +/** + * @file msdos_statvfs.c + * + * @brief Obtain MS-DOS filesystem information + * @ingroup libfs_msdos MSDOS FileSystem + */ + +/* + * Copyright (c) 2013 Andrey Mozzhuhin + * Copyright (c) 2013 Vitaly Belov + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include "fat.h" +#include "fat_fat_operations.h" +#include "msdos.h" + +int msdos_statvfs(const rtems_filesystem_location_info_t *root_loc, + struct statvfs *sb) +{ + msdos_fs_info_t *fs_info = root_loc->mt_entry->fs_info; + fat_vol_t *vol = &fs_info->fat.vol; + rtems_status_code sc = RTEMS_SUCCESSFUL; + + sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, + MSDOS_VOLUME_SEMAPHORE_TIMEOUT); + if (sc != RTEMS_SUCCESSFUL) + rtems_set_errno_and_return_minus_one(EIO); + + sb->f_bsize = FAT_SECTOR512_SIZE; + sb->f_frsize = vol->bpc; + sb->f_blocks = vol->data_cls; + sb->f_bfree = 0; + sb->f_bavail = 0; + sb->f_files = 0; // FAT doesn't store inodes + sb->f_ffree = 0; + sb->f_favail = 0; + sb->f_flag = 0; + sb->f_namemax = MSDOS_NAME_MAX_LNF_LEN; + + if (vol->free_cls == FAT_UNDEFINED_VALUE) + { + int rc; + uint32_t cur_cl = 2; + uint32_t value = 0; + uint32_t data_cls_val = vol->data_cls + 2; + + for (; cur_cl < data_cls_val; ++cur_cl) + { + rc = fat_get_fat_cluster(&fs_info->fat, cur_cl, &value); + if (rc != RC_OK) + { + rtems_semaphore_release(fs_info->vol_sema); + return rc; + } + + if (value == FAT_GENFAT_FREE) + { + sb->f_bfree++; + sb->f_bavail++; + } + } + } + else + { + sb->f_bfree = vol->free_cls; + sb->f_bavail = vol->free_cls; + } + + rtems_semaphore_release(fs_info->vol_sema); + return RC_OK; +} diff --git a/testsuites/fstests/Makefile.am b/testsuites/fstests/Makefile.am index 516138027b..f39055ee28 100644 --- a/testsuites/fstests/Makefile.am +++ b/testsuites/fstests/Makefile.am @@ -15,6 +15,7 @@ SUBDIRS += imfs_fstime SUBDIRS += mdosfs_fserror SUBDIRS += mdosfs_fspatheval SUBDIRS += mdosfs_fsrdwr +SUBDIRS += mdosfs_fsstatvfs SUBDIRS += mdosfs_fstime SUBDIRS += mimfs_fserror SUBDIRS += mimfs_fslink diff --git a/testsuites/fstests/configure.ac b/testsuites/fstests/configure.ac index 4993beb7c5..8985464a03 100644 --- a/testsuites/fstests/configure.ac +++ b/testsuites/fstests/configure.ac @@ -91,6 +91,7 @@ imfs_fstime/Makefile mdosfs_fserror/Makefile mdosfs_fspatheval/Makefile mdosfs_fsrdwr/Makefile +mdosfs_fsstatvfs/Makefile mdosfs_fstime/Makefile mimfs_fserror/Makefile mimfs_fslink/Makefile diff --git a/testsuites/fstests/fsstatvfs/fsstatvfs.doc b/testsuites/fstests/fsstatvfs/fsstatvfs.doc new file mode 100644 index 0000000000..85c329dfd1 --- /dev/null +++ b/testsuites/fstests/fsstatvfs/fsstatvfs.doc @@ -0,0 +1,21 @@ +# COPYRIGHT (c) 2013 Andrey Mozzhuhin +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.com/license/LICENSE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: fsstatvfs + +directives: + ++ statvfs + + + +concepts: + ++ Check that filesystem provide valid statistics + diff --git a/testsuites/fstests/fsstatvfs/test.c b/testsuites/fstests/fsstatvfs/test.c new file mode 100644 index 0000000000..88952ef156 --- /dev/null +++ b/testsuites/fstests/fsstatvfs/test.c @@ -0,0 +1,88 @@ +/* + * COPYRIGHT (c) 2013 Andrey Mozzhuhin + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "fstest.h" +#include "pmacros.h" + +static void statvfs_validate(struct statvfs *stat) +{ + rtems_test_assert(stat->f_bsize > 0); + rtems_test_assert(stat->f_frsize > 0); + rtems_test_assert(stat->f_blocks > 0); + rtems_test_assert(stat->f_bfree <= stat->f_blocks); + rtems_test_assert(stat->f_bavail <= stat->f_blocks); + rtems_test_assert(stat->f_ffree <= stat->f_files); + rtems_test_assert(stat->f_favail <= stat->f_files); + rtems_test_assert(stat->f_namemax > 0); +} + +static void statvfs_test01(void) +{ + struct statvfs statbuf1, statbuf2; + int status; + int fd; + ssize_t n; + const char *databuf = "STATVFS"; + int datalen = strlen(databuf); + const char *filename = __func__; + + /* + * Get current filesystem statistics + */ + status = statvfs("/", &statbuf1); + rtems_test_assert(status == 0); + statvfs_validate(&statbuf1); + + /* + * Create one file + */ + fd = open(filename, O_CREAT | O_WRONLY, 0775); + rtems_test_assert(fd >= 0); + n = write(fd, databuf, datalen); + rtems_test_assert(n == datalen); + status = close(fd); + rtems_test_assert(status == 0); + + /* + * Get new filesystem statistics + */ + status = statvfs("/", &statbuf2); + rtems_test_assert(status == 0); + statvfs_validate(&statbuf2); + + /* + * Compare old and new statistics + */ + rtems_test_assert(statbuf1.f_bsize == statbuf2.f_bsize); + rtems_test_assert(statbuf1.f_frsize == statbuf2.f_frsize); + rtems_test_assert(statbuf1.f_blocks == statbuf2.f_blocks); + rtems_test_assert(statbuf1.f_bfree >= statbuf2.f_bfree); + rtems_test_assert(statbuf1.f_bavail >= statbuf2.f_bavail); + rtems_test_assert(statbuf1.f_ffree >= statbuf2.f_ffree); + rtems_test_assert(statbuf1.f_favail >= statbuf2.f_favail); + rtems_test_assert(statbuf1.f_namemax == statbuf2.f_namemax); +} + +/* + * These tests only get time_t value, and test + * if they are changed. Thest tests don't check atime + */ +void test(void) +{ + puts( "\n\n*** STATVFS TEST ***"); + statvfs_test01(); + puts( "*** END OF STATVFS TEST ***"); +} diff --git a/testsuites/fstests/mdosfs_fsstatvfs/Makefile.am b/testsuites/fstests/mdosfs_fsstatvfs/Makefile.am new file mode 100644 index 0000000000..bb0d2ef505 --- /dev/null +++ b/testsuites/fstests/mdosfs_fsstatvfs/Makefile.am @@ -0,0 +1,30 @@ + +rtems_tests_PROGRAMS = mdosfs_fsstatvfs +mdosfs_fsstatvfs_SOURCES = ../fsstatvfs/test.c +mdosfs_fsstatvfs_SOURCES += ../support/ramdisk_support.c +mdosfs_fsstatvfs_SOURCES += ../support/fstest_support.c +mdosfs_fsstatvfs_SOURCES += ../support/fstest_support.h +mdosfs_fsstatvfs_SOURCES += ../support/ramdisk_support.h +mdosfs_fsstatvfs_SOURCES += ../support/fstest.h +mdosfs_fsstatvfs_SOURCES += ../../psxtests/include/pmacros.h +mdosfs_fsstatvfs_SOURCES += ../mdosfs_support/fs_support.c +mdosfs_fsstatvfs_SOURCES += ../mdosfs_support/fs_config.h + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + + +AM_CPPFLAGS += -I$(top_srcdir)/support +AM_CPPFLAGS += -I$(top_srcdir)/mdosfs_support +AM_CPPFLAGS += -I$(top_srcdir)/../support/include +AM_CPPFLAGS += -I$(top_srcdir)/../psxtests/include + +LINK_OBJS = $(mdosfs_fsstatvfs_OBJECTS) +LINK_LIBS = $(mdosfs_fsstatvfs_LDLIBS) + +mdosfs_ffsstatvfs$(EXEEXT): $(mdosfs_fsstatvfs_OBJECTS) $(mdosfs_fsstatvfs_DEPENDENCIES) + @rm -f mdosfs_fsstatvfs$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am -- cgit v1.2.3