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/01/30 16:39:23 UTC

[nuttx] 01/02: mm/iob: Support negative offset when copyin/out.

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 be89bcc0445eba4101d09960f0b58ee63824dbfd
Author: Zhe Weng <we...@xiaomi.com>
AuthorDate: Wed Jan 18 19:58:52 2023 +0800

    mm/iob: Support negative offset when copyin/out.
    
    Signed-off-by: Zhe Weng <we...@xiaomi.com>
---
 include/nuttx/mm/iob.h    |  6 +++---
 mm/iob/iob_copyin.c       | 21 ++++++++++++++-------
 mm/iob/iob_copyout.c      | 13 +++++++++++--
 net/devif/devif_poll.c    |  7 +------
 net/netdev/netdev_input.c | 23 +++++------------------
 5 files changed, 34 insertions(+), 36 deletions(-)

diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index ee3987d086..ede9816f9e 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -405,7 +405,7 @@ unsigned int iob_get_queue_size(FAR struct iob_queue_s *queue);
  ****************************************************************************/
 
 int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-               unsigned int len, unsigned int offset, bool throttled);
+               unsigned int len, int offset, bool throttled);
 
 /****************************************************************************
  * Name: iob_trycopyin
@@ -418,7 +418,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-                  unsigned int len, unsigned int offset, bool throttled);
+                  unsigned int len, int offset, bool throttled);
 
 /****************************************************************************
  * Name: iob_copyout
@@ -430,7 +430,7 @@ int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
-                unsigned int len, unsigned int offset);
+                unsigned int len, int offset);
 
 /****************************************************************************
  * Name: iob_tailroom
diff --git a/mm/iob/iob_copyin.c b/mm/iob/iob_copyin.c
index 039cd923bd..0d221ee3b9 100644
--- a/mm/iob/iob_copyin.c
+++ b/mm/iob/iob_copyin.c
@@ -51,7 +51,7 @@
  ****************************************************************************/
 
 static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src,
-                               unsigned int len, unsigned int offset,
+                               unsigned int len, int offset,
                                bool throttled, bool can_block)
 {
   FAR struct iob_s *head = iob;
@@ -61,23 +61,30 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src,
   unsigned int avail;
   unsigned int total = len;
 
-  iobinfo("iob=%p len=%u offset=%u\n", iob, len, offset);
+  iobinfo("iob=%p len=%u offset=%d\n", iob, len, offset);
   DEBUGASSERT(iob && src);
 
   /* The offset must applied to data that is already in the I/O buffer
    * chain
    */
 
-  if (offset > iob->io_pktlen)
+  if ((int)(offset - iob->io_pktlen) > 0)
     {
-      ioberr("ERROR: offset is past the end of data: %u > %u\n",
+      ioberr("ERROR: offset is past the end of data: %d > %u\n",
              offset, iob->io_pktlen);
       return -ESPIPE;
     }
 
+  if ((int)(offset + iob->io_offset) < 0)
+    {
+      ioberr("ERROR: offset is before the start of data: %d < %d\n",
+             offset, -(int)iob->io_offset);
+      return -ESPIPE;
+    }
+
   /* Skip to the I/O buffer containing the data offset */
 
-  while (offset > iob->io_len)
+  while ((int)(offset - iob->io_len) > 0)
     {
       offset -= iob->io_len;
       iob     = iob->io_flink;
@@ -216,7 +223,7 @@ static int iob_copyin_internal(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-               unsigned int len, unsigned int offset, bool throttled)
+               unsigned int len, int offset, bool throttled)
 {
   return iob_copyin_internal(iob, src, len, offset, throttled, true);
 }
@@ -232,7 +239,7 @@ int iob_copyin(FAR struct iob_s *iob, FAR const uint8_t *src,
  ****************************************************************************/
 
 int iob_trycopyin(FAR struct iob_s *iob, FAR const uint8_t *src,
-                  unsigned int len, unsigned int offset, bool throttled)
+                  unsigned int len, int offset, bool throttled)
 {
   return iob_copyin_internal(iob, src, len, offset, throttled, false);
 }
diff --git a/mm/iob/iob_copyout.c b/mm/iob/iob_copyout.c
index 5d9643c750..a32e777d10 100644
--- a/mm/iob/iob_copyout.c
+++ b/mm/iob/iob_copyout.c
@@ -54,16 +54,25 @@
  ****************************************************************************/
 
 int iob_copyout(FAR uint8_t *dest, FAR const struct iob_s *iob,
-                unsigned int len, unsigned int offset)
+                unsigned int len, int offset)
 {
   FAR const uint8_t *src;
   unsigned int ncopy;
   unsigned int avail;
   unsigned int remaining;
 
+  /* The offset must applied to data that is in the I/O buffer chain */
+
+  if ((int)(offset + iob->io_offset) < 0)
+    {
+      ioberr("ERROR: offset is before the start of data: %d < %d\n",
+             offset, -(int)iob->io_offset);
+      return -ESPIPE;
+    }
+
   /* Skip to the I/O buffer containing the offset */
 
-  while (offset >= iob->io_len)
+  while ((int)(offset - iob->io_len) >= 0)
     {
       offset -= iob->io_len;
       iob     = iob->io_flink;
diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c
index 7eb4e49776..5cf78a6949 100644
--- a/net/devif/devif_poll.c
+++ b/net/devif/devif_poll.c
@@ -1004,12 +1004,7 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
         {
           /* Copy iob to flat buffer */
 
-          iob_copyout(buf + llhdrlen,
-                      dev->d_iob, dev->d_len, 0);
-
-          /* Copy l2 header (arp out) */
-
-          memcpy(buf, IPBUF(-llhdrlen), llhdrlen);
+          iob_copyout(buf, dev->d_iob, dev->d_len, -llhdrlen);
 
           /* Restore flat buffer pointer */
 
diff --git a/net/netdev/netdev_input.c b/net/netdev/netdev_input.c
index 45a63d7176..85aa6e7e57 100644
--- a/net/netdev/netdev_input.c
+++ b/net/netdev/netdev_input.c
@@ -68,8 +68,6 @@ int netdev_input(FAR struct net_driver_s *dev,
 {
   uint16_t llhdrlen = NET_LL_HDRLEN(dev);
   FAR uint8_t *buf = dev->d_buf;
-  unsigned int offset;
-  unsigned int l3l4len;
   int ret;
 
   /* Prepare iob buffer */
@@ -80,32 +78,21 @@ int netdev_input(FAR struct net_driver_s *dev,
       return ret;
     }
 
-  /* Copy l2 header to gruard area */
+  /* Copy data to iob entry */
 
-  offset = dev->d_iob->io_offset - llhdrlen;
-  memcpy(dev->d_iob->io_data + offset, buf, llhdrlen);
-
-  /* Copy l3/l4 data to iob entry */
-
-  l3l4len = dev->d_len - llhdrlen;
-
-  ret = iob_trycopyin(dev->d_iob, buf + llhdrlen,
-                      l3l4len, 0, false);
-  if (ret == l3l4len)
+  ret = iob_trycopyin(dev->d_iob, buf, dev->d_len, -llhdrlen, false);
+  if (ret == dev->d_len)
     {
       /* Update device buffer to l2 start */
 
-      dev->d_buf = dev->d_iob->io_data + offset;
-
-      iob_update_pktlen(dev->d_iob, l3l4len);
+      dev->d_buf = NETLLBUF;
 
       ret = callback(dev);
       if (dev->d_iob != NULL && reply)
         {
           if (ret == OK && dev->d_len > 0)
             {
-              iob_copyout(buf + llhdrlen, dev->d_iob, dev->d_len, 0);
-              memcpy(buf, dev->d_iob->io_data + offset, llhdrlen);
+              iob_copyout(buf, dev->d_iob, dev->d_len, -llhdrlen);
             }
         }
     }