You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gu...@apache.org on 2021/05/14 01:33:22 UTC

[incubator-nuttx] 01/05: fs: nfs: Fix rpcclnt_send() in TCP mode

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

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

commit f0372dde6a0a6e7de7d0a7c2002d0282df6101eb
Author: Masayuki Ishikawa <ma...@gmail.com>
AuthorDate: Tue May 11 10:25:26 2021 +0900

    fs: nfs: Fix rpcclnt_send() in TCP mode
    
    Summary:
    - I noticed that NFS over TCP does not work with Ubuntu 18.04
    - Finally, I found that the record marking packet should not
      be sent separately
    - This commit fixes this issue
    
    Impact:
    - TCP mode only
    
    Testing:
    - Tested with NFS server on Ubuntu 18.04 (x86_64)
    - Tested with spresense:rndis (defconfig will be updated later)
    
    Signed-off-by: Masayuki Ishikawa <Ma...@jp.sony.com>
---
 fs/nfs/rpc_clnt.c | 49 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/fs/nfs/rpc_clnt.c b/fs/nfs/rpc_clnt.c
index f57fed2..9357966 100644
--- a/fs/nfs/rpc_clnt.c
+++ b/fs/nfs/rpc_clnt.c
@@ -297,32 +297,49 @@ bad:
 static int rpcclnt_send(FAR struct rpcclnt *rpc,
                         FAR void *call, int reqlen)
 {
+  struct iovec  iov[2];
+  struct msghdr msg;
   uint32_t mark;
   int ret = OK;
 
-  /* Send the record marking(RM) for stream only */
-
   if (rpc->rc_sotype == SOCK_STREAM)
     {
-      mark = txdr_unsigned(0x80000000 | reqlen);
-      ret = psock_send(&rpc->rc_so, &mark, sizeof(mark), 0);
-      if (ret < 0)
-        {
-          ferr("ERROR: psock_send mark failed: %d\n", ret);
-          return ret;
-        }
+      /* Prepare the record marking(RM) and compose an RPC request
+       * NOTE: Sending a separate packet does not work with Linux host
+       */
+
+      mark = txdr_unsigned(0x80000000 | (reqlen));
+
+      iov[0].iov_base = (FAR void *)&mark;
+      iov[0].iov_len = sizeof(mark);
+      iov[1].iov_base = (FAR void *)call;
+      iov[1].iov_len = reqlen;
+
+      msg.msg_name = NULL;
+      msg.msg_namelen = 0;
+      msg.msg_iov = iov;
+      msg.msg_iovlen = 2;
+      msg.msg_control = NULL;
+      msg.msg_controllen = 0;
+      msg.msg_flags = 0;
+
+      ret = psock_sendmsg(&rpc->rc_so, &msg, 0);
+      ferr("ERROR: psock_sendmsg request failed: %d\n", ret);
     }
+  else
+    {
+      /* Send the call message
+       *
+       * On success, psock_send returns the number of bytes sent;
+       * On failure, it returns a negated errno value.
+       */
 
-  /* Send the call message
-   *
-   * On success, psock_send returns the number of bytes sent;
-   * On failure, it returns a negated errno value.
-   */
+      ret = psock_send(&rpc->rc_so, call, reqlen, 0);
+      ferr("ERROR: psock_send request failed: %d\n", ret);
+    }
 
-  ret = psock_send(&rpc->rc_so, call, reqlen, 0);
   if (ret < 0)
     {
-      ferr("ERROR: psock_send request failed: %d\n", ret);
       return ret;
     }