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);
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);
bool ipc;
bool read_only; /* Attributes for the current user of the share. */
bool admin_user; /* Attributes for the current user of the share. */
+ bool hires_timestamps_avail; /* Does this filesystem honor
+ sub second timestamps on files
+ and directories ? */
char *connectpath;
char *origpath;
return 0;
}
+/****************************************************************************
+ Round up a timespec if nsec > 500000000, round down if lower,
+ then zero nsec.
+****************************************************************************/
+
+void round_timespec(struct timespec *ts)
+{
+ ts->tv_sec += ts->tv_nsec >= 500000000 ? 1 : 0;
+ ts->tv_nsec = 0;
+}
+
/****************************************************************************
Interprets an nt time into a unix struct timespec.
Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
/* Try and make a create timestamp, if required. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
if (lp_store_create_time(SNUM(conn))) {
+ struct timespec ts = smb_fname->st.st_ex_btime;
+ if (!conn->hires_timestamps_avail) {
+ round_timespec(&ts);
+ }
set_create_timespec_ea(conn, fsp,
- smb_fname, smb_fname->st.st_ex_btime);
+ smb_fname, ts);
}
}
goto err_root_exit;
}
+ if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
+ smb_fname_cpath->st.st_ex_atime.tv_nsec ||
+ smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
+ /* If any of the normal UNIX directory timestamps
+ * have a non-zero tv_nsec component assume
+ * we can fully store hires timestamps. We need
+ * to make a runtime/share level distinction
+ * as on Linux ext3 doesn't have hires timestamps, but
+ * ext4 does, so a compile time test won't work. JRA.
+ */
+ conn->hires_timestamps_avail = true;
+ }
+
string_set(&conn->origpath,conn->connectpath);
#if SOFTLINK_OPTIMISATION
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
+ if (!conn->hires_timestamps_avail) {
+ /* We can't store sub second timestamps
+ * on this share. Round to seconds. */
+ round_timespec(&ft->create_time);
+ round_timespec(&ft->ctime);
+ round_timespec(&ft->atime);
+ round_timespec(&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 ",