The branch, v3-4-test has been updated
       via  e971428f137dcb42e8b735386d79f1b3a6effe34 (commit)
       via  5cd771b964aa36082716352522a68c962e1aaba8 (commit)
      from  686439599ad78c6f4d5609129113e6da51fb4a57 (commit)

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


- Log -----------------------------------------------------------------
commit e971428f137dcb42e8b735386d79f1b3a6effe34
Author: Jeremy Allison <[email protected]>
Date:   Wed Sep 9 14:39:17 2009 -0700

    Fix bug 6529 - Offline files conflict with Vista and Office 2003. Jeremy.

commit 5cd771b964aa36082716352522a68c962e1aaba8
Author: Lars Müller <[email protected]>
Date:   Mon Feb 2 21:12:52 2009 +0100

    Conditional install of the cifs.upcall man page
    
    Only install the cifs.upcall man page if CIFSUPCALL_PROGS was set while
    configure.
    (cherry picked from commit e9e2414e798a2eb447de45803e61cc0a49752f11)

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

Summary of changes:
 source3/include/includes.h    |    6 ++
 source3/include/proto.h       |    5 +-
 source3/include/smb.h         |    4 +
 source3/lib/time.c            |   41 +++++++++++++-
 source3/modules/vfs_default.c |   51 ++++++++++++++++-
 source3/modules/vfs_onefs.c   |    4 +-
 source3/script/installman.sh  |    1 +
 source3/smbd/nttrans.c        |   16 +++---
 source3/smbd/trans2.c         |  126 ++++++++++++++++++++++-------------------
 9 files changed, 183 insertions(+), 71 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/includes.h b/source3/include/includes.h
index 248c326..4dee258 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -526,6 +526,12 @@ struct timespec {
 };
 #endif
 
+enum timestamp_set_resolution {
+       TIMESTAMP_SET_SECONDS = 0,
+       TIMESTAMP_SET_MSEC,
+       TIMESTAMP_SET_NT_OR_BETTER
+};
+
 #ifdef HAVE_BROKEN_GETGROUPS
 #define GID_T int
 #else
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d33a019..5873386 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1017,7 +1017,8 @@ char *current_timestring(TALLOC_CTX *ctx, bool hires);
 void srv_put_dos_date(char *buf,int offset,time_t unixdate);
 void srv_put_dos_date2(char *buf,int offset, time_t unixdate);
 void srv_put_dos_date3(char *buf,int offset,time_t unixdate);
-void put_long_date_timespec(char *p, struct timespec ts);
+void round_timespec(enum timestamp_set_resolution res, struct timespec *ts);
+void put_long_date_timespec(enum timestamp_set_resolution res, char *p, struct 
timespec ts);
 void put_long_date(char *p, time_t t);
 struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,bool fake_dirs);
 struct timespec get_atimespec(const SMB_STRUCT_STAT *pst);
@@ -1038,6 +1039,8 @@ struct timespec timespec_current(void);
 struct timespec timespec_min(const struct timespec *ts1,
                           const struct timespec *ts2);
 int timespec_compare(const struct timespec *ts1, const struct timespec *ts2);
+void round_timespec_to_sec(struct timespec *ts);
+void round_timespec_to_usec(struct timespec *ts);
 struct timespec interpret_long_date(const char *p);
 void cli_put_dos_date(struct cli_state *cli, char *buf, int offset, time_t 
unixdate);
 void cli_put_dos_date2(struct cli_state *cli, char *buf, int offset, time_t 
unixdate);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index b20a8ef..7cb8e95 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -559,6 +559,10 @@ typedef struct connection_struct {
        bool ipc;
        bool read_only; /* Attributes for the current user of the share. */
        bool admin_user; /* Attributes for the current user of the share. */
+       /* Does this filesystem honor
+          sub second timestamps on files
+          and directories when setting time ? */
+       enum timestamp_set_resolution ts_res;
        char *dirpath;
        char *connectpath;
        char *origpath;
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 865456b..839ebe9 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -301,14 +301,30 @@ void srv_put_dos_date3(char *buf,int offset,time_t 
unixdate)
        put_dos_date3(buf, offset, unixdate, server_zone_offset);
 }
 
+void round_timespec(enum timestamp_set_resolution res, struct timespec *ts)
+{
+       switch (res) {
+               case TIMESTAMP_SET_SECONDS:
+                       round_timespec_to_sec(ts);
+                       break;
+               case TIMESTAMP_SET_MSEC:
+                       round_timespec_to_usec(ts);
+                       break;
+               case TIMESTAMP_SET_NT_OR_BETTER:
+                       /* No rounding needed. */
+                       break;
+       }
+}
+
 /****************************************************************************
  Take a Unix time and convert to an NTTIME structure and place in buffer 
  pointed to by p.
 ****************************************************************************/
 
-void put_long_date_timespec(char *p, struct timespec ts)
+void put_long_date_timespec(enum timestamp_set_resolution res, char *p, struct 
timespec ts)
 {
        NTTIME nt;
+       round_timespec(res, &ts);
        unix_timespec_to_nt_time(&nt, ts);
        SIVAL(p, 0, nt & 0xFFFFFFFF);
        SIVAL(p, 4, nt >> 32);
@@ -319,7 +335,7 @@ void put_long_date(char *p, time_t t)
        struct timespec ts;
        ts.tv_sec = t;
        ts.tv_nsec = 0;
-       put_long_date_timespec(p, ts);
+       put_long_date_timespec(TIMESTAMP_SET_SECONDS, p, ts);
 }
 
 /****************************************************************************
@@ -713,6 +729,27 @@ int timespec_compare(const struct timespec *ts1, const 
struct timespec *ts2)
 }
 
 /****************************************************************************
+ Round up a timespec if nsec > 500000000, round down if lower,
+ then zero nsec.
+****************************************************************************/
+
+void round_timespec_to_sec(struct timespec *ts)
+{
+       ts->tv_sec = convert_timespec_to_time_t(*ts);
+       ts->tv_nsec = 0;
+}
+
+/****************************************************************************
+ Round a timespec to usec value.
+****************************************************************************/
+
+void round_timespec_to_usec(struct timespec *ts)
+{
+       struct timeval tv = convert_timespec_to_timeval(*ts);
+       *ts = convert_timeval_to_timespec(tv);
+}
+
+/****************************************************************************
  Interprets an nt time into a unix struct timespec.
  Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
  will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this 
case.
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index aa20705..0a66531 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -92,13 +92,62 @@ static int vfswrap_statvfs(struct vfs_handle_struct 
*handle,  const char *path,
 
 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
 {
+       connection_struct *conn = handle->conn;
+       uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+       SMB_STRUCT_STAT st;
+       NTSTATUS status;
+       struct timespec mtime_ts, ctime_ts, atime_ts;
+       int ret = -1;
+
 #if defined(DARWINOS)
        struct vfs_statvfs_struct statbuf;
        ZERO_STRUCT(statbuf);
        sys_statvfs(handle->conn->connectpath, &statbuf);
        return statbuf.FsCapabilities;
 #endif
-       return FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
+
+       conn->ts_res = TIMESTAMP_SET_SECONDS;
+
+       /* Work out what timestamp resolution we can
+        * use when setting a timestamp. */
+
+       ret = SMB_VFS_STAT(conn, conn->connectpath, &st);
+       if (ret == -1) {
+               return caps;
+       }
+
+       mtime_ts = get_mtimespec(&st);
+       ctime_ts = get_ctimespec(&st);
+       atime_ts = get_atimespec(&st);
+
+       if (mtime_ts.tv_nsec ||
+                       atime_ts.tv_nsec ||
+                       ctime_ts.tv_nsec) {
+               /* If any of the normal UNIX directory timestamps
+                * have a non-zero tv_nsec component assume
+                * we might be able to set sub-second timestamps.
+                * See what filetime set primitives we have.
+                */
+#if defined(HAVE_UTIMES)
+               /* utimes allows msec timestamps to be set. */
+               conn->ts_res = TIMESTAMP_SET_MSEC;
+#elif defined(HAVE_UTIME)
+               /* utime only allows sec timestamps to be set. */
+               conn->ts_res = TIMESTAMP_SET_SECONDS;
+#endif
+
+               /* TODO. Add a configure test for the Linux
+                * nsec timestamp set system call, and use it
+                * if available....
+                */
+               DEBUG(10,("vfswrap_fs_capabilities: timestamp "
+                       "resolution of %s "
+                       "available on share %s, directory %s\n",
+                       conn->ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
+                       lp_servicename(conn->cnum),
+                       conn->connectpath ));
+       }
+       return caps;
 }
 
 /* Directory operations */
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index e4a0feb..10c636d 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -241,7 +241,9 @@ static uint32_t onefs_fs_capabilities(struct 
vfs_handle_struct *handle)
                result |= FILE_NAMED_STREAMS;
        }
 
-       return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle);
+       result |= SMB_VFS_NEXT_FS_CAPABILITIES(handle);
+       conn->ts_res = TIMESTAMP_SET_MSEC;
+       return result;
 }
 
 static vfs_op_tuple onefs_ops[] = {
diff --git a/source3/script/installman.sh b/source3/script/installman.sh
index ab9bfe5..75e5381 100755
--- a/source3/script/installman.sh
+++ b/source3/script/installman.sh
@@ -48,6 +48,7 @@ for lang in $langs; do
 
            # Check if this man page if required by the configured feature set
            case "${MP_BASENAME}" in
+               cifs.upcall.8) test -z "${CIFSUPCALL_PROGS}" && continue ;;
                smbsh.1) test -z "${SMBWRAPPER}" && continue ;;
                *) ;;
            esac
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 0c0bebb..9f30f06 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -614,13 +614,13 @@ void reply_ntcreate_and_X(struct smb_request *req)
                dos_filetime_timespec(&m_timespec);
        }
 
-       put_long_date_timespec(p, c_timespec); /* create time. */
+       put_long_date_timespec(conn->ts_res, p, c_timespec); /* create time. */
        p += 8;
-       put_long_date_timespec(p, a_timespec); /* access time */
+       put_long_date_timespec(conn->ts_res, p, a_timespec); /* access time */
        p += 8;
-       put_long_date_timespec(p, m_timespec); /* write time */
+       put_long_date_timespec(conn->ts_res, p, m_timespec); /* write time */
        p += 8;
-       put_long_date_timespec(p, m_timespec); /* change time */
+       put_long_date_timespec(conn->ts_res, p, m_timespec); /* change time */
        p += 8;
        SIVAL(p,0,fattr); /* File Attributes. */
        p += 4;
@@ -1081,13 +1081,13 @@ static void call_nt_transact_create(connection_struct 
*conn,
                dos_filetime_timespec(&m_timespec);
        }
 
-       put_long_date_timespec(p, c_timespec); /* create time. */
+       put_long_date_timespec(conn->ts_res, p, c_timespec); /* create time. */
        p += 8;
-       put_long_date_timespec(p, a_timespec); /* access time */
+       put_long_date_timespec(conn->ts_res, p, a_timespec); /* access time */
        p += 8;
-       put_long_date_timespec(p, m_timespec); /* write time */
+       put_long_date_timespec(conn->ts_res, p, m_timespec); /* write time */
        p += 8;
-       put_long_date_timespec(p, m_timespec); /* change time */
+       put_long_date_timespec(conn->ts_res, p, m_timespec); /* change time */
        p += 8;
        SIVAL(p,0,fattr); /* File Attributes. */
        p += 4;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 7173796..68d2c97 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1598,10 +1598,10 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        was_8_3 = mangle_is_8_3(fname, True, conn->params);
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date_timespec(p,create_date_ts); p += 8;
-                       put_long_date_timespec(p,adate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(conn->ts_res, p,create_date_ts); 
p += 8;
+                       put_long_date_timespec(conn->ts_res, p,adate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1649,10 +1649,10 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        DEBUG(10,("get_lanman2_dir_entry: 
SMB_FIND_FILE_DIRECTORY_INFO\n"));
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date_timespec(p,create_date_ts); p += 8;
-                       put_long_date_timespec(p,adate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(conn->ts_res, p,create_date_ts); 
p += 8;
+                       put_long_date_timespec(conn->ts_res, p,adate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1672,10 +1672,10 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        DEBUG(10,("get_lanman2_dir_entry: 
SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date_timespec(p,create_date_ts); p += 8;
-                       put_long_date_timespec(p,adate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(conn->ts_res, p,create_date_ts); 
p += 8;
+                       put_long_date_timespec(conn->ts_res, p,adate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1721,10 +1721,10 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        DEBUG(10,("get_lanman2_dir_entry: 
SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date_timespec(p,create_date_ts); p += 8;
-                       put_long_date_timespec(p,adate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(conn->ts_res, p,create_date_ts); 
p += 8;
+                       put_long_date_timespec(conn->ts_res, p,adate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -1754,10 +1754,10 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                        was_8_3 = mangle_is_8_3(fname, True, conn->params);
                        p += 4;
                        SIVAL(p,0,reskey); p += 4;
-                       put_long_date_timespec(p,create_date_ts); p += 8;
-                       put_long_date_timespec(p,adate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
-                       put_long_date_timespec(p,mdate_ts); p += 8;
+                       put_long_date_timespec(conn->ts_res, p,create_date_ts); 
p += 8;
+                       put_long_date_timespec(conn->ts_res, p,adate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
+                       put_long_date_timespec(conn->ts_res, p,mdate_ts); p += 
8;
                        SOFF_T(p,0,file_size); p += 8;
                        SOFF_T(p,0,allocation_size); p += 8;
                        SIVAL(p,0,nt_extmode); p += 4;
@@ -3526,9 +3526,9 @@ static char *store_file_unix_basic(connection_struct 
*conn,
        SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of 
bytes used on disk - 64 Bit */
        pdata += 8;
 
-       put_long_date_timespec(pdata,get_ctimespec(psbuf));       /* Change 
Time 64 Bit */
-       put_long_date_timespec(pdata+8,get_atimespec(psbuf));     /* Last 
access time 64 Bit */
-       put_long_date_timespec(pdata+16,get_mtimespec(psbuf));    /* Last 
modification time 64 Bit */
+       put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, 
pdata,get_ctimespec(psbuf));       /* Change Time 64 Bit */
+       put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, 
pdata+8,get_atimespec(psbuf));     /* Last access time 64 Bit */
+       put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, 
pdata+16,get_mtimespec(psbuf));    /* Last modification time 64 Bit */
        pdata += 24;
 
        SIVAL(pdata,0,psbuf->st_uid);               /* user id for the owner */
@@ -3668,7 +3668,7 @@ static char 
*store_file_unix_basic_info2(connection_struct *conn,
        pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
 
        /* Create (birth) time 64 bit */
-       put_long_date_timespec(pdata, get_create_timespec(psbuf, False));
+       put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, 
get_create_timespec(psbuf, False));
        pdata += 8;
 
        map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
@@ -4309,10 +4309,10 @@ total_data=%u (should be %u)\n", (unsigned 
int)total_data, (unsigned int)IVAL(pd
                                data_size = 40;
                                SIVAL(pdata,36,0);
                        }
-                       put_long_date_timespec(pdata,create_time_ts);
-                       put_long_date_timespec(pdata+8,atime_ts);
-                       put_long_date_timespec(pdata+16,mtime_ts); /* write 
time */
-                       put_long_date_timespec(pdata+24,mtime_ts); /* change 
time */
+                       put_long_date_timespec(conn->ts_res, 
pdata,create_time_ts);
+                       put_long_date_timespec(conn->ts_res, pdata+8,atime_ts);
+                       put_long_date_timespec(conn->ts_res, 
pdata+16,mtime_ts); /* write time */
+                       put_long_date_timespec(conn->ts_res, 
pdata+24,mtime_ts); /* change time */
                        SIVAL(pdata,32,mode);
 
                        DEBUG(5,("SMB_QFBI - "));
@@ -4399,10 +4399,10 @@ total_data=%u (should be %u)\n", (unsigned 
int)total_data, (unsigned int)IVAL(pd
                {
                        unsigned int ea_size = estimate_ea_size(conn, fsp, 
fname);
                        DEBUG(10,("call_trans2qfilepathinfo: 
SMB_FILE_ALL_INFORMATION\n"));
-                       put_long_date_timespec(pdata,create_time_ts);
-                       put_long_date_timespec(pdata+8,atime_ts);
-                       put_long_date_timespec(pdata+16,mtime_ts); /* write 
time */
-                       put_long_date_timespec(pdata+24,mtime_ts); /* change 
time */
+                       put_long_date_timespec(conn->ts_res, 
pdata,create_time_ts);
+                       put_long_date_timespec(conn->ts_res, pdata+8,atime_ts);
+                       put_long_date_timespec(conn->ts_res, 
pdata+16,mtime_ts); /* write time */
+                       put_long_date_timespec(conn->ts_res, 
pdata+24,mtime_ts); /* change time */
                        SIVAL(pdata,32,mode);
                        SIVAL(pdata,36,0); /* padding. */
                        pdata += 40;
@@ -4537,10 +4537,10 @@ total_data=%u (should be %u)\n", (unsigned 
int)total_data, (unsigned int)IVAL(pd
 
                case SMB_FILE_NETWORK_OPEN_INFORMATION:
                        DEBUG(10,("call_trans2qfilepathinfo: 
SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
-                       put_long_date_timespec(pdata,create_time_ts);
-                       put_long_date_timespec(pdata+8,atime_ts);
-                       put_long_date_timespec(pdata+16,mtime_ts); /* write 
time */
-                       put_long_date_timespec(pdata+24,mtime_ts); /* change 
time */
+                       put_long_date_timespec(conn->ts_res, 
pdata,create_time_ts);
+                       put_long_date_timespec(conn->ts_res, pdata+8,atime_ts);
+                       put_long_date_timespec(conn->ts_res, 
pdata+16,mtime_ts); /* write time */
+                       put_long_date_timespec(conn->ts_res, 
pdata+24,mtime_ts); /* change time */
                        SOFF_T(pdata,32,allocation_size);
                        SOFF_T(pdata,40,file_size);
                        SIVAL(pdata,48,mode);
@@ -4894,15 +4894,22 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
                           struct smb_file_time *ft,
                           bool setting_write_time)
 {
+       struct smb_file_time ft_stat;
        uint32 action =
                FILE_NOTIFY_CHANGE_LAST_ACCESS
-               |FILE_NOTIFY_CHANGE_LAST_WRITE;
+               |FILE_NOTIFY_CHANGE_LAST_WRITE
+               |FILE_NOTIFY_CHANGE_CREATION;
 
        if (!VALID_STAT(*psbuf)) {
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        /* get some defaults (no modifications) if any info is zero or -1. */
+       if (null_timespec(ft->create_time)) {
+               ft->create_time = get_create_timespec(psbuf, 
lp_fake_dir_create_times(SNUM(conn)));
+               action &= ~FILE_NOTIFY_CHANGE_CREATION;
+       }
+
        if (null_timespec(ft->atime)) {
                ft->atime= get_atimespec(psbuf);
                action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
@@ -4918,28 +4925,19 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
                action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
        }
 
+       /* Ensure the resolution is the correct for
+        * what we can store on this filesystem. */
+
+       round_timespec(conn->ts_res, &ft->create_time);
+       round_timespec(conn->ts_res, &ft->atime);
+       round_timespec(conn->ts_res, &ft->mtime);
+
        DEBUG(5,("smb_set_filetime: actime: %s\n ",
                time_to_asc(convert_timespec_to_time_t(ft->atime))));
        DEBUG(5,("smb_set_filetime: modtime: %s\n ",
                time_to_asc(convert_timespec_to_time_t(ft->mtime))));
-       if (!null_timespec(ft->create_time)) {
-               DEBUG(5,("smb_set_file_time: createtime: %s\n ",
-                  time_to_asc(convert_timespec_to_time_t(ft->create_time))));
-       }
-
-       /*
-        * Try and set the times of this file if
-        * they are different from the current values.
-        */
-
-       {
-               struct timespec mts = get_mtimespec(psbuf);
-               struct timespec ats = get_atimespec(psbuf);
-               if ((timespec_compare(&ft->atime, &ats) == 0) &&
-                   (timespec_compare(&ft->mtime, &mts) == 0)) {
-                       return NT_STATUS_OK;
-               }
-       }
+       DEBUG(5,("smb_set_file_time: createtime: %s\n ",
+               time_to_asc(convert_timespec_to_time_t(ft->create_time))));
 
        if (setting_write_time) {
                /*
@@ -4969,14 +4967,26 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
                }
        }
 
-       DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
+       ft_stat.create_time = get_create_timespec(psbuf,
+                               lp_fake_dir_create_times(SNUM(conn)));
+       ft_stat.atime= get_atimespec(psbuf);
+       ft_stat.mtime = get_mtimespec(psbuf);
+
+       round_timespec(conn->ts_res, &ft_stat.create_time);
+       round_timespec(conn->ts_res, &ft_stat.atime);
+       round_timespec(conn->ts_res, &ft_stat.mtime);
 
        if (fsp && fsp->base_fsp) {
                fname = fsp->base_fsp->fsp_name;
        }
 
-       if(file_ntimes(conn, fname, ft)!=0) {
-               return map_nt_error_from_unix(errno);
+       if (timespec_compare(&ft_stat.create_time, &ft->create_time) ||
+                       timespec_compare(&ft_stat.atime, &ft->atime) ||
+                       timespec_compare(&ft_stat.mtime, &ft->mtime)) {
+               DEBUG(10,("smb_set_file_time: setting utimes to modified 
values.\n"));
+               if(file_ntimes(conn, fname, ft)!=0) {
+                       return map_nt_error_from_unix(errno);
+               }
        }
        notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname);


-- 
Samba Shared Repository

Reply via email to