diff options
author | Jeremy Allison <jra@samba.org> | 2009-07-08 17:51:35 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2009-07-08 17:51:35 -0700 |
commit | c9c3d4312d7281904fc4a1cc9abd4831cdf4bfb9 (patch) | |
tree | 78a1df33a6276aea076f57424d18729604970253 /source3/smbd | |
parent | 58daaa3d1e7075b23c8709889be9b461c6c6c174 (diff) | |
download | samba-c9c3d4312d7281904fc4a1cc9abd4831cdf4bfb9.tar.gz samba-c9c3d4312d7281904fc4a1cc9abd4831cdf4bfb9.tar.bz2 samba-c9c3d4312d7281904fc4a1cc9abd4831cdf4bfb9.zip |
The migration to struct stat_ex broke the calculation of
create time from the existing timestamps (for systems
that need to do this). Once the write time is changed
via a sticky write, the create time might need to be
recalculated. To do this I needed to add a bool into
struct stat_ex to remember if the st_ex_btime field
was calculated, or read from the OS. Also fixed the
returning of modified write timestamps in the return
from NTCreateX, SMBattr and SMBattrE (which weren't
taking into account the modified timestamp stored
in the open file table). Attempting to fix an issue
with Excel 2003 and offline files. Volker and Metze,
please review.
Jeremy
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/nttrans.c | 18 | ||||
-rw-r--r-- | source3/smbd/reply.c | 28 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 21 |
3 files changed, 57 insertions, 10 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index b970ffc05e..4f75b9f120 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -473,6 +473,7 @@ void reply_ntcreate_and_X(struct smb_request *req) struct timespec c_timespec; struct timespec a_timespec; struct timespec m_timespec; + struct timespec write_time_ts; NTSTATUS status; int oplock_request; uint8_t oplock_granted = NO_OPLOCK_RETURN; @@ -651,6 +652,14 @@ void reply_ntcreate_and_X(struct smb_request *req) } p += 4; + /* Deal with other possible opens having a modified + write time. JRA. */ + ZERO_STRUCT(write_time_ts); + get_file_infos(fsp->file_id, NULL, &write_time_ts); + if (!null_timespec(write_time_ts)) { + update_stat_ex_writetime(&smb_fname->st, write_time_ts); + } + /* Create time. */ c_timespec = smb_fname->st.st_ex_btime; a_timespec = smb_fname->st.st_ex_atime; @@ -908,6 +917,7 @@ static void call_nt_transact_create(connection_struct *conn, struct timespec c_timespec; struct timespec a_timespec; struct timespec m_timespec; + struct timespec write_time_ts; struct ea_list *ea_list = NULL; NTSTATUS status; size_t param_len; @@ -1133,6 +1143,14 @@ static void call_nt_transact_create(connection_struct *conn, } p += 8; + /* Deal with other possible opens having a modified + write time. JRA. */ + ZERO_STRUCT(write_time_ts); + get_file_infos(fsp->file_id, NULL, &write_time_ts); + if (!null_timespec(write_time_ts)) { + update_stat_ex_writetime(&smb_fname->st, write_time_ts); + } + /* Create time. */ c_timespec = smb_fname->st.st_ex_btime; a_timespec = smb_fname->st.st_ex_atime; diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c07ac33679..e02482ea4a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1065,6 +1065,7 @@ void reply_getatr(struct smb_request *req) const char *p; NTSTATUS status; TALLOC_CTX *ctx = talloc_tos(); + bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true); START_PROFILE(SMBgetatr); @@ -1111,6 +1112,19 @@ void reply_getatr(struct smb_request *req) mode = dos_mode(conn, fname, &smb_fname->st); size = smb_fname->st.st_ex_size; + + if (ask_sharemode) { + struct timespec write_time_ts; + struct file_id fileid; + + ZERO_STRUCT(write_time_ts); + fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); + get_file_infos(fileid, NULL, &write_time_ts); + if (!null_timespec(write_time_ts)) { + update_stat_ex_writetime(&smb_fname->st, write_time_ts); + } + } + mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime); if (mode & aDIR) { size = 0; @@ -1707,6 +1721,7 @@ void reply_open(struct smb_request *req) uint32 create_disposition; uint32 create_options = 0; NTSTATUS status; + bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true); TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBopen); @@ -1779,6 +1794,19 @@ void reply_open(struct smb_request *req) size = smb_fname->st.st_ex_size; fattr = dos_mode(conn,fsp->fsp_name,&smb_fname->st); + + /* Deal with other possible opens having a modified + write time. JRA. */ + if (ask_sharemode) { + struct timespec write_time_ts; + + ZERO_STRUCT(write_time_ts); + get_file_infos(fsp->file_id, NULL, &write_time_ts); + if (!null_timespec(write_time_ts)) { + update_stat_ex_writetime(&smb_fname->st, write_time_ts); + } + } + mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime); if (fattr & aDIR) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index e5f8039e6e..cb4f10fa79 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1455,21 +1455,22 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, } allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,NULL,&sbuf); - mdate_ts = sbuf.st_ex_mtime; - adate_ts = sbuf.st_ex_atime; - create_date_ts = sbuf.st_ex_btime; - if (ask_sharemode) { struct timespec write_time_ts; struct file_id fileid; + ZERO_STRUCT(write_time_ts); fileid = vfs_file_id_from_sbuf(conn, &sbuf); get_file_infos(fileid, NULL, &write_time_ts); if (!null_timespec(write_time_ts)) { - mdate_ts = write_time_ts; + update_stat_ex_writetime(&sbuf, write_time_ts); } } + mdate_ts = sbuf.st_ex_mtime; + adate_ts = sbuf.st_ex_atime; + create_date_ts = sbuf.st_ex_btime; + if (lp_dos_filetime_resolution(SNUM(conn))) { dos_filetime_timespec(&create_date_ts); dos_filetime_timespec(&mdate_ts); @@ -4244,10 +4245,6 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dstart = pdata; dend = dstart + data_size - 1; - create_time_ts = sbuf.st_ex_btime; - mtime_ts = sbuf.st_ex_mtime; - atime_ts = sbuf.st_ex_atime; - allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf); if (!fsp) { @@ -4261,9 +4258,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) { - mtime_ts = write_time_ts; + update_stat_ex_writetime(&sbuf, write_time_ts); } + create_time_ts = sbuf.st_ex_btime; + mtime_ts = sbuf.st_ex_mtime; + atime_ts = sbuf.st_ex_atime; + if (lp_dos_filetime_resolution(SNUM(conn))) { dos_filetime_timespec(&create_time_ts); dos_filetime_timespec(&mtime_ts); |