summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Mozzhuhin <nopscmn@gmail.com>2013-05-16 11:23:46 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-05-16 11:40:41 +0200
commit56f2260008ad5425ec89bfacafe9146422c2c3a7 (patch)
tree839bc4b6cc2f7bad839ded284522b18f90d33d37
parentshell: Fix NULL pointer access (diff)
downloadrtems-56f2260008ad5425ec89bfacafe9146422c2c3a7.tar.bz2
dosfs: Add statvfs() support
-rw-r--r--cpukit/libfs/Makefile.am2
-rw-r--r--cpukit/libfs/src/dosfs/msdos.h3
-rw-r--r--cpukit/libfs/src/dosfs/msdos_init.c2
-rw-r--r--cpukit/libfs/src/dosfs/msdos_statvfs.c75
-rw-r--r--testsuites/fstests/Makefile.am1
-rw-r--r--testsuites/fstests/configure.ac1
-rw-r--r--testsuites/fstests/fsstatvfs/fsstatvfs.doc21
-rw-r--r--testsuites/fstests/fsstatvfs/test.c88
-rw-r--r--testsuites/fstests/mdosfs_fsstatvfs/Makefile.am30
9 files changed, 221 insertions, 2 deletions
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 <sys/statvfs.h>
+#include <string.h>
+#include <fcntl.h>
+
+#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