This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 0cf3e49a129 fs/shm: Copy the data of a shm object page by page in the
kernel build.
0cf3e49a129 is described below
commit 0cf3e49a129243f1fc22cdd388dee93cb9badb31
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Oct 21 17:09:53 2026 +0200
fs/shm: Copy the data of a shm object page by page in the kernel build.
In the kernel build, a shm object is a list of single pages from the
page pool. shmfs_read() and shmfs_write() copied the data at the first
page plus the file position. After the first page, this is correct
only if the pages of the object are contiguous, and it uses the
physical address as the kernel address.
Copy the data page by page through the kernel address of each page
(up_addrenv_page_vaddr()). The flat and protected builds keep the
object in one block of memory and do not change.
Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <[email protected]>
---
fs/shm/shmfs.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/fs/shm/shmfs.c b/fs/shm/shmfs.c
index 37191f8ae41..63aacbff1b4 100644
--- a/fs/shm/shmfs.c
+++ b/fs/shm/shmfs.c
@@ -25,6 +25,9 @@
****************************************************************************/
#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/param.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/mm/map.h>
@@ -84,6 +87,58 @@ const struct file_operations g_shmfs_operations =
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: shmfs_copy
+ *
+ * Description:
+ * Copy data between a buffer and a memory object. In the kernel build
+ * the object is a list of single pages from the page pool, which are not
+ * always contiguous: copy page by page through the kernel address of
+ * each page. In the other builds the object is one block of memory.
+ *
+ ****************************************************************************/
+
+static void shmfs_copy(FAR struct shmfs_object_s *sho, off_t pos,
+ FAR char *buffer, size_t len, bool write)
+{
+#ifdef CONFIG_BUILD_KERNEL
+ FAR uintptr_t *pages = (FAR uintptr_t *)&sho->paddr;
+ FAR char *vaddr;
+ size_t offset;
+ size_t n;
+
+ while (len > 0)
+ {
+ offset = pos % MM_PGSIZE;
+ n = MIN(len, MM_PGSIZE - offset);
+ vaddr = (FAR char *)up_addrenv_page_vaddr(pages[pos / MM_PGSIZE]) +
+ offset;
+
+ if (write)
+ {
+ memcpy(vaddr, buffer, n);
+ }
+ else
+ {
+ memcpy(buffer, vaddr, n);
+ }
+
+ pos += n;
+ buffer += n;
+ len -= n;
+ }
+#else
+ if (write)
+ {
+ memcpy((FAR char *)sho->paddr + pos, buffer, len);
+ }
+ else
+ {
+ memcpy(buffer, (FAR char *)sho->paddr + pos, len);
+ }
+#endif
+}
+
/****************************************************************************
* Name: shmfs_read
****************************************************************************/
@@ -121,7 +176,7 @@ static ssize_t shmfs_read(FAR struct file *filep, FAR char
*buffer,
if (sho->paddr != NULL)
{
- memcpy(buffer, (FAR char *)sho->paddr + startpos, nread);
+ shmfs_copy(sho, startpos, buffer, nread, false);
filep->f_pos += nread;
}
else
@@ -165,7 +220,7 @@ static ssize_t shmfs_write(FAR struct file *filep, FAR
const char *buffer,
if (sho->paddr != NULL)
{
- memcpy((FAR char *)sho->paddr + startpos, buffer, nwritten);
+ shmfs_copy(sho, startpos, (FAR char *)buffer, nwritten, true);
filep->f_pos += nwritten;
}
else