Bug 13541 - Durable handle reconnect doesn't update fsp write-time from locking.tdb record
Summary: Durable handle reconnect doesn't update fsp write-time from locking.tdb record
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: File services (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Ralph Böhme
QA Contact: Samba QA Contact
Depends on:
Reported: 2018-07-22 21:14 UTC by Ralph Böhme
Modified: 2018-08-30 21:35 UTC (History)
2 users (show)

See Also:

Example network trace (600.63 KB, application/octet-stream)
2018-07-27 20:37 UTC, Ralph Böhme
no flags Details
Work in progress patches (645.45 KB, patch)
2018-08-17 13:22 UTC, Stefan Metzmacher
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ralph Böhme 2018-07-22 21:14:09 UTC
Durable handle reconnect doesn't update fsp write-time from locking.tdb record, as a result the timestamps in the craete response come from the filesystem via stat().

What's missing is a block like

+       write_time = get_share_mode_write_time(lck);                                                 
+       if (!null_timespec(write_time)) {         
+               update_stat_ex_mtime(&fsp->fsp_name->st, write_time);                                
+       }                                         

Have patch, need bugnumer.
Comment 1 Ralph Böhme 2018-07-27 17:33:26 UTC
Thinking about it, as the disconnect sets the timestamp (if any) from locking.tdb record *on the filesystem* with utimes(), the reconnect should pick up the correct mtime from the filesytem.

So before just applying the above fix  we need to understand the full picture.
Comment 2 Ralph Böhme 2018-07-27 20:37:40 UTC
Created attachment 14351 [details]
Example network trace

Packet 13479 gives an example of a wrong mtime in a DH reconnect response:

Last Write: Jul 19, 2018 17:43:05.088183000 CEST

This is the timestamp of the last processed write from packet 13332 or 13419.
Comment 3 Stefan Metzmacher 2018-08-17 13:08:39 UTC
(In reply to Ralph Böhme from comment #2)

It turns out that our write time update handling differs compared to
recent Windows releases.

We basically implement the behavior of Windows 2000:

- The only write time update happens ~2 seconds after
  the first write.
- If the handle was written the close will trigger
  a 2nd write time update.

Both updates use the current timestamp.

Windows >= 2008R2 behaves differently:
(Actually I don't know when the behavior changed,
I guess with 2008, as SMB2 was introduced):

Behavior without SMB1 Query Path Info:
- Write time updates are deferred up to 4 seconds
  after a write. Once the time is updated, the timer
  will be re-scheduled by the next write.
- Close only updates the write time if a pending
  update is still pending.
All updates use the current timestamp.

Additional behavior with SMB1 Query Path Info:
- If an SMB1 Query Path Info is processed
  Any pending timer on all open handles
  are removed. And no new timers are every scheduled
  on these handles.
- The only write time update will happen on close (to the current time).

I think we better implement the new behavior, as this is what all
Windows SMB2 enabled servers provide, even over SMB1.
First I was confused by the difference between the protocol,
but once I removed the SMB1 query path info calls from
the tests, SMB1 and SMB2 behaved in the same way for pure
handle based access.
Comment 4 Stefan Metzmacher 2018-08-17 13:22:20 UTC
Created attachment 14429 [details]
Work in progress patches
Comment 5 Stefan Metzmacher 2018-08-17 14:04:36 UTC
(In reply to Stefan Metzmacher from comment #3)

The documentation doesn't include any delayed updates at all.

[MS-FSA] Algorithm for Noting That a File Has Been Modified

The inputs for this algorithm are as follows:

    Open: The Open through which the file was modified.

The pseudocode for the algorithm is as follows:

    If Open.UserSetModificationTime is FALSE, set Open.File.LastModificationTime to the current system time.

    If Open.UserSetChangeTime is FALSE, set Open.File.LastChangeTime to the current system time.

    If Open.UserSetAccessTime is FALSE, set Open.File.LastAccessTime to the current system time.

    Set Open.File.FileAttributes.FILE_ATTRIBUTE_ARCHIVE to TRUE.
Comment 6 Stefan Metzmacher 2018-08-17 14:17:24 UTC
(In reply to Stefan Metzmacher from comment #5)

There're some more information in

- Set to the current time when the file is created during processing of
- Set to the current time on a supersede/overwrite open, or on a stream
- Set when IRP_MJ_SET_INFORMATION is processed for the following
  information classes:
  - FileAllocationInformation
  - FileBasicInformation
  - FileEndOfFileInformation
- Set when IRP_MJ_FLUSH_BUFFERS is processed.
- Noted when a write is made to the file, set to the current time when the file
  handle is closed.

Maybe the IRP_MJ_FLUSH_BUFFERS is the timer that updates the timestamp every few seconds.
Comment 7 Ralph Böhme 2018-08-30 14:59:09 UTC
(In reply to Ralph Böhme from comment #1)
Turns out this was caused by timestamps being inconsistent by default in GlusterFS. After setting

# gluster volume set VOLNAME features.utime on
# gluster volume set VOLNAME storage.ctime on

the DH2C create response has the correct mtime.

Nevertheless, we may want to apply the suggested patch to ensure the DHXC picks up any write time via a handle from another client, just like we do it in open_file_ntcreate().
Comment 8 Ralph Böhme 2018-08-30 15:07:12 UTC
(In reply to Ralph Böhme from comment #7)
Nevermind, contending opens would have invalidated the DH so this doesn't apply. :)