Ticket #2114: msdos_statvfs.patch

File msdos_statvfs.patch, 8.0 KB (added by Andrey Mozzhuhin, on 04/08/13 at 19:17:41)

statvfs for MS-DOS

  • cpukit/libfs/Makefile.am

    diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
    index 7535b5a..0828da8 100644
    a b  
    8080    src/dosfs/msdos_handlers_file.c src/dosfs/msdos_init.c \
    8181    src/dosfs/msdos_initsupp.c src/dosfs/msdos_misc.c \
    8282    src/dosfs/msdos_mknod.c src/dosfs/msdos_node_type.c \
    83     src/dosfs/msdos_rmnod.c \
     83    src/dosfs/msdos_rmnod.c src/dosfs/msdos_statvfs.c \
    8484    src/dosfs/msdos_conv.c src/dosfs/msdos.h src/dosfs/msdos_format.c \
    8585    src/dosfs/dosfs.h src/dosfs/msdos_rename.c
    8686endif
  • cpukit/libfs/src/dosfs/msdos.h

    diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h
    index 9465d26..7fb11d9 100644
    a b  
    293293  size_t new_namelen
    294294);
    295295
     296int msdos_statvfs(rtems_filesystem_location_info_t *root_loc,
     297  struct statvfs *sb);
     298
    296299void msdos_lock(const rtems_filesystem_mount_table_entry_t *mt_entry);
    297300
    298301void msdos_unlock(const rtems_filesystem_mount_table_entry_t *mt_entry);
  • cpukit/libfs/src/dosfs/msdos_init.c

    diff --git a/cpukit/libfs/src/dosfs/msdos_init.c b/cpukit/libfs/src/dosfs/msdos_init.c
    index eb46141..e82e3f5 100644
    a b  
    5353  .symlink_h      =  rtems_filesystem_default_symlink,
    5454  .readlink_h     =  rtems_filesystem_default_readlink,
    5555  .rename_h       =  msdos_rename,
    56   .statvfs_h      =  rtems_filesystem_default_statvfs
     56  .statvfs_h      =  msdos_statvfs
    5757};
    5858
    5959void msdos_lock(const rtems_filesystem_mount_table_entry_t *mt_entry)
  • new file cpukit/libfs/src/dosfs/msdos_statvfs.c

    diff --git a/cpukit/libfs/src/dosfs/msdos_statvfs.c b/cpukit/libfs/src/dosfs/msdos_statvfs.c
    new file mode 100644
    index 0000000..9f80b3a
    - +  
     1/**
     2 * @file msdos_statvfs.c
     3 *
     4 * @brief Obtain MS-DOS filesystem information
     5 * @ingroup libfs_msdos MSDOS FileSystem
     6 */
     7
     8#include "fat.h"
     9#include "dosfs.h"
     10
     11int msdos_statvfs(rtems_filesystem_location_info_t *root_loc,
     12                                  struct statvfs *sb)
     13{
     14        fat_fs_info_t *fs_info = root_loc->mt_entry->fs_info;
     15        fat_vol_t *vol = &fs_info->vol;
     16
     17        sb->f_bsize = FAT_SECTOR512_SIZE;
     18        sb->f_frsize = vol->bpc;
     19        sb->f_blocks = vol->data_cls;
     20        sb->f_namemax = MSDOS_NAME_MAX_LNF_LEN;
     21
     22        if (vol->free_cls == FAT_UNDEFINED_VALUE)
     23        {
     24                int rc;
     25                uint32_t       cur_cl = 2;
     26                uint32_t       value = 0;
     27                uint32_t       data_cls_val = fs_info->vol.data_cls + 2;
     28
     29                sb->f_bfree = 0;
     30
     31                for( ; cur_cl < data_cls_val; ++cur_cl)
     32                {
     33                        rc = fat_get_fat_cluster(fs_info, cur_cl, &value);
     34                        if(rc != RC_OK)
     35                                return rc;
     36
     37                        if (value == FAT_GENFAT_FREE)
     38                                ++sb->f_bfree;
     39                }
     40        }
     41        else
     42                sb->f_bfree = vol->free_cls;
     43
     44        return RC_OK;
     45}
  • cpukit/libmisc/Makefile.am

    diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am
    index b0b2195..5800a47 100644
    a b  
    102102    shell/hexdump-odsyntax.c shell/hexdump-parse.c shell/hexsyntax.c \
    103103    shell/main_time.c shell/main_mknod.c \
    104104    shell/main_setenv.c shell/main_getenv.c shell/main_unsetenv.c \
    105     shell/main_mkrfs.c shell/main_debugrfs.c \
     105    shell/main_mkrfs.c shell/main_debugrfs.c shell/main_df.c \
    106106    shell/main_lsof.c \
    107107    shell/main_blkstats.c \
    108108    shell/shell-wait-for-input.c
  • new file cpukit/libmisc/shell/main_df.c

    diff --git a/cpukit/libmisc/shell/main_df.c b/cpukit/libmisc/shell/main_df.c
    new file mode 100644
    index 0000000..9ac17c4
    - +  
     1/*
     2 *  df Shell Command Implmentation
     3 *
     4 *  The license and distribution terms for this file may be
     5 *  found in the file LICENSE in this distribution or at
     6 *  http://www.rtems.com/license/LICENSE.
     7 */
     8
     9#ifdef HAVE_CONFIG_H
     10#include "config.h"
     11#endif
     12
     13#include <rtems/shell.h>
     14
     15#define __need_getopt_newlib
     16#include <getopt.h>
     17
     18static const char suffixes[] = {'B', 'K', 'M', 'G', 'T'};
     19
     20struct df_context
     21{
     22        unsigned block_size;
     23};
     24
     25static unsigned rtems_shell_df_parse_size(const char *str)
     26{
     27        unsigned result;
     28        char suffix;
     29        int i;
     30
     31        if (sscanf(str, "%d%c", &result, &suffix) == 2)
     32        {
     33                for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
     34                {
     35                        if (suffix == suffixes[i])
     36                                break;
     37                        result *= 1024;
     38                }
     39        }
     40        else if (sscanf(str, "%d", &result) != 1)
     41        {
     42                result = 0;
     43        }
     44
     45        return result;
     46}
     47
     48static char *rtems_shell_df_humanize_size(unsigned block_size, char *buf, size_t size)
     49{
     50        int i = 0;
     51
     52        while (block_size >= 1024 && i < sizeof(suffixes) / sizeof(suffixes[0]) - 1)
     53        {
     54                block_size /= 1024;
     55                i++;
     56        }
     57
     58        snprintf(buf, size, "%d%c", block_size, suffixes[i]);
     59        return buf;
     60}
     61
     62static bool rtems_shell_df_print_entry(const rtems_filesystem_mount_table_entry_t *mt_entry, void *arg)
     63{
     64        struct df_context *context = arg;
     65
     66        struct statvfs svfs;
     67        int code;
     68        char        f_buf[16], u_buf[16], a_buf[16];
     69
     70        if ((code = statvfs(mt_entry->target, &svfs)))
     71                return false;
     72
     73        if (context->block_size > 0)
     74        {
     75                printf("%-15s %10llu %9llu %11llu %9llu%% %14s\n",
     76                                mt_entry->dev == NULL ? "none" : mt_entry->dev,
     77                                svfs.f_blocks * svfs.f_frsize / context->block_size,
     78                                (svfs.f_blocks - svfs.f_bfree) * svfs.f_frsize / context->block_size,
     79                                svfs.f_bfree * svfs.f_frsize / context->block_size,
     80                                ((svfs.f_blocks - svfs.f_bfree) * 100 / svfs.f_blocks),
     81                                mt_entry->target == NULL ? "none" : mt_entry->target);
     82        }
     83        else
     84        {
     85                rtems_shell_df_humanize_size(svfs.f_blocks * svfs.f_frsize, f_buf, sizeof(f_buf));
     86                rtems_shell_df_humanize_size((svfs.f_blocks - svfs.f_bfree) * svfs.f_frsize, u_buf, sizeof(u_buf));
     87                rtems_shell_df_humanize_size(svfs.f_bfree * svfs.f_frsize, a_buf, sizeof(a_buf));
     88                printf("%-15s %10s %9s %11s %9llu%% %14s\n",
     89                                mt_entry->dev == NULL ? "none" : mt_entry->dev, f_buf, u_buf, a_buf,
     90                                (svfs.f_blocks - svfs.f_bfree) * 100 / svfs.f_blocks,
     91                                mt_entry->target == NULL ? "none" : mt_entry->target);
     92        }
     93
     94        return false;
     95}
     96
     97int rtems_shell_main_df(int argc, char **argv)
     98{
     99        int c;
     100        struct getopt_data optdata;
     101        struct df_context context;
     102        char buf[32];
     103
     104        memset(&optdata, 0, sizeof(optdata));
     105        context.block_size = 1024;
     106
     107        while ((c = getopt_r(argc, (char**) argv, ":hB:", &optdata)) != -1)
     108        {
     109                switch (c)
     110                {
     111                        case 'h':
     112                                context.block_size = 0;
     113                                break;
     114                        case 'B':
     115                                context.block_size = rtems_shell_df_parse_size(optdata.optarg);
     116                                break;
     117                        default:
     118                                return -1;
     119                }
     120        }
     121
     122        if (context.block_size == 0)
     123                printf("Filesystem     Size             Used   Available       Use%%     Mounted on\n");
     124        else
     125                printf("Filesystem     %s-blocks        Used   Available       Use%%     Mounted on\n",
     126                                rtems_shell_df_humanize_size(context.block_size, buf, sizeof(buf)));
     127
     128        rtems_filesystem_mount_iterate(rtems_shell_df_print_entry, &context);
     129
     130        return 0;
     131}
     132
     133rtems_shell_cmd_t rtems_shell_DF_Command = {
     134  "df",                                                /* name */
     135  "[-hB]\n"
     136  " -h  human-readable output\n"
     137  " -B  scale sizes by SIZE before printing them\n",   /* usage */
     138  "files",                                             /* topic */
     139  rtems_shell_main_df,                                 /* command */
     140  NULL,                                                /* alias */
     141  NULL                                                 /* next */
     142};
  • cpukit/libmisc/shell/shellconfig.h

    diff --git a/cpukit/libmisc/shell/shellconfig.h b/cpukit/libmisc/shell/shellconfig.h
    index 9f45151..652d62b 100644
    a b  
    7070extern rtems_shell_cmd_t rtems_shell_DD_Command;
    7171extern rtems_shell_cmd_t rtems_shell_HEXDUMP_Command;
    7272extern rtems_shell_cmd_t rtems_shell_DEBUGRFS_Command;
     73extern rtems_shell_cmd_t rtems_shell_DF_Command;
    7374
    7475extern rtems_shell_cmd_t rtems_shell_RTC_Command;
    7576
     
    375376        defined(CONFIGURE_SHELL_COMMAND_DEBUGRFS)
    376377      &rtems_shell_DEBUGRFS_Command,
    377378    #endif
     379    #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \
     380         !defined(CONFIGURE_SHELL_NO_COMMAND_DF)) || \
     381        defined(CONFIGURE_SHELL_COMMAND_DF)
     382      &rtems_shell_DF_Command,
     383    #endif
    378384
    379385    /*
    380386     *  RTEMS Related commands