mirror of
https://github.com/samba-team/samba.git
synced 2025-01-22 22:04:08 +03:00
Second attempt at fix for bug 6529 - Offline files conflict with Vista and Office 2003.
Confirmation from reporter that this fixes the issue in master on ext3/ext4. Back-ports to follow. Jeremy.
This commit is contained in:
parent
9a86f26a5f
commit
c69f92d16d
@ -566,6 +566,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
|
||||
|
@ -1028,7 +1028,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);
|
||||
void dos_filetime_timespec(struct timespec *tsp);
|
||||
time_t make_unix_date2(const void *date_ptr, int zone_offset);
|
||||
@ -1044,7 +1045,7 @@ 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(struct timespec *ts);
|
||||
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);
|
||||
|
@ -557,9 +557,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. */
|
||||
bool hires_timestamps_avail; /* Does this filesystem honor
|
||||
sub second timestamps on files
|
||||
and directories ? */
|
||||
/* Does this filesystem honor
|
||||
sub second timestamps on files
|
||||
and directories when setting time ? */
|
||||
enum timestamp_set_resolution ts_res;
|
||||
char *connectpath;
|
||||
char *origpath;
|
||||
|
||||
|
@ -121,8 +121,9 @@
|
||||
/* Changed to version 26 - Plumb struct smb_filename to SMB_VFS_CREATE_FILE,
|
||||
SMB_VFS_OPEN, SMB_VFS_STAT, SMB_VFS_LSTAT,
|
||||
SMB_VFS_RENAME, SMB_VFS_UNLINK, SMB_VFS_NTIMES. */
|
||||
|
||||
#define SMB_VFS_INTERFACE_VERSION 26
|
||||
/* Changed to version 27 - not yet released. Added enum timestamp_set_resolution
|
||||
* return to fs_capabilities call. JRA. */
|
||||
#define SMB_VFS_INTERFACE_VERSION 27
|
||||
|
||||
|
||||
/* to bug old modules which are trying to compile with the old functions */
|
||||
@ -173,7 +174,7 @@ struct vfs_fn_pointers {
|
||||
int (*set_quota)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
|
||||
int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels);
|
||||
int (*statvfs)(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf);
|
||||
uint32_t (*fs_capabilities)(struct vfs_handle_struct *handle);
|
||||
uint32_t (*fs_capabilities)(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res);
|
||||
|
||||
/* Directory operations */
|
||||
|
||||
@ -488,7 +489,8 @@ int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
|
||||
bool labels);
|
||||
int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
|
||||
struct vfs_statvfs_struct *statbuf);
|
||||
uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle);
|
||||
uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
|
||||
enum timestamp_set_resolution *p_ts_res);
|
||||
SMB_STRUCT_DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
|
||||
const char *fname, const char *mask,
|
||||
uint32 attributes);
|
||||
|
@ -63,10 +63,10 @@
|
||||
#define SMB_VFS_NEXT_STATVFS(handle, path, statbuf) \
|
||||
smb_vfs_call_statvfs((handle)->next, (path), (statbuf))
|
||||
|
||||
#define SMB_VFS_FS_CAPABILITIES(conn) \
|
||||
smb_vfs_call_fs_capabilities((conn)->vfs_handles)
|
||||
#define SMB_VFS_NEXT_FS_CAPABILITIES(handle) \
|
||||
smb_vfs_call_fs_capabilities((handle)->next)
|
||||
#define SMB_VFS_FS_CAPABILITIES(conn, p_ts_res) \
|
||||
smb_vfs_call_fs_capabilities((conn)->vfs_handles, (p_ts_res))
|
||||
#define SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) \
|
||||
smb_vfs_call_fs_capabilities((handle)->next, (p_ts_res))
|
||||
|
||||
/* Directory operations */
|
||||
#define SMB_VFS_OPENDIR(conn, fname, mask, attr) \
|
||||
|
@ -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.
|
||||
pointed to by p, rounded to the correct resolution.
|
||||
****************************************************************************/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void dos_filetime_timespec(struct timespec *tsp)
|
||||
@ -472,7 +488,7 @@ int timespec_compare(const struct timespec *ts1, const struct timespec *ts2)
|
||||
then zero nsec.
|
||||
****************************************************************************/
|
||||
|
||||
void round_timespec(struct timespec *ts)
|
||||
void round_timespec_to_sec(struct timespec *ts)
|
||||
{
|
||||
ts->tv_sec = convert_timespec_to_time_t(*ts);
|
||||
ts->tv_nsec = 0;
|
||||
|
@ -90,15 +90,71 @@ static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path,
|
||||
return sys_statvfs(path, statbuf);
|
||||
}
|
||||
|
||||
static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
|
||||
enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
connection_struct *conn = handle->conn;
|
||||
uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
|
||||
struct smb_filename *smb_fname_cpath = NULL;
|
||||
NTSTATUS status;
|
||||
int ret = -1;
|
||||
|
||||
#if defined(DARWINOS)
|
||||
struct vfs_statvfs_struct statbuf;
|
||||
ZERO_STRUCT(statbuf);
|
||||
sys_statvfs(handle->conn->connectpath, &statbuf);
|
||||
return statbuf.FsCapabilities;
|
||||
sys_statvfs(conn->connectpath, &statbuf);
|
||||
caps = statbuf.FsCapabilities;
|
||||
#endif
|
||||
return FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
|
||||
|
||||
*p_ts_res = TIMESTAMP_SET_SECONDS;
|
||||
|
||||
/* Work out what timestamp resolution we can
|
||||
* use when setting a timestamp. */
|
||||
|
||||
status = create_synthetic_smb_fname(talloc_tos(),
|
||||
conn->connectpath,
|
||||
NULL,
|
||||
NULL,
|
||||
&smb_fname_cpath);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return caps;
|
||||
}
|
||||
|
||||
ret = SMB_VFS_STAT(conn, smb_fname_cpath);
|
||||
if (ret == -1) {
|
||||
TALLOC_FREE(smb_fname_cpath);
|
||||
return caps;
|
||||
}
|
||||
|
||||
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 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. */
|
||||
*p_ts_res = TIMESTAMP_SET_MSEC;
|
||||
#elif defined(HAVE_UTIME)
|
||||
/* utime only allows sec timestamps to be set. */
|
||||
*p_ts_res = TIMESTAMP_SET_SEC;
|
||||
#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",
|
||||
*p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
|
||||
lp_servicename(conn->cnum),
|
||||
conn->connectpath ));
|
||||
}
|
||||
TALLOC_FREE(smb_fname_cpath);
|
||||
return caps;
|
||||
}
|
||||
|
||||
/* Directory operations */
|
||||
@ -788,6 +844,14 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
|
||||
ft->mtime = smb_fname->st.st_ex_mtime;
|
||||
}
|
||||
|
||||
if (!null_timespec(ft->create_time) &&
|
||||
lp_store_create_time(SNUM(handle->conn))) {
|
||||
set_create_timespec_ea(handle->conn,
|
||||
NULL,
|
||||
smb_fname,
|
||||
ft->create_time);
|
||||
}
|
||||
|
||||
if ((timespec_compare(&ft->atime,
|
||||
&smb_fname->st.st_ex_atime) == 0) &&
|
||||
(timespec_compare(&ft->mtime,
|
||||
@ -818,14 +882,6 @@ static int vfswrap_ntimes(vfs_handle_struct *handle,
|
||||
result = -1;
|
||||
#endif
|
||||
|
||||
if (!null_timespec(ft->create_time) &&
|
||||
lp_store_create_time(SNUM(handle->conn))) {
|
||||
set_create_timespec_ea(handle->conn,
|
||||
NULL,
|
||||
smb_fname,
|
||||
ft->create_time);
|
||||
}
|
||||
|
||||
out:
|
||||
END_PROFILE(syscall_ntimes);
|
||||
return result;
|
||||
|
@ -710,11 +710,11 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = SMB_VFS_NEXT_FS_CAPABILITIES(handle);
|
||||
result = SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res);
|
||||
|
||||
do_log(SMB_VFS_OP_FS_CAPABILITIES, true, handle, "");
|
||||
|
||||
|
@ -234,7 +234,7 @@ static int onefs_ntimes(vfs_handle_struct *handle,
|
||||
return onefs_vtimes_streams(handle, smb_fname, flags, times);
|
||||
}
|
||||
|
||||
static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle, enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
@ -243,7 +243,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, p_ts_res);
|
||||
*p_ts_res = TIMESTAMP_SET_MSEC;
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct vfs_fn_pointers onefs_fns = {
|
||||
|
@ -875,9 +875,10 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle,
|
||||
return status;
|
||||
}
|
||||
|
||||
static uint32_t streams_depot_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
static uint32_t streams_depot_fs_capabilities(struct vfs_handle_struct *handle,
|
||||
enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
|
||||
return SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) | FILE_NAMED_STREAMS;
|
||||
}
|
||||
|
||||
static struct vfs_fn_pointers vfs_streams_depot_fns = {
|
||||
|
@ -837,9 +837,10 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static uint32_t streams_xattr_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
static uint32_t streams_xattr_fs_capabilities(struct vfs_handle_struct *handle,
|
||||
enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS;
|
||||
return SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) | FILE_NAMED_STREAMS;
|
||||
}
|
||||
|
||||
static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
|
||||
|
@ -357,9 +357,10 @@ static int tsmsm_set_offline(struct vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t tsmsm_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
static uint32_t tsmsm_fs_capabilities(struct vfs_handle_struct *handle,
|
||||
enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS;
|
||||
return SMB_VFS_NEXT_FS_CAPABILITIES(handle, p_ts_res) | FILE_SUPPORTS_REMOTE_STORAGE | FILE_SUPPORTS_REPARSE_POINTS;
|
||||
}
|
||||
|
||||
static struct vfs_fn_pointers tsmsm_fns = {
|
||||
|
@ -868,7 +868,7 @@ NTSTATUS set_create_timespec_ea(connection_struct *conn,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
put_long_date_timespec(buf, create_time);
|
||||
put_long_date_timespec(conn->ts_res, buf, create_time);
|
||||
if (fsp && fsp->fh->fd != -1) {
|
||||
ret = SMB_VFS_FSETXATTR(fsp,
|
||||
SAMBA_XATTR_DOSTIMESTAMPS,
|
||||
|
@ -272,7 +272,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
|
||||
return status;
|
||||
}
|
||||
|
||||
conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn);
|
||||
conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
|
||||
|
||||
/*
|
||||
* Windows seems to insist on doing trans2getdfsreferral() calls on
|
||||
|
@ -608,13 +608,13 @@ void reply_ntcreate_and_X(struct smb_request *req)
|
||||
dos_filetime_timespec(&c_timespec);
|
||||
}
|
||||
|
||||
put_long_date_timespec(p, create_timespec); /* create time. */
|
||||
put_long_date_timespec(conn->ts_res, p, create_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, c_timespec); /* change time */
|
||||
put_long_date_timespec(conn->ts_res, p, c_timespec); /* change time */
|
||||
p += 8;
|
||||
SIVAL(p,0,fattr); /* File Attributes. */
|
||||
p += 4;
|
||||
@ -1106,13 +1106,13 @@ static void call_nt_transact_create(connection_struct *conn,
|
||||
dos_filetime_timespec(&c_timespec);
|
||||
}
|
||||
|
||||
put_long_date_timespec(p, create_timespec); /* create time. */
|
||||
put_long_date_timespec(conn->ts_res, p, create_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, c_timespec); /* change time */
|
||||
put_long_date_timespec(conn->ts_res, p, c_timespec); /* change time */
|
||||
p += 8;
|
||||
SIVAL(p,0,fattr); /* File Attributes. */
|
||||
p += 4;
|
||||
|
@ -3284,12 +3284,8 @@ 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) {
|
||||
round_timespec(&ts);
|
||||
}
|
||||
set_create_timespec_ea(conn, fsp,
|
||||
smb_fname, ts);
|
||||
smb_fname, smb_fname->st.st_ex_btime);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1015,23 +1015,6 @@ 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, so a compile time test won't work. JRA.
|
||||
*/
|
||||
DEBUG(10,("make_connection_snum: hires timestamps "
|
||||
"available on share %s, directory %s\n",
|
||||
lp_servicename(snum),
|
||||
conn->connectpath ));
|
||||
conn->hires_timestamps_avail = true;
|
||||
}
|
||||
|
||||
string_set(&conn->origpath,conn->connectpath);
|
||||
|
||||
#if SOFTLINK_OPTIMISATION
|
||||
@ -1056,7 +1039,7 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
|
||||
* the same characteristics, which is likely but not guaranteed.
|
||||
*/
|
||||
|
||||
conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn);
|
||||
conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
|
||||
|
||||
/*
|
||||
* Print out the 'connected as' stuff here as we need
|
||||
|
@ -1669,10 +1669,10 @@ static bool smbd_marshall_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,cdate_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,cdate_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;
|
||||
@ -1735,10 +1735,10 @@ static bool smbd_marshall_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,cdate_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,cdate_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;
|
||||
@ -1771,10 +1771,10 @@ static bool smbd_marshall_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,cdate_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,cdate_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;
|
||||
@ -1846,10 +1846,10 @@ static bool smbd_marshall_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,cdate_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,cdate_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;
|
||||
@ -1893,10 +1893,10 @@ static bool smbd_marshall_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,cdate_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,cdate_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;
|
||||
@ -3855,9 +3855,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, psbuf->st_ex_ctime); /* Change Time 64 Bit */
|
||||
put_long_date_timespec(pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
|
||||
put_long_date_timespec(pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
|
||||
put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
|
||||
put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
|
||||
put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
|
||||
pdata += 24;
|
||||
|
||||
SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */
|
||||
@ -3991,7 +3991,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, psbuf->st_ex_btime);
|
||||
put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, psbuf->st_ex_btime);
|
||||
pdata += 8;
|
||||
|
||||
map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
|
||||
@ -4408,10 +4408,10 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
|
||||
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,ctime_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,ctime_ts); /* change time */
|
||||
SIVAL(pdata,32,mode);
|
||||
|
||||
DEBUG(5,("SMB_QFBI - "));
|
||||
@ -4503,10 +4503,10 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
|
||||
unsigned int ea_size =
|
||||
estimate_ea_size(conn, fsp, smb_fname->base_name);
|
||||
DEBUG(10,("smbd_do_qfilepathinfo: 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,ctime_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,ctime_ts); /* change time */
|
||||
SIVAL(pdata,32,mode);
|
||||
SIVAL(pdata,36,0); /* padding. */
|
||||
pdata += 40;
|
||||
@ -4535,10 +4535,10 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
|
||||
unsigned int ea_size =
|
||||
estimate_ea_size(conn, fsp, smb_fname->base_name);
|
||||
DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
|
||||
put_long_date_timespec(pdata+0x00,create_time_ts);
|
||||
put_long_date_timespec(pdata+0x08,atime_ts);
|
||||
put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */
|
||||
put_long_date_timespec(pdata+0x18,ctime_ts); /* change time */
|
||||
put_long_date_timespec(conn->ts_res,pdata+0x00,create_time_ts);
|
||||
put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
|
||||
put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
|
||||
put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
|
||||
SIVAL(pdata, 0x20, mode);
|
||||
SIVAL(pdata, 0x24, 0); /* padding. */
|
||||
SBVAL(pdata, 0x28, allocation_size);
|
||||
@ -4668,10 +4668,10 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
|
||||
|
||||
case SMB_FILE_NETWORK_OPEN_INFORMATION:
|
||||
DEBUG(10,("smbd_do_qfilepathinfo: 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,ctime_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,ctime_ts); /* change time */
|
||||
SOFF_T(pdata,32,allocation_size);
|
||||
SOFF_T(pdata,40,file_size);
|
||||
SIVAL(pdata,48,mode);
|
||||
@ -5402,25 +5402,13 @@ 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. Round to seconds. */
|
||||
round_timespec(&ft->create_time);
|
||||
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);
|
||||
}
|
||||
/* 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->ctime);
|
||||
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))));
|
||||
|
@ -1096,10 +1096,11 @@ int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
|
||||
return handle->fns->statvfs(handle, path, statbuf);
|
||||
}
|
||||
|
||||
uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle)
|
||||
uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
|
||||
enum timestamp_set_resolution *p_ts_res)
|
||||
{
|
||||
VFS_FIND(fs_capabilities);
|
||||
return handle->fns->fs_capabilities(handle);
|
||||
return handle->fns->fs_capabilities(handle, p_ts_res);
|
||||
}
|
||||
|
||||
SMB_STRUCT_DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
|
||||
|
Loading…
x
Reference in New Issue
Block a user