From 3d0c96c7f34204aa4386cd9c1cd4a3e7977d52a0 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 7 May 2012 16:31:15 +0200 Subject: 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. --- cpukit/libfs/src/dosfs/fat_file.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'cpukit/libfs/src/dosfs/fat_file.c') diff --git a/cpukit/libfs/src/dosfs/fat_file.c b/cpukit/libfs/src/dosfs/fat_file.c index 01dabc8f80..a10347ccc4 100644 --- a/cpukit/libfs/src/dosfs/fat_file.c +++ b/cpukit/libfs/src/dosfs/fat_file.c @@ -381,18 +381,18 @@ fat_file_write( uint32_t sec = 0; uint32_t byte = 0; uint32_t c = 0; + bool zero_fill = start > fat_fd->fat_file_size; if ( count == 0 ) return cmpltd; - if ( start > fat_fd->fat_file_size ) - rtems_set_errno_and_return_minus_one( EIO ); + if (start >= fat_fd->size_limit) + rtems_set_errno_and_return_minus_one(EFBIG); - if ((count > fat_fd->size_limit) || - (start > fat_fd->size_limit - count)) - rtems_set_errno_and_return_minus_one( EIO ); + if (count > fat_fd->size_limit - start) + count = fat_fd->size_limit - start; - rc = fat_file_extend(mt_entry, fat_fd, start + count, &c); + rc = fat_file_extend(mt_entry, fat_fd, zero_fill, start + count, &c); if (rc != RC_OK) return rc; @@ -475,6 +475,7 @@ int fat_file_extend( rtems_filesystem_mount_table_entry_t *mt_entry, fat_file_fd_t *fat_fd, + bool zero_fill, uint32_t new_length, uint32_t *a_length ) @@ -509,6 +510,27 @@ fat_file_extend( else bytes2add = 0; + if (zero_fill && bytes_remain > 0) { + uint32_t start = fat_fd->fat_file_size; + uint32_t cl_start = start >> fs_info->vol.bpc_log2; + uint32_t ofs = start & (fs_info->vol.bpc - 1); + uint32_t cur_cln; + uint32_t sec; + uint32_t byte; + + rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln); + if (rc != RC_OK) + return rc; + + sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln); + sec += ofs >> fs_info->vol.sec_log2; + byte = ofs & (fs_info->vol.bps - 1); + + rc = _fat_block_zero(mt_entry, sec, byte, bytes_remain); + if (rc != RC_OK) + return rc; + } + /* * if in last cluster allocated for the file there is enough room to * handle extention (hence we don't need to add even one cluster to the @@ -520,7 +542,7 @@ fat_file_extend( cls2add = ((bytes2add - 1) >> fs_info->vol.bpc_log2) + 1; rc = fat_scan_fat_for_free_clusters(mt_entry, &chain, cls2add, - &cls_added, &last_cl); + &cls_added, &last_cl, zero_fill); /* this means that low level I/O error occured */ if (rc != RC_OK) -- cgit v1.2.3