Attempt to fix bugs in write cache code (yes I know it's going away :-).
authorJeremy Allison <jra@samba.org>
Sun, 20 Jan 2002 00:04:15 +0000 (00:04 +0000)
committerJeremy Allison <jra@samba.org>
Sun, 20 Jan 2002 00:04:15 +0000 (00:04 +0000)
Jeremy.

source/smbd/fileio.c
source/smbd/vfs.c

index 38da96b7410ee962ea039fe4056da59bb15a9c95..84b8e35bf05c29683e87d8ed86a6b0bb8cd51d93 100644 (file)
@@ -419,7 +419,7 @@ len = %u\n",fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigne
       if ( n <= wcp->alloc_size && n > wcp->data_size) {
         cache_flush_needed = True;
       } else {
-       DO_PROFILE_INC(writecache_direct_writes);
+        DO_PROFILE_INC(writecache_direct_writes);
         return real_write_file(fsp, data, pos, n);
       }
 
@@ -552,7 +552,13 @@ static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
 void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
 {
   if(fsp->wcp) {
-    flush_write_cache(fsp, SIZECHANGE_FLUSH);
+    /* The cache *must* have been flushed before we do this. */
+    if (fsp->wcp->data_size != 0) {
+      pstring msg;
+      slprintf(msg, sizeof(msg)-1, "set_filelen_write_cache: size change \
+on file %s with write cache size = %u\n", fsp->fsp_name, fsp->wcp->data_size );
+      smb_panic(msg);
+    }
     fsp->wcp->file_size = file_size;
   }
 }
@@ -565,6 +571,7 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
 {
   write_cache *wcp = fsp->wcp;
   size_t data_size;
+  ssize_t ret;
 
   if(!wcp || !wcp->data_size)
     return 0;
@@ -582,7 +589,16 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
     DO_PROFILE_INC(writecache_num_perfect_writes);
 #endif
 
-  return real_write_file(fsp, wcp->data, wcp->offset, data_size);
+  ret = real_write_file(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;
 }
 
 /*******************************************************************
index 2396a43d48bb61b176c9ce35ae99662413316c1c..e05b217a14151c26212232ff1410d13a4dec3204 100644 (file)
@@ -351,6 +351,7 @@ int vfs_allocate_file_space(files_struct *fsp, SMB_OFF_T len)
                DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
                                fsp->fsp_name, (double)st.st_size ));
 
+               flush_write_cache(fsp, SIZECHANGE_FLUSH);
                if ((ret = vfs_ops->ftruncate(fsp, fsp->fd, len)) != -1) {
                        set_filelen_write_cache(fsp, len);
                }
@@ -389,6 +390,7 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
 
        release_level_2_oplocks_on_change(fsp);
        DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
+       flush_write_cache(fsp, SIZECHANGE_FLUSH);
        if ((ret = fsp->conn->vfs_ops.ftruncate(fsp, fsp->fd, len)) != -1)
                set_filelen_write_cache(fsp, len);