From d61b0a5abfb00abf91ef281a89cb3984b5eef737 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 7 May 2012 16:15:57 +0200 Subject: Filesystem: PR1871: Fix O_APPEND --- cpukit/libfs/src/dosfs/msdos.h | 16 ------- cpukit/libfs/src/dosfs/msdos_dir.c | 64 ---------------------------- cpukit/libfs/src/dosfs/msdos_file.c | 46 ++------------------ cpukit/libfs/src/dosfs/msdos_handlers_dir.c | 4 +- cpukit/libfs/src/dosfs/msdos_handlers_file.c | 2 +- cpukit/libfs/src/imfs/memfile.c | 7 +-- cpukit/libfs/src/rfs/rtems-rfs-file.c | 2 +- cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c | 35 +++++++++------ testsuites/fstests/fsrdwr/init.c | 10 ++++- 9 files changed, 42 insertions(+), 144 deletions(-) diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h index a7aff1d96d..0696b8f1fb 100644 --- a/cpukit/libfs/src/dosfs/msdos.h +++ b/cpukit/libfs/src/dosfs/msdos.h @@ -265,13 +265,6 @@ int msdos_initialize_support( const rtems_filesystem_file_handlers_r *directory_handlers ); -int msdos_file_open( - rtems_libio_t *iop, /* IN */ - const char *pathname, /* IN */ - int oflag, /* IN */ - mode_t mode /* IN */ -); - int msdos_file_close(rtems_libio_t *iop /* IN */); ssize_t msdos_file_read( @@ -301,15 +294,6 @@ int msdos_file_sync(rtems_libio_t *iop); int msdos_file_datasync(rtems_libio_t *iop); -int msdos_dir_open( - rtems_libio_t *iop, /* IN */ - const char *pathname, /* IN */ - int oflag, /* IN */ - mode_t mode /* IN */ -); - -int msdos_dir_close(rtems_libio_t *iop /* IN */); - ssize_t msdos_dir_read( rtems_libio_t *iop, /* IN */ void *buffer, /* IN */ diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c index be6b5a91ff..38ea6675f7 100644 --- a/cpukit/libfs/src/dosfs/msdos_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_dir.c @@ -30,70 +30,6 @@ #include "msdos.h" -/* msdos_dir_open -- - * Open fat-file which correspondes to the directory being opened and - * set offset field of file control block to zero. - */ -int -msdos_dir_open(rtems_libio_t *iop, const char *pathname, int oflag, - mode_t mode) -{ - int rc = RC_OK; - 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; - - 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_reopen(fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - iop->offset = 0; - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_dir_close -- - * Close fat-file which correspondes to the directory being closed - * - * PARAMETERS: - * iop - file control block - * - * RETURNS: - * RC_OK, if directory closed successfully, or -1 if error occured (errno - * set apropriately. - */ -int -msdos_dir_close(rtems_libio_t *iop) -{ - int rc = RC_OK; - 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; - - 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_close(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - /* msdos_format_dirent_with_dot -- * This routine convert a (short) MSDOS filename as present on disk * (fixed 8+3 characters, filled with blanks, without separator dot) diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c index c2db196c77..6eb9b7953a 100644 --- a/cpukit/libfs/src/dosfs/msdos_file.c +++ b/cpukit/libfs/src/dosfs/msdos_file.c @@ -27,47 +27,6 @@ #include "msdos.h" -/* msdos_file_open -- - * Open fat-file which correspondes to the file - * - * PARAMETERS: - * iop - file control block - * pathname - name - * flag - flags - * mode - mode - * - * RETURNS: - * RC_OK, if file opened successfully, or -1 if error occured - * and errno set appropriately - */ -int -msdos_file_open(rtems_libio_t *iop, const char *pathname, int oflag, - mode_t mode) -{ - int rc = RC_OK; - 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; - - 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_reopen(fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - if (iop->flags & LIBIO_FLAGS_APPEND) - iop->offset = fat_fd->fat_file_size; - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - /* msdos_file_close -- * Close fat-file which correspondes to the file. If fat-file descriptor * which correspondes to the file is not marked "removed", synchronize @@ -121,8 +80,6 @@ msdos_file_close(rtems_libio_t *iop) } } - rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd); - rtems_semaphore_release(fs_info->vol_sema); return rc; } @@ -186,6 +143,9 @@ msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count) if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); + if ((iop->flags & LIBIO_FLAGS_APPEND) != 0) + iop->offset = fat_fd->fat_file_size; + ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count, buffer); if (ret < 0) diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c index eeaa77d15e..8c7dcdc0a5 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c @@ -19,8 +19,8 @@ #include "msdos.h" const rtems_filesystem_file_handlers_r msdos_dir_handlers = { - msdos_dir_open, - msdos_dir_close, + rtems_filesystem_default_open, + rtems_filesystem_default_close, msdos_dir_read, rtems_filesystem_default_write, rtems_filesystem_default_ioctl, diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c index e68a09f1d3..12cdaa048e 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c @@ -19,7 +19,7 @@ #include "msdos.h" const rtems_filesystem_file_handlers_r msdos_file_handlers = { - msdos_file_open, + rtems_filesystem_default_open, msdos_file_close, msdos_file_read, msdos_file_write, diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c index 64679df037..d836172884 100644 --- a/cpukit/libfs/src/imfs/memfile.c +++ b/cpukit/libfs/src/imfs/memfile.c @@ -92,7 +92,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,8 +106,6 @@ 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; return 0; } @@ -146,6 +144,9 @@ 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 ); return status; diff --git a/cpukit/libfs/src/rfs/rtems-rfs-file.c b/cpukit/libfs/src/rfs/rtems-rfs-file.c index abd123da1b..ab195fac6f 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-file.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-file.c @@ -422,7 +422,7 @@ rtems_rfs_file_seek (rtems_rfs_file_handle* handle, * This means the file needs to set the file size to the pos only when a * write occurs. */ - if (pos < rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (handle), + if (pos <= rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (handle), handle->shared)) { rtems_rfs_file_set_bpos (handle, pos); diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c index b2ff45df8b..1b8b0d4441 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c @@ -185,6 +185,7 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop, { rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop); rtems_rfs_pos pos; + rtems_rfs_pos file_size; const uint8_t* data = buffer; ssize_t write = 0; int rc; @@ -195,26 +196,34 @@ 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. If the position equals the - * size of file we are still past the end of the file as positions number - * from 0. For a specific position we need a file that has a length of one - * more. - */ - - if (pos >= rtems_rfs_file_size (file)) + file_size = rtems_rfs_file_size (file); + if (pos > file_size) { - rc = rtems_rfs_file_set_size (file, pos + 1); + /* + * 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. The + * rtems_rfs_file_io_end() will grow the file subsequently. + */ + rc = rtems_rfs_file_set_size (file, pos); if (rc) { rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return rtems_rfs_rtems_error ("file-write: write extend", rc); } - } - rtems_rfs_file_set_bpos (file, pos); + rtems_rfs_file_set_bpos (file, pos); + } + else if (pos < file_size && (iop->flags & LIBIO_FLAGS_APPEND) != 0) + { + pos = file_size; + rc = rtems_rfs_file_seek (file, pos, &pos); + if (rc) + { + rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); + return rtems_rfs_rtems_error ("file-write: write append seek", rc); + } + iop->offset = pos; + } while (count) { diff --git a/testsuites/fstests/fsrdwr/init.c b/testsuites/fstests/fsrdwr/init.c index 8b40f07581..bfaa8abf7e 100644 --- a/testsuites/fstests/fsrdwr/init.c +++ b/testsuites/fstests/fsrdwr/init.c @@ -112,6 +112,12 @@ read_write_test (void) rtems_test_assert (n == len); pos = lseek (fd, 0, SEEK_CUR); rtems_test_assert (pos == 2 * len); + pos = lseek (fd, 0, SEEK_SET); + rtems_test_assert (pos == 0); + n = write (fd, databuf, len); + rtems_test_assert (n == len); + pos = lseek (fd, 0, SEEK_CUR); + rtems_test_assert (pos == 3 * len); status = close (fd); rtems_test_assert (status == 0); @@ -123,7 +129,9 @@ read_write_test (void) n = read (fd, readbuf, len); rtems_test_assert (n == len); rtems_test_assert (!strncmp (databuf, readbuf, len)); - + n = read (fd, readbuf, len); + rtems_test_assert (n == len); + rtems_test_assert (!strncmp (databuf, readbuf, len)); n = read (fd, readbuf, len); rtems_test_assert (n == len); rtems_test_assert (!strncmp (databuf, readbuf, len)); -- cgit v1.2.3