Remove forced overwrite which leads to file data corruption. The logic to determine a forced overwrite was fundamentally broken. For simplity, disable this feature.
Update #2622. --- cpukit/libfs/src/dosfs/fat.c | 15 +++++---------- cpukit/libfs/src/dosfs/fat.h | 3 +-- cpukit/libfs/src/dosfs/fat_file.c | 23 +++++------------------ testsuites/fstests/fsdosfswrite01/init.c | 26 ++++++++++++++++++++------ 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/cpukit/libfs/src/dosfs/fat.c b/cpukit/libfs/src/dosfs/fat.c index 2176ff3..a0475d4 100644 --- a/cpukit/libfs/src/dosfs/fat.c +++ b/cpukit/libfs/src/dosfs/fat.c @@ -200,13 +200,12 @@ _fat_block_read( } static ssize_t - fat_block_write( +fat_block_write( fat_fs_info_t *fs_info, const uint32_t start_blk, const uint32_t offset, const uint32_t count, - const void *buf, - const bool overwrite_block) + const void *buf) { int rc = RC_OK; uint32_t bytes_to_write = MIN(count, (fs_info->vol.bytes_per_block - offset)); @@ -215,8 +214,7 @@ static ssize_t if (0 < bytes_to_write) { - if ( overwrite_block - || (bytes_to_write == fs_info->vol.bytes_per_block)) + if (bytes_to_write == fs_info->vol.bytes_per_block) { rc = fat_buf_access(fs_info, sec_num, FAT_OP_TYPE_GET, &blk_buf); } @@ -399,7 +397,6 @@ _fat_block_release(fat_fs_info_t *fs_info) * offset - offset inside cluster 'start' * count - count of bytes to write * buff - buffer provided by user - * overwrite_cluster - true if cluster can get overwritten, false if cluster content must be kept * * RETURNS: * bytes written on success, or -1 if error occured @@ -411,8 +408,7 @@ fat_cluster_write( const uint32_t start_cln, const uint32_t offset, const uint32_t count, - const void *buff, - const bool overwrite_cluster) + const void *buff) { ssize_t rc = RC_OK; uint32_t bytes_to_write = MIN(count, (fs_info->vol.bpc - offset)); @@ -436,8 +432,7 @@ fat_cluster_write( cur_blk, ofs_blk, c, - &buffer[bytes_written], - overwrite_cluster); + &buffer[bytes_written]); if (c != ret) rc = -1; else diff --git a/cpukit/libfs/src/dosfs/fat.h b/cpukit/libfs/src/dosfs/fat.h index 8fcd17f..1cbf9a7 100644 --- a/cpukit/libfs/src/dosfs/fat.h +++ b/cpukit/libfs/src/dosfs/fat.h @@ -503,8 +503,7 @@ fat_cluster_write(fat_fs_info_t *fs_info, uint32_t start_cln, uint32_t offset, uint32_t count, - const void *buff, - bool overwrite_cluster); + const void *buff); ssize_t fat_sector_write(fat_fs_info_t *fs_info, diff --git a/cpukit/libfs/src/dosfs/fat_file.c b/cpukit/libfs/src/dosfs/fat_file.c index af71ee2..cbc0ab3 100644 --- a/cpukit/libfs/src/dosfs/fat_file.c +++ b/cpukit/libfs/src/dosfs/fat_file.c @@ -403,20 +403,18 @@ static bool * start - offset(in bytes) to write from * count - count * buf - buffer provided by user - * file_cln_initial - initial current cluster number of the file * * RETURNS: * number of bytes actually written to the file on success, or -1 if * error occured (errno set appropriately) */ static ssize_t - fat_file_write_fat32_or_non_root_dir( +fat_file_write_fat32_or_non_root_dir( fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd, const uint32_t start, const uint32_t count, - const uint8_t *buf, - const uint32_t file_cln_initial) + const uint8_t *buf) { int rc = RC_OK; uint32_t cmpltd = 0; @@ -426,35 +424,27 @@ static ssize_t uint32_t ofs_cln = start - (start_cln << fs_info->vol.bpc_log2); uint32_t ofs_cln_save = ofs_cln; uint32_t bytes_to_write = count; - uint32_t file_cln_cnt; ssize_t ret; uint32_t c; - bool overwrite_cluster = false; rc = fat_file_lseek(fs_info, fat_fd, start_cln, &cur_cln); if (RC_OK == rc) { - file_cln_cnt = cur_cln - fat_fd->cln; while ( (RC_OK == rc) && (bytes_to_write > 0)) { c = MIN(bytes_to_write, (fs_info->vol.bpc - ofs_cln)); - if (file_cln_initial < file_cln_cnt) - overwrite_cluster = true; - ret = fat_cluster_write(fs_info, cur_cln, ofs_cln, c, - &buf[cmpltd], - overwrite_cluster); + &buf[cmpltd]); if (0 > ret) rc = -1; if (RC_OK == rc) { - ++file_cln_cnt; bytes_to_write -= ret; cmpltd += ret; save_cln = cur_cln; @@ -509,7 +499,6 @@ fat_file_write( uint32_t byte; uint32_t c = 0; bool zero_fill = start > fat_fd->fat_file_size; - uint32_t file_cln_initial = fat_fd->map.file_cln; uint32_t cln; @@ -543,8 +532,7 @@ fat_file_write( cln, byte, count, - buf, - false); + buf); if (0 > ret) rc = -1; else @@ -556,8 +544,7 @@ fat_file_write( fat_fd, start, count, - buf, - file_cln_initial); + buf); if (0 > ret) rc = -1; else diff --git a/testsuites/fstests/fsdosfswrite01/init.c b/testsuites/fstests/fsdosfswrite01/init.c index 9ca1a2a..ba72507 100644 --- a/testsuites/fstests/fsdosfswrite01/init.c +++ b/testsuites/fstests/fsdosfswrite01/init.c @@ -125,7 +125,7 @@ static void test_normal_file_write( const char *mount_dir, const char *file_name ) { - static const rtems_blkdev_stats complete_block_stats = { + static const rtems_blkdev_stats complete_existing_block_stats = { .read_hits = 0, .read_misses = 0, .read_ahead_transfers = 0, @@ -135,14 +135,24 @@ static void test_normal_file_write( .write_blocks = 1, .write_errors = 0 }; - static const rtems_blkdev_stats new_block_stats = { - .read_hits = 8, + static const rtems_blkdev_stats complete_new_block_stats = { + .read_hits = 3, .read_misses = 2, .read_ahead_transfers = 0, .read_blocks = 2, .read_errors = 0, .write_transfers = 1, - .write_blocks = 4, + .write_blocks = 3, + .write_errors = 0 + }; + static const rtems_blkdev_stats partial_new_block_stats = { + .read_hits = 3, + .read_misses = 3, + .read_ahead_transfers = 0, + .read_blocks = 3, + .read_errors = 0, + .write_transfers = 1, + .write_blocks = 3, .write_errors = 0 }; @@ -174,17 +184,21 @@ static void test_normal_file_write( num_bytes = write( fd, cluster_buf, cluster_size ); rtems_test_assert( (ssize_t) cluster_size == num_bytes ); - check_block_stats( dev_name, mount_dir, &complete_block_stats ); + check_block_stats( dev_name, mount_dir, &complete_existing_block_stats ); reset_block_stats( dev_name, mount_dir ); + /* Write a complete cluster into a new file space */ num_bytes = write( fd, cluster_buf, cluster_size ); rtems_test_assert( (ssize_t) cluster_size == num_bytes ); + check_block_stats( dev_name, mount_dir, &complete_new_block_stats ); + reset_block_stats( dev_name, mount_dir ); + /* Write a new partial cluster into a new file space */ num_bytes = write( fd, cluster_buf, 1 ); rtems_test_assert( num_bytes == 1 ); - check_block_stats( dev_name, mount_dir, &new_block_stats ); + check_block_stats( dev_name, mount_dir, &partial_new_block_stats ); rv = close( fd ); rtems_test_assert( 0 == rv ); -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel