diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/dosmode.c | 52 | ||||
-rw-r--r-- | source3/smbd/fileio.c | 47 | ||||
-rw-r--r-- | source3/smbd/reply.c | 6 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 12 |
4 files changed, 82 insertions, 35 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 0ac3873275..88c6a51770 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -616,39 +616,51 @@ int file_ntimes(connection_struct *conn, const char *fname, const struct timespe return ret; } -/******************************************************************* - Change a filetime - possibly allowing DOS semantics. -*******************************************************************/ +/****************************************************************** + Force a "sticky" write time on a pathname. This will always be + returned on all future write time queries and set on close. +******************************************************************/ -bool set_write_time_path(connection_struct *conn, const char *fname, - struct file_id fileid, const struct timespec mtime, - bool overwrite) +bool set_sticky_write_time_path(connection_struct *conn, const char *fname, + struct file_id fileid, const struct timespec mtime) { if (null_timespec(mtime)) { return true; } - if (!set_write_time(fileid, mtime, overwrite)) { + if (!set_sticky_write_time(fileid, mtime)) { return false; } - /* in the overwrite case the caller should trigger the notify */ - if (!overwrite) { - notify_fname(conn, NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_WRITE, fname); - } - return true; } -bool set_write_time_fsp(struct files_struct *fsp, const struct timespec mtime, - bool overwrite) +/****************************************************************** + Force a "sticky" write time on an fsp. This will always be + returned on all future write time queries and set on close. +******************************************************************/ + +bool set_sticky_write_time_fsp(struct files_struct *fsp, const struct timespec mtime) { - if (overwrite) { - fsp->write_time_forced = true; - TALLOC_FREE(fsp->update_write_time_event); + fsp->write_time_forced = true; + TALLOC_FREE(fsp->update_write_time_event); + + return set_sticky_write_time_path(fsp->conn, fsp->fsp_name, + fsp->file_id, mtime); +} + +/****************************************************************** + Update a write time immediately, without the 2 second delay. +******************************************************************/ + +bool update_write_time(struct files_struct *fsp) +{ + if (!set_write_time(fsp->file_id, timespec_current())) { + return false; } - return set_write_time_path(fsp->conn, fsp->fsp_name, fsp->file_id, - mtime, overwrite); + notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name); + + return true; } diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 64cea7f7ce..63850f24eb 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -176,28 +176,38 @@ static void update_write_time_handler(struct event_context *ctx, const struct timeval *now, void *private_data) { - files_struct *fsp = (files_struct *)private_data; + files_struct *fsp = (files_struct *)private_data; - /* Remove the timed event handler. */ - TALLOC_FREE(fsp->update_write_time_event); - DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); + /* Remove the timed event handler. */ + TALLOC_FREE(fsp->update_write_time_event); + DEBUG(5, ("Update write time on %s\n", fsp->fsp_name)); - /* change the write time if not already changed by someoneelse */ - set_write_time_fsp(fsp, timespec_current(), false); + /* change the write time if not already changed by someone else */ + update_write_time(fsp); } +/********************************************************* + Schedule a write time update for WRITE_TIME_UPDATE_USEC_DELAY + in the future. +*********************************************************/ + void trigger_write_time_update(struct files_struct *fsp) { int delay; if (fsp->write_time_forced) { + /* No point - "sticky" write times + * in effect. + */ return; } - if (fsp->update_write_time_triggered) { + if (fsp->update_write_time_event) { + /* + * No point - an event is already scheduled. + */ return; } - fsp->update_write_time_triggered = true; delay = lp_parm_int(SNUM(fsp->conn), "smbd", "writetimeupdatedelay", @@ -212,6 +222,27 @@ void trigger_write_time_update(struct files_struct *fsp) update_write_time_handler, fsp); } +void trigger_write_time_update_immediate(struct files_struct *fsp) +{ + if (fsp->write_time_forced) { + /* + * No point - "sticky" write times + * in effect. + */ + return; + } + + if (fsp->update_write_time_event) { + /* + * No point - an event is already scheduled. + */ + return; + } + + fsp->update_write_time_on_close = true; + update_write_time(fsp); +} + /**************************************************************************** Write to a file. ****************************************************************************/ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 16f8a5b177..6933533672 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3810,9 +3810,11 @@ void reply_write(struct smb_request *req) END_PROFILE(SMBwrite); return; } - } else + trigger_write_time_update_immediate(fsp); + } else { nwritten = write_file(req,fsp,data,startpos,numtowrite); - + } + status = sync_file(conn, fsp, False); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("reply_write: sync_file for %s returned %s\n", diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 881b29c6f0..8d839b66b3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4900,11 +4900,11 @@ NTSTATUS smb_set_file_time(connection_struct *conn, time_to_asc(convert_timespec_to_time_t(ts[1])) )); if (fsp != NULL) { - set_write_time_fsp(fsp, ts[1], true); + set_sticky_write_time_fsp(fsp, ts[1]); } else { - set_write_time_path(conn, fname, + set_sticky_write_time_path(conn, fname, vfs_file_id_from_sbuf(conn, psbuf), - ts[1], true); + ts[1]); } } @@ -4988,6 +4988,7 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, if (vfs_set_filelen(fsp, size) == -1) { return map_nt_error_from_unix(errno); } + trigger_write_time_update_immediate(fsp); return NT_STATUS_OK; } @@ -5011,6 +5012,7 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, return status; } + trigger_write_time_update_immediate(new_fsp); close_file(new_fsp,NORMAL_CLOSE); return NT_STATUS_OK; } @@ -5737,7 +5739,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, * This is equivalent to a write. Ensure it's seen immediately * if there are no pending writes. */ - trigger_write_time_update(fsp); + trigger_write_time_update_immediate(fsp); return NT_STATUS_OK; } @@ -5771,7 +5773,7 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, * This is equivalent to a write. Ensure it's seen immediately * if there are no pending writes. */ - trigger_write_time_update(new_fsp); + trigger_write_time_update_immediate(new_fsp); close_file(new_fsp,NORMAL_CLOSE); return NT_STATUS_OK; |