You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/08/03 05:57:34 UTC

[nuttx] branch master updated (44442a655e -> 1adef07a79)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 44442a655e inet/ipv4_setsockopt.c:fix libuv udp option error
     new 5176fb917a fs/vfs: ftruncate produce EINVAL if fd is not open for writing
     new d892cda167 fs/mmap: fix mmap() wrong errno
     new d1825a7acb fs/mmap: only MAP_SHARED mapping need file write permisson
     new 2bf434214e libc/sysconf: add _SC_REALTIME_SIGNALS
     new 7e90855d76 drivers/pipe: implement pipe mmap just return ENODEV
     new 43b0421b2a mm/map: limit the count of memory mapping for the task
     new bfeb73e850 fs/tmpfs: fix use after free issue
     new ea52220509 fs/shmfs: fix inode leak issue
     new 1adef07a79 fs/shmfs: implement read and write interface

The 9 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 drivers/pipes/pipe.c           |  18 ++++++-
 fs/mmap/fs_mmap.c              |   7 +--
 fs/shm/shmfs.c                 | 108 ++++++++++++++++++++++++++++++++++++-----
 fs/tmpfs/fs_tmpfs.c            |  87 +++++++++++++++++----------------
 fs/vfs/fs_truncate.c           |   2 +-
 fs/vfs/fs_unlink.c             |   3 +-
 include/nuttx/mm/map.h         |   2 +
 include/unistd.h               |   2 +-
 libs/libc/unistd/lib_sysconf.c |   2 +
 mm/Kconfig                     |   6 +++
 mm/map/Make.defs               |   2 +-
 mm/map/mm_map.c                |  18 +++++++
 12 files changed, 196 insertions(+), 61 deletions(-)


[nuttx] 04/09: libc/sysconf: add _SC_REALTIME_SIGNALS

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 2bf434214ec73445d941dbcb60bcfd27a075d141
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Sat Jun 24 19:40:00 2023 +0800

    libc/sysconf: add _SC_REALTIME_SIGNALS
    
    pass ltp case: open_posix_testsuite/conformance/interfaces/sigwait/7-1.c
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 include/unistd.h               | 2 +-
 libs/libc/unistd/lib_sysconf.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/unistd.h b/include/unistd.h
index 4b2666a10e..4b2b89f6ec 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -45,7 +45,6 @@
 #define POSIX_VERSION
 #undef  _POSIX_SAVED_IDS
 #undef  _POSIX_JOB_CONTROL
-#define _POSIX_REALTIME_SIGNALS 1
 #define _POSIX_MESSAGE_PASSING 1
 #undef  _POSIX_MAPPED_FILES
 #undef  _POSIX_SHARED_MEMORY_OBJECTS
@@ -65,6 +64,7 @@
 #define _POSIX_PRIORITIZED_IO _POSIX_VERSION
 #define _POSIX_CPUTIME _POSIX_VERSION
 #define _POSIX_THREAD_CPUTIME _POSIX_VERSION
+#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION
 #define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
 
 #ifdef CONFIG_FS_AIO
diff --git a/libs/libc/unistd/lib_sysconf.c b/libs/libc/unistd/lib_sysconf.c
index f0fde4bfe2..eff4e718e2 100644
--- a/libs/libc/unistd/lib_sysconf.c
+++ b/libs/libc/unistd/lib_sysconf.c
@@ -227,6 +227,8 @@ long sysconf(int name)
         return _POSIX_CPUTIME;
       case _SC_THREAD_CPUTIME:
         return _POSIX_THREAD_CPUTIME;
+      case _SC_REALTIME_SIGNALS:
+        return _POSIX_REALTIME_SIGNALS;
       case _SC_CLK_TCK:
         return CLOCKS_PER_SEC;
 


[nuttx] 01/09: fs/vfs: ftruncate produce EINVAL if fd is not open for writing

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5176fb917a64e0657798cf7367817bd1c33af18c
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Fri Jun 9 21:13:21 2023 +0800

    fs/vfs: ftruncate produce EINVAL if fd is not open for writing
    
    As posix spec, ftruncate should produce EBADF or EINVAL error,
    if the file descriptor fd is not open for writing.
    
    Change the behavior to be similar to Linux and pass ltp open_posix test:
    testcases/open_posix_testsuite/conformance/interfaces/shm_open/20-1.c
    
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html
    https://man7.org/linux/man-pages/man2/ftruncate.2.html
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/vfs/fs_truncate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/vfs/fs_truncate.c b/fs/vfs/fs_truncate.c
index 91bbd8e5a0..2f11c17ec9 100644
--- a/fs/vfs/fs_truncate.c
+++ b/fs/vfs/fs_truncate.c
@@ -57,7 +57,7 @@ int file_truncate(FAR struct file *filep, off_t length)
   if ((filep->f_oflags & O_WROK) == 0)
     {
       fwarn("WARNING: Cannot truncate a file opened read-only\n");
-      return -EBADF;
+      return -EINVAL;
     }
 
   /* Is this inode a registered mountpoint? Does it support the


[nuttx] 06/09: mm/map: limit the count of memory mapping for the task

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 43b0421b2a51769304eab3c4bc26960c492bd324
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Tue Jul 18 19:39:26 2023 +0800

    mm/map: limit the count of memory mapping for the task
    
    No memory map count limit that will exhaust memory and cause
    the system hang. Also that fix pass LTP posix case mmap/24-1.c
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/shm/shmfs.c         |  2 +-
 include/nuttx/mm/map.h |  2 ++
 mm/Kconfig             |  6 ++++++
 mm/map/Make.defs       |  2 +-
 mm/map/mm_map.c        | 18 ++++++++++++++++++
 5 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/fs/shm/shmfs.c b/fs/shm/shmfs.c
index 21197f47a2..7f0d6d73dd 100644
--- a/fs/shm/shmfs.c
+++ b/fs/shm/shmfs.c
@@ -302,7 +302,7 @@ static int shmfs_mmap(FAR struct file *filep,
         {
           entry->munmap = shmfs_munmap;
           entry->priv.p = (FAR void *)filep->f_inode;
-          mm_map_add(get_current_mm(), entry);
+          ret = mm_map_add(get_current_mm(), entry);
         }
     }
 
diff --git a/include/nuttx/mm/map.h b/include/nuttx/mm/map.h
index 7bbaf94346..53c45c26b1 100644
--- a/include/nuttx/mm/map.h
+++ b/include/nuttx/mm/map.h
@@ -75,6 +75,8 @@ struct mm_map_s
 {
   sq_queue_t mm_map_sq;
 
+  size_t map_count;
+
 #ifdef CONFIG_ARCH_VMA_MAPPING
   GRAN_HANDLE mm_map_vpages;
 #endif
diff --git a/mm/Kconfig b/mm/Kconfig
index a2af336f7d..c6859f21cb 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -98,6 +98,12 @@ config MM_REGIONS
 		that the memory manager must handle and enables the API
 		mm_addregion(heap, start, end);
 
+config MM_MAP_COUNT_MAX
+	int "The maximum number of memory map areas for each task"
+	default 1024
+	---help---
+		The maximum number of memory map areas for each task.
+
 config ARCH_HAVE_HEAP2
 	bool
 	default n
diff --git a/mm/map/Make.defs b/mm/map/Make.defs
index 9a58507b27..9daa50c241 100644
--- a/mm/map/Make.defs
+++ b/mm/map/Make.defs
@@ -26,7 +26,7 @@ ifeq ($(CONFIG_ARCH_VMA_MAPPING),y)
 CSRCS += vm_region.c
 endif
 
-# Add the shared memory directory to the build
+# Add the map directory to the build
 
 DEPPATH += --dep-path map
 VPATH += :map
diff --git a/mm/map/mm_map.c b/mm/map/mm_map.c
index 1cb93970b3..f9bfe302cd 100644
--- a/mm/map/mm_map.c
+++ b/mm/map/mm_map.c
@@ -93,6 +93,7 @@ void mm_map_initialize(FAR struct mm_map_s *mm, bool kernel)
 {
   sq_init(&mm->mm_map_sq);
   nxrmutex_init(&mm->mm_map_mutex);
+  mm->map_count = 0;
 
   /* Create the virtual pages allocator for user process */
 
@@ -148,9 +149,13 @@ void mm_map_destroy(FAR struct mm_map_s *mm)
             }
         }
 
+      mm->map_count--;
+
       kmm_free(entry);
     }
 
+  DEBUGASSERT(mm->map_count == 0);
+
   nxrmutex_destroy(&mm->mm_map_mutex);
 
   /* Release the virtual pages allocator */
@@ -198,6 +203,17 @@ int mm_map_add(FAR struct mm_map_s *mm, FAR struct mm_map_entry_s *entry)
       return ret;
     }
 
+  /* Too many mappings? */
+
+  if (mm->map_count >= CONFIG_MM_MAP_COUNT_MAX)
+    {
+      kmm_free(new_entry);
+      nxrmutex_unlock(&mm->mm_map_mutex);
+      return -ENOMEM;
+    }
+
+  mm->map_count++;
+
   sq_addfirst((sq_entry_t *)new_entry, &mm->mm_map_sq);
 
   nxrmutex_unlock(&mm->mm_map_mutex);
@@ -309,6 +325,7 @@ int mm_map_remove(FAR struct mm_map_s *mm,
   if (entry == prev_entry)
     {
       sq_remfirst(&mm->mm_map_sq);
+      mm->map_count--;
       removed_entry = prev_entry;
     }
   else
@@ -321,6 +338,7 @@ int mm_map_remove(FAR struct mm_map_s *mm,
           if (entry == removed_entry)
             {
               sq_remafter((sq_entry_t *)prev_entry, &mm->mm_map_sq);
+              mm->map_count--;
               break;
             }
 


[nuttx] 08/09: fs/shmfs: fix inode leak issue

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit ea522205097ba4ff03484f9fc46b148d9bfc9ceb
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Tue Jul 25 01:16:19 2023 +0800

    fs/shmfs: fix inode leak issue
    
    If the shm file is removed and a subsequent close, only release shm
    object, but inode is leaked. Should decrease refcount to release inode
    when unmapped, that matched with refcount increase when mapped.
    
    Another fix that remove the shm file failed.
    nsh> rm /var/shm/pts_mmap_1_2_5
    nsh: rm: unlink failed: 6
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/shm/shmfs.c     | 32 +++++++++++++++++++++++---------
 fs/vfs/fs_unlink.c |  3 ++-
 2 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/fs/shm/shmfs.c b/fs/shm/shmfs.c
index 7f0d6d73dd..8e634e0005 100644
--- a/fs/shm/shmfs.c
+++ b/fs/shm/shmfs.c
@@ -258,6 +258,18 @@ static int shmfs_map_object(FAR struct shmfs_object_s *object,
   return ret;
 }
 
+/****************************************************************************
+ * Name: shmfs_add_map
+ ****************************************************************************/
+
+static int shmfs_add_map(FAR struct mm_map_entry_s *entry,
+                         FAR struct inode *inode)
+{
+  entry->munmap = shmfs_munmap;
+  entry->priv.p = (FAR void *)inode;
+  return mm_map_add(get_current_mm(), entry);
+}
+
 /****************************************************************************
  * Name: shmfs_mmap
  ****************************************************************************/
@@ -294,16 +306,11 @@ static int shmfs_mmap(FAR struct file *filep,
           ret = -EINVAL;
         }
 
-      if (ret < 0)
+      if (ret < 0 ||
+          (ret = shmfs_add_map(entry, filep->f_inode)) < 0)
         {
           inode_release(filep->f_inode);
         }
-      else
-        {
-          entry->munmap = shmfs_munmap;
-          entry->priv.p = (FAR void *)filep->f_inode;
-          ret = mm_map_add(get_current_mm(), entry);
-        }
     }
 
   return ret;
@@ -349,6 +356,7 @@ static int shmfs_munmap(FAR struct task_group_s *group,
                         FAR void *start,
                         size_t length)
 {
+  FAR struct inode *inode;
   int ret;
 
   /* Partial unmap is not supported yet */
@@ -358,6 +366,8 @@ static int shmfs_munmap(FAR struct task_group_s *group,
       return -EINVAL;
     }
 
+  inode = (FAR struct inode *)entry->priv.p;
+
   /* Unmap the virtual memory area from the user's address space */
 
   ret = shmfs_unmap_area(group, entry->vaddr, entry->length);
@@ -369,13 +379,17 @@ static int shmfs_munmap(FAR struct task_group_s *group,
 
   if (ret == OK)
     {
-      ret = shmfs_release((FAR struct inode *)entry->priv.p);
+      ret = shmfs_release(inode);
     }
 
-  /* Remove the mapping. */
+  /* Unkeep the inode when unmapped, decrease refcount */
 
   if (ret == OK)
     {
+      inode_release(inode);
+
+      /* Remove the mapping. */
+
       ret = mm_map_remove(get_group_mm(group), entry);
     }
 
diff --git a/fs/vfs/fs_unlink.c b/fs/vfs/fs_unlink.c
index e3b77b7846..515f577ff8 100644
--- a/fs/vfs/fs_unlink.c
+++ b/fs/vfs/fs_unlink.c
@@ -123,7 +123,8 @@ int nx_unlink(FAR const char *pathname)
        * release all resources because it is no longer accessible.
        */
 
-      if (INODE_IS_DRIVER(inode) && inode->u.i_ops->unlink)
+      if ((INODE_IS_DRIVER(inode) || INODE_IS_SHM(inode)) &&
+           inode->u.i_ops->unlink)
         {
           /* Notify the character driver that it has been unlinked */
 


[nuttx] 02/09: fs/mmap: fix mmap() wrong errno

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d892cda16736053868d28973ac53cc6826b00cc1
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Sat Jun 10 00:41:52 2023 +0800

    fs/mmap: fix mmap() wrong errno
    
    As posix spec, mmap() function shall fail with ENODEV if fd refers
    to a file whose type is not supported. Change to pass ltp open_posix test:
    testcases/open_posix_testsuite/conformance/interfaces/mmap/23-1.c
    
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/mmap/fs_mmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c
index d4bb97f29d..fcfdefeaed 100644
--- a/fs/mmap/fs_mmap.c
+++ b/fs/mmap/fs_mmap.c
@@ -269,8 +269,8 @@ FAR void *mmap(FAR void *start, size_t length, int prot, int flags,
 
   if (fd != -1 && fs_getfilep(fd, &filep) < 0)
     {
-      ferr("ERROR: Invalid file descriptor, fd=%d\n", fd);
-      ret = -EBADF;
+      ferr("ERROR: fd:%d referred file whose type is not supported\n", fd);
+      ret = -ENODEV;
       goto errout;
     }
 


[nuttx] 09/09: fs/shmfs: implement read and write interface

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 1adef07a791c74705aef465a70704c36710f6ecc
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Mon Jul 24 22:01:03 2023 +0800

    fs/shmfs: implement read and write interface
    
    To pass LTP posix case mmap/1-2.c
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/shm/shmfs.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 74 insertions(+), 2 deletions(-)

diff --git a/fs/shm/shmfs.c b/fs/shm/shmfs.c
index 8e634e0005..1adf884033 100644
--- a/fs/shm/shmfs.c
+++ b/fs/shm/shmfs.c
@@ -89,7 +89,45 @@ const struct file_operations g_shmfs_operations =
 static ssize_t shmfs_read(FAR struct file *filep, FAR char *buffer,
                           size_t buflen)
 {
-  return -ENOSYS;
+  FAR struct shmfs_object_s *sho;
+  ssize_t nread;
+  off_t startpos;
+  off_t endpos;
+
+  DEBUGASSERT(filep->f_inode != NULL && filep->f_inode->i_private != NULL);
+
+  sho = filep->f_inode->i_private;
+
+  if (filep->f_pos > sho->length)
+    {
+      return 0;
+    }
+
+  /* Handle attempts to read beyond the end of the file. */
+
+  startpos = filep->f_pos;
+  nread    = buflen;
+  endpos   = startpos + buflen;
+
+  if (endpos > sho->length)
+    {
+      endpos = sho->length;
+      nread  = endpos - startpos;
+    }
+
+  /* Copy data from the memory object to the user buffer */
+
+  if (sho->paddr != NULL)
+    {
+      memcpy(buffer, sho->paddr + startpos, nread);
+      filep->f_pos += nread;
+    }
+  else
+    {
+      DEBUGASSERT(sho->length == 0 && nread == 0);
+    }
+
+  return nread;
 }
 
 /****************************************************************************
@@ -99,7 +137,41 @@ static ssize_t shmfs_read(FAR struct file *filep, FAR char *buffer,
 static ssize_t shmfs_write(FAR struct file *filep, FAR const char *buffer,
                            size_t buflen)
 {
-  return -ENOSYS;
+  FAR struct shmfs_object_s *sho;
+  ssize_t nwritten;
+  off_t startpos;
+  off_t endpos;
+
+  DEBUGASSERT(filep->f_inode != NULL && filep->f_inode->i_private != NULL);
+
+  sho = filep->f_inode->i_private;
+
+  /* Handle attempts to write beyond the end of the file */
+
+  startpos = filep->f_pos;
+  nwritten = buflen;
+  endpos   = startpos + buflen;
+
+  /* Desn't support shm auto expand, truncate first */
+
+  if (endpos > sho->length)
+    {
+      return -EFBIG;
+    }
+
+  /* Copy data from the user buffer to the memory object */
+
+  if (sho->paddr != NULL)
+    {
+      memcpy(sho->paddr + startpos, buffer, nwritten);
+      filep->f_pos += nwritten;
+    }
+  else
+    {
+      DEBUGASSERT(sho->length == 0 && nwritten == 0);
+    }
+
+  return nwritten;
 }
 
 /****************************************************************************


[nuttx] 07/09: fs/tmpfs: fix use after free issue

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit bfeb73e850ec046293ab57084a10a96fd9e21009
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Wed Jul 19 19:27:03 2023 +0800

    fs/tmpfs: fix use after free issue
    
    mmap establish a mapping address space that refer to a tmpfs file,
    there are two issues:
    
    1. if the tmpfs file is removed and a subsequent close(), tmpfs_close
    will release the backend memory object, use after free errors occur
    when operating the mapping memory. We add an extra reference to memory object,
    memory will be released when there are no more mappings.
    
    2. if unmap only a portion of the memory, fix the bug that adds another map.
    Use realloc and shrink the mapping memory instead.
    
    The fix pass LTP posix case mmap/10-1.c and mmap/12-1.c
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/tmpfs/fs_tmpfs.c | 87 +++++++++++++++++++++++++++--------------------------
 1 file changed, 45 insertions(+), 42 deletions(-)

diff --git a/fs/tmpfs/fs_tmpfs.c b/fs/tmpfs/fs_tmpfs.c
index f9ce58d23c..b477e890ec 100644
--- a/fs/tmpfs/fs_tmpfs.c
+++ b/fs/tmpfs/fs_tmpfs.c
@@ -93,6 +93,7 @@ static int  tmpfs_realloc_file(FAR struct tmpfs_file_s *tfo,
               size_t newsize);
 static void tmpfs_release_lockedobject(FAR struct tmpfs_object_s *to);
 static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo);
+static int  tmpfs_release_file(FAR struct tmpfs_file_s *tfo);
 static int  tmpfs_find_dirent(FAR struct tmpfs_directory_s *tdo,
               FAR const char *name, size_t len);
 static int  tmpfs_remove_dirent(FAR struct tmpfs_directory_s *tdo,
@@ -349,6 +350,7 @@ static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo)
 
   if (tfo->tfo_refs == 1 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0)
     {
+      tmpfs_unlock_file(tfo);
       nxrmutex_destroy(&tfo->tfo_lock);
       kmm_free(tfo->tfo_data);
       kmm_free(tfo);
@@ -363,6 +365,28 @@ static void tmpfs_release_lockedfile(FAR struct tmpfs_file_s *tfo)
     }
 }
 
+/****************************************************************************
+ * Name: tmpfs_release_file
+ ****************************************************************************/
+
+static int tmpfs_release_file(FAR struct tmpfs_file_s *tfo)
+{
+  int ret;
+
+  DEBUGASSERT(tfo);
+
+  /* Get exclusive access to the file */
+
+  ret = tmpfs_lock_file(tfo);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  tmpfs_release_lockedfile(tfo);
+  return OK;
+}
+
 /****************************************************************************
  * Name: tmpfs_find_dirent
  ****************************************************************************/
@@ -1411,49 +1435,15 @@ static int tmpfs_close(FAR struct file *filep)
   finfo("filep: %p\n", filep);
   DEBUGASSERT(filep->f_priv != NULL && filep->f_inode != NULL);
 
-  /* Recover our private data from the struct file instance */
-
   tfo = filep->f_priv;
 
-  /* Get exclusive access to the file */
-
-  ret = tmpfs_lock_file(tfo);
-  if (ret < 0)
-    {
-      return ret;
-    }
-
-  /* Decrement the reference count on the file */
-
-  DEBUGASSERT(tfo->tfo_refs > 0);
-  if (tfo->tfo_refs > 0)
-    {
-      tfo->tfo_refs--;
-    }
-
-  filep->f_priv = NULL;
-
-  /* If the reference count decremented to zero and the file has been
-   * unlinked, then free the file allocation now.
-   */
-
-  if (tfo->tfo_refs == 0 && (tfo->tfo_flags & TFO_FLAG_UNLINKED) != 0)
+  ret = tmpfs_release_file(tfo);
+  if (ret >= 0)
     {
-      /* Free the file object while we hold the lock?  Weird but this
-       * should be safe because the object is unlinked and could not
-       * have any other references.
-       */
-
-      nxrmutex_destroy(&tfo->tfo_lock);
-      kmm_free(tfo->tfo_data);
-      kmm_free(tfo);
-      return OK;
+      filep->f_priv = NULL;
     }
 
-  /* Release the lock on the file */
-
-  tmpfs_unlock_file(tfo);
-  return OK;
+  return ret;
 }
 
 /****************************************************************************
@@ -1647,7 +1637,7 @@ static int tmpfs_unmap(FAR struct task_group_s *group,
                        FAR struct mm_map_entry_s *entry,
                        FAR void *start, size_t length)
 {
-  FAR struct file *filep = entry->priv.p;
+  FAR struct tmpfs_file_s *tfo = entry->priv.p;
   off_t offset;
   int ret;
 
@@ -1671,6 +1661,10 @@ static int tmpfs_unmap(FAR struct task_group_s *group,
       /* Then remove the mapping from the list */
 
       ret = mm_map_remove(get_group_mm(group), entry);
+      if (ret >= 0)
+        {
+          ret = tmpfs_release_file(tfo);
+        }
     }
 
   /* No.. We have been asked to "unmap' only a portion of the memory
@@ -1679,8 +1673,10 @@ static int tmpfs_unmap(FAR struct task_group_s *group,
 
   else
     {
-      entry->length = length;
-      ret = tmpfs_mmap(filep, entry);
+      entry->length = offset;
+      tmpfs_lock_file(tfo);
+      ret = tmpfs_realloc_file(tfo, offset);
+      tmpfs_unlock_file(tfo);
     }
 
   return ret;
@@ -1703,9 +1699,16 @@ static int tmpfs_mmap(FAR struct file *filep, FAR struct mm_map_entry_s *map)
       map->length && map->offset + map->length <= tfo->tfo_size)
     {
       map->vaddr = tfo->tfo_data + map->offset;
-      map->priv.p = filep;
+      map->priv.p = tfo;
       map->munmap = tmpfs_unmap;
       ret = mm_map_add(get_current_mm(), map);
+
+      if (ret >= 0)
+        {
+          tmpfs_lock_file(tfo);
+          tfo->tfo_refs++;
+          tmpfs_unlock_file(tfo);
+        }
     }
 
   return ret;


[nuttx] 05/09: drivers/pipe: implement pipe mmap just return ENODEV

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 7e90855d764b114c4cd3df62d8c228274561e610
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Tue Jul 18 20:32:59 2023 +0800

    drivers/pipe: implement pipe mmap just return ENODEV
    
    The fd of pipe type is not supported by mmap, mmap() shall failed
    with ENODEV. If pipe mmap is not implemented, mmap will forward to
    rammap() and get unexpected error.
    
    Implement pipe mmap just return ENODEV. That is to pass LTP posix
    test case mmap/23-1.c
    
    https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 drivers/pipes/pipe.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/pipes/pipe.c b/drivers/pipes/pipe.c
index 5ff22b044b..ab3220ebf4 100644
--- a/drivers/pipes/pipe.c
+++ b/drivers/pipes/pipe.c
@@ -49,6 +49,9 @@
 
 static int pipe_close(FAR struct file *filep);
 
+static int pipe_mmap(FAR struct file *filep,
+                     FAR struct mm_map_entry_s *entry);
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -61,7 +64,7 @@ static const struct file_operations g_pipe_fops =
   pipecommon_write,    /* write */
   NULL,                /* seek */
   pipecommon_ioctl,    /* ioctl */
-  NULL,                /* mmap */
+  pipe_mmap,           /* mmap */
   NULL,                /* truncate */
   pipecommon_poll      /* poll */
 };
@@ -122,6 +125,19 @@ static int pipe_close(FAR struct file *filep)
   return ret;
 }
 
+/****************************************************************************
+ * Name: pipe_mmap
+ ****************************************************************************/
+
+static int pipe_mmap(FAR struct file *filep,
+                     FAR struct mm_map_entry_s *entry)
+{
+  UNUSED(filep);
+  UNUSED(entry);
+
+  return -ENODEV;
+}
+
 /****************************************************************************
  * Name: pipe_register
  ****************************************************************************/


[nuttx] 03/09: fs/mmap: only MAP_SHARED mapping need file write permisson

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d1825a7acb01da26eea008866bea948ce7529186
Author: fangxinyong <fa...@xiaomi.com>
AuthorDate: Wed Jun 14 14:40:13 2023 +0800

    fs/mmap: only MAP_SHARED mapping need file write permisson
    
    If MAP_PRIVATE is specified, do not change the underlying object,
    that is OK to open file with read-only permission. Change to pass:
    testcases/open_posix_testsuite/conformance/interfaces/mmap/6-5.c
    
    Signed-off-by: fangxinyong <fa...@xiaomi.com>
---
 fs/mmap/fs_mmap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/mmap/fs_mmap.c b/fs/mmap/fs_mmap.c
index fcfdefeaed..b00ce43996 100644
--- a/fs/mmap/fs_mmap.c
+++ b/fs/mmap/fs_mmap.c
@@ -118,7 +118,8 @@ static int file_mmap_(FAR struct file *filep, FAR void *start,
       return -EBADF;
     }
 
-  if ((filep->f_oflags & O_WROK) == 0 && prot == PROT_WRITE)
+  if ((flags & MAP_SHARED) &&
+      (filep->f_oflags & O_WROK) == 0 && prot == PROT_WRITE)
     {
       ferr("ERROR: Unsupported options for read-only file descriptor,"
            "prot=%x flags=%04x\n", prot, flags);