From c6bb1c33bcf70d1398073c96a4fac4f9b031b9ab Mon Sep 17 00:00:00 2001 From: Kevin Kirspel Date: Thu, 29 Jun 2017 10:36:43 -0400 Subject: posix/mmap: Add support for file handler and MAP_ANON Added a mmap file handler to struct _rtems_filesystem_file_handlers_r. Updated each file handler object to support the default mmap handler. Updated mmap() to call the mmap handler for MAP_SHARED. Added a mmap file handler for shm Added support for MAP_ANON in mmap(). Updates #2859 --- cpukit/dev/i2c/i2c-bus.c | 1 + cpukit/dev/i2c/i2c-dev.c | 1 + cpukit/dev/spi/spi-bus.c | 1 + cpukit/libblock/src/blkdev-imfs.c | 1 + cpukit/libcsupport/include/rtems/libio.h | 38 ++++ cpukit/libcsupport/include/rtems/termiostypes.h | 13 ++ cpukit/libcsupport/src/__usrenv.c | 1 + cpukit/libcsupport/src/termios.c | 1 + cpukit/libfs/Makefile.am | 1 + cpukit/libfs/src/defaults/default_handlers.c | 1 + cpukit/libfs/src/defaults/default_mmap.c | 40 ++++ cpukit/libfs/src/devfs/devfs_init.c | 1 + cpukit/libfs/src/dosfs/msdos_handlers_dir.c | 1 + cpukit/libfs/src/dosfs/msdos_handlers_file.c | 1 + cpukit/libfs/src/imfs/imfs_dir_default.c | 1 + cpukit/libfs/src/imfs/imfs_dir_minimal.c | 1 + cpukit/libfs/src/imfs/imfs_fifo.c | 1 + cpukit/libfs/src/imfs/imfs_handlers_device.c | 1 + cpukit/libfs/src/imfs/imfs_linfile.c | 1 + cpukit/libfs/src/imfs/imfs_link.c | 1 + cpukit/libfs/src/imfs/imfs_memfile.c | 1 + cpukit/libfs/src/imfs/imfs_symlink.c | 1 + cpukit/libfs/src/jffs2/src/fs-rtems.c | 3 + cpukit/libfs/src/nfsclient/src/nfs.c | 3 + cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c | 1 + cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c | 1 + cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c | 1 + cpukit/libfs/src/rfs/rtems-rfs-rtems.c | 1 + cpukit/libnetworking/lib/ftpfs.c | 2 + cpukit/libnetworking/lib/tftpDriver.c | 1 + cpukit/libnetworking/rtems/rtems_syscall.c | 1 + cpukit/posix/src/mmap.c | 257 ++++++++++++++---------- cpukit/posix/src/munmap.c | 14 +- cpukit/posix/src/shmopen.c | 30 +++ 34 files changed, 312 insertions(+), 113 deletions(-) create mode 100644 cpukit/libfs/src/defaults/default_mmap.c diff --git a/cpukit/dev/i2c/i2c-bus.c b/cpukit/dev/i2c/i2c-bus.c index 0f27d06873..1297b1ef4c 100644 --- a/cpukit/dev/i2c/i2c-bus.c +++ b/cpukit/dev/i2c/i2c-bus.c @@ -218,6 +218,7 @@ static const rtems_filesystem_file_handlers_r i2c_bus_handler = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/dev/i2c/i2c-dev.c b/cpukit/dev/i2c/i2c-dev.c index b00a9bdf21..680732fa46 100644 --- a/cpukit/dev/i2c/i2c-dev.c +++ b/cpukit/dev/i2c/i2c-dev.c @@ -115,6 +115,7 @@ static const rtems_filesystem_file_handlers_r i2c_dev_handler = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/dev/spi/spi-bus.c b/cpukit/dev/spi/spi-bus.c index dd84b021b2..343e203485 100644 --- a/cpukit/dev/spi/spi-bus.c +++ b/cpukit/dev/spi/spi-bus.c @@ -235,6 +235,7 @@ static const rtems_filesystem_file_handlers_r spi_bus_handler = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c index 7a2d00bcaf..f2008aa2f9 100644 --- a/cpukit/libblock/src/blkdev-imfs.c +++ b/cpukit/libblock/src/blkdev-imfs.c @@ -222,6 +222,7 @@ static const rtems_filesystem_file_handlers_r rtems_blkdev_imfs_node = { .fdatasync_h = rtems_blkdev_imfs_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h index 4669cb52e1..8226d18ba2 100644 --- a/cpukit/libcsupport/include/rtems/libio.h +++ b/cpukit/libcsupport/include/rtems/libio.h @@ -976,6 +976,28 @@ typedef int (*rtems_filesystem_kqfilter_t)( struct knote *kn ); +/** + * @brief MMAP support. + * + * @param[in, out] iop The IO pointer. + * @param[in, out] addr The starting address of the mapped memory. + * @param[in] len The maximum number of bytes to map. + * @param[in] prot The desired memory protection. + * @param[in] off The offset within the file descriptor to map. + * + * @retval 0 Successful operation. + * @retval error An error occurred. This is usually EINVAL. + * + * @see rtems_filesystem_default_mmap(). + */ +typedef int (*rtems_filesystem_mmap_t)( + rtems_libio_t *iop, + void **addr, + size_t len, + int prot, + off_t off +); + /** * @brief File system node operations table. */ @@ -995,6 +1017,7 @@ struct _rtems_filesystem_file_handlers_r { rtems_filesystem_kqfilter_t kqfilter_h; rtems_filesystem_readv_t readv_h; rtems_filesystem_writev_t writev_h; + rtems_filesystem_mmap_t mmap_h; }; /** @@ -1216,6 +1239,21 @@ int rtems_filesystem_default_kqfilter( struct knote *kn ); +/** + * @brief Default MMAP handler. + * + * @retval ENOTSUP Always. + * + * @see rtems_filesystem_mmap_t. + */ +int rtems_filesystem_default_mmap( + rtems_libio_t *iop, + void **addr, + size_t len, + int prot, + off_t off +); + /** @} */ /** diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h index e91faa7376..b3cac66e92 100644 --- a/cpukit/libcsupport/include/rtems/termiostypes.h +++ b/cpukit/libcsupport/include/rtems/termiostypes.h @@ -564,6 +564,19 @@ int rtems_termios_kqfilter( struct knote *kn ); +/** + * @brief Termios mmap() filter filesystem node handler + * + * Real implementation is provided by libbsd. + */ +int rtems_termios_mmap( + rtems_libio_t *iop, + void **addr, + size_t len, + int prot, + off_t off +); + /** * @brief Termios poll() filesystem node handler. * diff --git a/cpukit/libcsupport/src/__usrenv.c b/cpukit/libcsupport/src/__usrenv.c index a05295d642..611e0d7a92 100644 --- a/cpukit/libcsupport/src/__usrenv.c +++ b/cpukit/libcsupport/src/__usrenv.c @@ -56,6 +56,7 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_null_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c index a22ae95719..7d843495c5 100644 --- a/cpukit/libcsupport/src/termios.c +++ b/cpukit/libcsupport/src/termios.c @@ -2212,6 +2212,7 @@ static const rtems_filesystem_file_handlers_r rtems_termios_imfs_handler = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_termios_kqfilter, + .mmap_h = rtems_termios_mmap, .poll_h = rtems_termios_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am index 2a09aaa62d..0985b2ffb4 100644 --- a/cpukit/libfs/Makefile.am +++ b/cpukit/libfs/Makefile.am @@ -33,6 +33,7 @@ libdefaultfs_a_SOURCES = \ src/defaults/default_ftruncate_directory.c \ src/defaults/default_handlers.c src/defaults/default_ops.c libdefaultfs_a_SOURCES += src/defaults/default_kqfilter.c +libdefaultfs_a_SOURCES += src/defaults/default_mmap.c libdefaultfs_a_SOURCES += src/defaults/default_poll.c libdefaultfs_a_SOURCES += src/defaults/default_readv.c libdefaultfs_a_SOURCES += src/defaults/default_writev.c diff --git a/cpukit/libfs/src/defaults/default_handlers.c b/cpukit/libfs/src/defaults/default_handlers.c index 903cddc7f3..3730f6c283 100644 --- a/cpukit/libfs/src/defaults/default_handlers.c +++ b/cpukit/libfs/src/defaults/default_handlers.c @@ -34,6 +34,7 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_handlers_default = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/defaults/default_mmap.c b/cpukit/libfs/src/defaults/default_mmap.c new file mode 100644 index 0000000000..08534eef31 --- /dev/null +++ b/cpukit/libfs/src/defaults/default_mmap.c @@ -0,0 +1,40 @@ +/** + * @file + * + * @brief Default MMAP Handler + * + * @ingroup LibIOFSHandler + */ + +/* + * Copyright (c) 2017 Kevin Kirspel (kirspkt@gmail.com) + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include + +int rtems_filesystem_default_mmap( + rtems_libio_t *iop, + void **addr, + size_t len, + int prot, + off_t off +) +{ + rtems_set_errno_and_return_minus_one( ENOTSUP ); +} + +int rtems_termios_mmap( + rtems_libio_t *iop, + void **addr, + size_t len, + int prot, + off_t off +) RTEMS_WEAK_ALIAS( rtems_filesystem_default_mmap ); diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c index cb5099cd0c..1e960d2b5a 100644 --- a/cpukit/libfs/src/devfs/devfs_init.c +++ b/cpukit/libfs/src/devfs/devfs_init.c @@ -52,6 +52,7 @@ const rtems_filesystem_file_handlers_r devFS_file_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c index 1365ca13e3..bc2d8961c9 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c @@ -34,6 +34,7 @@ const rtems_filesystem_file_handlers_r msdos_dir_handlers = { .fdatasync_h = msdos_sync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c index 0bea6e15dc..ed72fb6512 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c @@ -34,6 +34,7 @@ const rtems_filesystem_file_handlers_r msdos_file_handlers = { .fdatasync_h = msdos_sync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_dir_default.c b/cpukit/libfs/src/imfs/imfs_dir_default.c index b31a50e784..a1fc2439fb 100644 --- a/cpukit/libfs/src/imfs/imfs_dir_default.c +++ b/cpukit/libfs/src/imfs/imfs_dir_default.c @@ -130,6 +130,7 @@ static const rtems_filesystem_file_handlers_r IMFS_dir_default_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_dir_minimal.c b/cpukit/libfs/src/imfs/imfs_dir_minimal.c index 3ef5173535..e97468d0d7 100644 --- a/cpukit/libfs/src/imfs/imfs_dir_minimal.c +++ b/cpukit/libfs/src/imfs/imfs_dir_minimal.c @@ -32,6 +32,7 @@ static const rtems_filesystem_file_handlers_r IMFS_dir_minimal_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c index d6c2187055..b97694e38a 100644 --- a/cpukit/libfs/src/imfs/imfs_fifo.c +++ b/cpukit/libfs/src/imfs/imfs_fifo.c @@ -127,6 +127,7 @@ static const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c index 0a7cb5f722..df9f6fce5b 100644 --- a/cpukit/libfs/src/imfs/imfs_handlers_device.c +++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c @@ -45,6 +45,7 @@ static const rtems_filesystem_file_handlers_r IMFS_device_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_linfile.c b/cpukit/libfs/src/imfs/imfs_linfile.c index 5840c16d98..57e106d85a 100644 --- a/cpukit/libfs/src/imfs/imfs_linfile.c +++ b/cpukit/libfs/src/imfs/imfs_linfile.c @@ -87,6 +87,7 @@ static const rtems_filesystem_file_handlers_r IMFS_linfile_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_link.c b/cpukit/libfs/src/imfs/imfs_link.c index 06794af682..add93e4562 100644 --- a/cpukit/libfs/src/imfs/imfs_link.c +++ b/cpukit/libfs/src/imfs/imfs_link.c @@ -93,6 +93,7 @@ static const rtems_filesystem_file_handlers_r IMFS_link_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_memfile.c b/cpukit/libfs/src/imfs/imfs_memfile.c index 2b6a49698a..2227bba6af 100644 --- a/cpukit/libfs/src/imfs/imfs_memfile.c +++ b/cpukit/libfs/src/imfs/imfs_memfile.c @@ -844,6 +844,7 @@ static const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync_success, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/imfs/imfs_symlink.c b/cpukit/libfs/src/imfs/imfs_symlink.c index 0f0644622b..4358ad6885 100644 --- a/cpukit/libfs/src/imfs/imfs_symlink.c +++ b/cpukit/libfs/src/imfs/imfs_symlink.c @@ -95,6 +95,7 @@ static const rtems_filesystem_file_handlers_r IMFS_link_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c index 8084776659..5e702ce5ec 100644 --- a/cpukit/libfs/src/jffs2/src/fs-rtems.c +++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c @@ -606,6 +606,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_directory_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev @@ -748,6 +749,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_file_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev @@ -766,6 +768,7 @@ static const rtems_filesystem_file_handlers_r rtems_jffs2_link_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c index 5673a248a6..87fef54ac0 100644 --- a/cpukit/libfs/src/nfsclient/src/nfs.c +++ b/cpukit/libfs/src/nfsclient/src/nfs.c @@ -2884,6 +2884,7 @@ struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev @@ -2904,6 +2905,7 @@ struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev @@ -2924,6 +2926,7 @@ struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c index a8ba126f16..3c69eaa30e 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c @@ -195,6 +195,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_device_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c index df0e639dfa..ab4e56f53d 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c @@ -164,6 +164,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = { .fdatasync_h = rtems_rfs_rtems_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c index 31df78acf1..99782db72b 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c @@ -348,6 +348,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = { .fdatasync_h = rtems_rfs_rtems_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c index 5ce526a8ed..45455eb85c 100644 --- a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c +++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c @@ -701,6 +701,7 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers = .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libnetworking/lib/ftpfs.c b/cpukit/libnetworking/lib/ftpfs.c index e016caeb2e..912ec82b39 100644 --- a/cpukit/libnetworking/lib/ftpfs.c +++ b/cpukit/libnetworking/lib/ftpfs.c @@ -1404,6 +1404,7 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev @@ -1422,6 +1423,7 @@ static const rtems_filesystem_file_handlers_r rtems_ftpfs_root_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libnetworking/lib/tftpDriver.c b/cpukit/libnetworking/lib/tftpDriver.c index 52236bea83..1a5823bc12 100644 --- a/cpukit/libnetworking/lib/tftpDriver.c +++ b/cpukit/libnetworking/lib/tftpDriver.c @@ -1053,6 +1053,7 @@ static const rtems_filesystem_file_handlers_r rtems_tftp_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/libnetworking/rtems/rtems_syscall.c b/cpukit/libnetworking/rtems/rtems_syscall.c index 6bef21afc4..29b2b4cfda 100644 --- a/cpukit/libnetworking/rtems/rtems_syscall.c +++ b/cpukit/libnetworking/rtems/rtems_syscall.c @@ -822,6 +822,7 @@ static const rtems_filesystem_file_handlers_r socket_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_bsdnet_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = rtems_filesystem_default_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev diff --git a/cpukit/posix/src/mmap.c b/cpukit/posix/src/mmap.c index 5b6ac2e209..d9b663dd1e 100644 --- a/cpukit/posix/src/mmap.c +++ b/cpukit/posix/src/mmap.c @@ -5,6 +5,7 @@ /* * Copyright (c) 2012 Chris Johns (chrisj@rtems.org) * Copyright (c) 2017 Gedare Bloom (gedare@rtems.org) + * Copyright (c) 2017 Kevin kirspel (kirspkt@gmail.com) * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -107,30 +108,6 @@ bool mmap_mappings_lock_release( return true; } -/* Helper function only gets called for mmap mappings of shared memory objects - * with the MAP_SHARED flag. - */ -static void *shm_mmap( rtems_libio_t *iop, size_t len, int prot, off_t off) -{ - POSIX_Shm_Control *shm = iop_to_shm( iop ); - void *m; - - _Objects_Allocator_lock(); - - m = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off); - if ( m != NULL ) { - /* Keep a reference in the shared memory to prevent its removal. */ - ++shm->reference_count; - - /* Update atime */ - _POSIX_Shm_Update_atime(shm); - } - - _Objects_Allocator_unlock(); - - return m; -} - void *mmap( void *addr, size_t len, int prot, int flags, int fildes, off_t off ) @@ -140,37 +117,25 @@ void *mmap( ssize_t r; rtems_libio_t *iop; bool map_fixed; + bool map_anonymous; + bool map_shared; + bool map_private; + int err; map_fixed = (flags & MAP_FIXED) == MAP_FIXED; + map_anonymous = (flags & MAP_ANON) == MAP_ANON; + map_shared = (flags & MAP_SHARED) == MAP_SHARED; + map_private = (flags & MAP_PRIVATE) == MAP_PRIVATE; /* Clear errno. */ errno = 0; - - /* - * Get a stat of the file to get the dev + inode number and to make sure the - * fd is ok. The normal libio calls cannot be used because we need to return - * MAP_FAILED on error and they return -1 directly without coming back to - * here. - */ - if ( fstat( fildes, &sb ) < 0 ) { - errno = EBADF; - return MAP_FAILED; - } - - /* fstat ensures we have a good file descriptor. Hold on to iop. */ - iop = rtems_libio_iop( fildes ); + iop = NULL; if ( len == 0 ) { errno = EINVAL; return MAP_FAILED; } - /* Check the type of file we have and make sure it is supported. */ - if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) { - errno = ENODEV; - return MAP_FAILED; - } - /* * We can provide read, write and execute because the memory in RTEMS does * not normally have protections but we cannot hide access to memory. @@ -180,17 +145,6 @@ void *mmap( return MAP_FAILED; } - /* Either MAP_SHARED or MAP_PRIVATE must be defined, but not both */ - if ( (flags & MAP_SHARED) == MAP_SHARED ) { - if ( (flags & MAP_PRIVATE) == MAP_PRIVATE ) { - errno = EINVAL; - return MAP_FAILED; - } - } else if ( (flags & MAP_PRIVATE) != MAP_PRIVATE ) { - errno = EINVAL; - return MAP_FAILED; - } - /* * We can not normally provide restriction of write access. Reject any * attempt to map without write permission, since we are not able to @@ -201,27 +155,104 @@ void *mmap( return MAP_FAILED; } - /* Check to see if the mapping is valid for a regular file. */ - if ( S_ISREG( sb.st_mode ) - /* FIXME: Should this be using strict inequality (>) comparisons? It would - * be valid to map a region exactly equal to the st_size, e.g. see below. */ - && (( off >= sb.st_size ) || (( off + len ) >= sb.st_size ))) { - errno = EOVERFLOW; + /* + * Anonymous mappings must have file descriptor set to -1 and the offset + * set to 0. Shared mappings are not supported with Anonymous mappings at + * this time + */ + if ( map_anonymous && (fildes != -1 || off != 0 || map_shared) ) { + errno = EINVAL; return MAP_FAILED; } /* - * Check to see if the mapping is valid for other file/object types. - * Does this satisfy for devices? + * If MAP_ANON is declared without MAP_PRIVATE or MAP_SHARED, + * force MAP_PRIVATE */ - if ( sb.st_size < off + len ) { - errno = ENXIO; + if ( map_anonymous && !map_private && !map_shared ) { + flags |= MAP_PRIVATE; + map_private = true; + } + + /* Check for supported flags */ + if ((flags & ~(MAP_SHARED | MAP_PRIVATE | MAP_FIXED | MAP_ANON)) != 0) { + errno = EINVAL; return MAP_FAILED; } - /* Do not seek on character devices, pipes, sockets, or memory objects. */ - if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) { - if ( lseek( fildes, off, SEEK_SET ) < 0 ) { + /* Either MAP_SHARED or MAP_PRIVATE must be defined, but not both */ + if ( map_shared ) { + if ( map_private ) { + errno = EINVAL; + return MAP_FAILED; + } + } else if ( !map_private ) { + errno = EINVAL; + return MAP_FAILED; + } + + /* Check for illegal addresses. Watch out for address wrap. */ + if ( map_fixed ) { + if ((uintptr_t)addr & PAGE_MASK) { + errno = EINVAL; + return MAP_FAILED; + } + if ( addr == NULL ) { + errno = EINVAL; + return MAP_FAILED; + } + if (addr + len < addr) { + errno = EINVAL; + return MAP_FAILED; + } + } + + if ( !map_anonymous ) { + /* + * Get a stat of the file to get the dev + inode number and to make sure the + * fd is ok. The normal libio calls cannot be used because we need to return + * MAP_FAILED on error and they return -1 directly without coming back to + * here. + */ + if ( fstat( fildes, &sb ) < 0 ) { + errno = EBADF; + return MAP_FAILED; + } + + /* fstat ensures we have a good file descriptor. Hold on to iop. */ + iop = rtems_libio_iop( fildes ); + + /* Check the type of file we have and make sure it is supported. */ + if ( S_ISDIR( sb.st_mode ) || S_ISLNK( sb.st_mode )) { + errno = ENODEV; + return MAP_FAILED; + } + + /* Check to see if the mapping is valid for a regular file. */ + if ( S_ISREG( sb.st_mode ) + /* FIXME: Should this be using strict inequality (>) comparisons? It would + * be valid to map a region exactly equal to the st_size, e.g. see below. */ + && (( off >= sb.st_size ) || (( off + len ) >= sb.st_size ))) { + errno = EOVERFLOW; + return MAP_FAILED; + } + + /* Check to see if the mapping is valid for other file/object types. */ + if ( !S_ISCHR( sb.st_mode ) && sb.st_size < off + len ) { + errno = ENXIO; + return MAP_FAILED; + } + + /* Do not seek on character devices, pipes, sockets, or memory objects. */ + if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) ) { + if ( lseek( fildes, off, SEEK_SET ) < 0 ) { + return MAP_FAILED; + } + } + + /* cdevs do not provide private mappings of any kind. */ + if ( S_ISCHR( sb.st_mode ) && map_private ) { + errno = EINVAL; return MAP_FAILED; } } @@ -230,42 +261,37 @@ void *mmap( mapping = malloc( sizeof( mmap_mapping )); if ( !mapping ) { errno = ENOMEM; - return NULL; + return MAP_FAILED; } memset( mapping, 0, sizeof( mmap_mapping )); mapping->len = len; mapping->flags = flags; mapping->iop = iop; - /* - * HACK: We should have a better generic way to distinguish between - * shm objects and other mmap'd files. We need to know at munmap time - * if the mapping is to a shared memory object in order to refcnt shms. - * We could do this by providing mmap in the file operations if needed. - */ - if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) || - S_ISCHR( sb.st_mode ) || S_ISFIFO( sb.st_mode ) || - S_ISSOCK( sb.st_mode ) ) { - mapping->is_shared_shm = false; + if ( !map_anonymous ) { + /* + * HACK: We should have a better generic way to distinguish between + * shm objects and other mmap'd files. We need to know at munmap time + * if the mapping is to a shared memory object in order to refcnt shms. + * We could do this by providing mmap in the file operations if needed. + */ + if ( S_ISREG( sb.st_mode ) || S_ISBLK( sb.st_mode ) || + S_ISCHR( sb.st_mode ) || S_ISFIFO( sb.st_mode ) || + S_ISSOCK( sb.st_mode ) ) { + mapping->is_shared_shm = false; + } else { + mapping->is_shared_shm = true; + } } else { - mapping->is_shared_shm = true; - } - - /* - * MAP_SHARED currently is only supported for shared memory objects. - */ - if ( (MAP_SHARED == (flags & MAP_SHARED)) && (mapping->is_shared_shm == false) ) { - free( mapping ); - errno = ENOTSUP; - return MAP_FAILED; + mapping->is_shared_shm = false; } if ( map_fixed ) { mapping->addr = addr; - } else if ( MAP_PRIVATE == (flags & MAP_PRIVATE) ) { + } else if ( map_private ) { /* private mappings of shared memory do not need special treatment. */ mapping->is_shared_shm = false; - mapping->addr = malloc( len ); + posix_memalign( &mapping->addr, PAGE_SIZE, len ); if ( !mapping->addr ) { free( mapping ); errno = ENOMEM; @@ -306,32 +332,43 @@ void *mmap( } /* Populate the data */ - if ( MAP_PRIVATE == (flags & MAP_PRIVATE) ) { - /* - * Use read() for private mappings. This updates atime as needed. - * Changes to the underlying object will NOT be reflected in the mapping. - * The underlying object can be removed while the mapping exists. - */ - r = read( fildes, mapping->addr, len ); + if ( map_private ) { + if ( !map_anonymous ) { + /* + * Use read() for private mappings. This updates atime as needed. + * Changes to the underlying object will NOT be reflected in the mapping. + * The underlying object can be removed while the mapping exists. + */ + r = read( fildes, mapping->addr, len ); - if ( r != len ) { - mmap_mappings_lock_release( ); - if ( !map_fixed ) { - free( mapping->addr ); + if ( r != len ) { + mmap_mappings_lock_release( ); + if ( !map_fixed ) { + free( mapping->addr ); + } + free( mapping ); + errno = ENXIO; + return MAP_FAILED; } + } else if ( !map_fixed ) { + memset( mapping->addr, 0, len ); + } + } else if ( map_shared ) { + err = (*iop->pathinfo.handlers->mmap_h)( + iop, &mapping->addr, len, prot, off ); + if ( err != 0 ) { + mmap_mappings_lock_release( ); free( mapping ); - errno = ENXIO; return MAP_FAILED; } - } else if ( MAP_SHARED == (flags & MAP_SHARED) ) { - /* Currently only shm objects can be MAP_SHARED. */ - mapping->addr = shm_mmap(iop, len, prot, off); } - /* add an extra reference to the file associated with fildes that - * is not removed by a subsequent close(). This reference shall be removed - * when there are no more mappings to the file. */ - rtems_libio_increment_mapping_refcnt(iop); + if ( iop != NULL ) { + /* add an extra reference to the file associated with fildes that + * is not removed by a subsequent close(). This reference shall be removed + * when there are no more mappings to the file. */ + rtems_libio_increment_mapping_refcnt(iop); + } rtems_chain_append( &mmap_mappings, &mapping->node ); diff --git a/cpukit/posix/src/munmap.c b/cpukit/posix/src/munmap.c index 323a24e6f4..2d812ae041 100644 --- a/cpukit/posix/src/munmap.c +++ b/cpukit/posix/src/munmap.c @@ -46,6 +46,12 @@ int munmap(void *addr, size_t len) return -1; } + /* Check for illegal addresses. Watch out for address wrap. */ + if (addr + len < addr) { + errno = EINVAL; + return -1; + } + /* * Obtain the mmap lock. Sets errno on failure. */ @@ -63,9 +69,11 @@ int munmap(void *addr, size_t len) if ( mapping->is_shared_shm == true ) { shm_munmap(mapping->iop); } - refcnt = rtems_libio_decrement_mapping_refcnt(mapping->iop); - if ( refcnt == 0 ) { - rtems_libio_check_deferred_free(mapping->iop); + if ( mapping->iop != NULL ) { + refcnt = rtems_libio_decrement_mapping_refcnt(mapping->iop); + if ( refcnt == 0 ) { + rtems_libio_check_deferred_free(mapping->iop); + } } /* only free the mapping address for non-fixed mapping */ if (( mapping->flags & MAP_FIXED ) != MAP_FIXED ) { diff --git a/cpukit/posix/src/shmopen.c b/cpukit/posix/src/shmopen.c index fa1027e30c..e729f9bd4e 100644 --- a/cpukit/posix/src/shmopen.c +++ b/cpukit/posix/src/shmopen.c @@ -106,6 +106,35 @@ static int shm_close( rtems_libio_t *iop ) return 0; } +static int shm_mmap( + rtems_libio_t *iop, + void** addr, + size_t len, + int prot, + off_t off +) +{ + POSIX_Shm_Control *shm = iop_to_shm( iop ); + + _Objects_Allocator_lock(); + + *addr = (*shm->shm_object.ops->object_mmap)( &shm->shm_object, len, prot, off); + if ( *addr != NULL ) { + /* Keep a reference in the shared memory to prevent its removal. */ + ++shm->reference_count; + + /* Update atime */ + _POSIX_Shm_Update_atime(shm); + } else { + _Objects_Allocator_unlock(); + rtems_set_errno_and_return_minus_one( ENOMEM ); + } + + _Objects_Allocator_unlock(); + + return 0; +} + static inline POSIX_Shm_Control *shm_allocate( const char *name_arg, size_t name_len, @@ -275,6 +304,7 @@ static const rtems_filesystem_file_handlers_r shm_handlers = { .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync, .fcntl_h = rtems_filesystem_default_fcntl, .kqfilter_h = rtems_filesystem_default_kqfilter, + .mmap_h = shm_mmap, .poll_h = rtems_filesystem_default_poll, .readv_h = rtems_filesystem_default_readv, .writev_h = rtems_filesystem_default_writev -- cgit v1.2.3