The Samba-Bugzilla – Attachment 4684 Details for
Bug 6529
Offline files conflict with Vista and Office 2003
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Regular format patch for 3.0.x.
look (text/plain), 17.03 KB, created by
Jeremy Allison
on 2009-09-11 14:00:38 UTC
(
hide
)
Description:
Regular format patch for 3.0.x.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2009-09-11 14:00:38 UTC
Size:
17.03 KB
patch
obsolete
>diff --git a/source/include/includes.h b/source/include/includes.h >index 8aa34ff..7548a7d 100644 >--- a/source/include/includes.h >+++ b/source/include/includes.h >@@ -623,6 +623,12 @@ typedef int BOOL; > #define _UPPER_BOOL > #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 >diff --git a/source/include/smb.h b/source/include/smb.h >index 7484efd..95bef1d 100644 >--- a/source/include/smb.h >+++ b/source/include/smb.h >@@ -652,6 +652,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. */ >+ /* Does this filesystem honor >+ sub second timestamps on files >+ and directories when setting time ? */ >+ enum timestamp_set_resolution ts_res; > char *dirpath; > char *connectpath; > char *origpath; >diff --git a/source/lib/time.c b/source/lib/time.c >index 8e28fcc..dd0f9db 100644 >--- a/source/lib/time.c >+++ b/source/lib/time.c >@@ -801,14 +801,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. > ****************************************************************************/ > >-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); >@@ -819,7 +835,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); > } > > /**************************************************************************** >@@ -1145,6 +1161,27 @@ int timespec_compare(const struct timespec *ts1, const struct timespec *ts2) > } > > /**************************************************************************** >+ Round up a timespec if nsec > 500000000, round down if lower, >+ then zero nsec. >+****************************************************************************/ >+ >+void round_timespec_to_sec(struct timespec *ts) >+{ >+ ts->tv_sec = convert_timespec_to_time_t(*ts); >+ ts->tv_nsec = 0; >+} >+ >+/**************************************************************************** >+ Round a timespec to usec value. >+****************************************************************************/ >+ >+void round_timespec_to_usec(struct timespec *ts) >+{ >+ struct timeval tv = convert_timespec_to_timeval(*ts); >+ *ts = convert_timeval_to_timespec(tv); >+} >+ >+/**************************************************************************** > Interprets an nt time into a unix struct timespec. > Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff > will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this case. >diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c >index 2b9d5da..dd7aec5 100644 >--- a/source/smbd/nttrans.c >+++ b/source/smbd/nttrans.c >@@ -906,13 +906,13 @@ int reply_ntcreate_and_X(connection_struct *conn, > dos_filetime_timespec(&m_timespec); > } > >- put_long_date_timespec(p, c_timespec); /* create time. */ >+ put_long_date_timespec(conn->ts_res, p, c_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, m_timespec); /* change time */ >+ put_long_date_timespec(conn->ts_res, p, m_timespec); /* change time */ > p += 8; > SIVAL(p,0,fattr); /* File Attributes. */ > p += 4; >@@ -1584,13 +1584,13 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o > dos_filetime_timespec(&m_timespec); > } > >- put_long_date_timespec(p, c_timespec); /* create time. */ >+ put_long_date_timespec(conn->ts_res, p, c_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, m_timespec); /* change time */ >+ put_long_date_timespec(conn->ts_res, p, m_timespec); /* change time */ > p += 8; > SIVAL(p,0,fattr); /* File Attributes. */ > p += 4; >diff --git a/source/smbd/service.c b/source/smbd/service.c >index bfe9649..6aad9bb 100644 >--- a/source/smbd/service.c >+++ b/source/smbd/service.c >@@ -548,6 +548,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, > fstring user; > fstring dev; > int ret; >+ struct timespec atime_ts, mtime_ts, ctime_ts; > > *user = 0; > fstrcpy(dev, pdev); >@@ -1010,9 +1011,43 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, > *status = NT_STATUS_BAD_NETWORK_NAME; > return NULL; > } >- >+ > string_set(&conn->origpath,conn->connectpath); >- >+ >+ mtime_ts = get_mtimespec(&st); >+ ctime_ts = get_ctimespec(&st); >+ atime_ts = get_atimespec(&st); >+ >+ conn->ts_res = TIMESTAMP_SET_SECONDS; >+ >+ if (mtime_ts.tv_nsec || >+ atime_ts.tv_nsec || >+ ctime_ts.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. */ >+ conn->ts_res = TIMESTAMP_SET_MSEC; >+#elif defined(HAVE_UTIME) >+ /* utime only allows sec timestamps to be set. */ >+ conn->ts_res = TIMESTAMP_SET_SECONDS; >+#endif >+ >+ /* TODO. Add a configure test for the Linux >+ * nsec timestamp set system call, and use it >+ * if available.... >+ */ >+ DEBUG(10,("make_connection_snum: timestamp " >+ "resolution of %s " >+ "available on share %s, directory %s\n", >+ conn->ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec", >+ lp_servicename(conn->cnum), >+ conn->connectpath )); >+ } >+ > #if SOFTLINK_OPTIMISATION > /* resolve any soft links early if possible */ > if (vfs_ChDir(conn,conn->connectpath) == 0) { >diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c >index d3b4fb9..5af592d 100644 >--- a/source/smbd/trans2.c >+++ b/source/smbd/trans2.c >@@ -1184,6 +1184,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > } > > if(got_match) { >+ files_struct *fsp = NULL; >+ > BOOL isdots = (strequal(fname,"..") || strequal(fname,".")); > if (dont_descend && !isdots) > continue; >@@ -1236,7 +1238,15 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > file_size = get_file_size(sbuf); > allocation_size = get_allocation_size(conn,NULL,&sbuf); > >- mdate_ts = get_mtimespec(&sbuf); >+ /* Check if we already have this file open >+ * with a pending modtime. */ >+ fsp = file_find_di_first(sbuf.st_dev, sbuf.st_ino); >+ if (fsp && !null_timespec(fsp->pending_modtime)) { >+ mdate_ts = fsp->pending_modtime; >+ } else { >+ mdate_ts = get_mtimespec(&sbuf); >+ } >+ > adate_ts = get_atimespec(&sbuf); > create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn))); > >@@ -1397,10 +1407,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > 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,mdate_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,mdate_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; >@@ -1443,10 +1453,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > 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,mdate_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,mdate_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; >@@ -1464,10 +1474,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > 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,mdate_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,mdate_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; >@@ -1509,10 +1519,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > 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,mdate_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,mdate_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; >@@ -1540,10 +1550,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, > 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,mdate_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,mdate_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; >@@ -3038,9 +3048,9 @@ static char *store_file_unix_basic(connection_struct *conn, > SOFF_T(pdata,0,get_allocation_size(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */ > pdata += 8; > >- put_long_date_timespec(pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */ >- put_long_date_timespec(pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */ >- put_long_date_timespec(pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */ >+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata,get_ctimespec(psbuf)); /* Change Time 64 Bit */ >+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+8,get_atimespec(psbuf)); /* Last access time 64 Bit */ >+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16,get_mtimespec(psbuf)); /* Last modification time 64 Bit */ > pdata += 24; > > SIVAL(pdata,0,psbuf->st_uid); /* user id for the owner */ >@@ -3180,7 +3190,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, get_create_timespec(psbuf, False)); >+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, get_create_timespec(psbuf, False)); > pdata += 8; > > map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask); >@@ -3589,10 +3599,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd > 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,mtime_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,mtime_ts); /* change time */ > SIVAL(pdata,32,mode); > > DEBUG(5,("SMB_QFBI - ")); >@@ -3673,10 +3683,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd > { > unsigned int ea_size = estimate_ea_size(conn, fsp, fname); > DEBUG(10,("call_trans2qfilepathinfo: 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,mtime_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,mtime_ts); /* change time */ > SIVAL(pdata,32,mode); > SIVAL(pdata,36,0); /* padding. */ > pdata += 40; >@@ -3782,10 +3792,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd > > case SMB_FILE_NETWORK_OPEN_INFORMATION: > DEBUG(10,("call_trans2qfilepathinfo: 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,mtime_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,mtime_ts); /* change time */ > SOFF_T(pdata,32,allocation_size); > SOFF_T(pdata,40,file_size); > SIVAL(pdata,48,mode); >@@ -4097,6 +4107,7 @@ static NTSTATUS smb_set_file_time(connection_struct *conn, > const SMB_STRUCT_STAT *psbuf, > struct timespec ts[2]) > { >+ struct timespec ts_stat[2]; > uint32 action = > FILE_NOTIFY_CHANGE_LAST_ACCESS > |FILE_NOTIFY_CHANGE_LAST_WRITE; >@@ -4117,21 +4128,14 @@ static NTSTATUS smb_set_file_time(connection_struct *conn, > action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE; > } > >- DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) )); >- DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) )); >+ /* Ensure the resolution is the correct for >+ * what we can store on this filesystem. */ > >- /* >- * Try and set the times of this file if >- * they are different from the current values. >- */ >+ round_timespec(conn->ts_res, &ts[0]); >+ round_timespec(conn->ts_res, &ts[1]); > >- { >- struct timespec mts = get_mtimespec(psbuf); >- struct timespec ats = get_atimespec(psbuf); >- if ((timespec_compare(&ts[0], &ats) == 0) && (timespec_compare(&ts[1], &mts) == 0)) { >- return NT_STATUS_OK; >- } >- } >+ DEBUG(6,("smb_set_file_time: actime: %s " , time_to_asc(convert_timespec_to_time_t(ts[0])) )); >+ DEBUG(6,("smb_set_file_time: modtime: %s ", time_to_asc(convert_timespec_to_time_t(ts[1])) )); > > if(fsp != NULL) { > /* >@@ -4153,9 +4157,18 @@ static NTSTATUS smb_set_file_time(connection_struct *conn, > } > DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n")); > >- if(file_ntimes(conn, fname, ts)!=0) { >- return map_nt_error_from_unix(errno); >+ ts_stat[0] = get_atimespec(psbuf); >+ ts_stat[1] = get_mtimespec(psbuf); >+ round_timespec(conn->ts_res, &ts_stat[0]); >+ round_timespec(conn->ts_res, &ts_stat[1]); >+ >+ if (timespec_compare(&ts[0], &ts_stat[0]) || >+ timespec_compare(&ts[1], &ts_stat[1])) { >+ if(file_ntimes(conn, fname, ts)!=0) { >+ return map_nt_error_from_unix(errno); >+ } > } >+ > if (action != 0) { > notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, fname); > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6529
:
4390
|
4587
|
4588
|
4589
|
4590
|
4591
|
4592
|
4593
|
4594
|
4651
|
4652
|
4669
|
4670
|
4684
|
4685
|
4692
|
4697
|
4698