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

Jones jones.kstw at gmail.com
Wed Apr 2 02:07:10 MDT 2014


>
> 2014-04-01 1:22 GMT+08:00 Jeremy Allison <jra at samba.org>:
>
> Try scoping out a loop around the RECVFILE
>> call to do what I mentioned earlier and
>> send it in as a proposed patch. If you don't
>> get time I might have a go at it :-).
>
>
Hello Jeremy,

Not sure if this attached file matches what you mentioned earlier,

> please kindly help comment,
thanks.

2013-04-06 12:14 GMT+08:00 Jeremy Allison <jra at samba.org>:

The EAGAIN case would only happen on (a)
> high latency link or (b) a network undergoing severe
> congestion, neither of which is a good use case for SMB
> in any case :-).


Notice this one,
next plan would try over high latency network to see if errors returned,
thanks.


-- 
Regards,
Jones
-------------- next part --------------
From c577e244dd317aa78d0d6a729617543ae932116b Mon Sep 17 00:00:00 2001
From: Jones Syue <jones.kstw at gmail.com>
Date: Wed, 2 Apr 2014 15:41:19 +0800
Subject: [PATCH] Scoping out a loop around the RECVFILE call.

Per suggestion from Jeremy.
Be rewritten to do RECVFILE in a loop and 
advance the offset (and reduce N) by the 
amount read in previous RECVFILES. 

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

diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index bc9157a..d6f11dc 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -468,8 +468,11 @@ ssize_t vfs_pwrite_data(struct smb_request *req,
 			size_t N,
 			off_t offset)
 {
-	size_t total=0;
-	ssize_t ret;
+	size_t total = 0;
+	ssize_t ret = 0;
+	ssize_t thistime = 0;
+	size_t left = N;
+	off_t next = offset;
 
 	if (req && req->unread_bytes) {
 		int sockfd = req->sconn->sock;
@@ -478,18 +481,16 @@ ssize_t vfs_pwrite_data(struct smb_request *req,
 		/* 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;
-		}
+		/* Scoping out a loop around the RECVFILE call. */
+		do {
+			thistime = SMB_VFS_RECVFILE(sockfd,
+						    fsp,
+						    next,
+						    left);
+			left -= thistime;
+			next += thistime;
+			ret += thistime;
+		} while (left > 0);
 		return ret;
 	}
 
-- 
1.8.3.4


More information about the samba-technical mailing list