diff --git a/source3/include/smb.h b/source3/include/smb.h index 9d1e22b..1347ab2 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -557,6 +557,9 @@ 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. */ + bool hires_timestamps_avail; /* Does this filesystem honor + sub second timestamps on files + and directories ? */ char *connectpath; char *origpath; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 0456355..dc0bc4f 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3284,8 +3284,12 @@ static NTSTATUS create_file_unixpath(connection_struct *conn, /* 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) { + ts.tv_nsec = 0; + } set_create_timespec_ea(conn, fsp, - smb_fname, smb_fname->st.st_ex_btime); + smb_fname, ts); } } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index fc56105..88b21d5 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -1015,6 +1015,19 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, 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. JRA. + */ + conn->hires_timestamps_avail = true; + } + string_set(&conn->origpath,conn->connectpath); #if SOFTLINK_OPTIMISATION diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 56651b4..56de650 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5402,6 +5402,15 @@ NTSTATUS smb_set_file_time(connection_struct *conn, action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; } + if (!conn->hires_timestamps_avail) { + /* We can't store sub second timestamps + * on this share. Truncate to seconds. */ + ft->create_time.tv_nsec = 0; + ft->ctime.tv_nsec = 0; + ft->atime.tv_nsec = 0; + ft->mtime.tv_nsec = 0; + } + 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 ",