mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
Got the logic simplification worked out so we still pass
BASE-DELAYWRITE and also RAW-CLOSE. Jeremy.
This commit is contained in:
parent
977fa4e377
commit
c99dd5c23e
@ -6108,9 +6108,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
|
||||
|
||||
/* The following definitions come from smbd/close.c */
|
||||
|
||||
void set_close_write_time(struct share_mode_lock *lck,
|
||||
struct files_struct *fsp,
|
||||
struct timespec ts);
|
||||
void set_close_write_time(struct files_struct *fsp, struct timespec ts);
|
||||
NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
|
||||
enum file_close_type close_type);
|
||||
void msg_close_file(struct messaging_context *msg_ctx,
|
||||
@ -6309,6 +6307,10 @@ bool directory_has_default_acl(connection_struct *conn, const char *fname);
|
||||
/* The following definitions come from smbd/fileio.c */
|
||||
|
||||
ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
|
||||
void update_write_time_handler(struct event_context *ctx,
|
||||
struct timed_event *te,
|
||||
struct timeval now,
|
||||
void *private_data);
|
||||
void trigger_write_time_update(struct files_struct *fsp);
|
||||
void trigger_write_time_update_immediate(struct files_struct *fsp);
|
||||
ssize_t write_file(struct smb_request *req,
|
||||
|
@ -274,6 +274,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
|
||||
NTSTATUS tmp_status;
|
||||
struct file_id id;
|
||||
|
||||
/* Ensure any pending write time updates are done. */
|
||||
if (fsp->update_write_time_event) {
|
||||
update_write_time_handler(smbd_event_context(),
|
||||
fsp->update_write_time_event,
|
||||
timeval_current(),
|
||||
(void *)fsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock the share entries, and determine if we should delete
|
||||
* on close. If so delete whilst the lock is still in effect.
|
||||
@ -294,15 +302,21 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
|
||||
DEBUG(10,("close_remove_share_mode: write time forced "
|
||||
"for file %s\n",
|
||||
fsp_str_dbg(fsp)));
|
||||
set_close_write_time(lck, fsp, lck->changed_write_time);
|
||||
set_close_write_time(fsp, lck->changed_write_time);
|
||||
} else if (fsp->update_write_time_on_close) {
|
||||
DEBUG(10,("close_remove_share_mode: update_write_time_on_close "
|
||||
"set for file %s\n",
|
||||
fsp_str_dbg(fsp)));
|
||||
/* Someone had a pending write. */
|
||||
if (null_timespec(fsp->close_write_time)) {
|
||||
set_close_write_time(lck, fsp, timespec_current());
|
||||
DEBUG(10,("close_remove_share_mode: update to current time "
|
||||
"for file %s\n",
|
||||
fsp_str_dbg(fsp)));
|
||||
/* Update to current time due to "normal" write. */
|
||||
set_close_write_time(fsp, timespec_current());
|
||||
} else {
|
||||
set_close_write_time(lck, fsp, fsp->close_write_time);
|
||||
DEBUG(10,("close_remove_share_mode: write time pending "
|
||||
"for file %s\n",
|
||||
fsp_str_dbg(fsp)));
|
||||
/* Update to time set on close call. */
|
||||
set_close_write_time(fsp, fsp->close_write_time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -480,36 +494,23 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
|
||||
return status;
|
||||
}
|
||||
|
||||
void set_close_write_time(struct share_mode_lock *lck,
|
||||
struct files_struct *fsp, struct timespec ts)
|
||||
void set_close_write_time(struct files_struct *fsp, struct timespec ts)
|
||||
{
|
||||
DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
|
||||
|
||||
if (null_timespec(ts)) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* if the write time on close is explict set, then don't
|
||||
* need to fix it up to the value in the locking db
|
||||
*/
|
||||
fsp->write_time_forced = false;
|
||||
|
||||
fsp->update_write_time_on_close = true;
|
||||
fsp->close_write_time = ts;
|
||||
|
||||
/* On close if we're changing the real file time we
|
||||
* must update it in the open file db too. */
|
||||
(void)set_write_time(fsp->file_id, ts);
|
||||
/* If someone has a sticky write time then update it as well. */
|
||||
if (lck && !null_timespec(lck->changed_write_time)) {
|
||||
(void)set_sticky_write_time(fsp->file_id, ts);
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
|
||||
{
|
||||
struct smb_file_time ft;
|
||||
NTSTATUS status;
|
||||
struct share_mode_lock *lck = NULL;
|
||||
|
||||
ZERO_STRUCT(ft);
|
||||
|
||||
@ -532,8 +533,22 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* On close if we're changing the real file time we
|
||||
* must update it in the open file db too. */
|
||||
(void)set_write_time(fsp->file_id, fsp->close_write_time);
|
||||
|
||||
lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
|
||||
if (lck) {
|
||||
/* Close write times overwrite sticky write times
|
||||
so we must replace any sticky write time here. */
|
||||
if (!null_timespec(lck->changed_write_time)) {
|
||||
(void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
|
||||
}
|
||||
TALLOC_FREE(lck);
|
||||
}
|
||||
|
||||
ft.mtime = fsp->close_write_time;
|
||||
status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true);
|
||||
status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -171,16 +171,13 @@ static int wcp_file_size_change(files_struct *fsp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void update_write_time_handler(struct event_context *ctx,
|
||||
void update_write_time_handler(struct event_context *ctx,
|
||||
struct timed_event *te,
|
||||
struct timeval now,
|
||||
void *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_str_dbg(fsp)));
|
||||
|
||||
/* change the write time in the open file db. */
|
||||
@ -189,6 +186,9 @@ static void update_write_time_handler(struct event_context *ctx,
|
||||
/* And notify. */
|
||||
notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
|
||||
|
||||
/* Remove the timed event handler. */
|
||||
TALLOC_FREE(fsp->update_write_time_event);
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
|
@ -1296,7 +1296,7 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
|
||||
close_file(NULL, fsp1, NORMAL_CLOSE);
|
||||
|
||||
/* Ensure the modtime is set correctly on the destination file. */
|
||||
set_close_write_time(NULL, fsp2, smb_fname_src->st.st_ex_mtime);
|
||||
set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
|
||||
|
||||
status = close_file(NULL, fsp2, NORMAL_CLOSE);
|
||||
|
||||
|
@ -4646,7 +4646,7 @@ void reply_close(struct smb_request *req)
|
||||
*/
|
||||
|
||||
t = srv_make_unix_date3(req->vwv+1);
|
||||
set_close_write_time(NULL, fsp, convert_time_t_to_timespec(t));
|
||||
set_close_write_time(fsp, convert_time_t_to_timespec(t));
|
||||
|
||||
/*
|
||||
* close_file() returns the unix errno if an error
|
||||
@ -4723,7 +4723,7 @@ void reply_writeclose(struct smb_request *req)
|
||||
|
||||
nwritten = write_file(req,fsp,data,startpos,numtowrite);
|
||||
|
||||
set_close_write_time(NULL, fsp, mtime);
|
||||
set_close_write_time(fsp, mtime);
|
||||
|
||||
/*
|
||||
* More insanity. W2K only closes the file if writelen > 0.
|
||||
@ -6691,7 +6691,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
|
||||
close_file(NULL, fsp1, NORMAL_CLOSE);
|
||||
|
||||
/* Ensure the modtime is set correctly on the destination file. */
|
||||
set_close_write_time(NULL, fsp2, smb_fname_src->st.st_ex_mtime);
|
||||
set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
|
||||
|
||||
/*
|
||||
* As we are opening fsp1 read-only we only expect
|
||||
|
Loading…
x
Reference in New Issue
Block a user