summaryrefslogtreecommitdiffstats
path: root/source3/smbd/fileio.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-10-30 16:22:24 -0700
committerJeremy Allison <jra@samba.org>2007-10-30 16:22:24 -0700
commitc3250149e12338fac5093991b385ad2807c92d1f (patch)
treefa1e5387fb10d02b1f09da59fc20d7a8520e65fc /source3/smbd/fileio.c
parent4367f4b4d4ce075f3fe8e88e68dbda47e2252349 (diff)
downloadsamba-c3250149e12338fac5093991b385ad2807c92d1f.tar.gz
samba-c3250149e12338fac5093991b385ad2807c92d1f.tar.xz
samba-c3250149e12338fac5093991b385ad2807c92d1f.zip
Add new parameter, "min receivefile size" (by default set
to zero). If non-zero, writeX calls greater than this value will be left in the socket buffer for later handling with recvfile (or userspace equivalent). Definition of recvfile for your system is left as an exercise for the reader (I'm working on getting splice working :-). Jeremy. (This used to be commit 11c03b75ddbcb6e36b231bb40a1773d1c550621c)
Diffstat (limited to 'source3/smbd/fileio.c')
-rw-r--r--source3/smbd/fileio.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 14056ddc803..9e296f2204e 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -116,12 +116,16 @@ static unsigned int allocated_write_caches;
*Really* write to a file.
****************************************************************************/
-static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos, size_t n)
+static ssize_t real_write_file(struct smb_request *req,
+ files_struct *fsp,
+ const char *data,
+ SMB_OFF_T pos,
+ size_t n)
{
ssize_t ret;
if (pos == -1) {
- ret = vfs_write_data(fsp, data, n);
+ ret = vfs_write_data(req, fsp, data, n);
} else {
fsp->fh->pos = pos;
if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
@@ -129,7 +133,7 @@ static ssize_t real_write_file(files_struct *fsp,const char *data, SMB_OFF_T pos
return -1;
}
}
- ret = vfs_pwrite_data(fsp, data, n, pos);
+ ret = vfs_pwrite_data(req, fsp, data, n, pos);
}
DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
@@ -191,11 +195,15 @@ static int wcp_file_size_change(files_struct *fsp)
Write to a file.
****************************************************************************/
-ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n)
+ssize_t write_file(struct smb_request *req,
+ files_struct *fsp,
+ const char *data,
+ SMB_OFF_T pos,
+ size_t n)
{
write_cache *wcp = fsp->wcp;
ssize_t total_written = 0;
- int write_path = -1;
+ int write_path = -1;
if (fsp->print_file) {
fstring sharename;
@@ -234,8 +242,8 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n)
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
setup_write_cache(fsp, st.st_size);
wcp = fsp->wcp;
- }
- }
+ }
+ }
}
#ifdef WITH_PROFILE
@@ -280,9 +288,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
}
#endif
+ if (wcp && req->unread_bytes) {
+ /* If we're using receivefile don't
+ * deal with a write cache.
+ */
+ flush_write_cache(fsp, WRITE_FLUSH);
+ delete_write_cache(fsp);
+ wcp = NULL;
+ }
+
if(!wcp) {
DO_PROFILE_INC(writecache_direct_writes);
- total_written = real_write_file(fsp, data, pos, n);
+ total_written = real_write_file(req, fsp, data, pos, n);
return total_written;
}
@@ -291,7 +308,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
fsp->fh->pos = pos + n;
- /*
+ /*
* If we have active cache and it isn't contiguous then we flush.
* NOTE: There is a small problem with running out of disk ....
*/
@@ -610,7 +627,7 @@ len = %u\n",fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (uns
if ( n <= wcp->alloc_size && n > wcp->data_size) {
cache_flush_needed = True;
} else {
- ssize_t ret = real_write_file(fsp, data, pos, n);
+ ssize_t ret = real_write_file(NULL,fsp, data, pos, n);
/*
* If the write overlaps the entire cache, then
@@ -657,7 +674,7 @@ n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
*/
if (n > wcp->alloc_size ) {
- ssize_t ret = real_write_file(fsp, data, pos, n);
+ ssize_t ret = real_write_file(NULL,fsp, data, pos, n);
if (ret == -1) {
return -1;
}
@@ -828,7 +845,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
}
#endif
- ret = real_write_file(fsp, wcp->data, wcp->offset, data_size);
+ ret = real_write_file(NULL, fsp, wcp->data, wcp->offset, data_size);
/*
* Ensure file size if kept up to date if write extends file.