[SCM] Samba Shared Repository - branch v3-5-test updated

Karolin Seeger kseeger at samba.org
Wed Jan 4 13:31:18 MST 2012


The branch, v3-5-test has been updated
       via  610053a Final part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
       via  b0bc8be Third part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
       via  1076d0d Second part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
       via  e1cbc6b Fix bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write
      from  b217fc3 s3-cli: fix bug 563, >8GB tar on BE machines

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit 610053a6dbe0fc109e3e73c1f7cb26ec8dc48c11
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Dec 30 21:19:08 2011 -0800

    Final part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
    
    The code to set a DOS error on short writeX return is amazingly
    legacy code, and also breaks the reply as fixup_chain_error_packet()
    enforces a 2-byte wct on any reply where smb_rcls != 0.
    
    Found in testing by Andrew Bartlett. Thanks Andrew !
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Sat Dec 31 08:05:35 CET 2011 on sn-devel-104
    (cherry picked from commit e39df67669f61056692736db9c8dc16fbf2c3624)
    (cherry picked from commit 627f57f0714f257c6082b21447d122935c6e92e2)

commit b0bc8bec29bce808253adf2a95b7fdb7d36a176f
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Dec 30 20:45:10 2011 -0800

    Third part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
    
    Fix default_sys_recvfile() to correctly cope with
    short writes. Return the amount written. Return
    -1 and set errno if no data could be written.
    (cherry picked from commit 5e6263960aaf1a5f9993cb7bb5646d36ff92b9cc)
    (cherry picked from commit ec9b07e84e806705e22f0cf2eb527fed14efac55)

commit 1076d0d0491ca9d988c8095514838975e6fce4ec
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Dec 30 20:23:00 2011 -0800

    Second part of fix for bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write.
    
    Split out the functionality of drain_socket() into a separate
    function from default_sys_recvfile().
    (cherry picked from commit a5715420e37b98038fe8f2c3028e4c6938400eed)
    (cherry picked from commit 7924e459b6677ba3500afff4b78f797e1e0ad83d)

commit e1cbc6b4ac55d2cdb55bcfa4dbcd667cedf6ffb2
Author: Jeremy Allison <jra at samba.org>
Date:   Sat Dec 24 21:12:09 2011 -0800

    Fix bug #8679 - recvfile code path using splice() on Linux leaves data in the pipe on short write
    
    Bug found and fix suggested by Andrew Bartlett.
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Sun Dec 25 07:46:38 CET 2011 on sn-devel-104
    (cherry picked from commit eb617374a673bb1189dd9b6bccbf3f1d9fb91010)
    (cherry picked from commit b3f344b5b52096715eb5670b146f477a67af8245)

-----------------------------------------------------------------------

Summary of changes:
 source3/lib/recvfile.c |   75 ++++++++++++++++++++++++++++++++----------------
 source3/smbd/reply.c   |    5 ---
 2 files changed, 50 insertions(+), 30 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c
index ea01596..cc69d42 100644
--- a/source3/lib/recvfile.c
+++ b/source3/lib/recvfile.c
@@ -29,16 +29,10 @@
  * It's safe to make direct syscalls to lseek/write here
  * as we're below the Samba vfs layer.
  *
- * If tofd is -1 we just drain the incoming socket of count
- * bytes without writing to the outgoing fd.
- * If a write fails we do the same (to cope with disk full)
- * errors.
- *
  * Returns -1 on short reads from fromfd (read error)
  * and sets errno.
  *
  * Returns number of bytes written to 'tofd'
- * or thrown away if 'tofd == -1'.
  * return != count then sets errno.
  * Returns count if complete success.
  */
@@ -95,23 +89,26 @@ static ssize_t default_sys_recvfile(int fromfd,
 
 		num_written = 0;
 
-		while (num_written < read_ret) {
+		/* Don't write any more after a write error. */
+		while (tofd != -1 && (num_written < read_ret)) {
 			ssize_t write_ret;
 
-			if (tofd == -1) {
-				write_ret = read_ret;
-			} else {
-				/* Write to file - ignore EINTR. */
-				write_ret = sys_write(tofd,
-						buffer + num_written,
-						read_ret - num_written);
-
-				if (write_ret <= 0) {
-					/* write error - stop writing. */
-					tofd = -1;
-					saved_errno = errno;
-					continue;
-				}
+			/* Write to file - ignore EINTR. */
+			write_ret = sys_write(tofd,
+					buffer + num_written,
+					read_ret - num_written);
+
+			if (write_ret <= 0) {
+				/* write error - stop writing. */
+				tofd = -1;
+                                if (total_written == 0) {
+					/* Ensure we return
+					   -1 if the first
+					   write failed. */
+                                        total_written = -1;
+                                }
+				saved_errno = errno;
+				break;
 			}
 
 			num_written += (size_t)write_ret;
@@ -213,10 +210,9 @@ ssize_t sys_recvfile(int fromfd,
 	}
 
  done:
-	if (total_written < count) {
+	if (count) {
 		int saved_errno = errno;
-		if (drain_socket(fromfd, count-total_written) !=
-				count-total_written) {
+		if (drain_socket(fromfd, count) != count) {
 			/* socket is dead. */
 			return -1;
 		}
@@ -242,9 +238,38 @@ ssize_t sys_recvfile(int fromfd,
 
 /*****************************************************************
  Throw away "count" bytes from the client socket.
+ Returns count or -1 on error.
 *****************************************************************/
 
 ssize_t drain_socket(int sockfd, size_t count)
 {
-	return default_sys_recvfile(sockfd, -1, (SMB_OFF_T)-1, count);
+	size_t total = 0;
+	size_t bufsize = MIN(TRANSFER_BUF_SIZE,count);
+	char *buffer = NULL;
+
+	if (count == 0) {
+		return 0;
+	}
+
+	buffer = SMB_MALLOC_ARRAY(char, bufsize);
+	if (buffer == NULL) {
+		return -1;
+	}
+
+	while (total < count) {
+		ssize_t read_ret;
+		size_t toread = MIN(bufsize,count - total);
+
+		/* Read from socket - ignore EINTR. */
+		read_ret = sys_read(sockfd, buffer, toread);
+		if (read_ret <= 0) {
+			/* EOF or socket error. */
+			free(buffer);
+			return -1;
+		}
+		total += read_ret;
+	}
+
+	free(buffer);
+	return count;
 }
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 43cdf96..12d20ff 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -4429,11 +4429,6 @@ void reply_write_and_X(struct smb_request *req)
 	SSVAL(req->outbuf,smb_vwv2,nwritten);
 	SSVAL(req->outbuf,smb_vwv4,nwritten>>16);
 
-	if (nwritten < (ssize_t)numtowrite) {
-		SCVAL(req->outbuf,smb_rcls,ERRHRD);
-		SSVAL(req->outbuf,smb_err,ERRdiskfull);
-	}
-
 	DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
 		fsp->fnum, (int)numtowrite, (int)nwritten));
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list