[PATCH] Fix bug 9412 - SMB2 server doesn't support recvfile.
Jones
jones.kstw at gmail.com
Thu Apr 3 04:11:54 MDT 2014
Hello Jeremy, Metze,
Thanks for kindly response!
Am 02.04.2014 19:51, schrieb Jeremy Allison:
> Not quite right I'm afraid, you need to
> catch a RECVFILE return of -1 within the loop.
That's great!
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.
But i am concerned that use poll() to instead of original fcntl(),
perhaps this is not a good method.
Should still use fcntl() to make sure the socket fd is into blocking mode?
Please kindly help comment,
thanks.
--
Regards,
Jones
-------------- next part --------------
From 6a354e372c1ed9bc24dd32d69859c82d24b5b5ac Mon Sep 17 00:00:00 2001
From: Jones Syue <jones.kstw at gmail.com>
Date: Thu, 3 Apr 2014 17:37:00 +0800
Subject: [PATCH] Scoping out a loop around the RECVFILE call.
Signed-off-by: Jones Syue <jones.kstw at gmail.com>
---
source3/smbd/vfs.c | 45 ++++++++++++++++++++++++++++++---------------
1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index bc9157a..157c8cd 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -468,28 +468,43 @@ 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;
+ int revent;
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;
- }
+ /* Scoping out a loop around the RECVFILE call. */
+ do {
+ thistime = SMB_VFS_RECVFILE(sockfd,
+ fsp,
+ next,
+ left);
+#if defined(EWOULDBLOCK)
+ if (thistime == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+#else /* EWOULDBLOCK */
+ if (thistime == -1 && errno == EAGAIN) {
+#endif /* EWOULDBLOCK */
+ poll_one_fd(sockfd, POLLIN, -1, &revent);
+ continue;
+ } else if (thistime == -1) {
+ if (ret == 0) {
+ ret = thistime;
+ }
+ break;
+ } else {
+ left -= thistime;
+ next += thistime;
+ ret += thistime;
+ }
+ } while (left > 0);
return ret;
}
--
1.8.3.4
More information about the samba-technical
mailing list