summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-07 14:30:37 (UTC)
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-05-11 11:58:43 (UTC)
commit30d412469c930fe4150ad2b9a321eea2747ec6f4 (patch)
treed91c4bfaa8e968a6da87ba9b5860502758d4a26f
parenteb7c6a84b65e110034ec481c6e9dd09f728240e7 (diff)
downloadrtems-30d412469c930fe4150ad2b9a321eea2747ec6f4.tar.bz2
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().
-rw-r--r--cpukit/libblock/src/blkdev-imfs.c2
-rw-r--r--cpukit/libcsupport/include/rtems/libio.h50
-rw-r--r--cpukit/libcsupport/src/lseek.c54
-rw-r--r--cpukit/libfs/Makefile.am3
-rw-r--r--cpukit/libfs/src/defaults/default_lseek_directory.c (renamed from cpukit/libfs/src/defaults/default_lseek_success.c)14
-rw-r--r--cpukit/libfs/src/defaults/default_lseek_file.c70
-rw-r--r--cpukit/libfs/src/devfs/devfs_init.c2
-rw-r--r--cpukit/libfs/src/dosfs/msdos.h12
-rw-r--r--cpukit/libfs/src/dosfs/msdos_dir.c32
-rw-r--r--cpukit/libfs/src/dosfs/msdos_file.c54
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_dir.c2
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_file.c2
-rw-r--r--cpukit/libfs/src/imfs/deviceio.c17
-rw-r--r--cpukit/libfs/src/imfs/imfs.h18
-rw-r--r--cpukit/libfs/src/imfs/imfs_directory.c38
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_device.c2
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_directory.c2
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_memfile.c2
-rw-r--r--cpukit/libfs/src/imfs/memfile.c35
-rw-r--r--cpukit/libfs/src/nfsclient/src/nfs.c58
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c20
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c39
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c29
-rw-r--r--testsuites/fstests/fsrdwr/init.c2
-rw-r--r--testsuites/psxtests/psximfs01/init.c63
25 files changed, 197 insertions, 425 deletions
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index fe7a80c..8645593 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -206,7 +206,7 @@ static const rtems_filesystem_file_handlers_r rtems_blkdev_imfs_node = {
.read_h = rtems_blkdev_imfs_read,
.write_h = rtems_blkdev_imfs_write,
.ioctl_h = rtems_blkdev_imfs_ioctl,
- .lseek_h = rtems_filesystem_default_lseek_success,
+ .lseek_h = rtems_filesystem_default_lseek_file,
.fstat_h = rtems_blkdev_imfs_fstat,
.ftruncate_h = rtems_filesystem_default_ftruncate,
.fsync_h = rtems_blkdev_imfs_fsync_or_fdatasync,
diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
index 04ca52c..a740a40 100644
--- a/cpukit/libcsupport/include/rtems/libio.h
+++ b/cpukit/libcsupport/include/rtems/libio.h
@@ -849,8 +849,9 @@ typedef int (*rtems_filesystem_ioctl_t)(
* @retval non-negative The new offset from the beginning of the file.
* @retval -1 An error occured. The errno is set to indicate the error.
*
- * @see rtems_filesystem_default_lseek() and
- * rtems_filesystem_default_lseek_success().
+ * @see rtems_filesystem_default_lseek(),
+ * rtems_filesystem_default_lseek_file(), and
+ * rtems_filesystem_default_lseek_directory().
*/
typedef off_t (*rtems_filesystem_lseek_t)(
rtems_libio_t *iop,
@@ -1026,11 +1027,51 @@ off_t rtems_filesystem_default_lseek(
);
/**
+ * @brief An offset 0 with a whence of SEEK_SET will perform a directory rewind
+ * operation.
+ *
+ * This function has no protection against concurrent access.
+ *
+ * @retval -1 The offset is not zero or the whence is not SEEK_SET.
+ * @retval 0 Successful rewind operation.
+ *
+ * @see rtems_filesystem_lseek_t.
+ */
+off_t rtems_filesystem_default_lseek_directory(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+);
+
+/**
+ * @brief Default lseek() handler for files.
+ *
+ * The fstat() handler will be used to obtain the file size in case whence is
+ * SEEK_END.
+ *
+ * This function has no protection against concurrent access.
+ *
+ * @retval -1 An error occured. In case an integer overflow occured, then the
+ * errno will be set to EOVERFLOW. In case the new offset is negative, then
+ * the errno will be set to EINVAL. In case the whence is SEEK_END and the
+ * fstat() handler to obtain the current file size returned an error status,
+ * then the errno will be set by the fstat() handler.
+ * @retval offset The new offset.
+ *
+ * @see rtems_filesystem_lseek_t.
+ */
+off_t rtems_filesystem_default_lseek_file(
+ rtems_libio_t *iop,
+ off_t offset,
+ int whence
+);
+
+/**
* @retval 0 Always.
*
* @see rtems_filesystem_lseek_t.
*/
-off_t rtems_filesystem_default_lseek_success(
+off_t rtems_filesystem_default_lseek_file(
rtems_libio_t *iop,
off_t offset,
int whence
@@ -1157,11 +1198,10 @@ extern const rtems_filesystem_limits_and_options_t
* It will be indexed by 'fd'.
*
* @todo Should really have a separate per/file data structure that this points
- * to (eg: size, offset, driver, pathname should be in that)
+ * to (eg: offset, driver, pathname should be in that)
*/
struct rtems_libio_tt {
rtems_driver_name_t *driver;
- off_t size; /* size of file */
off_t offset; /* current offset into file */
uint32_t flags;
rtems_filesystem_location_info_t pathinfo;
diff --git a/cpukit/libcsupport/src/lseek.c b/cpukit/libcsupport/src/lseek.c
index 7c1f76b..fa18db3 100644
--- a/cpukit/libcsupport/src/lseek.c
+++ b/cpukit/libcsupport/src/lseek.c
@@ -21,65 +21,13 @@
off_t lseek( int fd, off_t offset, int whence )
{
- off_t rv = 0;
rtems_libio_t *iop;
- off_t reference_offset;
- off_t old_offset;
- off_t new_offset;
rtems_libio_check_fd( fd );
iop = rtems_libio_iop( fd );
rtems_libio_check_is_open(iop);
- old_offset = iop->offset;
- switch ( whence ) {
- case SEEK_SET:
- reference_offset = 0;
- break;
- case SEEK_CUR:
- reference_offset = old_offset;
- break;
- case SEEK_END:
- reference_offset = iop->size;
- break;
- default:
- errno = EINVAL;
- rv = (off_t) -1;
- break;
- }
- new_offset = reference_offset + offset;
-
- if ( rv == 0 ) {
- if (
- (reference_offset >= 0 && new_offset >= offset)
- || (reference_offset < 0 && new_offset <= offset)
- ) {
- switch ( rtems_filesystem_node_type( &iop->pathinfo ) ) {
- case RTEMS_FILESYSTEM_DIRECTORY:
- case RTEMS_FILESYSTEM_MEMORY_FILE:
- if ( new_offset < 0 ) {
- errno = EINVAL;
- rv = (off_t) -1;
- }
- break;
- default:
- break;
- }
-
- if ( rv == 0 ) {
- iop->offset = new_offset;
- rv = (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence );
- if ( rv == (off_t) -1 ) {
- iop->offset = old_offset;
- }
- }
- } else {
- errno = EOVERFLOW;
- rv = (off_t) -1;
- }
- }
-
- return rv;
+ return (*iop->pathinfo.handlers->lseek_h)( iop, offset, whence );
}
/*
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
index c629bc9..f236704 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_success.c b/cpukit/libfs/src/defaults/default_lseek_directory.c
index d6a1cb4..e50eefd 100644
--- a/cpukit/libfs/src/defaults/default_lseek_success.c
+++ b/cpukit/libfs/src/defaults/default_lseek_directory.c
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2012 embedded brains GmbH. All rights reserved.
*
@@ -19,11 +18,20 @@
#include <rtems/libio_.h>
-off_t rtems_filesystem_default_lseek_success(
+off_t rtems_filesystem_default_lseek_directory(
rtems_libio_t *iop,
off_t offset,
int whence
)
{
- return 0;
+ 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 0000000..9d80b2a
--- /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
+ * <rtems@embedded-brains.de>
+ *
+ * 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 <rtems/libio_.h>
+
+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/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c
index db856d2..154f1b9 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 9bdfd88..a7aff1d 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 67a0bda..be6b5a9 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 7cd55b0..c2db196 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 193d796..eeaa77d 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 fefb679..e68a09f 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 c4e7a92..f18c9e7 100644
--- a/cpukit/libfs/src/imfs/deviceio.c
+++ b/cpukit/libfs/src/imfs/deviceio.c
@@ -192,23 +192,6 @@ int device_ioctl(
}
/*
- * 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
*
* The IMFS_stat() is used.
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index dd7c158..daad052 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 c6be71f..f77b68b 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 dfbd894..fe3973d 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 9c3f774..579fdec 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 57d488a..262b93a 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 d2cff01..64679df 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;
}
@@ -170,34 +168,6 @@ int memfile_ioctl(
}
/*
- * 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
*
* This IMFS_stat() can be used.
@@ -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 15b6def..09a9278 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 d66e429..0325885 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
@@ -214,24 +214,6 @@ rtems_rfs_rtems_device_ioctl (rtems_libio_t* iop,
}
/**
- * 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.
*
* @param iop
@@ -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 550973d..88f71e5 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 0a15652..b2ff45d 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;
diff --git a/testsuites/fstests/fsrdwr/init.c b/testsuites/fstests/fsrdwr/init.c
index ef2b02a..8b40f07 100644
--- a/testsuites/fstests/fsrdwr/init.c
+++ b/testsuites/fstests/fsrdwr/init.c
@@ -371,7 +371,7 @@ lseek_test (void)
*/
status = fstat (fd, &statbuf);
rtems_test_assert (status == 0);
- rtems_test_assert (statbuf.st_size == total_written + 1);
+ rtems_test_assert (statbuf.st_size == total_written);
status = ftruncate (fd, total_written);
rtems_test_assert (status == 0);
diff --git a/testsuites/psxtests/psximfs01/init.c b/testsuites/psxtests/psximfs01/init.c
index c567eee..88796ba 100644
--- a/testsuites/psxtests/psximfs01/init.c
+++ b/testsuites/psxtests/psximfs01/init.c
@@ -56,7 +56,7 @@ void write_helper(void)
do {
written = write( TestFd, Buffer, sizeof(Buffer) );
if ( written == -1 ) {
- if ( errno == ENOSPC ) {
+ if ( errno == EFBIG ) {
printf( "Total written = %zd\n", TotalWritten );
return;
}
@@ -93,22 +93,21 @@ void read_helper(void)
rtems_test_exit(0);
}
i++;
- continue;
- }
- /* Unsure if ENOSPC is the write error to be returned */
- if ( errno == ENOSPC && i == TotalWritten ) {
- puts( "File correctly read until ENOSPC returned\n" );
- return;
+ } else if ( sc != 0 ) {
+ fprintf(
+ stderr,
+ "ERROR - at offset %d - returned %zd and error=%s\n",
+ i,
+ sc,
+ strerror( errno )
+ );
+ rtems_test_exit(0);
}
- fprintf(
- stderr,
- "ERROR - at offset %d - returned %zd and error=%s\n",
- i,
- sc,
- strerror( errno )
- );
- rtems_test_exit(0);
- } while (1);
+ } while ( sc > 0 );
+
+ if ( i == TotalWritten ) {
+ puts( "File correctly read until EOF returned\n" );
+ }
}
void truncate_helper(void)
@@ -143,7 +142,7 @@ void truncate_helper(void)
} while (new > 0);
}
-void extend_helper(void)
+void extend_helper(int eno)
{
off_t position;
off_t new;
@@ -164,18 +163,11 @@ void extend_helper(void)
new = position;
do {
sc = lseek( TestFd, new, SEEK_SET );
- if( sc == -1 ) {
- if( errno == ENOSPC ) {
- break;
- }
- else {
- rtems_test_assert( 0 );
- }
- }
+ rtems_test_assert( sc == new );
rc = ftruncate( TestFd, new );
if ( rc != 0 ) {
- if( errno != ENOSPC ) {
+ if( errno != eno ) {
fprintf(
stderr,
"ERROR - at offset %d - returned %d and error=%s\n",
@@ -218,8 +210,10 @@ rtems_task Init(
{
int i;
void *alloc_ptr = (void *)0;
- int position = 0;
- int status = 0;
+ off_t position;
+ off_t new_position;
+ char buf [1];
+ ssize_t n;
puts( "\n\n*** TEST IMFS 01 ***" );
@@ -244,18 +238,21 @@ rtems_task Init(
*/
alloc_ptr = malloc( malloc_free_space() - 4 );
- extend_helper();
+ extend_helper(ENOSPC);
/*
* free the allocated heap memory
*/
free(alloc_ptr);
- extend_helper();
+ extend_helper(EFBIG);
position = lseek( TestFd , 0, SEEK_END );
- status = lseek( TestFd, position+2, SEEK_SET );
- rtems_test_assert( status == -1 );
- rtems_test_assert( errno == ENOSPC );
+ new_position = lseek( TestFd, position + 2, SEEK_SET );
+ rtems_test_assert( new_position == position + 2 );
+
+ n = write( TestFd, buf, sizeof(buf) );
+ rtems_test_assert( n == -1 );
+ rtems_test_assert( errno == EFBIG );
close_it();
unlink_it();