diff options
Diffstat (limited to 'cpukit/libfs/src/jffs2/src/fs-rtems.c')
-rw-r--r-- | cpukit/libfs/src/jffs2/src/fs-rtems.c | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c index ce84d44470..c8045dbed7 100644 --- a/cpukit/libfs/src/jffs2/src/fs-rtems.c +++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c @@ -4,7 +4,7 @@ * Copyright © 2001-2003 Free Software Foundation, Inc. * Copyright © 2001-2007 Red Hat, Inc. * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org> - * Copyright © 2013 embedded brains GmbH <rtems@embedded-brains.de> + * Copyright © 2013, 2016 embedded brains GmbH <rtems@embedded-brains.de> * * Created by Dominic Ostrowski <dominic.ostrowski@3glab.com> * Contributors: David Woodhouse, Nick Garnett, Richard Panton. @@ -512,12 +512,78 @@ static ssize_t rtems_jffs2_dir_read(rtems_libio_t *iop, void *buf, size_t len) } } +static uint32_t rtems_jffs2_count_blocks(const struct list_head *list) +{ + uint32_t count = 0; + struct jffs2_eraseblock *jeb; + + list_for_each_entry(jeb, list, list) { + ++count; + } + + return count; +} + +static void rtems_jffs2_get_info( + const struct jffs2_sb_info *c, + rtems_jffs2_info *info +) +{ + info->flash_size = c->flash_size; + info->flash_blocks = c->nr_blocks; + info->flash_block_size = c->sector_size; + info->used_size = c->used_size; + info->dirty_size = c->dirty_size; + info->wasted_size = c->wasted_size; + info->free_size = c->free_size; + info->bad_size = c->bad_size; + info->clean_blocks = rtems_jffs2_count_blocks(&c->clean_list); + info->dirty_blocks = rtems_jffs2_count_blocks(&c->very_dirty_list) + + rtems_jffs2_count_blocks(&c->dirty_list); + info->dirty_blocks += c->gcblock != NULL; + info->erasable_blocks = rtems_jffs2_count_blocks(&c->erasable_list) + + rtems_jffs2_count_blocks(&c->erasable_pending_wbuf_list) + + rtems_jffs2_count_blocks(&c->erasing_list) + + rtems_jffs2_count_blocks(&c->erase_checking_list) + + rtems_jffs2_count_blocks(&c->erase_pending_list) + + rtems_jffs2_count_blocks(&c->erase_complete_list); + info->free_blocks = rtems_jffs2_count_blocks(&c->free_list); + info->free_blocks += c->nextblock != NULL; + info->bad_blocks = rtems_jffs2_count_blocks(&c->bad_list); +} + +static int rtems_jffs2_ioctl( + rtems_libio_t *iop, + ioctl_command_t request, + void *buffer +) +{ + struct _inode *inode = rtems_jffs2_get_inode_by_iop(iop); + int eno; + + rtems_jffs2_do_lock(inode->i_sb); + + switch (request) { + case RTEMS_JFFS2_GET_INFO: + rtems_jffs2_get_info(&inode->i_sb->jffs2_sb, buffer); + eno = 0; + break; + default: + eno = EINVAL; + break; + } + + rtems_jffs2_do_unlock(inode->i_sb); + + return rtems_jffs2_eno_to_rv_and_errno(eno); +} + static const rtems_filesystem_file_handlers_r rtems_jffs2_directory_handlers = { .open_h = rtems_filesystem_default_open, .close_h = rtems_filesystem_default_close, .read_h = rtems_jffs2_dir_read, .write_h = rtems_filesystem_default_write, - .ioctl_h = rtems_filesystem_default_ioctl, + .ioctl_h = rtems_jffs2_ioctl, .lseek_h = rtems_filesystem_default_lseek_directory, .fstat_h = rtems_jffs2_fstat, .ftruncate_h = rtems_filesystem_default_ftruncate_directory, @@ -659,7 +725,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_file_handlers = { .close_h = rtems_filesystem_default_close, .read_h = rtems_jffs2_file_read, .write_h = rtems_jffs2_file_write, - .ioctl_h = rtems_filesystem_default_ioctl, + .ioctl_h = rtems_jffs2_ioctl, .lseek_h = rtems_filesystem_default_lseek_file, .fstat_h = rtems_jffs2_fstat, .ftruncate_h = rtems_jffs2_file_ftruncate, @@ -677,7 +743,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_link_handlers = { .close_h = rtems_filesystem_default_close, .read_h = rtems_filesystem_default_read, .write_h = rtems_filesystem_default_write, - .ioctl_h = rtems_filesystem_default_ioctl, + .ioctl_h = rtems_jffs2_ioctl, .lseek_h = rtems_filesystem_default_lseek, .fstat_h = rtems_jffs2_fstat, .ftruncate_h = rtems_filesystem_default_ftruncate, |