summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-08-24 12:30:05 -0700
committerJeremy Allison <jra@samba.org>2009-08-24 12:30:05 -0700
commit87d30a1968af66619dfd60f9bc7accde2ac22345 (patch)
treea9a0c9abf074e997cbceae34f121fa4a6adb1d61
parente829ca560d20e02f34831680a12f3163aee76665 (diff)
downloadsamba-87d30a1968af66619dfd60f9bc7accde2ac22345.tar.gz
samba-87d30a1968af66619dfd60f9bc7accde2ac22345.tar.bz2
samba-87d30a1968af66619dfd60f9bc7accde2ac22345.zip
Second part of fix for 6529 - Offline files conflict with Vista and Office 2003.
ext4 may be able to store ns timestamps, but the only API to *set* timestamps takes usec, not nsec. Round to usec on set requests. Jeremy.
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/lib/time.c10
-rw-r--r--source3/smbd/trans2.c11
3 files changed, 22 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 1b09732679..97d05b3699 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1045,6 +1045,7 @@ 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(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/lib/time.c b/source3/lib/time.c
index 06605cd30a..c80b59a662 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -479,6 +479,16 @@ void round_timespec(struct timespec *ts)
}
/****************************************************************************
+ 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/smbd/trans2.c b/source3/smbd/trans2.c
index 2900e764e8..a1043e27ff 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -5409,6 +5409,17 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
round_timespec(&ft->ctime);
round_timespec(&ft->atime);
round_timespec(&ft->mtime);
+ } else {
+ /* The highest resolution timestamp
+ * setting function available in POSIX
+ * is utimes(), which uses usec resolution,
+ * not nsec resolution. So we must round to
+ * usec, then back to nsec. JRA.
+ */
+ round_timespec_to_usec(&ft->create_time);
+ round_timespec_to_usec(&ft->ctime);
+ round_timespec_to_usec(&ft->atime);
+ round_timespec_to_usec(&ft->mtime);
}
DEBUG(5,("smb_set_filetime: actime: %s\n ",