diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-05-07 16:31:15 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-05-11 13:58:43 +0200 |
commit | 3d0c96c7f34204aa4386cd9c1cd4a3e7977d52a0 (patch) | |
tree | 1fd0314bc888815401bead7e9c59cf9e15b7ae67 /cpukit/libfs/src/dosfs/msdos_file.c | |
parent | Filesystem: PR1871: Fix O_APPEND (diff) | |
download | rtems-3d0c96c7f34204aa4386cd9c1cd4a3e7977d52a0.tar.bz2 |
Filesystem: PR1893: Fix write and truncate handler
Space that grows due to truncate or write offsets beyond the current
file size must be zero filled.
Diffstat (limited to '')
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_file.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c index 6eb9b7953a..f68e44f948 100644 --- a/cpukit/libfs/src/dosfs/msdos_file.c +++ b/cpukit/libfs/src/dosfs/msdos_file.c @@ -203,7 +203,7 @@ msdos_file_stat( } /* msdos_file_ftruncate -- - * Truncate the file (if new length is greater then current do nothing). + * Truncate the file. * * PARAMETERS: * iop - file control block @@ -219,31 +219,38 @@ msdos_file_ftruncate(rtems_libio_t *iop, off_t length) rtems_status_code sc = RTEMS_SUCCESSFUL; msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; fat_file_fd_t *fat_fd = iop->pathinfo.node_access; - - if (length >= fat_fd->fat_file_size) - return RC_OK; + uint32_t old_length; 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); - rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; + old_length = fat_fd->fat_file_size; + if (length < old_length) { + rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length); + } else { + uint32_t new_length; + + rc = fat_file_extend(iop->pathinfo.mt_entry, + fat_fd, + true, + length, + &new_length); + if (rc == RC_OK && length != new_length) { + fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, old_length); + errno = ENOSPC; + rc = -1; + } } - /* - * fat_file_truncate do nothing if new length >= fat-file size, so update - * file size only if length < fat-file size - */ - if (length < fat_fd->fat_file_size) + if (rc == RC_OK) { fat_fd->fat_file_size = length; + } rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; + + return rc; } /* msdos_file_sync -- |