forked from Imagelibrary/rtems
010-02-26 Chris Johns <chrisj@rtems.org>
* libfs/src/rfs/rtems-rfs-block.c: Reset a buffer handle after
moving down an indirection level.
* libfs/src/rfs/rtems-rfs-dir.c: Move directory entry validation
into a macro and use the macro. Fix the range check on the ino so
all inodes can be used.
* libfs/src/rfs/rtems-rfs-file-system.c,
libfs/src/rfs/rtems-rfs-file-system.h:: Add a version number to
the superblock. Use RTEMS_RFS_INODE_SIZE.
* libfs/src/rfs/rtems-rfs-file.c: Fix the size offset on partial
block lengths. Set the size in the file handle on a truncate to
0.
* libfs/src/rfs/rtems-rfs-format.c: Add a version number to
the superblock. Use RTEMS_RFS_INODE_SIZE. A better set of defaults
for small disks.
* libfs/src/rfs/rtems-rfs-inode.c: Use RTEMS_RFS_INODE_SIZE. Free
the allocated inode if it cannot be opened.
* libfs/src/rfs/rtems-rfs-inode.h: Add RTEMS_RFS_INODE_SIZE.
* libfs/src/rfs/rtems-rfs-rtems-file.c: Move some of the iop
acceses inside the fs lock.
* libfs/src/rfs/rtems-rfs-shell.c: Use RTEMS_RFS_INODE_SIZE.
This commit is contained in:
@@ -1,3 +1,34 @@
|
||||
2010-02-26 Chris Johns <chrisj@rtems.org>
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-block.c: Reset a buffer handle after
|
||||
moving down an indirection level.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-dir.c: Move directory entry validation
|
||||
into a macro and use the macro. Fix the range check on the ino so
|
||||
all inodes can be used.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-file-system.c,
|
||||
libfs/src/rfs/rtems-rfs-file-system.h:: Add a version number to
|
||||
the superblock. Use RTEMS_RFS_INODE_SIZE.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-file.c: Fix the size offset on partial
|
||||
block lengths. Set the size in the file handle on a truncate to
|
||||
0.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-format.c: Add a version number to
|
||||
the superblock. Use RTEMS_RFS_INODE_SIZE. A better set of defaults
|
||||
for small disks.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-inode.c: Use RTEMS_RFS_INODE_SIZE. Free
|
||||
the allocated inode if it cannot be opened.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-inode.h: Add RTEMS_RFS_INODE_SIZE.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-rtems-file.c: Move some of the iop
|
||||
acceses inside the fs lock.
|
||||
|
||||
* libfs/src/rfs/rtems-rfs-shell.c: Use RTEMS_RFS_INODE_SIZE.
|
||||
|
||||
2010-02-24 Chris Johns <chrisj@rtems.org>
|
||||
|
||||
* libmisc/shell/main_msdosfmt.c, libmisc/shell/shellconfig.h: Fix
|
||||
|
||||
@@ -626,6 +626,8 @@ rtems_rfs_block_map_indirect_shrink (rtems_rfs_file_system* fs,
|
||||
int b;
|
||||
for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++)
|
||||
map->blocks[b] = rtems_rfs_block_get_number (buffer, b);
|
||||
|
||||
rtems_rfs_buffer_handle_reset (buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
#include <rtems/rfs/rtems-rfs-dir.h>
|
||||
#include <rtems/rfs/rtems-rfs-dir-hash.h>
|
||||
|
||||
/**
|
||||
* Validate the directory entry data.
|
||||
*/
|
||||
#define rtems_rfs_dir_entry_valid(_f, _l, _i) \
|
||||
(((_l) <= RTEMS_RFS_DIR_ENTRY_SIZE) || ((_l) >= rtems_rfs_fs_max_name (_f)) \
|
||||
|| (_i < RTEMS_RFS_ROOT_INO) || (_i > rtems_rfs_fs_inodes (_f)))
|
||||
|
||||
int
|
||||
rtems_rfs_dir_lookup_ino (rtems_rfs_file_system* fs,
|
||||
rtems_rfs_inode_handle* inode,
|
||||
@@ -136,10 +143,7 @@ rtems_rfs_dir_lookup_ino (rtems_rfs_file_system* fs,
|
||||
if (elength == RTEMS_RFS_DIR_ENTRY_EMPTY)
|
||||
break;
|
||||
|
||||
if ((elength <= RTEMS_RFS_DIR_ENTRY_SIZE)
|
||||
|| (elength >= rtems_rfs_fs_max_name (fs))
|
||||
|| (*ino < RTEMS_RFS_ROOT_INO)
|
||||
|| (*ino >= rtems_rfs_fs_inodes (fs)))
|
||||
if (rtems_rfs_dir_entry_valid (fs, elength, *ino))
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_DIR_LOOKUP_INO))
|
||||
printf ("rtems-rfs: dir-lookup-ino: " \
|
||||
@@ -331,10 +335,7 @@ rtems_rfs_dir_add_entry (rtems_rfs_file_system* fs,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((elength <= RTEMS_RFS_DIR_ENTRY_SIZE)
|
||||
|| (elength >= rtems_rfs_fs_max_name (fs))
|
||||
|| (eino < RTEMS_RFS_ROOT_INO)
|
||||
|| (eino >= rtems_rfs_fs_inodes (fs)))
|
||||
if (rtems_rfs_dir_entry_valid (fs, elength, eino))
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_DIR_ADD_ENTRY))
|
||||
printf ("rtems-rfs: dir-add-entry: " \
|
||||
@@ -425,10 +426,7 @@ rtems_rfs_dir_del_entry (rtems_rfs_file_system* fs,
|
||||
if (elength == RTEMS_RFS_DIR_ENTRY_EMPTY)
|
||||
break;
|
||||
|
||||
if ((elength <= RTEMS_RFS_DIR_ENTRY_SIZE)
|
||||
|| (elength >= rtems_rfs_fs_max_name (fs))
|
||||
|| (eino < RTEMS_RFS_ROOT_INO)
|
||||
|| (eino >= rtems_rfs_fs_inodes (fs)))
|
||||
if (rtems_rfs_dir_entry_valid (fs, elength, eino))
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_DIR_DEL_ENTRY))
|
||||
printf ("rtems-rfs: dir-del-entry: " \
|
||||
@@ -572,10 +570,7 @@ rtems_rfs_dir_read (rtems_rfs_file_system* fs,
|
||||
|
||||
if (elength != RTEMS_RFS_DIR_ENTRY_EMPTY)
|
||||
{
|
||||
if ((elength <= RTEMS_RFS_DIR_ENTRY_SIZE)
|
||||
|| (elength >= rtems_rfs_fs_max_name (fs))
|
||||
|| (eino < RTEMS_RFS_ROOT_INO)
|
||||
|| (eino >= rtems_rfs_fs_inodes (fs)))
|
||||
if (rtems_rfs_dir_entry_valid (fs, elength, eino))
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_DIR_READ))
|
||||
printf ("rtems-rfs: dir-read: " \
|
||||
@@ -690,10 +685,7 @@ rtems_rfs_dir_empty (rtems_rfs_file_system* fs,
|
||||
if (elength == RTEMS_RFS_DIR_ENTRY_EMPTY)
|
||||
break;
|
||||
|
||||
if ((elength <= RTEMS_RFS_DIR_ENTRY_SIZE)
|
||||
|| (elength >= rtems_rfs_fs_max_name (fs))
|
||||
|| (eino < RTEMS_RFS_ROOT_INO)
|
||||
|| (eino >= rtems_rfs_fs_inodes (fs)))
|
||||
if (rtems_rfs_dir_entry_valid (fs, elength, eino))
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_DIR_EMPTY))
|
||||
printf ("rtems-rfs: dir-empty: " \
|
||||
|
||||
@@ -54,9 +54,9 @@ rtems_rfs_fs_read_superblock (rtems_rfs_file_system* fs)
|
||||
|
||||
if (read_sb (RTEMS_RFS_SB_OFFSET_MAGIC) != RTEMS_RFS_SB_MAGIC)
|
||||
{
|
||||
rtems_rfs_buffer_handle_close (fs, &handle);
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
|
||||
printf ("rtems-rfs: read-superblock: invalid superblock, bad magic\n");
|
||||
rtems_rfs_buffer_handle_close (fs, &handle);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
@@ -65,19 +65,39 @@ rtems_rfs_fs_read_superblock (rtems_rfs_file_system* fs)
|
||||
|
||||
if (rtems_rfs_fs_size(fs) > rtems_rfs_fs_media_size (fs))
|
||||
{
|
||||
rtems_rfs_buffer_handle_close (fs, &handle);
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
|
||||
printf ("rtems-rfs: read-superblock: invalid superblock block/size count\n");
|
||||
rtems_rfs_buffer_handle_close (fs, &handle);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if ((read_sb (RTEMS_RFS_SB_OFFSET_VERSION) & RTEMS_RFS_VERSION_MASK) !=
|
||||
(RTEMS_RFS_VERSION * RTEMS_RFS_VERSION_MASK))
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
|
||||
printf ("rtems-rfs: read-superblock: incompatible version: %08x (%08x)\n",
|
||||
read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
|
||||
rtems_rfs_buffer_handle_close (fs, &handle);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
if (read_sb (RTEMS_RFS_SB_OFFSET_INODE_SIZE) != RTEMS_RFS_INODE_SIZE)
|
||||
{
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
|
||||
printf ("rtems-rfs: read-superblock: inode size mismatch: fs:%d target:%d\n",
|
||||
read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
|
||||
rtems_rfs_buffer_handle_close (fs, &handle);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
fs->bad_blocks = read_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS);
|
||||
fs->max_name_length = read_sb (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH);
|
||||
fs->group_count = read_sb (RTEMS_RFS_SB_OFFSET_GROUPS);
|
||||
fs->group_blocks = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS);
|
||||
fs->group_inodes = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES);
|
||||
|
||||
fs->blocks_per_block = rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode_block);
|
||||
fs->blocks_per_block =
|
||||
rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode_block);
|
||||
|
||||
fs->block_map_singly_blocks =
|
||||
fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
|
||||
@@ -86,7 +106,7 @@ rtems_rfs_fs_read_superblock (rtems_rfs_file_system* fs)
|
||||
|
||||
fs->inodes = fs->group_count * fs->group_inodes;
|
||||
|
||||
fs->inodes_per_block = fs->block_size / sizeof (rtems_rfs_inode);
|
||||
fs->inodes_per_block = fs->block_size / RTEMS_RFS_INODE_SIZE;
|
||||
|
||||
if (fs->group_blocks >
|
||||
rtems_rfs_bitmap_numof_bits (rtems_rfs_fs_block_size (fs)))
|
||||
|
||||
@@ -27,13 +27,26 @@
|
||||
*/
|
||||
#define RTEMS_RFS_SB_OFFSET_MAGIC (0)
|
||||
#define RTEMS_RFS_SB_MAGIC (0x28092001)
|
||||
#define RTEMS_RFS_SB_OFFSET_BLOCK_SIZE (4)
|
||||
#define RTEMS_RFS_SB_OFFSET_BLOCKS (8)
|
||||
#define RTEMS_RFS_SB_OFFSET_BAD_BLOCKS (12)
|
||||
#define RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH (16)
|
||||
#define RTEMS_RFS_SB_OFFSET_GROUPS (20)
|
||||
#define RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS (24)
|
||||
#define RTEMS_RFS_SB_OFFSET_GROUP_INODES (28)
|
||||
#define RTEMS_RFS_SB_OFFSET_VERSION (RTEMS_RFS_SB_OFFSET_MAGIC + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_BLOCK_SIZE (RTEMS_RFS_SB_OFFSET_VERSION + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_BLOCKS (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_BAD_BLOCKS (RTEMS_RFS_SB_OFFSET_BLOCKS + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_GROUPS (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS (RTEMS_RFS_SB_OFFSET_GROUPS + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_GROUP_INODES (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS + 4)
|
||||
#define RTEMS_RFS_SB_OFFSET_INODE_SIZE (RTEMS_RFS_SB_OFFSET_GROUP_INODES + 4)
|
||||
|
||||
/**
|
||||
* RFS Version Number.
|
||||
*/
|
||||
#define RTEMS_RFS_VERSION (0x00000000)
|
||||
|
||||
/**
|
||||
* RFS Version Number Mask. The mask determines which bits of the version
|
||||
* number indicate compatility issues.
|
||||
*/
|
||||
#define RTEMS_RFS_VERSION_MASK (0x00000000)
|
||||
|
||||
/**
|
||||
* The root inode number. Do not use 0 as this has special meaning in some Unix
|
||||
|
||||
@@ -275,7 +275,9 @@ rtems_rfs_file_io_start (rtems_rfs_file_handle* handle,
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (read && rtems_rfs_block_map_last (rtems_rfs_file_map (handle)))
|
||||
if (read
|
||||
&& rtems_rfs_block_map_last (rtems_rfs_file_map (handle))
|
||||
&& rtems_rfs_block_map_size_offset (rtems_rfs_file_map (handle)))
|
||||
size = rtems_rfs_block_map_size_offset (rtems_rfs_file_map (handle));
|
||||
else
|
||||
size = rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle));
|
||||
@@ -419,6 +421,7 @@ rtems_rfs_file_set_size (rtems_rfs_file_handle* handle,
|
||||
{
|
||||
rtems_rfs_block_map* map = rtems_rfs_file_map (handle);
|
||||
rtems_rfs_pos size;
|
||||
int rc;
|
||||
|
||||
if (rtems_rfs_trace (RTEMS_RFS_TRACE_FILE_IO))
|
||||
printf ("rtems-rfs: file-set-size: size=%Lu\n", new_size);
|
||||
@@ -427,131 +430,136 @@ rtems_rfs_file_set_size (rtems_rfs_file_handle* handle,
|
||||
* Short cut for the common truncate on open call.
|
||||
*/
|
||||
if (new_size == 0)
|
||||
return rtems_rfs_block_map_free_all (rtems_rfs_file_fs (handle), map);
|
||||
|
||||
size = rtems_rfs_file_size (handle);
|
||||
|
||||
/*
|
||||
* If the file is same size do nothing else grow or shrink it ?
|
||||
*/
|
||||
if (size != new_size)
|
||||
{
|
||||
if (size < new_size)
|
||||
rc = rtems_rfs_block_map_free_all (rtems_rfs_file_fs (handle), map);
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = rtems_rfs_file_size (handle);
|
||||
|
||||
/*
|
||||
* If the file is same size do nothing else grow or shrink it ?
|
||||
*/
|
||||
if (size != new_size)
|
||||
{
|
||||
/*
|
||||
* Grow. Fill with 0's.
|
||||
*/
|
||||
rtems_rfs_pos count;
|
||||
uint32_t length;
|
||||
bool read_block;
|
||||
|
||||
count = new_size - size;
|
||||
length = rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle));
|
||||
read_block = false;
|
||||
|
||||
while (count)
|
||||
if (size < new_size)
|
||||
{
|
||||
rtems_rfs_buffer_block block;
|
||||
rtems_rfs_block_pos bpos;
|
||||
uint8_t* dst;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Get the block position for the current end of the file as seen by
|
||||
* the map. If not found and the EOF grow the map then fill the block
|
||||
* with 0.
|
||||
* Grow. Fill with 0's.
|
||||
*/
|
||||
rtems_rfs_block_size_get_bpos (rtems_rfs_block_map_size (map), &bpos);
|
||||
rc = rtems_rfs_block_map_find (rtems_rfs_file_fs (handle),
|
||||
map, &bpos, &block);
|
||||
if (rc > 0)
|
||||
rtems_rfs_pos count;
|
||||
uint32_t length;
|
||||
bool read_block;
|
||||
|
||||
count = new_size - size;
|
||||
length = rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle));
|
||||
read_block = false;
|
||||
|
||||
while (count)
|
||||
{
|
||||
rtems_rfs_buffer_block block;
|
||||
rtems_rfs_block_pos bpos;
|
||||
uint8_t* dst;
|
||||
|
||||
/*
|
||||
* Have we reached the EOF ?
|
||||
* Get the block position for the current end of the file as seen by
|
||||
* the map. If not found and the EOF grow the map then fill the block
|
||||
* with 0.
|
||||
*/
|
||||
if (rc != ENXIO)
|
||||
rtems_rfs_block_size_get_bpos (rtems_rfs_block_map_size (map), &bpos);
|
||||
rc = rtems_rfs_block_map_find (rtems_rfs_file_fs (handle),
|
||||
map, &bpos, &block);
|
||||
if (rc > 0)
|
||||
{
|
||||
/*
|
||||
* Have we reached the EOF ?
|
||||
*/
|
||||
if (rc != ENXIO)
|
||||
return rc;
|
||||
|
||||
rc = rtems_rfs_block_map_grow (rtems_rfs_file_fs (handle),
|
||||
map, 1, &block);
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (count < (length - bpos.boff))
|
||||
{
|
||||
length = count + bpos.boff;
|
||||
read_block = true;
|
||||
rtems_rfs_block_map_set_size_offset (map, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_rfs_block_map_set_size_offset (map, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only read the block if the length is not the block size.
|
||||
*/
|
||||
rc = rtems_rfs_buffer_handle_request (rtems_rfs_file_fs (handle),
|
||||
rtems_rfs_file_buffer (handle),
|
||||
block, read_block);
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
|
||||
rc = rtems_rfs_block_map_grow (rtems_rfs_file_fs (handle),
|
||||
map, 1, &block);
|
||||
dst = rtems_rfs_buffer_data (&handle->buffer);
|
||||
memset (dst + bpos.boff, 0, length - bpos.boff);
|
||||
|
||||
rtems_rfs_buffer_mark_dirty (rtems_rfs_file_buffer (handle));
|
||||
|
||||
rc = rtems_rfs_buffer_handle_release (rtems_rfs_file_fs (handle),
|
||||
rtems_rfs_file_buffer (handle));
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
|
||||
count -= length - bpos.boff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Shrink
|
||||
*/
|
||||
rtems_rfs_block_no blocks;
|
||||
uint32_t offset;
|
||||
|
||||
blocks =
|
||||
rtems_rfs_block_map_count (map) -
|
||||
(((new_size - 1) /
|
||||
rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle))) + 1);
|
||||
|
||||
offset =
|
||||
new_size % rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle));
|
||||
|
||||
if (blocks)
|
||||
{
|
||||
int rc;
|
||||
rc = rtems_rfs_block_map_shrink (rtems_rfs_file_fs (handle),
|
||||
rtems_rfs_file_map (handle),
|
||||
blocks);
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (count < (length - bpos.boff))
|
||||
{
|
||||
length = count + bpos.boff;
|
||||
read_block = true;
|
||||
rtems_rfs_block_map_set_size_offset (map, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_rfs_block_map_set_size_offset (map, 0);
|
||||
}
|
||||
rtems_rfs_block_map_set_size_offset (map, offset);
|
||||
|
||||
/*
|
||||
* Only read the block if the length is not the block size.
|
||||
*/
|
||||
rc = rtems_rfs_buffer_handle_request (rtems_rfs_file_fs (handle),
|
||||
rtems_rfs_file_buffer (handle),
|
||||
block, read_block);
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
|
||||
dst = rtems_rfs_buffer_data (&handle->buffer);
|
||||
memset (dst + bpos.boff, 0, length - bpos.boff);
|
||||
|
||||
rtems_rfs_buffer_mark_dirty (rtems_rfs_file_buffer (handle));
|
||||
|
||||
rc = rtems_rfs_buffer_handle_release (rtems_rfs_file_fs (handle),
|
||||
rtems_rfs_file_buffer (handle));
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
|
||||
count -= length - bpos.boff;
|
||||
if (rtems_rfs_block_pos_past_end (rtems_rfs_file_bpos (handle),
|
||||
rtems_rfs_block_map_size (map)))
|
||||
rtems_rfs_block_size_get_bpos (rtems_rfs_block_map_size (map),
|
||||
rtems_rfs_file_bpos (handle));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Shrink
|
||||
*/
|
||||
rtems_rfs_block_no blocks;
|
||||
uint32_t offset;
|
||||
|
||||
blocks =
|
||||
rtems_rfs_block_map_count (map) -
|
||||
(((new_size - 1) /
|
||||
rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle))) + 1);
|
||||
|
||||
offset =
|
||||
new_size % rtems_rfs_fs_block_size (rtems_rfs_file_fs (handle));
|
||||
|
||||
if (blocks)
|
||||
{
|
||||
int rc;
|
||||
rc = rtems_rfs_block_map_shrink (rtems_rfs_file_fs (handle),
|
||||
rtems_rfs_file_map (handle),
|
||||
blocks);
|
||||
if (rc > 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rtems_rfs_block_map_set_size_offset (map, offset);
|
||||
|
||||
if (rtems_rfs_block_pos_past_end (rtems_rfs_file_bpos (handle),
|
||||
rtems_rfs_block_map_size (map)))
|
||||
rtems_rfs_block_size_get_bpos (rtems_rfs_block_map_size (map),
|
||||
rtems_rfs_file_bpos (handle));
|
||||
}
|
||||
|
||||
handle->shared->size.count = rtems_rfs_block_map_count (map);
|
||||
handle->shared->size.offset = rtems_rfs_block_map_size_offset (map);
|
||||
|
||||
if (rtems_rfs_file_update_mtime (handle))
|
||||
handle->shared->mtime = time (NULL);
|
||||
}
|
||||
|
||||
|
||||
handle->shared->size.count = rtems_rfs_block_map_count (map);
|
||||
handle->shared->size.offset = rtems_rfs_block_map_size_offset (map);
|
||||
|
||||
if (rtems_rfs_file_update_mtime (handle))
|
||||
handle->shared->mtime = time (NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,10 @@ rtems_rfs_inodes_from_percent (rtems_rfs_file_system* fs,
|
||||
int percentage)
|
||||
{
|
||||
int blocks;
|
||||
blocks = (rtems_rfs_bits_per_block (fs) * percentage) / 100;
|
||||
return blocks * (rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode));
|
||||
blocks = ((rtems_rfs_fs_blocks (fs) -
|
||||
RTEMS_RFS_SUPERBLOCK_SIZE) * percentage) / 100;
|
||||
blocks = rtems_rfs_rup_quotient (blocks, fs->group_count);
|
||||
return blocks * (rtems_rfs_fs_block_size (fs) / RTEMS_RFS_INODE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,9 +74,17 @@ static int
|
||||
rtems_rfs_inode_overhead (rtems_rfs_file_system* fs)
|
||||
{
|
||||
int blocks;
|
||||
blocks =
|
||||
(fs->group_inodes * sizeof (rtems_rfs_inode)) / rtems_rfs_fs_block_size (fs);
|
||||
return ((blocks + 1) * 100 * 10) / rtems_rfs_bits_per_block (fs);
|
||||
int bits_per_block;
|
||||
blocks = rtems_rfs_rup_quotient(fs->group_inodes * RTEMS_RFS_INODE_SIZE,
|
||||
rtems_rfs_fs_block_size (fs));
|
||||
bits_per_block = rtems_rfs_bits_per_block (fs);
|
||||
/*
|
||||
* There could be more bits that there are blocks, eg 512K disk with 512
|
||||
* blocks.
|
||||
*/
|
||||
if (bits_per_block > (rtems_rfs_fs_blocks (fs) - RTEMS_RFS_SUPERBLOCK_SIZE))
|
||||
bits_per_block = rtems_rfs_fs_blocks (fs) - RTEMS_RFS_SUPERBLOCK_SIZE;
|
||||
return ((blocks + 1) * 100 * 10) / bits_per_block;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -86,7 +96,7 @@ rtems_rfs_check_config (rtems_rfs_file_system* fs,
|
||||
{
|
||||
uint64_t total_size = rtems_rfs_fs_media_size (fs);
|
||||
|
||||
if (total_size > GIGS (2))
|
||||
if (total_size >= GIGS (1))
|
||||
{
|
||||
uint32_t gigs = (total_size + GIGS (1)) / GIGS (1);
|
||||
int b;
|
||||
@@ -96,8 +106,8 @@ rtems_rfs_check_config (rtems_rfs_file_system* fs,
|
||||
fs->block_size = 1 << b;
|
||||
}
|
||||
|
||||
if (fs->block_size < 1024)
|
||||
fs->block_size = 1024;
|
||||
if (fs->block_size < 512)
|
||||
fs->block_size = 512;
|
||||
|
||||
if (fs->block_size > (4 * 1024))
|
||||
fs->block_size = (4 * 1024);
|
||||
@@ -126,6 +136,16 @@ rtems_rfs_check_config (rtems_rfs_file_system* fs,
|
||||
return false;
|
||||
}
|
||||
|
||||
fs->blocks = rtems_rfs_fs_media_size (fs) / fs->block_size;
|
||||
|
||||
/*
|
||||
* The bits per block sets the upper limit for the number of blocks in a
|
||||
* group. The disk will be divided into groups which are the number of bits
|
||||
* per block.
|
||||
*/
|
||||
fs->group_count = rtems_rfs_rup_quotient (rtems_rfs_fs_blocks (fs),
|
||||
rtems_rfs_bits_per_block (fs));
|
||||
|
||||
fs->group_inodes = config->group_inodes;
|
||||
if (!fs->group_inodes)
|
||||
{
|
||||
@@ -143,7 +163,7 @@ rtems_rfs_check_config (rtems_rfs_file_system* fs,
|
||||
/*
|
||||
* Round up to fill a block because the minimum allocation unit is a block.
|
||||
*/
|
||||
fs->inodes_per_block = rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode);
|
||||
fs->inodes_per_block = rtems_rfs_fs_block_size (fs) / RTEMS_RFS_INODE_SIZE;
|
||||
fs->group_inodes =
|
||||
rtems_rfs_rup_quotient (fs->group_inodes,
|
||||
fs->inodes_per_block) * fs->inodes_per_block;
|
||||
@@ -398,6 +418,7 @@ rtems_rfs_write_superblock (rtems_rfs_file_system* fs)
|
||||
memset (sb, 0xff, rtems_rfs_fs_block_size (fs));
|
||||
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_MAGIC, RTEMS_RFS_SB_MAGIC);
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_VERSION, RTEMS_RFS_VERSION);
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_BLOCKS, rtems_rfs_fs_blocks (fs));
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE, rtems_rfs_fs_block_size (fs));
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS, fs->bad_blocks);
|
||||
@@ -405,6 +426,7 @@ rtems_rfs_write_superblock (rtems_rfs_file_system* fs)
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_GROUPS, fs->group_count);
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS, fs->group_blocks);
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES, fs->group_inodes);
|
||||
write_sb (RTEMS_RFS_SB_OFFSET_INODE_SIZE, RTEMS_RFS_INODE_SIZE);
|
||||
|
||||
rtems_rfs_buffer_mark_dirty (&handle);
|
||||
|
||||
@@ -549,16 +571,6 @@ rtems_rfs_format (const char* name, const rtems_rfs_format_config* config)
|
||||
if (!rtems_rfs_check_config (&fs, config))
|
||||
return -1;
|
||||
|
||||
fs.blocks = rtems_rfs_fs_media_size (&fs) / fs.block_size;
|
||||
|
||||
/*
|
||||
* The bits per block sets the upper limit for the number of blocks in a
|
||||
* group. The disk will be divided into groups which are the number of bits
|
||||
* per block.
|
||||
*/
|
||||
fs.group_count =
|
||||
((rtems_rfs_fs_blocks (&fs) - 1) / rtems_rfs_bits_per_block (&fs)) + 1;
|
||||
|
||||
if (config->verbose)
|
||||
{
|
||||
printf ("rtems-rfs: format: media size = %llu\n",
|
||||
@@ -575,7 +587,7 @@ rtems_rfs_format (const char* name, const rtems_rfs_format_config* config)
|
||||
rtems_rfs_fs_block_size (&fs));
|
||||
printf ("rtems-rfs: format: bits per block = %u\n",
|
||||
rtems_rfs_bits_per_block (&fs));
|
||||
printf ("rtems-rfs: format: inode size = %lu\n", sizeof (rtems_rfs_inode));
|
||||
printf ("rtems-rfs: format: inode size = %lu\n", RTEMS_RFS_INODE_SIZE);
|
||||
printf ("rtems-rfs: format: inodes = %lu (%d.%d%%)\n",
|
||||
fs.group_inodes * fs.group_count,
|
||||
rtems_rfs_inode_overhead (&fs) / 10,
|
||||
|
||||
@@ -211,8 +211,11 @@ rtems_rfs_inode_create (rtems_rfs_file_system* fs,
|
||||
|
||||
rc = rtems_rfs_inode_open (fs, *ino, &inode, true);
|
||||
if (rc > 0)
|
||||
{
|
||||
rtems_rfs_inode_free (fs, *ino);
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
rc = rtems_rfs_inode_initialise (&inode, links, mode, uid, gid);
|
||||
if (rc > 0)
|
||||
{
|
||||
@@ -223,6 +226,8 @@ rtems_rfs_inode_create (rtems_rfs_file_system* fs,
|
||||
|
||||
/*
|
||||
* Only handle the specifics of a directory. Let caller handle the others.
|
||||
*
|
||||
* The inode delete will free the inode.
|
||||
*/
|
||||
if (RTEMS_RFS_S_ISDIR (mode))
|
||||
{
|
||||
@@ -307,7 +312,7 @@ rtems_rfs_inode_delete (rtems_rfs_file_system* fs,
|
||||
rc = rtems_rfs_block_map_close (fs, &map);
|
||||
if (rc > 0)
|
||||
rrc = rc;
|
||||
memset (handle->node, 0xff, sizeof (rtems_rfs_inode));
|
||||
memset (handle->node, 0xff, RTEMS_RFS_INODE_SIZE);
|
||||
rtems_rfs_buffer_mark_dirty (&handle->buffer);
|
||||
/*
|
||||
* Do the release here to avoid the ctime field being set on a
|
||||
|
||||
@@ -168,6 +168,11 @@ typedef struct rtems_rfs_inode_t
|
||||
|
||||
} rtems_rfs_inode;
|
||||
|
||||
/**
|
||||
* The size of an inode.
|
||||
*/
|
||||
#define RTEMS_RFS_INODE_SIZE (sizeof (rtems_rfs_inode))
|
||||
|
||||
/**
|
||||
* RFS Inode Handle.
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,7 @@ rtems_rfs_rtems_file_open (rtems_libio_t* iop,
|
||||
uint32_t mode)
|
||||
{
|
||||
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
|
||||
rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop);
|
||||
rtems_rfs_ino ino;
|
||||
rtems_rfs_file_handle* file;
|
||||
uint32_t flags;
|
||||
int rc;
|
||||
@@ -52,6 +52,8 @@ rtems_rfs_rtems_file_open (rtems_libio_t* iop,
|
||||
|
||||
rtems_rfs_rtems_lock (fs);
|
||||
|
||||
ino = rtems_rfs_rtems_get_iop_ino (iop);
|
||||
|
||||
rc = rtems_rfs_file_open (fs, ino, flags, &file);
|
||||
if (rc > 0)
|
||||
{
|
||||
@@ -109,7 +111,7 @@ rtems_rfs_rtems_file_read (rtems_libio_t* iop,
|
||||
size_t count)
|
||||
{
|
||||
rtems_rfs_file_handle* file = iop->file_info;
|
||||
rtems_rfs_pos pos = iop->offset;
|
||||
rtems_rfs_pos pos;
|
||||
uint8_t* data = buffer;
|
||||
ssize_t read = 0;
|
||||
int rc;
|
||||
@@ -119,6 +121,8 @@ rtems_rfs_rtems_file_read (rtems_libio_t* iop,
|
||||
|
||||
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
|
||||
|
||||
pos = iop->offset;
|
||||
|
||||
if (pos < rtems_rfs_file_size (file))
|
||||
{
|
||||
while (count)
|
||||
@@ -172,7 +176,7 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop,
|
||||
size_t count)
|
||||
{
|
||||
rtems_rfs_file_handle* file = iop->file_info;
|
||||
rtems_rfs_pos pos = iop->offset;
|
||||
rtems_rfs_pos pos;
|
||||
const uint8_t* data = buffer;
|
||||
ssize_t write = 0;
|
||||
int rc;
|
||||
@@ -182,6 +186,8 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop,
|
||||
|
||||
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
|
||||
|
||||
pos = iop->offset;
|
||||
|
||||
/*
|
||||
* If the iop position is past the physical end of the file we need to set the
|
||||
* file size to the new length before writing.
|
||||
@@ -266,10 +272,10 @@ rtems_rfs_rtems_file_lseek (rtems_libio_t* iop,
|
||||
if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK))
|
||||
printf("rtems-rfs: file-lseek: handle:%p offset:%Ld\n", file, offset);
|
||||
|
||||
pos = iop->offset;
|
||||
|
||||
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
|
||||
|
||||
pos = iop->offset;
|
||||
|
||||
rc = rtems_rfs_file_seek (file, pos, &pos);
|
||||
if (rc)
|
||||
{
|
||||
@@ -300,7 +306,7 @@ rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop,
|
||||
printf("rtems-rfs: file-ftrunc: handle:%p length:%Ld\n", file, length);
|
||||
|
||||
rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
|
||||
|
||||
|
||||
rc = rtems_rfs_file_set_size (file, length);
|
||||
if (rc)
|
||||
rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc);
|
||||
|
||||
@@ -114,7 +114,6 @@ rtems_rfs_shell_data (rtems_rfs_file_system* fs, int argc, char *argv[])
|
||||
size_t inodes;
|
||||
int bpcent;
|
||||
int ipcent;
|
||||
int g;
|
||||
|
||||
printf ("RFS Filesystem Data\n");
|
||||
printf (" flags: %08lx\n", fs->flags);
|
||||
@@ -367,7 +366,7 @@ rtems_rfs_shell_inode (rtems_rfs_file_system* fs, int argc, char *argv[])
|
||||
{
|
||||
printf (" %5lu: pos=%06lu:%04lx %c ",
|
||||
ino, rtems_rfs_buffer_bnum (&inode.buffer),
|
||||
inode.offset * sizeof (rtems_rfs_inode),
|
||||
inode.offset * RTEMS_RFS_INODE_SIZE,
|
||||
allocated ? 'A' : 'F');
|
||||
|
||||
if (!allocated && !forced)
|
||||
|
||||
Reference in New Issue
Block a user