summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs
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 /cpukit/libfs
parentshell: Fix NULL pointer access (diff)
downloadrtems-56f2260008ad5425ec89bfacafe9146422c2c3a7.tar.bz2
dosfs: Add statvfs() support
Diffstat (limited to 'cpukit/libfs')
-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
4 files changed, 80 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;
+}