[PATCH] Fix bug 9412 - SMB2 server doesn't support recvfile.

Jones jones.kstw at gmail.com
Mon Apr 7 04:43:35 MDT 2014


2014-04-03 18:11 GMT+08:00 Jones <jones.kstw at gmail.com>:

>
>> 2014-04-03 2:06 GMT+08:00 Stefan (metze) Metzmacher <metze at samba.org>:
>>
>> And turn the socket into blocking mode once we get EAGAIN?
>>
>
> Add poll_one_fd() and infinite waiting for socket fd is ready to read.
>
>
Hello Jeremy, Metze,

After lookup the BUGS section in man page select/poll,
it seems not a good idea to select/poll a fd with O_NONBLOCK,
my modification may cause undefined behavior which is platform dependent.

After checking sys_sendfile(),
a preliminary thought prompt to handle the EAGAIN in sys_recvfile(),
please kindly help comment,
thanks.

-- 
Regards,
Jones
-------------- next part --------------
From b344fef38ff94af42dae8b4a1cfb230fae5e3b23 Mon Sep 17 00:00:00 2001
From: Jones Syue <jones.kstw at gmail.com>
Date: Mon, 7 Apr 2014 18:40:18 +0800
Subject: [PATCH 1/2] Remove fcntl

Signed-off-by: Jones Syue <jones.kstw at gmail.com>
---
 source3/smbd/vfs.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index bc9157a..0ae7da0 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -473,23 +473,14 @@ ssize_t vfs_pwrite_data(struct smb_request *req,
 
 	if (req && req->unread_bytes) {
 		int sockfd = req->sconn->sock;
-		int old_flags;
 		SMB_ASSERT(req->unread_bytes == N);
 		/* VFS_RECVFILE must drain the socket
 		 * before returning. */
 		req->unread_bytes = 0;
-		/* Ensure the socket is blocking. */
-		old_flags = fcntl(sockfd, F_GETFL, 0);
-		if (set_blocking(sockfd, true) == -1) {
-			return (ssize_t)-1;
-		}
 		ret = SMB_VFS_RECVFILE(sockfd,
 					fsp,
 					offset,
 					N);
-		if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
-			return (ssize_t)-1;
-		}
 		return ret;
 	}
 
-- 
1.8.3.4


From 36f240d9512eea0d8125cf2da907a3a137259cd3 Mon Sep 17 00:00:00 2001
From: Jones Syue <jones.kstw at gmail.com>
Date: Mon, 7 Apr 2014 18:40:38 +0800
Subject: [PATCH 2/2] Handle EAGAIN

Signed-off-by: Jones Syue <jones.kstw at gmail.com>
---
 source3/lib/recvfile.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c
index 72f4257..357a2ab 100644
--- a/source3/lib/recvfile.c
+++ b/source3/lib/recvfile.c
@@ -182,6 +182,17 @@ ssize_t sys_recvfile(int fromfd,
 		nread = splice(fromfd, NULL, pipefd[1], NULL,
 			       MIN(count, 16384), SPLICE_F_MOVE);
 		if (nread == -1) {
+#if defined(EWOULDBLOCK)
+			if (errno == EAGAIN || errno == EWOULDBLOCK) {
+#else /* EWOULDBLOCK */
+			if (errno == EAGAIN) {
+#endif /* EWOULDBLOCK */
+				/* FIXME: For rare cases:
+				 * case1) a high latency network.
+				 * case2) a network undergoing severe congestion.
+				 * Should use fcntl + O_NONBLOCK here ? */
+				continue;
+			}
 			if (errno == EINTR) {
 				continue;
 			}
-- 
1.8.3.4


More information about the samba-technical mailing list