smbd: always flush pending write time update when setting filesize
authorRalph Boehme <slow@samba.org>
Thu, 12 Mar 2020 15:52:34 +0000 (16:52 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 19 Mar 2020 01:20:34 +0000 (01:20 +0000)
We need to flush a pending write time update even when we're setting the
filesize to current filesize.

Note that we're already doing it this way in the relevant places listed my
dochelp@MS in

https://lists.samba.org/archive/cifs-protocol/2019-December/003364.html

  Cleanup (= Close)
  SetBasicInfo
  SetAllocationInfo
  SetEndOfFileInfo
  SetValidDataLengthInfo
  Flush
  FSCTL_SET_ENCRYPTION
  FSCTL_OFFLOAD_WRITE

Cleanup (= Close):

  Already implemented by update_write_time_on_close() and friends.

SetBasicInfo:

  Currently doesn't flush pending updates. Fixed by a subsequent commit.

SetAllocationInfo:

  smb_set_file_allocation_info() when setting a file's allocation size.

SetEndOfFileInfo:

  Currently doesn't flush pending updates. Fixed by a subsequent commit.

SetValidDataLengthInfo:

  Not implemented, returns NT_STATUS_NOT_SUPPORTED which seems wrong btw, as
  SetValidDataLengthInfo IS listed in MS-SMB2 2.2.39.

Flush:

  Currently doesn't flush pending updates. Fixed by subsequent commit.

FSCTL_SET_ENCRYPTION:

  Windows 2016 doesn't flush a pending writetime update, verified with a
  smbtorture test.

FSCTL_OFFLOAD_WRITE:

  NT_STATUS_NOT_IMPLEMENTED

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14150

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
selftest/knownfail.d/samba3.smb2.timestamps
source3/smbd/trans2.c

index 33c9d9a42681c81bcd9fe305a5bde9c3e2b3d629..c7d0ff2849e33345d39196d4343e98fbc765f660 100644 (file)
@@ -1,3 +1,2 @@
-^samba3.smb2.timestamps.delayed-write-vs-seteof\(.*\)$
 ^samba3.smb2.timestamps.delayed-write-vs-flush\(.*\)$
 ^samba3.smb2.timestamps.delayed-write-vs-setbasic\(.*\)$
index a7a4d32b2c325daa10cfce78b098b657d4c2594c..8000e1ae924e361a9e980f4a165e0c15b0d93d85 100644 (file)
@@ -6687,6 +6687,13 @@ static NTSTATUS smb_set_file_size(connection_struct *conn,
                 get_file_size_stat(psbuf));
 
        if (size == get_file_size_stat(psbuf)) {
+               if (fsp == NULL) {
+                       return NT_STATUS_OK;
+               }
+               if (!fsp->modified) {
+                       return NT_STATUS_OK;
+               }
+               trigger_write_time_update_immediate(fsp);
                return NT_STATUS_OK;
        }