diff options
author | Jeremy Allison <jra@samba.org> | 2009-08-24 20:57:37 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2009-08-24 20:57:37 -0700 |
commit | c69f92d16d57c2387d31b5dfd01aab0685a671d0 (patch) | |
tree | 4eef7104df67108cde2fd436a28c51176473f5e5 /source3/smbd | |
parent | 9a86f26a5f0b421f8cf259e579fe5946b39623f6 (diff) | |
download | samba-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.c | 2 | ||||
-rw-r--r-- | source3/smbd/msdfs.c | 2 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 16 | ||||
-rw-r--r-- | source3/smbd/open.c | 6 | ||||
-rw-r--r-- | source3/smbd/service.c | 19 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 106 | ||||
-rw-r--r-- | source3/smbd/vfs.c | 5 |
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, |