[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Thu Apr 10 14:07:04 MDT 2014
The branch, master has been updated
via 4daf7d4 libs: s3 and s4: make our dns lookup code signal-safe.
via f5a3d74 s3: smbd: Performance optimization for RECVFILE.
from 88ba811 s4-wbclient: Fix wbc_sids_to_xids to correctly indicate the length of the SID list
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 4daf7d475c8cca69e2e3b20dc9fb84c4bd8cb4cb
Author: Jeremy Allison <jra at samba.org>
Date: Wed Apr 9 15:27:45 2014 -0700
libs: s3 and s4: make our dns lookup code signal-safe.
Cope with -1,EINTR returns. Needed as this code can be
called from inside smbd.
Also fixes a bug in not checking the return from poll()
correctly.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Kai Blin <kai at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Thu Apr 10 22:06:08 CEST 2014 on sn-devel-104
commit f5a3d74264abb25009e73b1b35d62db34fa62343
Author: Jeremy Allison <jra at samba.org>
Date: Wed Apr 9 09:50:46 2014 -0700
s3: smbd: Performance optimization for RECVFILE.
Based on work proposed by Jones <jones.kstw at gmail.com>.
Removes set_blocking()/set_unblocking() fcntl
calls around RECVFILE on the non-blocking socket.
Instead uses RECVFILE in a loop, and only drops
back to set_blocking()/set_unblocking() once
RECVFILE returns -1/EAGAIN/EWOULDBLOCK.
From the samba-technical list:
------------------------------------------------
The iometer 512b sequential write shows following result,
Before applying this patch: 75333 IOps
After applying this patch: 82691 IOps
------------------------------------------------
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/addns/dnssock.c | 29 +++++++++++++++++++++----
source3/smbd/vfs.c | 56 +++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 67 insertions(+), 18 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/addns/dnssock.c b/lib/addns/dnssock.c
index 5f99519..13649b5 100644
--- a/lib/addns/dnssock.c
+++ b/lib/addns/dnssock.c
@@ -70,7 +70,9 @@ static DNS_ERROR dns_tcp_open( const char *nameserver,
s_in.sin_addr.s_addr = ulAddress;
s_in.sin_port = htons( DNS_TCP_PORT );
- res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in ));
+ do {
+ res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in ));
+ } while ((res == -1) && (errno == EINTR));
if (res == -1) {
TALLOC_FREE(conn);
return ERROR_DNS_CONNECTION_FAILED;
@@ -155,7 +157,11 @@ static DNS_ERROR write_all(int fd, uint8_t *data, size_t len)
while (total < len) {
- ssize_t ret = write(fd, data + total, len - total);
+ ssize_t ret;
+
+ do {
+ ret = write(fd, data + total, len - total);
+ } while ((ret == -1) && (errno == EINTR));
if (ret <= 0) {
/*
@@ -187,9 +193,11 @@ static DNS_ERROR dns_send_udp(struct dns_connection *conn,
{
ssize_t ret;
- ret = sendto(conn->s, buf->data, buf->offset, 0,
+ do {
+ ret = sendto(conn->s, buf->data, buf->offset, 0,
(struct sockaddr *)&conn->RecvAddr,
sizeof(conn->RecvAddr));
+ } while ((ret == -1) && (errno == EINTR));
if (ret != buf->offset) {
return ERROR_DNS_SOCKET_ERROR;
@@ -225,12 +233,21 @@ static DNS_ERROR read_all(int fd, uint8_t *data, size_t len)
pfd.events = POLLIN|POLLHUP;
fd_ready = poll(&pfd, 1, 10000);
+ if (fd_ready == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+ return ERROR_DNS_SOCKET_ERROR;
+ }
if ( fd_ready == 0 ) {
/* read timeout */
return ERROR_DNS_SOCKET_ERROR;
}
- ret = read(fd, data + total, len - total);
+ do {
+ ret = read(fd, data + total, len - total);
+ } while ((ret == -1) && (errno == EINTR));
+
if (ret <= 0) {
/* EOF or error */
return ERROR_DNS_SOCKET_ERROR;
@@ -300,7 +317,9 @@ static DNS_ERROR dns_receive_udp(TALLOC_CTX *mem_ctx,
return ERROR_DNS_NO_MEMORY;
}
- received = recv(conn->s, (void *)buf->data, 512, 0);
+ do {
+ received = recv(conn->s, (void *)buf->data, 512, 0);
+ } while ((received == -1) && (errno == EINTR));
if (received == -1) {
TALLOC_FREE(buf);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index bc9157a..897bf1f 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -473,24 +473,54 @@ 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;
+ /*
+ * Leave the socket non-blocking and
+ * use SMB_VFS_RECVFILE. If it returns
+ * EAGAIN || EWOULDBLOCK temporarily set
+ * the socket blocking and retry
+ * the RECVFILE.
+ */
+ while (total < N) {
+ ret = SMB_VFS_RECVFILE(sockfd,
+ fsp,
+ offset + total,
+ N - total);
+#if defined(EWOULDBLOCK)
+ if (ret == 0 || (ret == -1 &&
+ (errno == EAGAIN || errno == EWOULDBLOCK))) {
+#else /* EWOULDBLOCK */
+ if (ret == 0 || (ret == -1 && errno == EAGAIN)) {
+#endif /* EWOULDBLOCK */
+ int old_flags;
+ /* 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 + total,
+ N - total);
+ if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
+ return (ssize_t)-1;
+ }
+ if (ret == -1) {
+ return (ssize_t)-1;
+ }
+ total += ret;
+ return (ssize_t)total;
+ }
+ /* Any other error case. */
+ if (ret == -1) {
+ return ret;
+ }
+ total += ret;
}
- return ret;
+ return (ssize_t)total;
}
while (total < N) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list