svn commit: samba r3894 - in trunk/source/smbd: .

jra at samba.org jra at samba.org
Sat Nov 20 21:24:43 GMT 2004


Author: jra
Date: 2004-11-20 21:24:43 +0000 (Sat, 20 Nov 2004)
New Revision: 3894

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=3894

Log:
Fix for bug #2045. May also fix other timestamp bugs with Excel
(Volker please test). Setting a last write timestamp from Windows
overrides any subsequent write timestamp changes and must be immediately
seen by and findfirst/findnexts. This is a racy solution, but should
work most of the time. This may also fix #1061, not sure.
Jeremy.

Modified:
   trunk/source/smbd/fileio.c
   trunk/source/smbd/trans2.c


Changeset:
Modified: trunk/source/smbd/fileio.c
===================================================================
--- trunk/source/smbd/fileio.c	2004-11-20 20:11:21 UTC (rev 3893)
+++ trunk/source/smbd/fileio.c	2004-11-20 21:24:43 UTC (rev 3894)
@@ -130,6 +130,20 @@
 	if (ret != -1) {
 		fsp->pos += ret;
 
+		/*
+		 * It turns out that setting the last write time from a Windows
+		 * client stops any subsequent writes from updating the write time.
+		 * Doing this after the write gives a race condition here where
+		 * a stat may see the changed write time before we reset it here,
+		 * but it's cheaper than having to store the write time in shared
+		 * memory and look it up using dev/inode across all running smbd's.
+		 * The 99% solution will hopefully be good enough in this case. JRA.
+		 */
+
+		if (fsp->pending_modtime) {
+			set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime);
+		}
+
 /* Yes - this is correct - writes don't update this. JRA. */
 /* Found by Samba4 tests. */
 #if 0

Modified: trunk/source/smbd/trans2.c
===================================================================
--- trunk/source/smbd/trans2.c	2004-11-20 20:11:21 UTC (rev 3893)
+++ trunk/source/smbd/trans2.c	2004-11-20 21:24:43 UTC (rev 3894)
@@ -2540,6 +2540,11 @@
 
 	c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
 
+	if (fsp && fsp->pending_modtime) {
+		/* the pending modtime overrides the current modtime */
+		sbuf.st_mtime = fsp->pending_modtime;
+	}
+
 	if (lp_dos_filetime_resolution(SNUM(conn))) {
 		c_time &= ~1;
 		sbuf.st_atime &= ~1;
@@ -3904,10 +3909,12 @@
 		if(fsp != NULL) {
 			/*
 			 * This was a setfileinfo on an open file.
-			 * NT does this a lot. It's actually pointless
-			 * setting the time here, as it will be overwritten
-			 * on the next write, so we save the request
-			 * away and will set it on file close. JRA.
+			 * NT does this a lot. We also need to 
+			 * set the time here, as it can be read by 
+			 * FindFirst/FindNext and with the patch for bug #2045
+			 * in smbd/fileio.c it ensures that this timestamp is
+			 * kept sticky even after a write. We save the request
+			 * away and will set it on file close and after a write. JRA.
 			 */
 
 			if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
@@ -3915,12 +3922,11 @@
 				fsp->pending_modtime = tvs.modtime;
 			}
 
-		} else {
-
 			DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
 
-			if(file_utime(conn, fname, &tvs)!=0)
+			if(file_utime(conn, fname, &tvs)!=0) {
 				return(UNIXERROR(ERRDOS,ERRnoaccess));
+			}
 		}
 	}
 



More information about the samba-cvs mailing list