smbd: Remove write cache
authorVolker Lendecke <vl@samba.org>
Mon, 27 May 2019 09:24:14 +0000 (11:24 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 13 Nov 2019 00:20:55 +0000 (00:20 +0000)
Since this was written, our write path has changed significantly. In
particular we have gained very flexible support for async I/O, with the
linux io_uring in the pipeline. Caching stuff in main memory and then
doing a blocking pwrite nowadays does not belong into the core smbd
code. If someone wants it back, it should be doable in a VFS module.

Removes: "write cache size" parameter.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Nov 13 00:20:55 UTC 2019 on sn-devel-184

18 files changed:
WHATSNEW.txt
docs-xml/smbdotconf/tuning/writecachesize.xml [deleted file]
source3/include/smb.h
source3/include/smbprofile.h
source3/include/vfs.h
source3/param/loadparm.c
source3/smbd/aio.c
source3/smbd/close.c
source3/smbd/fileio.c
source3/smbd/globals.c
source3/smbd/globals.h
source3/smbd/open.c
source3/smbd/oplock.c
source3/smbd/proto.h
source3/smbd/reply.c
source3/smbd/smb2_flush.c
source3/smbd/smb2_read.c
source3/smbd/vfs.c

index dccb44dbd27ea78e1d7b6fee35e7ac37db6ec0e5..cc43b29b3d11974f9e6427c255ed1bac82dde33f 100644 (file)
@@ -56,6 +56,23 @@ applies.
 REMOVED FEATURES
 ================
 
+The smb.conf parameter "write cache size" has been removed.
+
+Since the in-memory write caching code was written, our write path has
+changed significantly. In particular we have gained very flexible
+support for async I/O, with the new linux io_uring interface in
+development.  The old write cache concept which cached data in main
+memory followed by a blocking pwrite no longer gives any improvement
+on modern systems, and may make performance worse on memory-contrained
+systems, so this functionality should not be enabled in core smbd
+code.
+
+In addition, it complicated the write code, which is a performance
+critical code path.
+
+If required for specialist purposes, it can be recreated as a VFS
+module.
+
 BIND9_FLATFILE deprecated
 -------------------------
 
@@ -77,6 +94,7 @@ smb.conf changes
 
   nfs4:acedup                        Changed default            merge
   rndc command                       Removed
+  write cache size                   Removed
 
 KNOWN ISSUES
 ============
diff --git a/docs-xml/smbdotconf/tuning/writecachesize.xml b/docs-xml/smbdotconf/tuning/writecachesize.xml
deleted file mode 100644 (file)
index 484b353..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<samba:parameter name="write cache size"
-                 context="S"
-                 type="bytes"
-                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
-<description>
-    <para>If this integer parameter is set to non-zero value,
-    Samba will create an in-memory cache for each oplocked file 
-    (it does <emphasis>not</emphasis> do this for 
-    non-oplocked files). All writes that the client does not request 
-    to be flushed directly to disk will be stored in this cache if possible. 
-    The cache is flushed onto disk when a write comes in whose offset 
-    would not fit into the cache or when the file is closed by the client. 
-    Reads for the file are also served from this cache if the data is stored 
-    within it.</para>
-
-    <para>This cache allows Samba to batch client writes into a more 
-    efficient write size for RAID disks (i.e. writes may be tuned to 
-    be the RAID stripe size) and can improve performance on systems 
-    where the disk subsystem is a bottleneck but there is free 
-    memory for userspace programs.</para>
-
-    <para>The integer parameter specifies the size of this cache 
-               (per oplocked file) in bytes.</para>
-
-    <para>Note that the write cache won't be used for file handles with a smb2 write lease.</para>
-</description>
-
-<related>aio read size</related>
-<related>aio write size</related>
-<related>smb2 leases</related>
-<value type="default">0</value>
-<value type="example">262144<comment> for a 256k cache size per file</comment></value>
-</samba:parameter>
index 012ed48549421c6e23a57dca3babca28604507b0..162cdcc1a32854c5365eaf8c87ac5eaa7b81d974 100644 (file)
@@ -749,19 +749,4 @@ struct smb_extended_info {
        char   samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH];
 };
 
-/*
- * Reasons for cache flush.
- */
-
-enum flush_reason_enum {
-    SAMBA_SEEK_FLUSH,
-    SAMBA_READ_FLUSH,
-    SAMBA_WRITE_FLUSH,
-    SAMBA_READRAW_FLUSH,
-    SAMBA_OPLOCK_RELEASE_FLUSH,
-    SAMBA_CLOSE_FLUSH,
-    SAMBA_SYNC_FLUSH,
-    SAMBA_SIZECHANGE_FLUSH,
-};
-
 #endif /* _SMB_H */
index a003a1d9df090f12762eef190e2534d4da73c480..b771c26c81b4f678b7a61eb35171e92846c8b823 100644 (file)
@@ -108,27 +108,6 @@ struct tevent_context;
        SMBPROFILE_STATS_COUNT(statcache_hits) \
        SMBPROFILE_STATS_SECTION_END \
        \
-       SMBPROFILE_STATS_SECTION_START(writecache, "Write Cache") \
-       SMBPROFILE_STATS_COUNT(writecache_allocations) \
-       SMBPROFILE_STATS_COUNT(writecache_deallocations) \
-       SMBPROFILE_STATS_COUNT(writecache_cached_reads) \
-       SMBPROFILE_STATS_COUNT(writecache_total_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_init_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_abutted_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_non_oplock_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_direct_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_cached_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_perfect_writes) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_seek) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_read) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_readraw) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_write) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_oplock) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_close) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_sync) \
-       SMBPROFILE_STATS_COUNT(writecache_flush_reason_sizechange) \
-       SMBPROFILE_STATS_SECTION_END \
-       \
        SMBPROFILE_STATS_SECTION_START(SMB, "SMB Calls") \
        SMBPROFILE_STATS_BASIC(SMBmkdir) \
        SMBPROFILE_STATS_BASIC(SMBrmdir) \
index 802eb8d02923af7099b8aeb78478ff849accbed6..a6c57c6bcbc3d2912e80908d4e884b4e8e9db9e5 100644 (file)
 /* Version 42 - Remove SMB_VFS_RMDIR.
                Use SMB_VFS_UNLINKAT(.., AT_REMOVEDIR) instead. */
 /* Version 42 - Remove SMB_VFS_CHOWN */
+/* Version 42 - Remove struct write_cache *wcp from files_struct */
 
 #define SMB_VFS_INTERFACE_VERSION 42
 
@@ -347,7 +348,6 @@ typedef struct files_struct {
        uint64_t initial_allocation_size; /* Faked up initial allocation on disk. */
        uint16_t file_pid;
        uint64_t vuid; /* SMB2 compat */
-       struct write_cache *wcp;
        struct timeval open_time;
        uint32_t access_mask;           /* NTCreateX access bits (FILE_READ_DATA etc.) */
        bool kernel_share_modes_taken;
index 433762eedfb650c11ad1702ff027b2d7945f5131..31fa229d5ff93a319a9accc99efc7e9147368294 100644 (file)
@@ -160,7 +160,6 @@ static const struct loadparm_service _sDefault =
        .min_print_space = 0,
        .max_print_jobs = 1000,
        .max_reported_print_jobs = 0,
-       .write_cache_size = 0,
        .create_mask = 0744,
        .force_create_mode = 0,
        .directory_mask = 0755,
index 8ac3ef7278ec30348c7742f6049f39350e31dd06..0f824f5aa1f69171e7fb71f8c4ec099c313e4cde 100644 (file)
@@ -172,9 +172,8 @@ NTSTATUS schedule_aio_read_and_X(connection_struct *conn,
                return NT_STATUS_RETRY;
        }
 
-       /* Only do this on non-chained and non-chaining reads not using the
-        * write cache. */
-        if (req_is_in_chain(smbreq) || (lp_write_cache_size(SNUM(conn)) != 0)) {
+       /* Only do this on non-chained and non-chaining reads */
+        if (req_is_in_chain(smbreq)) {
                return NT_STATUS_RETRY;
        }
 
@@ -428,9 +427,8 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
                return NT_STATUS_RETRY;
        }
 
-       /* Only do this on non-chained and non-chaining writes not using the
-        * write cache. */
-        if (req_is_in_chain(smbreq) || (lp_write_cache_size(SNUM(conn)) != 0)) {
+       /* Only do this on non-chained and non-chaining writes */
+        if (req_is_in_chain(smbreq)) {
                return NT_STATUS_RETRY;
        }
 
@@ -673,11 +671,6 @@ NTSTATUS schedule_smb2_aio_read(connection_struct *conn,
                return NT_STATUS_RETRY;
        }
 
-       /* Only do this on reads not using the write cache. */
-       if (lp_write_cache_size(SNUM(conn)) != 0) {
-               return NT_STATUS_RETRY;
-       }
-
        if (smbd_smb2_is_compound(smbreq->smb2req)) {
                return NT_STATUS_RETRY;
        }
@@ -813,11 +806,6 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
                return NT_STATUS_RETRY;
        }
 
-       /* Only do this on writes not using the write cache. */
-       if (lp_write_cache_size(SNUM(conn)) != 0) {
-               return NT_STATUS_RETRY;
-       }
-
        if (smbd_smb2_is_compound(smbreq->smb2req)) {
                return NT_STATUS_RETRY;
        }
index e62480d69da3628302ac2bc99598529a74ddb074..180a5da735b4970af2d80dc1c907505d252c3cc7 100644 (file)
@@ -140,24 +140,6 @@ static NTSTATUS check_magic(struct files_struct *fsp)
        return status;
 }
 
-/****************************************************************************
-  Common code to close a file or a directory.
-****************************************************************************/
-
-static NTSTATUS close_filestruct(files_struct *fsp)
-{
-       NTSTATUS status = NT_STATUS_OK;
-
-       if (fsp->fh->fd != -1) {
-               if(flush_write_cache(fsp, SAMBA_CLOSE_FLUSH) == -1) {
-                       status = map_nt_error_from_unix(errno);
-               }
-               delete_write_cache(fsp);
-       }
-
-       return status;
-}
-
 /****************************************************************************
  Delete all streams
 ****************************************************************************/
@@ -715,9 +697,6 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
         * error here, we must remember this.
         */
 
-       tmp = close_filestruct(fsp);
-       status = ntstatus_keeperror(status, tmp);
-
        if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
                is_durable = fsp->op->global->durable;
        }
@@ -1182,7 +1161,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
        if (lck == NULL) {
                DEBUG(0, ("close_directory: Could not get share mode lock for "
                          "%s\n", fsp_str_dbg(fsp)));
-               close_filestruct(fsp);
                file_free(req, fsp);
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -1242,7 +1220,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
                        if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(5, ("delete_all_streams failed: %s\n",
                                          nt_errstr(status)));
-                               close_filestruct(fsp);
                                file_free(req, fsp);
                                return status;
                        }
@@ -1287,7 +1264,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
        /*
         * Do the code common to files and directories.
         */
-       close_filestruct(fsp);
        file_free(req, fsp);
 
        if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
index 067ce5a9ad408befbc87fe3f7424c0827607505c..b03f86d49d67235a6e89539205f591a9fadce19e 100644 (file)
 #include "smbd/globals.h"
 #include "smbprofile.h"
 
-struct write_cache {
-       off_t file_size;
-       off_t offset;
-       size_t alloc_size;
-       size_t data_size;
-       char *data;
-};
-
-static bool setup_write_cache(files_struct *, off_t);
-
-/****************************************************************************
- Read from write cache if we can.
-****************************************************************************/
-
-static bool read_from_write_cache(files_struct *fsp,char *data,off_t pos,size_t n)
-{
-       struct write_cache *wcp = fsp->wcp;
-
-       if(!wcp) {
-               return False;
-       }
-
-       if( n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size) {
-               return False;
-       }
-
-       memcpy(data, wcp->data + (pos - wcp->offset), n);
-
-       DO_PROFILE_INC(writecache_cached_reads);
-
-       return True;
-}
-
 /****************************************************************************
  Read from a file.
 ****************************************************************************/
@@ -72,18 +39,6 @@ ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n)
                return -1;
        }
 
-       /*
-        * Serve from write cache if we can.
-        */
-
-       if(read_from_write_cache(fsp, data, pos, n)) {
-               fsp->fh->pos = pos + n;
-               fsp->fh->position_information = fsp->fh->pos;
-               return n;
-       }
-
-       flush_write_cache(fsp, SAMBA_READ_FLUSH);
-
        fsp->fh->pos = pos;
 
        if (n > 0) {
@@ -140,26 +95,6 @@ static ssize_t real_write_file(struct smb_request *req,
        return ret;
 }
 
-/****************************************************************************
- File size cache change.
- Updates size on disk but doesn't flush the cache.
-****************************************************************************/
-
-static int wcp_file_size_change(files_struct *fsp)
-{
-       int ret;
-       struct write_cache *wcp = fsp->wcp;
-
-       wcp->file_size = wcp->offset + wcp->data_size;
-       ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size);
-       if (ret == -1) {
-               DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f "
-                        "error %s\n", fsp_str_dbg(fsp),
-                        (double)wcp->file_size, strerror(errno)));
-       }
-       return ret;
-}
-
 void fsp_flush_write_time_update(struct files_struct *fsp)
 {
        /*
@@ -314,9 +249,7 @@ ssize_t write_file(struct smb_request *req,
                        off_t pos,
                        size_t n)
 {
-       struct write_cache *wcp = fsp->wcp;
        ssize_t total_written = 0;
-       int write_path = -1;
 
        if (fsp->print_file) {
                uint32_t t;
@@ -335,30 +268,8 @@ ssize_t write_file(struct smb_request *req,
                return -1;
        }
 
-       /*
-        * If this is the first write and we have an exclusive oplock
-        * then setup the write cache.
-        */
-
-       if (!fsp->modified &&
-           EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
-           (wcp == NULL)) {
-               /*
-                * Note: no write cache with leases!
-                * as the handles would have to share the write cache
-                * that's possible but an improvement for another day...
-                */
-               setup_write_cache(fsp, fsp->fsp_name->st.st_ex_size);
-               wcp = fsp->wcp;
-       }
-
        mark_file_modified(fsp);
 
-       DO_PROFILE_INC(writecache_total_writes);
-       if (!fsp->oplock_type) {
-               DO_PROFILE_INC(writecache_non_oplock_writes);
-       }
-
        /*
         * If this file is level II oplocked then we need
         * to grab the shared memory lock and inform all
@@ -371,681 +282,10 @@ ssize_t write_file(struct smb_request *req,
        contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_WRITE);
        contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_WRITE);
 
-       if (wcp && req->unread_bytes) {
-               /* If we're using receivefile don't
-                * deal with a write cache.
-                */
-               flush_write_cache(fsp, SAMBA_WRITE_FLUSH);
-               delete_write_cache(fsp);
-               wcp = NULL;
-       }
-
-       if(!wcp) {
-               DO_PROFILE_INC(writecache_direct_writes);
-               total_written = real_write_file(req, fsp, data, pos, n);
-               return total_written;
-       }
-
-       DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f "
-                "wcp->data_size=%u\n", fsp_str_dbg(fsp), fsp->fh->fd,
-                (double)pos, (unsigned int)n, (double)wcp->offset,
-                (unsigned int)wcp->data_size));
-
-       fsp->fh->pos = pos + n;
-
-       if ((n == 1) && (data[0] == '\0') && (pos > wcp->file_size)) {
-               int ret;
-
-               /*
-                * This is a 1-byte write of a 0 beyond the EOF and
-                * thus implicitly also beyond the current active
-                * write cache, the typical file-extending (and
-                * allocating, but we're using the write cache here)
-                * write done by Windows. We just have to ftruncate
-                * the file and rely on posix semantics to return
-                * zeros for non-written file data that is within the
-                * file length.
-                *
-                * We can not use wcp_file_size_change here because we
-                * might have an existing write cache, and
-                * wcp_file_size_change assumes a change to just the
-                * end of the current write cache.
-                */
-
-               wcp->file_size = pos + 1;
-               ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size);
-               if (ret == -1) {
-                       DEBUG(0, ("wcp_file_size_change (%s): ftruncate of "
-                                 "size %.0f error %s\n", fsp_str_dbg(fsp),
-                                 (double)wcp->file_size, strerror(errno)));
-                       return -1;
-               }
-               return 1;
-       }
-
-
-       /*
-        * If we have active cache and it isn't contiguous then we flush.
-        * NOTE: There is a small problem with running out of disk ....
-        */
-
-       if (wcp->data_size) {
-               bool cache_flush_needed = False;
-
-               if ((pos >= wcp->offset) &&
-                   (pos <= wcp->offset + wcp->data_size)) {
-
-                       /* ASCII art.... JRA.
-
-      +--------------+-----
-      | Cached data  | Rest of allocated cache buffer....
-      +--------------+-----
-
-            +-------------------+
-            | Data to write     |
-            +-------------------+
-
-                       */
-
-                       /*
-                        * Start of write overlaps or abutts the existing data.
-                        */
-
-                       size_t data_used;
-
-                       data_used = MIN((wcp->alloc_size - (pos - wcp->offset)),
-                                       n);
-
-                       memcpy(wcp->data + (pos - wcp->offset), data,
-                              data_used);
-
-                       /*
-                        * Update the current buffer size with the new data.
-                        */
-
-                       if(pos + data_used > wcp->offset + wcp->data_size) {
-                               wcp->data_size = pos + data_used - wcp->offset;
-                       }
-
-                       /*
-                        * Update the file size if changed.
-                        */
-
-                       if (wcp->offset + wcp->data_size > wcp->file_size) {
-                               if (wcp_file_size_change(fsp) == -1) {
-                                       return -1;
-                               }
-                       }
-
-                       /*
-                        * If we used all the data then
-                        * return here.
-                        */
-
-                       if(n == data_used) {
-                               return n;
-                       } else {
-                               cache_flush_needed = True;
-                       }
-                       /*
-                        * Move the start of data forward by the amount used,
-                        * cut down the amount left by the same amount.
-                        */
-
-                       data += data_used;
-                       pos += data_used;
-                       n -= data_used;
-
-                       DO_PROFILE_INC(writecache_abutted_writes);
-                       total_written = data_used;
-
-                       write_path = 1;
-
-               } else if ((pos < wcp->offset) &&
-                          (pos + n > wcp->offset) &&
-                          (pos + n <= wcp->offset + wcp->alloc_size)) {
-
-                       /* ASCII art.... JRA.
-
-                        +---------------+
-                        | Cache buffer  |
-                        +---------------+
-
-            +-------------------+
-            | Data to write     |
-            +-------------------+
-
-                       */
-
-                       /*
-                        * End of write overlaps the existing data.
-                        */
-
-                       size_t data_used = pos + n - wcp->offset;
-
-                       memcpy(wcp->data, data + n - data_used, data_used);
-
-                       /*
-                        * Update the current buffer size with the new data.
-                        */
-
-                       if(pos + n > wcp->offset + wcp->data_size) {
-                               wcp->data_size = pos + n - wcp->offset;
-                       }
-
-                       /*
-                        * Update the file size if changed.
-                        */
-
-                       if (wcp->offset + wcp->data_size > wcp->file_size) {
-                               if (wcp_file_size_change(fsp) == -1) {
-                                       return -1;
-                               }
-                       }
-
-                       /*
-                        * We don't need to move the start of data, but we
-                        * cut down the amount left by the amount used.
-                        */
-
-                       n -= data_used;
-
-                       /*
-                        * We cannot have used all the data here.
-                        */
-
-                       cache_flush_needed = True;
-
-                       DO_PROFILE_INC(writecache_abutted_writes);
-                       total_written = data_used;
-
-                       write_path = 2;
-
-               } else if ((pos >= wcp->file_size) &&
-                          (wcp->offset + wcp->data_size == wcp->file_size) &&
-                          (pos > wcp->offset + wcp->data_size) &&
-                          (pos < wcp->offset + wcp->alloc_size) ) {
-
-                       /* ASCII art.... JRA.
-
-                       End of file ---->|
-
-                        +---------------+---------------+
-                        | Cached data   | Cache buffer  |
-                        +---------------+---------------+
-
-                                              +-------------------+
-                                              | Data to write     |
-                                              +-------------------+
-
-                       */
-
-                       /*
-                        * Non-contiguous write part of which fits within
-                        * the cache buffer and is extending the file
-                        * and the cache contents reflect the current
-                        * data up to the current end of the file.
-                        */
-
-                       size_t data_used;
-
-                       if(pos + n <= wcp->offset + wcp->alloc_size) {
-                               data_used = n;
-                       } else {
-                               data_used = wcp->offset+wcp->alloc_size-pos;
-                       }
-
-                       /*
-                        * Fill in the non-continuous area with zeros.
-                        */
-
-                       memset(wcp->data + wcp->data_size, '\0',
-                               pos - (wcp->offset + wcp->data_size) );
-
-                       memcpy(wcp->data + (pos - wcp->offset), data,
-                              data_used);
-
-                       /*
-                        * Update the current buffer size with the new data.
-                        */
-
-                       if(pos + data_used > wcp->offset + wcp->data_size) {
-                               wcp->data_size = pos + data_used - wcp->offset;
-                       }
-
-                       /*
-                        * Update the file size if changed.
-                        */
-
-                       if (wcp->offset + wcp->data_size > wcp->file_size) {
-                               if (wcp_file_size_change(fsp) == -1) {
-                                       return -1;
-                               }
-                       }
-
-                       /*
-                        * If we used all the data then
-                        * return here.
-                        */
-
-                       if(n == data_used) {
-                               return n;
-                       } else {
-                               cache_flush_needed = True;
-                       }
-
-                       /*
-                        * Move the start of data forward by the amount used,
-                        * cut down the amount left by the same amount.
-                        */
-
-                       data += data_used;
-                       pos += data_used;
-                       n -= data_used;
-
-                       DO_PROFILE_INC(writecache_abutted_writes);
-                       total_written = data_used;
-
-                       write_path = 3;
-
-                } else if ( (pos >= wcp->file_size) &&
-                           (n == 1) &&
-                           (wcp->file_size == wcp->offset + wcp->data_size) &&
-                           (pos < wcp->file_size + wcp->alloc_size)) {
-
-                        /*
-
-                End of file ---->|
-
-                 +---------------+---------------+
-                 | Cached data   | Cache buffer  |
-                 +---------------+---------------+
-
-                                 |<------- allocated size ---------------->|
-
-                                                         +--------+
-                                                         | 1 Byte |
-                                                         +--------+
-
-                       MS-Office seems to do this a lot to determine if
-                       there's enough space on the filesystem to write a new
-                       file.
-
-                       Change to :
-
-                End of file ---->|
-                                 +-----------------------+--------+
-                                 | Zeroed Cached data    | 1 Byte |
-                                 +-----------------------+--------+
-                        */
-
-                       flush_write_cache(fsp, SAMBA_WRITE_FLUSH);
-                       wcp->offset = wcp->file_size;
-                       wcp->data_size = pos - wcp->file_size + 1;
-                       memset(wcp->data, '\0', wcp->data_size);
-                       memcpy(wcp->data + wcp->data_size-1, data, 1);
-
-                       /*
-                        * Update the file size if changed.
-                        */
-
-                       if (wcp->offset + wcp->data_size > wcp->file_size) {
-                               if (wcp_file_size_change(fsp) == -1) {
-                                       return -1;
-                               }
-                       }
-
-                       return n;
-
-               } else {
-
-                       /* ASCII art..... JRA.
-
-   Case 1).
-
-                        +---------------+---------------+
-                        | Cached data   | Cache buffer  |
-                        +---------------+---------------+
-
-                                                              +---------------+
-                                                              | Data to write |
-                                                              +---------------+
-
-   Case 2).
-
-                           +---------------+---------------+
-                           | Cached data   | Cache buffer  |
-                           +---------------+---------------+
-
-   +-------------------+
-   | Data to write     |
-   +-------------------+
-
-    Case 3).
-
-                           +---------------+---------------+
-                           | Cached data   | Cache buffer  |
-                           +---------------+---------------+
-
-                  +-----------------------------------------------------+
-                  | Data to write                                       |
-                  +-----------------------------------------------------+
-
-                 */
-
-                       /*
-                        * Write is bigger than buffer, or there is no
-                        * overlap on the low or high ends.
-                        */
-
-                       DEBUG(9,("write_file: non cacheable write : fd = %d, "
-                                "pos = %.0f, len = %u, "
-                                "current cache pos = %.0f len = %u\n",
-                                fsp->fh->fd, (double)pos, (unsigned int)n,
-                                (double)wcp->offset,
-                                (unsigned int)wcp->data_size ));
-
-                       /*
-                        * If write would fit in the cache, and is
-                        * larger than the data already in the cache,
-                        * flush the cache and preferentially copy the
-                        * data new data into it. Otherwise just write
-                        * the data directly.
-                        */
-
-                       if ( n <= wcp->alloc_size && n > wcp->data_size) {
-                               cache_flush_needed = True;
-                       } else {
-                               ssize_t ret = real_write_file(NULL, fsp, data,
-                                                             pos, n);
-
-                               /*
-                                * If the write overlaps the entire
-                                * cache, then discard the current
-                                * contents of the cache.  Fix from
-                                * Rasmus Borup Hansen rbh@math.ku.dk.
-                                */
-
-                               if ((pos <= wcp->offset) &&
-                                   (pos + n >= wcp->offset+wcp->data_size)) {
-                                       DEBUG(9,("write_file: discarding "
-                                                "overwritten write cache: "
-                                                "fd = %d, off=%.0f, "
-                                                "size=%u\n", fsp->fh->fd,
-                                                (double)wcp->offset,
-                                                (unsigned)wcp->data_size));
-                                       wcp->data_size = 0;
-                               }
-
-                               DO_PROFILE_INC(writecache_direct_writes);
-                               if (ret == -1) {
-                                       return ret;
-                               }
-
-                               if (pos + ret > wcp->file_size) {
-                                       wcp->file_size = pos + ret;
-                               }
-
-                               return ret;
-                       }
-
-                       write_path = 4;
-
-               }
-
-               if (cache_flush_needed) {
-                       DEBUG(3, ("SAMBA_WRITE_FLUSH:%d: due to noncontinuous "
-                                 "write: fd = %d, size = %.0f, pos = %.0f, "
-                                 "n = %u, wcp->offset=%.0f, "
-                                 "wcp->data_size=%u\n",
-                                 write_path, fsp->fh->fd,
-                                 (double)wcp->file_size, (double)pos,
-                                 (unsigned int)n, (double)wcp->offset,
-                                 (unsigned int)wcp->data_size ));
-
-                       flush_write_cache(fsp, SAMBA_WRITE_FLUSH);
-               }
-       }
-
-       /*
-        * If the write request is bigger than the cache
-        * size, write it all out.
-        */
-
-       if (n > wcp->alloc_size ) {
-               ssize_t ret = real_write_file(NULL,fsp, data, pos, n);
-               if (ret == -1) {
-                       return -1;
-               }
-
-               if (pos + ret > wcp->file_size) {
-                       wcp->file_size = pos + n;
-               }
-
-               DO_PROFILE_INC(writecache_direct_writes);
-               return total_written + n;
-       }
-
-       /*
-        * If there's any data left, cache it.
-        */
-
-       if (n) {
-               DO_PROFILE_INC(writecache_cached_writes);
-               if (wcp->data_size) {
-                       DO_PROFILE_INC(writecache_abutted_writes);
-               } else {
-                       DO_PROFILE_INC(writecache_init_writes);
-               }
-
-               if ((wcp->data_size == 0)
-                   && (pos > wcp->file_size)
-                   && (pos + n <= wcp->file_size + wcp->alloc_size)) {
-                       /*
-                        * This is a write completely beyond the
-                        * current EOF, but within reach of the write
-                        * cache. We expect fill-up writes pretty
-                        * soon, so it does not make sense to start
-                        * the write cache at the current
-                        * offset. These fill-up writes would trigger
-                        * separate pwrites or even unnecessary cache
-                        * flushes because they overlap if this is a
-                        * one-byte allocating write.
-                        */
-                       wcp->offset = wcp->file_size;
-                       wcp->data_size = pos - wcp->file_size;
-                       memset(wcp->data, 0, wcp->data_size);
-               }
-
-               memcpy(wcp->data+wcp->data_size, data, n);
-               if (wcp->data_size == 0) {
-                       wcp->offset = pos;
-               }
-               wcp->data_size += n;
-
-               /*
-                * Update the file size if changed.
-                */
-
-               if (wcp->offset + wcp->data_size > wcp->file_size) {
-                       if (wcp_file_size_change(fsp) == -1) {
-                               return -1;
-                       }
-               }
-               DEBUG(9, ("wcp->offset = %.0f wcp->data_size = %u cache "
-                         "return %u\n",
-                         (double)wcp->offset, (unsigned int)wcp->data_size,
-                         (unsigned int)n));
-
-               total_written += n;
-               return total_written; /* .... that's a write :) */
-       }
-
+       total_written = real_write_file(req, fsp, data, pos, n);
        return total_written;
 }
 
-/****************************************************************************
- Delete the write cache structure.
-****************************************************************************/
-
-void delete_write_cache(files_struct *fsp)
-{
-       struct write_cache *wcp;
-
-       if(!fsp) {
-               return;
-       }
-
-       if(!(wcp = fsp->wcp)) {
-               return;
-       }
-
-       DO_PROFILE_INC(writecache_deallocations);
-       allocated_write_caches--;
-
-       SMB_ASSERT(wcp->data_size == 0);
-
-       SAFE_FREE(wcp->data);
-       SAFE_FREE(fsp->wcp);
-
-       DEBUG(10,("delete_write_cache: File %s deleted write cache\n",
-                 fsp_str_dbg(fsp)));
-}
-
-/****************************************************************************
- Setup the write cache structure.
-****************************************************************************/
-
-static bool setup_write_cache(files_struct *fsp, off_t file_size)
-{
-       ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn));
-       struct write_cache *wcp;
-
-       if (allocated_write_caches >= MAX_WRITE_CACHES) {
-               return False;
-       }
-
-       if(alloc_size == 0 || fsp->wcp) {
-               return False;
-       }
-
-       if((wcp = SMB_MALLOC_P(struct write_cache)) == NULL) {
-               DEBUG(0,("setup_write_cache: malloc fail.\n"));
-               return False;
-       }
-
-       wcp->file_size = file_size;
-       wcp->offset = 0;
-       wcp->alloc_size = alloc_size;
-       wcp->data_size = 0;
-       if((wcp->data = (char *)SMB_MALLOC(wcp->alloc_size)) == NULL) {
-               DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n",
-                       (unsigned int)wcp->alloc_size ));
-               SAFE_FREE(wcp);
-               return False;
-       }
-
-       memset(wcp->data, '\0', wcp->alloc_size );
-
-       fsp->wcp = wcp;
-       DO_PROFILE_INC(writecache_allocations);
-       allocated_write_caches++;
-
-       DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n",
-                 fsp_str_dbg(fsp), (unsigned long)wcp->alloc_size));
-
-       return True;
-}
-
-/****************************************************************************
- Cope with a size change.
-****************************************************************************/
-
-void set_filelen_write_cache(files_struct *fsp, off_t file_size)
-{
-       if(fsp->wcp) {
-               /* The cache *must* have been flushed before we do this. */
-               if (fsp->wcp->data_size != 0) {
-                       char *msg;
-                       if (asprintf(&msg, "set_filelen_write_cache: size change "
-                                "on file %s with write cache size = %lu\n",
-                                fsp->fsp_name->base_name,
-                                (unsigned long)fsp->wcp->data_size) != -1) {
-                               smb_panic(msg);
-                       } else {
-                               smb_panic("set_filelen_write_cache");
-                       }
-               }
-               fsp->wcp->file_size = file_size;
-       }
-}
-
-/*******************************************************************
- Flush a write cache struct to disk.
-********************************************************************/
-
-ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
-{
-       struct write_cache *wcp = fsp->wcp;
-       size_t data_size;
-       ssize_t ret;
-
-       if(!wcp || !wcp->data_size) {
-               return 0;
-       }
-
-       data_size = wcp->data_size;
-       wcp->data_size = 0;
-
-       switch (reason) {
-       case SAMBA_SEEK_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_seek);
-               break;
-       case SAMBA_READ_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_read);
-               break;
-       case SAMBA_WRITE_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_write);;
-               break;
-       case SAMBA_READRAW_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_readraw);
-               break;
-       case SAMBA_OPLOCK_RELEASE_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_oplock);
-               break;
-       case SAMBA_CLOSE_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_close);
-               break;
-       case SAMBA_SYNC_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_sync);
-               break;
-       case SAMBA_SIZECHANGE_FLUSH:
-               DO_PROFILE_INC(writecache_flush_reason_sizechange);
-               break;
-       default:
-               break;
-       }
-
-       DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n",
-               fsp->fh->fd, (double)wcp->offset, (unsigned int)data_size));
-
-       if(data_size == wcp->alloc_size) {
-               DO_PROFILE_INC(writecache_perfect_writes);
-       }
-
-       ret = real_write_file(NULL, fsp, wcp->data, wcp->offset, data_size);
-
-       /*
-        * Ensure file size if kept up to date if write extends file.
-        */
-
-       if ((ret != -1) && (wcp->offset + ret > wcp->file_size)) {
-               wcp->file_size = wcp->offset + ret;
-       }
-
-       return ret;
-}
-
 /*******************************************************************
 sync a file
 ********************************************************************/
@@ -1057,10 +297,7 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug
 
        if (lp_strict_sync(SNUM(conn)) &&
            (lp_sync_always(SNUM(conn)) || write_through)) {
-               int ret = flush_write_cache(fsp, SAMBA_SYNC_FLUSH);
-               if (ret == -1) {
-                       return map_nt_error_from_unix(errno);
-               }
+               int ret;
                ret = smb_vfs_fsync_sync(fsp);
                if (ret == -1) {
                        return map_nt_error_from_unix(errno);
index 0cdce20d12287f4bba1d6b84efcd7170128ae9cf..c0fafecd2eb806a0ba45f2f16c0c7864f73607ba 100644 (file)
@@ -28,9 +28,6 @@
 struct smbd_dmapi_context *dmapi_ctx = NULL;
 #endif
 
-/* how many write cache buffers have been allocated */
-unsigned int allocated_write_caches = 0;
-
 const struct mangle_fns *mangle_fns = NULL;
 
 unsigned char *chartest = NULL;
index d7d584eb274e3a9cebe98f43cef254ece0c92a22..c791eb0fa6f14e9e7b94ead44d9bc6ed41c0098d 100644 (file)
@@ -30,9 +30,6 @@ struct smbd_dmapi_context;
 extern struct smbd_dmapi_context *dmapi_ctx;
 #endif
 
-/* how many write cache buffers have been allocated */
-extern unsigned int allocated_write_caches;
-
 /* A singleton cache to speed up searching by dev/inode. */
 struct fsp_singleton_cache {
        files_struct *fsp;
index 2d4168c3ebe9cdfdbbb619ef816e5b7ad6f0a857..fa990cacd5e05d1037296d5201a994c0e9713155 100644 (file)
@@ -1451,8 +1451,6 @@ static NTSTATUS open_file(files_struct *fsp,
                fsp->aio_write_behind = True;
        }
 
-       fsp->wcp = NULL; /* Write cache pointer. */
-
        DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
                 conn->session_info->unix_info->unix_name,
                 smb_fname_str_dbg(smb_fname),
index 1a62821c760e5cf03b7458c6575b2bd5f59168ee..ad993cc95b04205abbdaebcff348447220123362 100644 (file)
@@ -139,9 +139,6 @@ static void release_file_oplock(files_struct *fsp)
        fsp->oplock_type = NO_OPLOCK;
        fsp->sent_oplock_break = NO_BREAK_SENT;
 
-       flush_write_cache(fsp, SAMBA_OPLOCK_RELEASE_FLUSH);
-       delete_write_cache(fsp);
-
        TALLOC_FREE(fsp->oplock_timeout);
 }
 
@@ -169,9 +166,6 @@ static void downgrade_file_oplock(files_struct *fsp)
        sconn->oplocks.level_II_open++;
        fsp->sent_oplock_break = NO_BREAK_SENT;
 
-       flush_write_cache(fsp, SAMBA_OPLOCK_RELEASE_FLUSH);
-       delete_write_cache(fsp);
-
        TALLOC_FREE(fsp->oplock_timeout);
 }
 
index dd6993a60f0992881278a000b04405b9c5ac44b6..4bb0f9a54c82d6186ffb3bbf40cb092d2e9787fd 100644 (file)
@@ -330,9 +330,6 @@ ssize_t write_file(struct smb_request *req,
                        const char *data,
                        off_t pos,
                        size_t n);
-void delete_write_cache(files_struct *fsp);
-void set_filelen_write_cache(files_struct *fsp, off_t file_size);
-ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason);
 NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_through);
 
 /* The following definitions come from smbd/filename.c  */
index 6c71b57e04661eb7c400c2f38fd33f764055e919..9e126cd36924dae0bba2070c12ce8ac457995f47 100644 (file)
@@ -3643,7 +3643,6 @@ static void send_file_readbraw(connection_struct *conn,
         */
 
        if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
-           (fsp->wcp == NULL) &&
            lp_use_sendfile(SNUM(conn), xconn->smb1.signing_state) ) {
                ssize_t sendfile_read = -1;
                char header[4];
@@ -3827,8 +3826,6 @@ void reply_readbraw(struct smb_request *req)
                return;
        }
 
-       flush_write_cache(fsp, SAMBA_READRAW_FLUSH);
-
        startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0);
        if(req->wct == 10) {
                /*
@@ -4215,7 +4212,6 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
        if (!req_is_in_chain(req) &&
            !req->encrypted &&
            (fsp->base_fsp == NULL) &&
-           (fsp->wcp == NULL) &&
            lp_use_sendfile(SNUM(conn), xconn->smb1.signing_state) ) {
                uint8_t headerbuf[smb_size + 12 * 2 + 1 /* padding byte */];
                DATA_BLOB header;
@@ -5446,8 +5442,6 @@ void reply_lseek(struct smb_request *req)
                return;
        }
 
-       flush_write_cache(fsp, SAMBA_SEEK_FLUSH);
-
        mode = SVAL(req->vwv+1, 0) & 3;
        /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
        startpos = (off_t)IVALS(req->vwv+2, 0);
index 470a8df494420215d0aaeb7c85611dc3a90e79e6..86d5bbc58f0e64b2db21a3cfad9c6a9d5d9af20f 100644 (file)
@@ -125,7 +125,6 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
        struct tevent_req *subreq;
        struct smbd_smb2_flush_state *state;
        struct smb_request *smbreq;
-       int ret;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct smbd_smb2_flush_state);
@@ -187,12 +186,6 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
-       ret = flush_write_cache(fsp, SAMBA_SYNC_FLUSH);
-       if (ret == -1) {
-               tevent_req_nterror(req,  map_nt_error_from_unix(errno));
-               return tevent_req_post(req, ev);
-       }
-
        subreq = SMB_VFS_FSYNC_SEND(state, ev, fsp);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
index a7d2496bc6f30e4a7f425fa9fe9a0d53116f1b66..e84584349ab9aa8c56becb1059d2605bd02cd6f8 100644 (file)
@@ -355,7 +355,6 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
            smb2req->do_encryption ||
            smbd_smb2_is_compound(smb2req) ||
            (fsp->base_fsp != NULL) ||
-           (fsp->wcp != NULL) ||
            (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) ||
            (state->in_offset >= fsp->fsp_name->st.st_ex_size) ||
            (fsp->fsp_name->st.st_ex_size < state->in_offset + state->in_length))
index a104921784f1685cb76d82dad00c574149e8db27..dbf42cd56f42600b499702bd9bf94908dd1f8bce 100644 (file)
@@ -515,10 +515,7 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
 
                contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
 
-               flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
-               if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
-                       set_filelen_write_cache(fsp, len);
-               }
+               ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len);
 
                contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
 
@@ -585,9 +582,7 @@ int vfs_set_filelen(files_struct *fsp, off_t len)
 
        DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
                  fsp_str_dbg(fsp), (double)len));
-       flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
        if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
-               set_filelen_write_cache(fsp, len);
                notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_SIZE
                             | FILE_NOTIFY_CHANGE_ATTRIBUTES,
@@ -676,8 +671,6 @@ int vfs_fill_sparse(files_struct *fsp, off_t len)
 
        contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
 
-       flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
-
        offset = fsp->fsp_name->st.st_ex_size;
        num_to_write = len - fsp->fsp_name->st.st_ex_size;
 
@@ -703,10 +696,6 @@ int vfs_fill_sparse(files_struct *fsp, off_t len)
 
  out:
 
-       if (ret == 0) {
-               set_filelen_write_cache(fsp, len);
-       }
-
        contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
        return ret;
 }