[SCM] Samba Shared Repository - branch v3-5-test updated

Jeremy Allison jra at samba.org
Thu Nov 5 17:25:55 MST 2009


The branch, v3-5-test has been updated
       via  a153f7d... Get closer to an accurate model of Windows timestamp changes. "Normal" non truncate writes always cause the timestamp to be set on close. Once a close is done on a handle this can reset the sticky write time to current time also. Updated smbtorture4 confirms this. Jeremy. (cherry picked from commit 7f9fe127ba31e6dd064d090d5ffc8eeb377627ab)
      from  139711d... Fix up some of the timing constants for DELAYWRITE. Add some extra tests up test_delayed_write_update6 to investigate what happens to a sticky write handle after a second handle close. Jeremy. (cherry picked from commit c2df97f57ce205935c37cd5a90cfeddb129cd92b)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit a153f7ddd8b40cbf9c26ef66ad397ad41cdc9cc4
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Nov 5 16:20:11 2009 -0800

    Get closer to an accurate model of Windows timestamp changes.
    "Normal" non truncate writes always cause the timestamp to
    be set on close. Once a close is done on a handle this can
    reset the sticky write time to current time also.
    Updated smbtorture4 confirms this.
    Jeremy.
    (cherry picked from commit 7f9fe127ba31e6dd064d090d5ffc8eeb377627ab)

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h |    5 +++--
 source3/smbd/close.c    |   21 +++++++++++++++++++--
 source3/smbd/dosmode.c  |   16 ----------------
 source3/smbd/fileio.c   |   38 ++++++++++++++++++++++++++++++--------
 source3/smbd/nttrans.c  |    2 +-
 source3/smbd/reply.c    |    6 +++---
 6 files changed, 56 insertions(+), 32 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index f224da7..cd93bb3 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6108,7 +6108,9 @@ 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 files_struct *fsp, struct timespec ts);
+void set_close_write_time(struct share_mode_lock *lck,
+			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,
@@ -6249,7 +6251,6 @@ int file_ntimes(connection_struct *conn, const struct smb_filename *smb_fname,
 bool set_sticky_write_time_path(struct file_id fileid, struct timespec mtime);
 bool set_sticky_write_time_fsp(struct files_struct *fsp,
 			       struct timespec mtime);
-bool update_write_time(struct files_struct *fsp);
 
 NTSTATUS set_create_timespec_ea(connection_struct *conn,
 				struct files_struct *fsp,
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 642864f..c1623ce 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -291,7 +291,15 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 	}
 
 	if (fsp->write_time_forced) {
-		set_close_write_time(fsp, lck->changed_write_time);
+		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);
+	} 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)));
+		set_close_write_time(lck, fsp, timespec_current());
 	}
 
 	if (!del_share_mode(lck, fsp)) {
@@ -468,7 +476,8 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 	return status;
 }
 
-void set_close_write_time(struct files_struct *fsp, struct timespec ts)
+void set_close_write_time(struct share_mode_lock *lck,
+			struct files_struct *fsp, struct timespec ts)
 {
 	DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
 
@@ -483,6 +492,14 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts)
 
 	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)
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 949c438..e10f239 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -849,22 +849,6 @@ bool set_sticky_write_time_fsp(struct files_struct *fsp, struct timespec 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;
-	}
-
-	notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
-		     FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
-
-	return true;
-}
-
-/******************************************************************
  Set a create time EA.
 ******************************************************************/
 
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index bd609d3..62e9a98 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -180,10 +180,15 @@ static void update_write_time_handler(struct event_context *ctx,
 
 	/* 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 if not already changed by someone else */
-	update_write_time(fsp);
+	/* change the write time in the open file db. */
+	(void)set_write_time(fsp->file_id, timespec_current());
+
+	/* And notify. */
+        notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
+                     FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
 }
 
 /*********************************************************
@@ -207,11 +212,16 @@ void trigger_write_time_update(struct files_struct *fsp)
 		return;
 	}
 
+	/* We need to remember someone did a write
+	 * and update to current time on close. */
+
+	fsp->update_write_time_on_close = true;
+
 	if (fsp->update_write_time_triggered) {
 		/*
-		 * We only update the write time
-		 * on the first write. After that
-		 * no other writes affect this.
+		 * We only update the write time after 2 seconds
+		 * on the first normal write. After that
+		 * no other writes affect this until close.
 		 */
 		return;
 	}
@@ -221,8 +231,10 @@ void trigger_write_time_update(struct files_struct *fsp)
 			    "smbd", "writetimeupdatedelay",
 			    WRITE_TIME_UPDATE_USEC_DELAY);
 
+	DEBUG(5, ("Update write time %d usec later on %s\n",
+		  delay, fsp_str_dbg(fsp)));
+
 	/* trigger the update 2 seconds later */
-	fsp->update_write_time_on_close = true;
 	fsp->update_write_time_event =
 		event_add_timed(smbd_event_context(), NULL,
 				timeval_current_ofs(0, delay),
@@ -231,6 +243,8 @@ void trigger_write_time_update(struct files_struct *fsp)
 
 void trigger_write_time_update_immediate(struct files_struct *fsp)
 {
+	struct smb_file_time ft;
+
 	if (fsp->posix_open) {
 		/* Don't use delayed writes on POSIX files. */
 		return;
@@ -248,10 +262,18 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
 	DEBUG(5, ("Update write time immediate on %s\n",
 		  fsp_str_dbg(fsp)));
 
+	/* After an immediate update, reset the trigger. */
 	fsp->update_write_time_triggered = true;
-
         fsp->update_write_time_on_close = false;
-	update_write_time(fsp);
+
+	ZERO_STRUCT(ft);
+	ft.mtime = timespec_current();
+
+	/* Update the time in the open file db. */
+	(void)set_write_time(fsp->file_id, ft.mtime);
+
+	/* Now set on disk - takes care of notify. */
+	(void)smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
 }
 
 /****************************************************************************
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 66102fa..a1e7889 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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(fsp2, smb_fname_src->st.st_ex_mtime);
+	set_close_write_time(NULL, fsp2, smb_fname_src->st.st_ex_mtime);
 
 	status = close_file(NULL, fsp2, NORMAL_CLOSE);
 
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 984cf56..37634ac 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -4646,7 +4646,7 @@ void reply_close(struct smb_request *req)
 		 */
 
 		t = srv_make_unix_date3(req->vwv+1);
-		set_close_write_time(fsp, convert_time_t_to_timespec(t));
+		set_close_write_time(NULL, 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(fsp, mtime);
+	set_close_write_time(NULL, 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(fsp2, smb_fname_src->st.st_ex_mtime);
+	set_close_write_time(NULL, fsp2, smb_fname_src->st.st_ex_mtime);
 
 	/*
 	 * As we are opening fsp1 read-only we only expect


-- 
Samba Shared Repository


More information about the samba-cvs mailing list