]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r3895: Fix for bug #2045. May also fix other timestamp bugs with Excel
authorJeremy Allison <jra@samba.org>
Sat, 20 Nov 2004 21:24:52 +0000 (21:24 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:24 +0000 (10:53 -0500)
(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.

source/smbd/fileio.c
source/smbd/trans2.c

index b9fe1ad1cfcb7220a07f627f759d57f5452f7bf4..dde254644ff35ae78516f90dcdf27786ffc010fa 100644 (file)
@@ -130,6 +130,20 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
        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
index 633325638ad71310d0cf03cf7be2a8e1e74eaf58..b877f7c518c6c9eaab83766f47d1811aacffaefd 100644 (file)
@@ -2540,6 +2540,11 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
 
        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 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                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 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                                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));
+                       }
                }
        }