diff options
Diffstat (limited to 'cpukit/libfs/src/imfs/memfile.c')
-rw-r--r-- | cpukit/libfs/src/imfs/memfile.c | 63 |
1 files changed, 24 insertions, 39 deletions
diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c index d2cff01517..b2797875fc 100644 --- a/cpukit/libfs/src/imfs/memfile.c +++ b/cpukit/libfs/src/imfs/memfile.c @@ -33,6 +33,7 @@ */ MEMFILE_STATIC int IMFS_memfile_extend( IMFS_jnode_t *the_jnode, + bool zero_fill, off_t new_length ); @@ -92,7 +93,7 @@ int memfile_open( /* * Perform 'copy on write' for linear files */ - if ((iop->flags & (LIBIO_FLAGS_WRITE | LIBIO_FLAGS_APPEND)) + if ((iop->flags & LIBIO_FLAGS_WRITE) && (IMFS_type( the_jnode ) == IMFS_LINEAR_FILE)) { uint32_t count = the_jnode->info.linearfile.size; const unsigned char *buffer = the_jnode->info.linearfile.direct; @@ -106,10 +107,7 @@ int memfile_open( && (IMFS_memfile_write(the_jnode, 0, buffer, count) == -1)) return -1; } - if (iop->flags & LIBIO_FLAGS_APPEND) - iop->offset = the_jnode->info.file.size; - iop->size = the_jnode->info.file.size; return 0; } @@ -147,8 +145,10 @@ ssize_t memfile_write( the_jnode = iop->pathinfo.node_access; + if ((iop->flags & LIBIO_FLAGS_APPEND) != 0) + iop->offset = the_jnode->info.file.size; + status = IMFS_memfile_write( the_jnode, iop->offset, buffer, count ); - iop->size = the_jnode->info.file.size; return status; } @@ -170,34 +170,6 @@ int memfile_ioctl( } /* - * memfile_lseek - * - * This routine processes the lseek() system call. - */ -off_t memfile_lseek( - rtems_libio_t *iop, - off_t offset, - int whence -) -{ - IMFS_jnode_t *the_jnode; - - the_jnode = iop->pathinfo.node_access; - - if (IMFS_type( the_jnode ) == IMFS_LINEAR_FILE) { - if (iop->offset > the_jnode->info.linearfile.size) - iop->offset = the_jnode->info.linearfile.size; - } - else { /* Must be a block file (IMFS_MEMORY_FILE). */ - if (IMFS_memfile_extend( the_jnode, iop->offset )) - rtems_set_errno_and_return_minus_one( ENOSPC ); - - iop->size = the_jnode->info.file.size; - } - return iop->offset; -} - -/* * memfile_stat * * This IMFS_stat() can be used. @@ -224,7 +196,7 @@ int memfile_ftruncate( */ if ( length > the_jnode->info.file.size ) - return IMFS_memfile_extend( the_jnode, length ); + return IMFS_memfile_extend( the_jnode, true, length ); /* * The in-memory files do not currently reclaim memory until the file is @@ -232,7 +204,6 @@ int memfile_ftruncate( * future use and just set the length. */ the_jnode->info.file.size = length; - iop->size = the_jnode->info.file.size; IMFS_update_atime( the_jnode ); @@ -248,12 +219,14 @@ int memfile_ftruncate( */ MEMFILE_STATIC int IMFS_memfile_extend( IMFS_jnode_t *the_jnode, + bool zero_fill, off_t new_length ) { unsigned int block; unsigned int new_blocks; unsigned int old_blocks; + unsigned int offset; /* * Perform internal consistency checks @@ -265,7 +238,7 @@ MEMFILE_STATIC int IMFS_memfile_extend( * Verify new file size is supported */ if ( new_length >= IMFS_MEMFILE_MAXIMUM_SIZE ) - rtems_set_errno_and_return_minus_one( EINVAL ); + rtems_set_errno_and_return_minus_one( EFBIG ); /* * Verify new file size is actually larger than current size @@ -278,12 +251,22 @@ MEMFILE_STATIC int IMFS_memfile_extend( */ new_blocks = new_length / IMFS_MEMFILE_BYTES_PER_BLOCK; old_blocks = the_jnode->info.file.size / IMFS_MEMFILE_BYTES_PER_BLOCK; + offset = the_jnode->info.file.size - old_blocks * IMFS_MEMFILE_BYTES_PER_BLOCK; /* * Now allocate each of those blocks. */ for ( block=old_blocks ; block<=new_blocks ; block++ ) { - if ( IMFS_memfile_addblock( the_jnode, block ) ) { + if ( !IMFS_memfile_addblock( the_jnode, block ) ) { + if ( zero_fill ) { + size_t count = IMFS_MEMFILE_BYTES_PER_BLOCK - offset; + block_p *block_ptr = + IMFS_memfile_get_block_pointer( the_jnode, block, 0 ); + + memset( &(*block_ptr) [offset], 0, count); + offset = 0; + } + } else { for ( ; block>=old_blocks ; block-- ) { IMFS_memfile_remove_block( the_jnode, block ); } @@ -652,9 +635,11 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write( last_byte = start + my_length; if ( last_byte > the_jnode->info.file.size ) { - status = IMFS_memfile_extend( the_jnode, last_byte ); + bool zero_fill = start > the_jnode->info.file.size; + + status = IMFS_memfile_extend( the_jnode, zero_fill, last_byte ); if ( status ) - rtems_set_errno_and_return_minus_one( ENOSPC ); + return status; } copied = 0; |