summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-08-24 20:57:37 -0700
committerJeremy Allison <jra@samba.org>2009-08-24 20:57:37 -0700
commitc69f92d16d57c2387d31b5dfd01aab0685a671d0 (patch)
tree4eef7104df67108cde2fd436a28c51176473f5e5 /source3/smbd
parent9a86f26a5f0b421f8cf259e579fe5946b39623f6 (diff)
downloadsamba-c69f92d16d57c2387d31b5dfd01aab0685a671d0.tar.gz
samba-c69f92d16d57c2387d31b5dfd01aab0685a671d0.tar.bz2
samba-c69f92d16d57c2387d31b5dfd01aab0685a671d0.zip
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.
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/dosmode.c2
-rw-r--r--source3/smbd/msdfs.c2
-rw-r--r--source3/smbd/nttrans.c16
-rw-r--r--source3/smbd/open.c6
-rw-r--r--source3/smbd/service.c19
-rw-r--r--source3/smbd/trans2.c106
-rw-r--r--source3/smbd/vfs.c5
7 files changed, 62 insertions, 94 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index e9345cc029..7cb84b35a7 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -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,
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 767c8fe297..74e46527bc 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -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
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 03fdff3900..434bf34e40 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 9b4eedf432..045635535f 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -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);
}
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 36b783ee78..3520f0d411 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -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
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a1043e27ff..da23697771 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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))));
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 75fd8396e6..5425c55198 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -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,