From 30d412469c930fe4150ad2b9a321eea2747ec6f4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 7 May 2012 16:30:37 +0200 Subject: Filesystem: PR1398: Fix lseek() mechanic According to POSIX the lseek() function shall not, by itself, extend the size of a file. Remove the size field of rtems_libio_t. A file has only one size but may have multiple open file descriptors. Thus a file size field in the file descriptor may lead to inconsistencies. New default handlers rtems_filesystem_default_lseek_file() and rtems_filesystem_default_lseek_directory(). --- cpukit/libfs/Makefile.am | 3 +- .../libfs/src/defaults/default_lseek_directory.c | 37 ++++++++++++ cpukit/libfs/src/defaults/default_lseek_file.c | 70 ++++++++++++++++++++++ cpukit/libfs/src/defaults/default_lseek_success.c | 29 --------- cpukit/libfs/src/devfs/devfs_init.c | 2 +- cpukit/libfs/src/dosfs/msdos.h | 12 ---- cpukit/libfs/src/dosfs/msdos_dir.c | 32 ---------- cpukit/libfs/src/dosfs/msdos_file.c | 54 +---------------- cpukit/libfs/src/dosfs/msdos_handlers_dir.c | 2 +- cpukit/libfs/src/dosfs/msdos_handlers_file.c | 2 +- cpukit/libfs/src/imfs/deviceio.c | 17 ------ cpukit/libfs/src/imfs/imfs.h | 18 ------ cpukit/libfs/src/imfs/imfs_directory.c | 38 ------------ cpukit/libfs/src/imfs/imfs_handlers_device.c | 2 +- cpukit/libfs/src/imfs/imfs_handlers_directory.c | 2 +- cpukit/libfs/src/imfs/imfs_handlers_memfile.c | 2 +- cpukit/libfs/src/imfs/memfile.c | 35 +---------- cpukit/libfs/src/nfsclient/src/nfs.c | 58 ++++-------------- cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c | 20 +------ cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c | 39 +----------- cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c | 29 ++++----- 21 files changed, 145 insertions(+), 358 deletions(-) create mode 100644 cpukit/libfs/src/defaults/default_lseek_directory.c create mode 100644 cpukit/libfs/src/defaults/default_lseek_file.c delete mode 100644 cpukit/libfs/src/defaults/default_lseek_success.c (limited to 'cpukit/libfs') diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am index c629bc99a1..f236704bdd 100644 --- a/cpukit/libfs/Makefile.am +++ b/cpukit/libfs/Makefile.am @@ -23,7 +23,8 @@ libdefaultfs_a_SOURCES = \ src/defaults/default_chown.c \ src/defaults/default_fcntl.c src/defaults/default_fsmount.c \ src/defaults/default_ftruncate.c src/defaults/default_lseek.c \ - src/defaults/default_lseek_success.c \ + src/defaults/default_lseek_file.c \ + src/defaults/default_lseek_directory.c \ src/defaults/default_readlink.c src/defaults/default_statvfs.c \ src/defaults/default_utime.c \ src/defaults/default_fstat.c \ diff --git a/cpukit/libfs/src/defaults/default_lseek_directory.c b/cpukit/libfs/src/defaults/default_lseek_directory.c new file mode 100644 index 0000000000..e50eefd667 --- /dev/null +++ b/cpukit/libfs/src/defaults/default_lseek_directory.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include + +off_t rtems_filesystem_default_lseek_directory( + rtems_libio_t *iop, + off_t offset, + int whence +) +{ + off_t rv = 0; + + if ( offset == 0 && whence == SEEK_SET ) { + iop->offset = 0; + } else { + errno = EINVAL; + rv = -1; + } + + return rv; +} diff --git a/cpukit/libfs/src/defaults/default_lseek_file.c b/cpukit/libfs/src/defaults/default_lseek_file.c new file mode 100644 index 0000000000..9d80b2a176 --- /dev/null +++ b/cpukit/libfs/src/defaults/default_lseek_file.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2012 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include + +off_t rtems_filesystem_default_lseek_file( + rtems_libio_t *iop, + off_t offset, + int whence +) +{ + off_t rv = 0; + off_t reference_offset; + off_t new_offset; + struct stat st; + + switch ( whence ) { + case SEEK_SET: + reference_offset = 0; + break; + case SEEK_CUR: + reference_offset = iop->offset; + break; + case SEEK_END: + st.st_size = 0; + rv = (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, &st ); + reference_offset = st.st_size; + break; + default: + errno = EINVAL; + rv = -1; + break; + } + new_offset = reference_offset + offset; + + if ( rv == 0 ) { + if ( + (offset >= 0 && new_offset >= reference_offset) + || (offset < 0 && new_offset < reference_offset) + ) { + if ( new_offset >= 0 ) { + iop->offset = new_offset; + rv = new_offset; + } else { + errno = EINVAL; + rv = -1; + } + } else { + errno = EOVERFLOW; + rv = -1; + } + } + + return rv; +} diff --git a/cpukit/libfs/src/defaults/default_lseek_success.c b/cpukit/libfs/src/defaults/default_lseek_success.c deleted file mode 100644 index d6a1cb4d8c..0000000000 --- a/cpukit/libfs/src/defaults/default_lseek_success.c +++ /dev/null @@ -1,29 +0,0 @@ - -/* - * Copyright (c) 2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -off_t rtems_filesystem_default_lseek_success( - rtems_libio_t *iop, - off_t offset, - int whence -) -{ - return 0; -} diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c index db856d21fa..154f1b9176 100644 --- a/cpukit/libfs/src/devfs/devfs_init.c +++ b/cpukit/libfs/src/devfs/devfs_init.c @@ -42,7 +42,7 @@ const rtems_filesystem_file_handlers_r devFS_file_handlers = { .read_h = devFS_read, .write_h = devFS_write, .ioctl_h = devFS_ioctl, - .lseek_h = rtems_filesystem_default_lseek, + .lseek_h = rtems_filesystem_default_lseek_file, .fstat_h = devFS_stat, .ftruncate_h = rtems_filesystem_default_ftruncate, .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h index 9bdfd881ec..a7aff1d96d 100644 --- a/cpukit/libfs/src/dosfs/msdos.h +++ b/cpukit/libfs/src/dosfs/msdos.h @@ -286,12 +286,6 @@ ssize_t msdos_file_write( size_t count /* IN */ ); -off_t msdos_file_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - int msdos_file_stat( const rtems_filesystem_location_info_t *loc, struct stat *buf @@ -322,12 +316,6 @@ ssize_t msdos_dir_read( size_t count /* IN */ ); -off_t msdos_dir_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - int msdos_dir_sync(rtems_libio_t *iop); int msdos_dir_stat( diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c index 67a0bdaaa9..be6b5a91ff 100644 --- a/cpukit/libfs/src/dosfs/msdos_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_dir.c @@ -465,38 +465,6 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count) * no write for directory */ -/* msdos_dir_lseek -- - * - * This routine will behave in one of three ways based on the state of - * argument whence. Based on the state of its value the offset argument will - * be interpreted using one of the following methods: - * - * SEEK_SET - offset is the absolute byte offset from the start of the - * logical start of the dirent sequence that represents the - * directory - * SEEK_CUR - offset is used as the relative byte offset from the current - * directory position index held in the iop structure - * SEEK_END - N/A --> This will cause an assert. - * - * PARAMETERS: - * iop - file control block - * offset - offset - * whence - predefine directive - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno - * set apropriately). - */ -off_t -msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence) -{ - if (iop->offset >= 0 && iop->offset <= iop->size) { - return 0; - } else { - rtems_set_errno_and_return_minus_one(EINVAL); - } -} - /* msdos_dir_stat -- * * This routine will obtain the following information concerning the current diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c index 7cd55b0494..c2db196c77 100644 --- a/cpukit/libfs/src/dosfs/msdos_file.c +++ b/cpukit/libfs/src/dosfs/msdos_file.c @@ -64,8 +64,6 @@ msdos_file_open(rtems_libio_t *iop, const char *pathname, int oflag, if (iop->flags & LIBIO_FLAGS_APPEND) iop->offset = fat_fd->fat_file_size; - iop->size = fat_fd->fat_file_size; - rtems_semaphore_release(fs_info->vol_sema); return RC_OK; } @@ -203,60 +201,10 @@ msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count) if (iop->offset + ret > fat_fd->fat_file_size) fat_fd->fat_file_size = iop->offset + ret; - iop->size = fat_fd->fat_file_size; - rtems_semaphore_release(fs_info->vol_sema); return ret; } -/* msdos_file_lseek -- - * Process lseek call to the file: extend file if lseek is up to the end - * of the file. - * - * PARAMETERS: - * iop - file control block - * offset - new offset - * whence - predefine directive - * - * RETURNS: - * new offset on success, or -1 if error occured (errno set - * appropriately). - */ -off_t -msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence) -{ - 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; - uint32_t real_size = 0; - - if (iop->offset < 0 || iop->offset > UINT32_MAX) { - rtems_set_errno_and_return_minus_one(EINVAL); - } - - 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_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset, - &real_size); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - if (real_size > fat_fd->fat_file_size) - fat_fd->fat_file_size = iop->offset = real_size; - - iop->size = fat_fd->fat_file_size; - - rtems_semaphore_release(fs_info->vol_sema); - return iop->offset; -} - /* msdos_file_stat -- * * PARAMETERS: @@ -332,7 +280,7 @@ msdos_file_ftruncate(rtems_libio_t *iop, off_t length) * file size only if length < fat-file size */ if (length < fat_fd->fat_file_size) - iop->size = fat_fd->fat_file_size = length; + fat_fd->fat_file_size = length; rtems_semaphore_release(fs_info->vol_sema); return RC_OK; diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c index 193d796dd9..eeaa77d15e 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c @@ -24,7 +24,7 @@ const rtems_filesystem_file_handlers_r msdos_dir_handlers = { msdos_dir_read, rtems_filesystem_default_write, rtems_filesystem_default_ioctl, - msdos_dir_lseek, + rtems_filesystem_default_lseek_directory, msdos_dir_stat, rtems_filesystem_default_ftruncate_directory, msdos_dir_sync, diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c index fefb6795d9..e68a09f1d3 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c @@ -24,7 +24,7 @@ const rtems_filesystem_file_handlers_r msdos_file_handlers = { msdos_file_read, msdos_file_write, rtems_filesystem_default_ioctl, - msdos_file_lseek, + rtems_filesystem_default_lseek_file, msdos_file_stat, msdos_file_ftruncate, msdos_file_sync, diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c index c4e7a921ff..f18c9e7cee 100644 --- a/cpukit/libfs/src/imfs/deviceio.c +++ b/cpukit/libfs/src/imfs/deviceio.c @@ -191,23 +191,6 @@ int device_ioctl( return args.ioctl_return; } -/* - * device_lseek - * - * This handler eats all lseek() operations and does not create - * an error. It assumes all devices can handle the seek. The - * writes fail. - */ - -off_t device_lseek( - rtems_libio_t *iop, - off_t offset, - int whence -) -{ - return offset; -} - /* * device_stat * diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index dd7c158383..daad052f9d 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/libfs/src/imfs/imfs.h @@ -418,12 +418,6 @@ extern ssize_t imfs_dir_read( size_t count /* IN */ ); -extern off_t imfs_dir_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - extern int memfile_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ @@ -449,12 +443,6 @@ extern int memfile_ioctl( void *buffer /* IN */ ); -extern off_t memfile_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - extern int device_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ @@ -484,12 +472,6 @@ extern int device_ioctl( void *buffer /* IN */ ); -extern off_t device_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - extern int device_ftruncate( rtems_libio_t *iop, /* IN */ off_t length /* IN */ diff --git a/cpukit/libfs/src/imfs/imfs_directory.c b/cpukit/libfs/src/imfs/imfs_directory.c index c6be71ffcc..f77b68bc14 100644 --- a/cpukit/libfs/src/imfs/imfs_directory.c +++ b/cpukit/libfs/src/imfs/imfs_directory.c @@ -99,41 +99,3 @@ ssize_t imfs_dir_read( return bytes_transferred; } - -/* - * imfs_dir_lseek - * - * This routine will behave in one of three ways based on the state of - * argument whence. Based on the state of its value the offset argument will - * be interpreted using one of the following methods: - * - * SEEK_SET - offset is the absolute byte offset from the start of the - * logical start of the dirent sequence that represents the - * directory - * SEEK_CUR - offset is used as the relative byte offset from the current - * directory position index held in the iop structure - * SEEK_END - N/A --> This will cause an EINVAL to be returned. - */ - -off_t imfs_dir_lseek( - rtems_libio_t *iop, - off_t offset, - int whence -) -{ - switch( whence ) { - case SEEK_SET: /* absolute move from the start of the file */ - case SEEK_CUR: /* relative move */ - iop->offset = (iop->offset/sizeof(struct dirent)) * - sizeof(struct dirent); - break; - - case SEEK_END: /* Movement past the end of the directory via lseek */ - /* is not a permitted operation */ - default: - rtems_set_errno_and_return_minus_one( EINVAL ); - break; - } - - return 0; -} diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c index dfbd8949c5..fe3973df05 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_device.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c @@ -36,7 +36,7 @@ static const rtems_filesystem_file_handlers_r IMFS_device_handlers = { device_read, device_write, device_ioctl, - device_lseek, + rtems_filesystem_default_lseek_file, IMFS_stat_device, device_ftruncate, rtems_filesystem_default_fsync_or_fdatasync, diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c index 9c3f77416a..579fdec2ea 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_directory.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c @@ -52,7 +52,7 @@ static const rtems_filesystem_file_handlers_r IMFS_directory_handlers = { imfs_dir_read, rtems_filesystem_default_write, rtems_filesystem_default_ioctl, - imfs_dir_lseek, + rtems_filesystem_default_lseek_directory, IMFS_stat_directory, rtems_filesystem_default_ftruncate_directory, rtems_filesystem_default_fsync_or_fdatasync_success, diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c index 57d488af6f..262b93aa2a 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c @@ -36,7 +36,7 @@ static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { memfile_read, memfile_write, memfile_ioctl, - memfile_lseek, + rtems_filesystem_default_lseek_file, IMFS_stat_file, memfile_ftruncate, rtems_filesystem_default_fsync_or_fdatasync_success, diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c index d2cff01517..64679df037 100644 --- a/cpukit/libfs/src/imfs/memfile.c +++ b/cpukit/libfs/src/imfs/memfile.c @@ -109,7 +109,6 @@ int memfile_open( if (iop->flags & LIBIO_FLAGS_APPEND) iop->offset = the_jnode->info.file.size; - iop->size = the_jnode->info.file.size; return 0; } @@ -148,7 +147,6 @@ ssize_t memfile_write( the_jnode = iop->pathinfo.node_access; status = IMFS_memfile_write( the_jnode, iop->offset, buffer, count ); - iop->size = the_jnode->info.file.size; return status; } @@ -169,34 +167,6 @@ int memfile_ioctl( return 0; } -/* - * 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 * @@ -232,7 +202,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 ); @@ -265,7 +234,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 @@ -654,7 +623,7 @@ MEMFILE_STATIC ssize_t IMFS_memfile_write( if ( last_byte > the_jnode->info.file.size ) { status = IMFS_memfile_extend( the_jnode, last_byte ); if ( status ) - rtems_set_errno_and_return_minus_one( ENOSPC ); + return status; } copied = 0; diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c index 15b6def0d2..09a9278952 100644 --- a/cpukit/libfs/src/nfsclient/src/nfs.c +++ b/cpukit/libfs/src/nfsclient/src/nfs.c @@ -2424,63 +2424,25 @@ int e; return count; } -static off_t nfs_file_lseek( - rtems_libio_t *iop, - off_t length, - int whence -) -{ -#if DEBUG & DEBUG_SYSCALLS - fprintf(stderr, - "lseek to %i (length %i, whence %i)\n", - iop->offset, - length, - whence); -#endif - if ( SEEK_END == whence ) { - /* rtems (4.6.2) libcsupport code 'lseek' uses iop->size to - * compute the offset. We don't want to track the file size - * by updating 'iop->size' constantly. - * Since lseek is the only place using iop->size, we work - * around this by tweaking the offset here... - */ - NfsNode node = iop->pathinfo.node_access; - fattr *fa = &SERP_ATTR(node); - - if (updateAttr(node, 0 /* only if old */)) { - return -1; - } - iop->offset = fa->size; - } - - /* this is particularly easy :-) */ - return iop->offset; -} - static off_t nfs_dir_lseek( rtems_libio_t *iop, off_t length, int whence ) { -DirInfo di = iop->pathinfo.node_access_2; + off_t rv = rtems_filesystem_default_lseek_directory(iop, length, whence); - /* we don't support anything other than - * rewinding - */ - if (SEEK_SET != whence || 0 != length) { - errno = ENOTSUP; - return -1; - } + if (rv == 0) { + DirInfo di = iop->pathinfo.node_access_2; + nfscookie *cookie = &di->readdirargs.cookie; - /* rewind cookie */ - memset( &di->readdirargs.cookie, - 0, - sizeof(di->readdirargs.cookie) ); + di->eofreached = FALSE; - di->eofreached = FALSE; + /* rewind cookie */ + memset(cookie, 0, sizeof(*cookie)); + } - return iop->offset; + return rv; } #if 0 /* structure types for reference */ @@ -2703,7 +2665,7 @@ struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = { .read_h = nfs_file_read, .write_h = nfs_file_write, .ioctl_h = rtems_filesystem_default_ioctl, - .lseek_h = nfs_file_lseek, + .lseek_h = rtems_filesystem_default_lseek_file, .fstat_h = nfs_fstat, .ftruncate_h = nfs_file_ftruncate, .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c index d66e4296c5..0325885d84 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c @@ -213,24 +213,6 @@ rtems_rfs_rtems_device_ioctl (rtems_libio_t* iop, return args.ioctl_return; } -/** - * This handler eats all lseek() operations and does not create an error. It - * assumes all devices can handle the seek. The writes fail. - * - * @param iop - * @param offset - * @param whence - * @return off_t - */ - -static off_t -rtems_rfs_rtems_device_lseek (rtems_libio_t* iop, - off_t offset, - int whence) -{ - return offset; -} - /** * The consumes the truncate call. You cannot truncate device files. * @@ -255,7 +237,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_device_handlers = { .read_h = rtems_rfs_rtems_device_read, .write_h = rtems_rfs_rtems_device_write, .ioctl_h = rtems_rfs_rtems_device_ioctl, - .lseek_h = rtems_rfs_rtems_device_lseek, + .lseek_h = rtems_filesystem_default_lseek_file, .fstat_h = rtems_rfs_rtems_fstat, .ftruncate_h = rtems_rfs_rtems_device_ftruncate, .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c index 550973db0c..88f71e53a9 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c @@ -150,43 +150,6 @@ rtems_rfs_rtems_dir_read (rtems_libio_t* iop, return bytes_transferred; } -/** - * This routine will behave in one of three ways based on the state of argument - * whence. Based on the state of its value the offset argument will be - * interpreted using one of the following methods: - * - * SEEK_SET - offset is the absolute byte offset from the start of the - * logical start of the dirent sequence that represents the - * directory - * SEEK_CUR - offset is used as the relative byte offset from the current - * directory position index held in the iop structure - * SEEK_END - N/A --> This will cause an assert. - * - * @param iop - * @param offset - * @param whence - * return off_t - */ -static off_t -rtems_rfs_rtems_dir_lseek (rtems_libio_t* iop, - off_t offset, - int whence) -{ - switch (whence) - { - case SEEK_SET: /* absolute move from the start of the file */ - case SEEK_CUR: /* relative move */ - break; - - case SEEK_END: /* Movement past the end of the directory via lseek */ - /* is not a permitted operation */ - default: - return rtems_rfs_rtems_error ("dir_lseek: bad whence", EINVAL); - break; - } - return 0; -} - /* * Set of operations handlers for operations on directories. */ @@ -197,7 +160,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = { .read_h = rtems_rfs_rtems_dir_read, .write_h = rtems_filesystem_default_write, .ioctl_h = rtems_filesystem_default_ioctl, - .lseek_h = rtems_rfs_rtems_dir_lseek, + .lseek_h = rtems_filesystem_default_lseek_directory, .fstat_h = rtems_rfs_rtems_fstat, .ftruncate_h = rtems_filesystem_default_ftruncate_directory, .fsync_h = rtems_filesystem_default_fsync_or_fdatasync, diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c index 0a15652dfc..b2ff45df8b 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c @@ -72,7 +72,6 @@ rtems_rfs_rtems_file_open (rtems_libio_t* iop, if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN)) printf("rtems-rfs: file-open: handle:%p\n", file); - iop->size = rtems_rfs_file_size (file); rtems_rfs_rtems_set_iop_file_handle (iop, file); rtems_rfs_rtems_unlock (fs); @@ -245,8 +244,6 @@ rtems_rfs_rtems_file_write (rtems_libio_t* iop, } } - iop->size = rtems_rfs_file_size (file); - rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return write; @@ -282,26 +279,32 @@ rtems_rfs_rtems_file_lseek (rtems_libio_t* iop, int whence) { rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop); - rtems_rfs_pos pos; - int rc; + off_t old_offset; + off_t new_offset; if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK)) printf("rtems-rfs: file-lseek: handle:%p offset:%" PRIdoff_t "\n", file, offset); rtems_rfs_rtems_lock (rtems_rfs_file_fs (file)); - pos = iop->offset; - - rc = rtems_rfs_file_seek (file, pos, &pos); - if (rc) + old_offset = iop->offset; + new_offset = rtems_filesystem_default_lseek_file (iop, offset, whence); + if (new_offset != -1) { - rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); - return rtems_rfs_rtems_error ("file_lseek: lseek", rc); + rtems_rfs_pos pos = iop->offset; + int rc = rtems_rfs_file_seek (file, pos, &pos); + + if (rc) + { + rtems_rfs_rtems_error ("file_lseek: lseek", rc); + iop->offset = old_offset; + new_offset = -1; + } } rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); - return iop->offset; + return new_offset; } /** @@ -327,8 +330,6 @@ rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop, if (rc) rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc); - iop->size = rtems_rfs_file_size (file); - rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file)); return rc; -- cgit v1.2.3