The Samba-Bugzilla – Attachment 14429 Details for
Bug 13541
Durable handle reconnect doesn't update fsp write-time from locking.tdb record
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Work in progress patches
tmp.diff.txt (text/plain), 645.45 KB, created by
Stefan Metzmacher
on 2018-08-17 13:22:20 UTC
(
hide
)
Description:
Work in progress patches
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2018-08-17 13:22:20 UTC
Size:
645.45 KB
patch
obsolete
>From 0b53e7a46e7a7f821fef88a0954403b859e04c39 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 13 Aug 2018 18:24:17 +0200 >Subject: [PATCH 01/48] TODO: bin/smbtorture //172.31.9.187/torture > -Uadministrator%A1b2C3d4 smb2.durable-v2-open.delaywrite1 > >https://bugzilla.samba.org/show_bug.cgi?id=13541 >--- > source4/torture/smb2/durable_v2_open.c | 669 +++++++++++++++++++++++++ > 1 file changed, 669 insertions(+) > >diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c >index 0a928ec8c265..df755bbe286b 100644 >--- a/source4/torture/smb2/durable_v2_open.c >+++ b/source4/torture/smb2/durable_v2_open.c >@@ -2011,6 +2011,674 @@ bool test_persistent_open_lease(struct torture_context *tctx, > return ret; > } > >+#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >+ uint64_t r = 10*1000*1000; \ >+ NTTIME g = (given).basic_info.out.write_time; \ >+ NTTIME gr = (g / r) * r; \ >+ NTTIME _c = (correct).basic_info.out.write_time; \ >+ NTTIME cr = (_c / r) * r; \ >+ bool strict = torture_setting_bool(tctx, "strict mode", false); \ >+ bool err = false; \ >+ if (strict && (g cmp _c)) { \ >+ err = true; \ >+ } else if ((g cmp _c) && (gr cmp cr)) { \ >+ /* handle filesystem without high resolution timestamps */ \ >+ err = true; \ >+ } \ >+ if (err) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": wrong write_time (%s)%s(%llu) %s (%s)%s(%llu)", \ >+ #given, nt_time_string(tctx, g), (unsigned long long)g, \ >+ #cmp, #correct, nt_time_string(tctx, _c), (unsigned long long)_c); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,!=) >+#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,<=) >+#define COMPARE_WRITE_TIME_LESS(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,>=) >+ >+#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >+ NTTIME g = (given).basic_info.out.access_time; \ >+ NTTIME c = (correct).basic_info.out.access_time; \ >+ if (g cmp c) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": wrong access_time (%s)%s %s (%s)%s", \ >+ #given, nt_time_string(tctx, g), \ >+ #cmp, #correct, nt_time_string(tctx, c)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_BOTH_TIMES_EQUAL(given,correct) do { \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_WRITE_TIME_EQUAL(given,correct); \ >+} while (0) >+ >+#define GET_INFO_FILE(finfo) do { \ >+ NTSTATUS _status; \ >+ _status = smb2_getinfo_file(tree, tctx, &finfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ ret = false; \ >+ torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ goto done; \ >+ } \ >+ torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ >+ nt_time_string(tctx, finfo.basic_info.out.access_time), \ >+ nt_time_string(tctx, finfo.basic_info.out.write_time)); \ >+} while (0) >+ >+#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ >+ NTSTATUS _status; \ >+ union smb_setfileinfo sfinfo; \ >+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >+ sfinfo.basic_info.in.file.fnum = tfnum; \ >+ sfinfo.basic_info.in.create_time = 0; \ >+ sfinfo.basic_info.in.access_time = 0; \ >+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >+ sfinfo.basic_info.in.change_time = 0; \ >+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >+ _status = smb_raw_setfileinfo(tree, &sfinfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define SET_INFO_FILE(finfo, wrtime) \ >+ SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) >+ >+#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ >+ NTSTATUS _status; \ >+ union smb_setfileinfo sfinfo; \ >+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >+ sfinfo.basic_info.in.file.fnum = tfnum; \ >+ sfinfo.basic_info.in.create_time = 0; \ >+ sfinfo.basic_info.in.access_time = 0; \ >+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >+ sfinfo.basic_info.in.write_time += (ns); \ >+ sfinfo.basic_info.in.change_time = 0; \ >+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >+ _status = smb_raw_setfileinfo(tree, &sfinfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+ >+#if 0 >+static bool test_delayed_write_update3(struct torture_context *tctx, >+ struct smbcli_state *cli, >+ struct smbcli_state *cli2) >+{ >+ union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >+ union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >+ const char *fname = BASEDIR "\\torture_file3.txt"; >+ int fnum1 = -1; >+ bool ret = true; >+ ssize_t written; >+ struct timeval start; >+ struct timeval end; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ >+ torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Open the file handle\n"); >+ fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (fnum1 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } >+ >+ finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ finfo0.basic_info.in.file.fnum = fnum1; >+ finfo1 = finfo0; >+ finfo2 = finfo0; >+ finfo3 = finfo0; >+ pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ pinfo0.basic_info.in.file.path = fname; >+ pinfo1 = pinfo0; >+ pinfo2 = pinfo0; >+ pinfo3 = pinfo0; >+ pinfo4 = pinfo0; >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo0,pinfo0); >+ >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_FILE(finfo1); >+ >+ if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(write time update delay == %.2f) (wrong!)\n", >+ diff, used_delay / (double)1000000); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ break; >+ } >+ smb_msleep(0.5 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ >+ if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ break; >+ } >+ smb_msleep(1 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >+ if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update write_time (correct)\n"); >+ } >+ >+ /* sleep */ >+ smb_msleep(5 * msec); >+ >+ GET_INFO_BOTH(finfo3,pinfo3); >+ COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ smbcli_close(cli->tree, fnum1); >+ fnum1 = -1; >+ >+ GET_INFO_PATH(pinfo4); >+ COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); >+ >+ if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >+ torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >+ } >+ >+ done: >+ if (fnum1 != -1) >+ smbcli_close(cli->tree, fnum1); >+ smbcli_unlink(cli->tree, fname); >+ smbcli_deltree(cli->tree, BASEDIR); >+ >+ return ret; >+} >+ >+/* >+ * Show that a truncate write always updates the write time even >+ * if an initial write has already updated the write time. >+ */ >+ >+static bool test_delayed_write_update3a(struct torture_context *tctx, >+ struct smbcli_state *cli, >+ struct smbcli_state *cli2) >+{ >+ union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >+ union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >+ const char *fname = BASEDIR "\\torture_file3a.txt"; >+ int fnum1 = -1; >+ bool ret = true; >+ ssize_t written; >+ int i; >+ struct timeval start; >+ struct timeval end; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ >+ torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Open the file handle\n"); >+ fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (fnum1 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } >+ >+ finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ finfo0.basic_info.in.file.fnum = fnum1; >+ finfo1 = finfo0; >+ finfo2 = finfo0; >+ finfo3 = finfo0; >+ pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ pinfo0.basic_info.in.file.path = fname; >+ pinfo1 = pinfo0; >+ pinfo2 = pinfo0; >+ pinfo3 = pinfo0; >+ pinfo4 = pinfo0; >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo0,pinfo0); >+ >+ /* >+ * sleep some time, to demonstrate the handling of write times >+ * doesn't depend on the time since the open >+ */ >+ smb_msleep(5 * msec); >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); >+ >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_FILE(finfo1); >+ >+ if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(1sec == %.2f) (wrong!)\n", >+ diff, sec); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ break; >+ } >+ smb_msleep(0.5 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >+ >+ smb_msleep(3 * msec); >+ >+ /* >+ * demonstrate that a truncate write always >+ * updates the write time immediately >+ */ >+ for (i=0; i < 3; i++) { >+ smb_msleep(2 * msec); >+ /* do a write */ >+ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >+ written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); >+ if (written != 0) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >+ finfo1 = finfo2; >+ } >+ >+ smb_msleep(3 * msec); >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ >+ if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ break; >+ } >+ smb_msleep(1 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >+ if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update write_time (correct)\n"); >+ } >+ >+ /* sleep */ >+ smb_msleep(3 * msec); >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); >+ >+ /* >+ * demonstrate that a truncate write always >+ * updates the write time immediately >+ */ >+ for (i=0; i < 3; i++) { >+ smb_msleep(2 * msec); >+ /* do a write */ >+ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >+ written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); >+ if (written != 0) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >+ finfo1 = finfo2; >+ } >+ >+ /* sleep */ >+ smb_msleep(3 * msec); >+ >+ GET_INFO_BOTH(finfo3,pinfo3); >+ COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ >+ /* >+ * the close doesn't update the write time >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ smbcli_close(cli->tree, fnum1); >+ fnum1 = -1; >+ >+ GET_INFO_PATH(pinfo4); >+ COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); >+ >+ if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); >+ } >+ >+ done: >+ if (fnum1 != -1) >+ smbcli_close(cli->tree, fnum1); >+ smbcli_unlink(cli->tree, fname); >+ smbcli_deltree(cli->tree, BASEDIR); >+ >+ return ret; >+} >+#endif >+ >+ >+static bool test_durable_v2_delaywrite1(struct torture_context *tctx, >+ struct smb2_tree *tree) >+{ >+ NTSTATUS status; >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ char fname[256]; >+ struct smb2_handle _h; >+ struct smb2_handle *h = NULL; >+ struct smb2_create io; >+ struct GUID create_guid = GUID_random(); >+ union smb_fileinfo finfo0; >+ union smb_fileinfo finfo1; >+ union smb_fileinfo finfo2; >+ union smb_fileinfo finfo3; >+ struct smb2_close cl; >+ struct smb2_write wr; >+ ssize_t written; >+ struct timeval start; >+ struct timeval end; >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; >+ //int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ bool ret = true; >+ >+ /* Choose a random name in case the state is left a little funky. */ >+ snprintf(fname, 256, "durable_v2_delaywrite1_%s.dat", >+ generate_random_str(tctx, 8)); >+ >+ smb2_util_unlink(tree, fname); >+ >+ smb2_oplock_create_share(&io, fname, >+ smb2_util_share_access(""), >+ smb2_util_oplock_level("b")); >+ io.in.durable_open = false; >+ io.in.durable_open_v2 = true; >+ io.in.persistent_open = false; >+ io.in.create_guid = create_guid; >+ io.in.timeout = UINT32_MAX; >+ >+ status = smb2_create(tree, mem_ctx, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h = io.out.file.handle; >+ h = &_h; >+ CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); >+ CHECK_VAL(io.out.durable_open, false); >+ CHECK_VAL(io.out.durable_open_v2, true); >+ CHECK_VAL(io.out.persistent_open, false); >+ //CHECK_VAL(io.out.timeout, io.in.timeout); >+ >+ ZERO_STRUCT(finfo0); >+ finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ finfo0.basic_info.in.file.handle = *h; >+ finfo1 = finfo0; >+ finfo2 = finfo0; >+ finfo3 = finfo0; >+ >+ /* get the initial times */ >+ GET_INFO_FILE(finfo0); >+ >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ ZERO_STRUCT(wr); >+ wr.in.file.handle = *h; >+ wr.in.offset = 0; >+ wr.in.data = data_blob_const("x", 1); >+ status = smb2_write(tree, &wr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ written = wr.out.nwritten; >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_FILE(finfo1); >+ >+ if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(write time update delay == %.2f) (wrong!)\n", >+ diff, used_delay / (double)1000000); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ break; >+ } >+ smb_msleep(0.5 * msec); >+ } >+ >+ GET_INFO_FILE(finfo1); >+ COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ ZERO_STRUCT(wr); >+ wr.in.file.handle = *h; >+ wr.in.offset = 0; >+ wr.in.data = data_blob_const("x", 1); >+ status = smb2_write(tree, &wr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ written = wr.out.nwritten; >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_FILE(finfo2); >+ >+ if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ break; >+ } >+ smb_msleep(1 * msec); >+ } >+ >+ GET_INFO_FILE(finfo2); >+ COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >+ if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update write_time (correct)\n"); >+ } >+ >+ /* sleep */ >+ smb_msleep(5 * msec); >+ >+ GET_INFO_FILE(finfo3); >+ COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ >+ ZERO_STRUCT(cl); >+ cl.in.file.handle = *h; >+ cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(tree, &cl); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ h = NULL; >+ //struct { >+ // /* static body buffer 60 (0x3C) bytes */ >+ // /* uint16_t buffer_code; 0x3C */ >+ // uint16_t flags; >+ // uint32_t _pad; >+ // NTTIME create_time; >+ // NTTIME access_time; >+ // NTTIME write_time; >+ // NTTIME change_time; >+ // uint64_t alloc_size; >+ // uint64_t size; >+ // uint32_t file_attr; >+ //} out; >+ >+ //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >+ // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >+ //} >+ ///* try a durable reconnect while the file is still open */ >+ //ZERO_STRUCT(io); >+ //io.in.fname = ""; >+ //io.in.durable_handle_v2 = h; >+ //io.in.create_guid = create_guid; >+ //status = smb2_create(tree, mem_ctx, &io); >+ //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); >+ >+done: >+ if (h != NULL) { >+ smb2_util_close(tree, *h); >+ } >+ >+ smb2_util_unlink(tree, fname); >+ >+ talloc_free(tree); >+ >+ talloc_free(mem_ctx); >+ >+ return ret; >+} >+ > struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) > { > struct torture_suite *suite = >@@ -2030,6 +2698,7 @@ struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) > torture_suite_add_2smb2_test(suite, "app-instance", test_durable_v2_open_app_instance); > torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock); > torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease); >+ torture_suite_add_1smb2_test(suite, "delaywrite1", test_durable_v2_delaywrite1); > > suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests"); > >-- >2.17.1 > > >From 67a374490b3b537fabb02faf25af06a4dfc56eab Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 15:15:43 +0200 >Subject: [PATCH 02/48] HACK source4/torture/basic/delaywrite.c > >--- > source4/torture/basic/delaywrite.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 347871688729..dd261d86d096 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -30,6 +30,7 @@ > #include "libcli/libcli.h" > #include "torture/util.h" > #include "torture/basic/proto.h" >+#include "lib/util/time_basic.h" > > #define BASEDIR "\\delaywrite" > >@@ -1308,6 +1309,10 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s > } while (0) > > #define GET_INFO_FILE(finfo) do { \ >+ struct timeval atv; \ >+ struct timeval wtv; \ >+ struct timeval_buf atvb; \ >+ struct timeval_buf wtvb; \ > NTSTATUS _status; \ > _status = smb_raw_fileinfo(cli->tree, tctx, &finfo); \ > if (!NT_STATUS_IS_OK(_status)) { \ >@@ -1316,9 +1321,11 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s > nt_errstr(_status)); \ > goto done; \ > } \ >+ nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \ >+ nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \ > torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ >- nt_time_string(tctx, finfo.basic_info.out.access_time), \ >- nt_time_string(tctx, finfo.basic_info.out.write_time)); \ >+ timeval_str_buf(&atv, false, true, &atvb), \ >+ timeval_str_buf(&wtv, false, true, &wtvb)); \ > } while (0) > #define GET_INFO_FILE2(finfo) do { \ > NTSTATUS _status; \ >@@ -1406,6 +1413,8 @@ static bool test_delayed_write_update3(struct torture_context *tctx, > struct timeval start; > struct timeval end; > double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ //int normal_delay = 1000000; > int normal_delay = 2000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; >@@ -1459,7 +1468,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, > if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { > double diff = timeval_elapsed(&start); > if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ torture_result(tctx, TORTURE_FAIL, "111Server updated write_time after %.2f seconds " > "(write time update delay == %.2f) (wrong!)\n", > diff, used_delay / (double)1000000); > ret = false; >-- >2.17.1 > > >From c272320ea8996686dd1d9072ceee2c56c8ee2e29 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 15:16:21 +0200 >Subject: [PATCH 03/48] TODO source4/torture/smb2/durable_open.c > >--- > source4/torture/smb2/durable_open.c | 1121 +++++++++++++++++++++++++++ > 1 file changed, 1121 insertions(+) > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 17b3b217b56e..092294ff5341 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -27,6 +27,7 @@ > #include "torture/torture.h" > #include "torture/smb2/proto.h" > #include "../libcli/smb/smbXcli_base.h" >+#include "lib/util/time_basic.h" > > #define CHECK_VAL(v, correct) do { \ > if ((v) != (correct)) { \ >@@ -2752,6 +2753,1124 @@ done: > return ret; > } > >+#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ >+ const uint64_t _r = 10*1000*1000; \ >+ NTTIME _g = (given).basic_info.out.gelem; \ >+ NTTIME _gr = (_g / _r) * _r; \ >+ NTTIME _c = (correct).basic_info.out.celem; \ >+ NTTIME _cr = (_c / _r) * _r; \ >+ bool _strict = torture_setting_bool(tctx, "strict mode", false); \ >+ const char *_err = NULL; \ >+ if (_strict && (_g cmp _c)) { \ >+ _err = "strict"; \ >+ } else if ((_g cmp _c) && (_gr cmp _cr)) { \ >+ /* handle filesystem without high resolution timestamps */ \ >+ _err = "rounded"; \ >+ } \ >+ if (_err != NULL) { \ >+ struct timeval _gtv; \ >+ struct timeval _ctv; \ >+ struct timeval_buf _gtvb; \ >+ struct timeval_buf _ctvb; \ >+ nttime_to_timeval(&_gtv, _g); \ >+ nttime_to_timeval(&_ctv, _c); \ >+ torture_result(tctx, TORTURE_FAIL, \ >+ __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ >+ _err, \ >+ #given, #gelem, \ >+ timeval_str_buf(&_gtv, false, true, &_gtvb), \ >+ #cmp, \ >+ #correct, #celem, \ >+ timeval_str_buf(&_ctv, false, true, &_ctvb)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ >+} while (0) >+#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,!=) >+#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,<=) >+#define COMPARE_WRITE_TIME_LESS(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,>=) >+ >+#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ >+} while (0) >+#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ >+} while (0) >+#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >+} while (0) >+#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ >+ COMPARE_CREATE_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_WRITE_TIME_EQUAL(given,correct); \ >+ COMPARE_CHANGE_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+} while (0) >+ >+#define GET_INFO_FILE(tree, finfo) do { \ >+ struct timeval _atv; \ >+ struct timeval _wtv; \ >+ struct timeval_buf _atvb; \ >+ struct timeval_buf _wtvb; \ >+ NTSTATUS _status; \ >+ _status = smb2_getinfo_file(tree, tctx, &finfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ ret = false; \ >+ torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ goto done; \ >+ } \ >+ nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ >+ nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ >+ torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ >+ #tree, #finfo, \ >+ timeval_str_buf(&_atv, false, true, &_atvb), \ >+ timeval_str_buf(&_wtv, false, true, &_wtvb)); \ >+} while (0) >+ >+#define GET_INFO_BOTH(finfo1, finfo2) do { \ >+ GET_INFO_FILE(tree2, finfo2); \ >+ GET_INFO_FILE(tree1, finfo1); \ >+ COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ >+} while (0) >+ >+#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ >+ NTSTATUS _status; \ >+ union smb_setfileinfo sfinfo; \ >+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >+ sfinfo.basic_info.in.file.fnum = tfnum; \ >+ sfinfo.basic_info.in.create_time = 0; \ >+ sfinfo.basic_info.in.access_time = 0; \ >+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >+ sfinfo.basic_info.in.change_time = 0; \ >+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >+ _status = smb_raw_setfileinfo(tree, &sfinfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define SET_INFO_FILE(finfo, wrtime) \ >+ SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) >+ >+#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ >+ NTSTATUS _status; \ >+ union smb_setfileinfo sfinfo; \ >+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >+ sfinfo.basic_info.in.file.fnum = tfnum; \ >+ sfinfo.basic_info.in.create_time = 0; \ >+ sfinfo.basic_info.in.access_time = 0; \ >+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >+ sfinfo.basic_info.in.write_time += (ns); \ >+ sfinfo.basic_info.in.change_time = 0; \ >+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >+ _status = smb_raw_setfileinfo(tree, &sfinfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+ >+#if 0 >+static bool test_delayed_write_update3(struct torture_context *tctx, >+ struct smbcli_state *cli, >+ struct smbcli_state *cli2) >+{ >+ union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >+ union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >+ const char *fname = BASEDIR "\\torture_file3.txt"; >+ int fnum1 = -1; >+ bool ret = true; >+ ssize_t written; >+ struct timeval start; >+ struct timeval end; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ >+ torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Open the file handle\n"); >+ fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (fnum1 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } >+ >+ finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ finfo0.basic_info.in.file.fnum = fnum1; >+ finfo1 = finfo0; >+ finfo2 = finfo0; >+ finfo3 = finfo0; >+ pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ pinfo0.basic_info.in.file.path = fname; >+ pinfo1 = pinfo0; >+ pinfo2 = pinfo0; >+ pinfo3 = pinfo0; >+ pinfo4 = pinfo0; >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo0,pinfo0); >+ >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_FILE(finfo1); >+ >+ if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(write time update delay == %.2f) (wrong!)\n", >+ diff, used_delay / (double)1000000); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ break; >+ } >+ smb_msleep(0.5 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ >+ if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ break; >+ } >+ smb_msleep(1 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >+ if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update write_time (correct)\n"); >+ } >+ >+ /* sleep */ >+ smb_msleep(5 * msec); >+ >+ GET_INFO_BOTH(finfo3,pinfo3); >+ COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ smbcli_close(cli->tree, fnum1); >+ fnum1 = -1; >+ >+ GET_INFO_PATH(pinfo4); >+ COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); >+ >+ if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >+ torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >+ } >+ >+ done: >+ if (fnum1 != -1) >+ smbcli_close(cli->tree, fnum1); >+ smbcli_unlink(cli->tree, fname); >+ smbcli_deltree(cli->tree, BASEDIR); >+ >+ return ret; >+} >+ >+/* >+ * Show that a truncate write always updates the write time even >+ * if an initial write has already updated the write time. >+ */ >+ >+static bool test_delayed_write_update3a(struct torture_context *tctx, >+ struct smbcli_state *cli, >+ struct smbcli_state *cli2) >+{ >+ union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >+ union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >+ const char *fname = BASEDIR "\\torture_file3a.txt"; >+ int fnum1 = -1; >+ bool ret = true; >+ ssize_t written; >+ int i; >+ struct timeval start; >+ struct timeval end; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ >+ torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Open the file handle\n"); >+ fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (fnum1 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } >+ >+ finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ finfo0.basic_info.in.file.fnum = fnum1; >+ finfo1 = finfo0; >+ finfo2 = finfo0; >+ finfo3 = finfo0; >+ pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ pinfo0.basic_info.in.file.path = fname; >+ pinfo1 = pinfo0; >+ pinfo2 = pinfo0; >+ pinfo3 = pinfo0; >+ pinfo4 = pinfo0; >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo0,pinfo0); >+ >+ /* >+ * sleep some time, to demonstrate the handling of write times >+ * doesn't depend on the time since the open >+ */ >+ smb_msleep(5 * msec); >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); >+ >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_FILE(finfo1); >+ >+ if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(1sec == %.2f) (wrong!)\n", >+ diff, sec); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ break; >+ } >+ smb_msleep(0.5 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >+ >+ smb_msleep(3 * msec); >+ >+ /* >+ * demonstrate that a truncate write always >+ * updates the write time immediately >+ */ >+ for (i=0; i < 3; i++) { >+ smb_msleep(2 * msec); >+ /* do a write */ >+ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >+ written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); >+ if (written != 0) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >+ finfo1 = finfo2; >+ } >+ >+ smb_msleep(3 * msec); >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ >+ if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ break; >+ } >+ smb_msleep(1 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >+ if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update write_time (correct)\n"); >+ } >+ >+ /* sleep */ >+ smb_msleep(3 * msec); >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); >+ >+ /* >+ * demonstrate that a truncate write always >+ * updates the write time immediately >+ */ >+ for (i=0; i < 3; i++) { >+ smb_msleep(2 * msec); >+ /* do a write */ >+ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >+ written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); >+ if (written != 0) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2,pinfo2); >+ COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >+ finfo1 = finfo2; >+ } >+ >+ /* sleep */ >+ smb_msleep(3 * msec); >+ >+ GET_INFO_BOTH(finfo3,pinfo3); >+ COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ >+ /* >+ * the close doesn't update the write time >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ smbcli_close(cli->tree, fnum1); >+ fnum1 = -1; >+ >+ GET_INFO_PATH(pinfo4); >+ COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); >+ >+ if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); >+ } >+ >+ done: >+ if (fnum1 != -1) >+ smbcli_close(cli->tree, fnum1); >+ smbcli_unlink(cli->tree, fname); >+ smbcli_deltree(cli->tree, BASEDIR); >+ >+ return ret; >+} >+#endif >+ >+static bool test_delay_writetime(struct torture_context *tctx, >+ double used_delay, >+ double normal_delay, >+ const char *description, >+ bool (*get_basic_info_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ bool (*write_data_cb)(void *private_data), >+ void *private_data) >+{ >+ union smb_fileinfo finfo0, finfo1, finfoT; >+ struct timeval before_write; >+ struct timeval after_write; >+ struct timeval start; >+ struct timeval end; >+ double sec = used_delay / normal_delay; >+ int msec = 1000 * sec; >+ bool ret = true; >+ bool ok; >+ >+ torture_comment(tctx, "START: %s\n", description); >+ >+ /* get the initial times */ >+ ok = get_basic_info_cb(private_data, &finfo0); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); >+ >+ /* >+ * Make sure the time doesn't change during the next 5 seconds >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 5 * sec, 0); >+ while (!timeval_expired(&end)) { >+ smb_msleep(1 * msec); >+ torture_comment(tctx, "Check for no change\n"); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >+ >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ before_write = timeval_current(); >+ ok = write_data_cb(private_data); >+ after_write = timeval_current(); >+ torture_assert(tctx, ok, "write_data_cb"); >+ (void)(&before_write == &after_write); >+ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ struct timeval before_get; >+ struct timeval after_get; >+ >+ torture_comment(tctx, "Wait for change\n"); >+ before_get = timeval_current(); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ after_get = timeval_current(); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ (void)(&before_get == &after_get); >+ >+ if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ diff = timeval_elapsed2(&before_write, &after_get); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >+ "(write time update delay == %.2f) (wrong!)\n", >+ diff, used_delay / (double)1000000); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ break; >+ } >+ >+ COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >+ smb_msleep(0.5 * msec); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfo1); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); >+ COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >+ >+ /* >+ * Make sure the time doesn't change during the next 5 seconds >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 5 * sec, 0); >+ while (!timeval_expired(&end)) { >+ smb_msleep(1 * msec); >+ torture_comment(tctx, "Check for no change\n"); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); >+#if 0 >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ union smb_fileinfo finfoT0; >+ union smb_fileinfo finfoT1; >+ >+ ok = get_basic_info_cb(private_data, &finfoT0); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT0"); >+ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ ok = write_data_cb(private_data); >+ torture_assert_ntstatus_ok(tctx, status); >+ >+ ok = get_basic_info_cb(private_data, &finfoT1); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT1"); >+ COMPARE_WRITE_TIME_EQUAL(finfoT1, finfoT0); >+ >+ if (finfo.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >+ "(write time update delay == %.2f) (wrong!)\n", >+ diff, used_delay / (double)1000000); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ changed = true; >+ break; >+ } >+ ok = get_basic_info_cb(private_data, &finfo1); >+ torture_assert_ntstatus_ok(tctx, status); >+ >+ COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); >+ smb_msleep(0.5 * msec); >+ } >+ changed = false; >+ GET_INFO_BOTH(finfo1, c2finfo1); >+ COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >+#endif >+done: >+ return ret; >+} >+ >+struct test_durable_open_delaywrite1_state { >+ struct torture_context *tctx; >+ struct smb2_tree *tree1; >+ struct smb2_tree *tree2; >+ struct smb2_handle *h1; >+ struct smb2_handle *h2; >+}; >+ >+static bool test_durable_open_delaywrite1_get_info(void *private_data, >+ union smb_fileinfo *finfo) >+{ >+ struct test_durable_open_delaywrite1_state *state = >+ (struct test_durable_open_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ union smb_fileinfo t1finfo; >+ union smb_fileinfo t2finfo; >+ bool ret = true; >+ >+ ZERO_STRUCTP(finfo); >+ >+ ZERO_STRUCT(t1finfo); >+ t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t1finfo.basic_info.in.file.handle = *state->h1; >+ >+ ZERO_STRUCT(t2finfo); >+ t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t2finfo.basic_info.in.file.handle = *state->h2; >+ >+ GET_INFO_FILE(state->tree2, t2finfo); >+ GET_INFO_FILE(state->tree1, t1finfo); >+ COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); >+ >+ finfo->basic_info.out = t1finfo.basic_info.out; >+done: >+ return ret; >+} >+ >+static bool test_durable_open_delaywrite1_write_data(void *private_data) >+{ >+ struct test_durable_open_delaywrite1_state *state = >+ (struct test_durable_open_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ struct smb2_write wr; >+ NTSTATUS status; >+ bool ret = true; >+ >+ ZERO_STRUCT(wr); >+ wr.in.file.handle = *state->h1; >+ wr.in.offset = 0; >+ wr.in.data = data_blob_const("x", 1); >+ status = smb2_write(state->tree1, &wr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ torture_assert_int_equal_goto(tctx, wr.out.nwritten, 1, >+ ret, done, "smb2_write"); >+ >+done: >+ return ret; >+} >+ >+static bool test_durable_open_delaywrite1(struct torture_context *tctx, >+ struct smb2_tree *tree1, >+ struct smb2_tree *tree2) >+{ >+ struct test_durable_open_delaywrite1_state state = { >+ .tctx = tctx, >+ .tree1 = tree1, >+ .tree2 = tree2, >+ }; >+ NTSTATUS status; >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ char fname[256]; >+ struct smb2_handle _h; >+ struct smb2_handle *h = NULL; >+ struct smb2_handle _h2; >+ struct smb2_handle *h2 = NULL; >+ struct smb2_create cr; >+ struct smb2_create cr2; >+ union smb_fileinfo finfoCR, finfo0, finfo1, finfo2, finfo3, finfo4, finfoT, finfoCL; >+ union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfo4, c2finfoT, c2finfoCL; >+ struct smb2_close cl; >+ struct smb2_close cl2; >+ struct smb2_write wr; >+ ssize_t written; >+ struct timeval start; >+ struct timeval end; >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ double normal_delay = 1000000; >+ //int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ bool ret = true; >+ bool changed = false; >+ bool ok; >+ >+ /* Choose a random name in case the state is left a little funky. */ >+ snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", >+ generate_random_str(tctx, 8)); >+ >+ smb2_util_unlink(tree1, fname); >+ >+ smb2_oplock_create_share(&cr, fname, >+ smb2_util_share_access(""), >+ smb2_util_oplock_level("b")); >+ cr.in.durable_open = true; >+ >+ status = smb2_create(tree1, mem_ctx, &cr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h = cr.out.file.handle; >+ h = &_h; >+ CHECK_CREATED(&cr, CREATED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr.out.oplock_level, smb2_util_oplock_level("b")); >+ CHECK_VAL(cr.out.durable_open, true); >+ CHECK_VAL(cr.out.durable_open_v2, false); >+ CHECK_VAL(cr.out.persistent_open, false); >+ //CHECK_VAL(io.out.timeout, io.in.timeout); >+ >+ // struct { >+ // NTTIME create_time; >+ // NTTIME access_time; >+ // NTTIME write_time; >+ // NTTIME change_time; >+ // uint32_t attrib; >+ // } out; >+ //} basic_info; >+ ZERO_STRUCT(finfoCR); >+ finfoCR.basic_info.out.create_time = cr.out.create_time; >+ finfoCR.basic_info.out.access_time = cr.out.access_time; >+ finfoCR.basic_info.out.write_time = cr.out.write_time; >+ finfoCR.basic_info.out.change_time = cr.out.change_time; >+ finfoCR.basic_info.out.attrib = cr.out.file_attr; >+ >+ ZERO_STRUCT(finfo0); >+ finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ finfo0.basic_info.in.file.handle = *h; >+ finfo1 = finfo0; >+ finfo2 = finfo0; >+ finfo3 = finfo0; >+ finfo4 = finfo0; >+ finfoT = finfo0; >+ >+ /* get the initial times */ >+ GET_INFO_FILE(tree1, finfo0); >+ COMPARE_WRITE_TIME_EQUAL(finfoCR, finfo0); >+ >+ ///* static body buffer 56 (0x38) bytes */ >+ //uint8_t security_flags; /* SMB2_SECURITY_* */ >+ //uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */ >+ //uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */ >+ //uint64_t create_flags; >+ //uint64_t reserved; >+ //uint32_t desired_access; >+ //uint32_t file_attributes; >+ //uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */ >+ //uint32_t create_disposition; /* NTCREATEX_DISP_* */ >+ //uint32_t create_options; /* NTCREATEX_OPTIONS_* */ >+ >+ ///* uint16_t fname_ofs */ >+ ///* uint16_t fname_size */ >+ ///* uint32_t blob_ofs; */ >+ ///* uint32_t blob_size; */ >+ >+ ///* dynamic body */ >+ //const char *fname; >+ >+ ///* now some optional parameters - encoded as tagged blobs */ >+ //struct smb_ea_list eas; >+ //uint64_t alloc_size; >+ //struct security_descriptor *sec_desc; >+ //bool durable_open; >+ //struct smb2_handle *durable_handle; >+ >+ ///* data for durable handle v2 */ >+ //bool durable_open_v2; >+ //struct GUID create_guid; >+ //bool persistent_open; >+ //uint32_t timeout; >+ //struct smb2_handle *durable_handle_v2; >+ >+ //bool query_maximal_access; >+ //NTTIME timewarp; >+ //bool query_on_disk_id; >+ //struct smb2_lease *lease_request; >+ //struct smb2_lease *lease_request_v2; >+ >+ //struct GUID *app_instance_id; >+ >+ ///* and any additional blobs the caller wants */ >+ //struct smb2_create_blobs blobs; >+ //} in; >+ //struct {// >+ //union smb_handle file; >+ >+ ///* static body buffer 88 (0x58) bytes */ >+ ///* uint16_t buffer_code; 0x59 = 0x58 + 1 */ >+ //uint8_t oplock_level; >+ //uint8_t reserved; >+ //uint32_t create_action; >+ //NTTIME create_time; >+ //NTTIME access_time; >+ //NTTIME write_time; >+ //NTTIME change_time; >+ //uint64_t alloc_size; >+ //uint64_t size; >+ //uint32_t file_attr; >+ //uint32_t reserved2; >+ ///* struct smb2_handle handle;*/ >+ ///* uint32_t blob_ofs; */ >+ ///* uint32_t blob_size; */ >+ >+ ///* optional return values matching tagged values in the call */ >+ //uint32_t maximal_access; >+ //uint8_t on_disk_id[32]; >+ //struct smb2_lease lease_response; >+ //struct smb2_lease lease_response_v2; >+ //bool durable_open; >+ >+ ///* durable handle v2 */ >+ //bool durable_open_v2; >+ //bool persistent_open; >+ //uint32_t timeout; >+ >+ ///* tagged blobs in the reply */ >+ //struct smb2_create_blobs blobs; >+ //} out; >+ cr2 = cr; >+ cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE;//FILE_READ_ATTRIBUTES; >+ cr2.in.durable_open = false; >+ cr2.in.oplock_level = 0; >+ cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >+ status = smb2_create(tree2, mem_ctx, &cr2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h2 = cr2.out.file.handle; >+ h2 = &_h2; >+ CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr2.out.oplock_level, 0); >+ CHECK_VAL(cr2.out.durable_open, false); >+ CHECK_VAL(cr2.out.durable_open_v2, false); >+ CHECK_VAL(cr2.out.persistent_open, false); >+ >+ ZERO_STRUCT(c2finfoCR); >+ c2finfoCR.basic_info.out.create_time = cr2.out.create_time; >+ c2finfoCR.basic_info.out.access_time = cr2.out.access_time; >+ c2finfoCR.basic_info.out.write_time = cr2.out.write_time; >+ c2finfoCR.basic_info.out.change_time = cr2.out.change_time; >+ c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; >+ >+ ZERO_STRUCT(c2finfo0); >+ c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ c2finfo0.basic_info.in.file.handle = *h2; >+ c2finfo1 = c2finfo0; >+ c2finfo2 = c2finfo0; >+ c2finfo3 = c2finfo0; >+ c2finfo4 = c2finfo0; >+ c2finfoT = c2finfo0; >+ >+ /* get the initial times */ >+ GET_INFO_FILE(tree2, c2finfo0); >+ COMPARE_WRITE_TIME_EQUAL(c2finfoCR, c2finfo0); >+ >+ state.h1 = h; >+ state.h2 = h2; >+ >+ ok = test_delay_writetime(tctx, used_delay, normal_delay, >+ "some description", >+ test_durable_open_delaywrite1_get_info, >+ test_durable_open_delaywrite1_write_data, >+ &state); >+ torture_assert(tctx, ok, "test_delay_writetime"); >+goto done; >+ /* >+ * make sure the write time is updated 2 seconds later >+ * calcuated from the first write >+ * (but expect upto 5 seconds extra time for a busy server) >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, 7 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ GET_INFO_BOTH(finfoT, c2finfoT); >+ ZERO_STRUCT(wr); >+ wr.in.file.handle = *h; >+ wr.in.offset = 0; >+ wr.in.data = data_blob_const("x", 1); >+ status = smb2_write(tree1, &wr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ written = wr.out.nwritten; >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo1, c2finfo1); >+ if (changed) { >+ COMPARE_WRITE_TIME_GREATER(finfo1, finfoT); >+ } >+ >+ if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ if (diff < (used_delay / (double)1000000)) { >+ torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >+ "(write time update delay == %.2f) (wrong!)\n", >+ diff, used_delay / (double)1000000); >+ ret = false; >+ break; >+ } >+ >+ torture_comment(tctx, "Server updated write_time after %.2f seconds " >+ "(correct)\n", >+ diff); >+ changed = true; >+ break; >+ } >+ COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); >+ smb_msleep(0.5 * msec); >+ } >+ >+ changed = false; >+ GET_INFO_BOTH(finfo1, c2finfo1); >+ COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ ZERO_STRUCT(wr); >+ wr.in.file.handle = *h; >+ wr.in.offset = 0; >+ wr.in.data = data_blob_const("x", 1); >+ status = smb2_write(tree1, &wr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ written = wr.out.nwritten; >+ if (written != 1) { >+ torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >+ ret = false; >+ goto done; >+ } >+ /* get the times after the write */ >+ GET_INFO_BOTH(finfo2, c2finfo2); >+ >+ if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ //break; >+ } >+ smb_msleep(0.1 * msec); >+ //smb_msleep(1 * msec); >+ } >+ >+ GET_INFO_BOTH(finfo2, c2finfo2); >+ //COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >+ COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >+ if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >+ torture_comment(tctx, "Server did not update write_time (correct)\n"); >+ } >+ >+ /* sure any further write doesn't update the write time */ >+ start = timeval_current(); >+ end = timeval_add(&start, 15 * sec, 0); >+ while (!timeval_expired(&end)) { >+ /* do a write */ >+ torture_comment(tctx, "Check on both file handles\n"); >+ GET_INFO_BOTH(finfo3, c2finfo3); >+ >+ if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) { >+ double diff = timeval_elapsed(&start); >+ torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >+ "(wrong!)\n", >+ diff); >+ ret = false; >+ break; >+ } >+ smb_msleep(0.1 * msec); >+ //smb_msleep(1 * msec); >+ } >+ GET_INFO_BOTH(finfo3, c2finfo3); >+ //COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ >+ /* sleep */ >+ torture_comment(tctx, "Sleep ...\n"); >+ smb_msleep(5 * msec); >+ torture_comment(tctx, "... continue\n"); >+ >+ GET_INFO_BOTH(finfo4, c2finfo4); >+ COMPARE_WRITE_TIME_EQUAL(finfo4, finfo3); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ >+ ZERO_STRUCT(cl); >+ cl.in.file.handle = *h; >+ cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(tree1, &cl); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ h = NULL; >+ ZERO_STRUCT(finfoCL); >+ finfoCL.basic_info.out.create_time = cl.out.create_time; >+ finfoCL.basic_info.out.access_time = cl.out.access_time; >+ finfoCL.basic_info.out.write_time = cl.out.write_time; >+ finfoCL.basic_info.out.change_time = cl.out.change_time; >+ finfoCL.basic_info.out.attrib = cl.out.file_attr; >+ COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); >+ >+ ZERO_STRUCT(cl2); >+ cl2.in.file.handle = *h2; >+ cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(tree2, &cl2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ h2 = NULL; >+ ZERO_STRUCT(c2finfoCL); >+ c2finfoCL.basic_info.out.create_time = cl2.out.create_time; >+ c2finfoCL.basic_info.out.access_time = cl2.out.access_time; >+ c2finfoCL.basic_info.out.write_time = cl2.out.write_time; >+ c2finfoCL.basic_info.out.change_time = cl2.out.change_time; >+ c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >+ COMPARE_WRITE_TIME_EQUAL(c2finfoCL, finfoCL); >+ //struct { >+ // /* static body buffer 60 (0x3C) bytes */ >+ // /* uint16_t buffer_code; 0x3C */ >+ // uint16_t flags; >+ // uint32_t _pad; >+ // NTTIME create_time; >+ // NTTIME access_time; >+ // NTTIME write_time; >+ // NTTIME change_time; >+ // uint64_t alloc_size; >+ // uint64_t size; >+ // uint32_t file_attr; >+ //} out; >+ >+ //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >+ // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >+ //} >+ ///* try a durable reconnect while the file is still open */ >+ //ZERO_STRUCT(io); >+ //io.in.fname = ""; >+ //io.in.durable_handle_v2 = h; >+ //io.in.create_guid = create_guid; >+ //status = smb2_create(tree1, mem_ctx, &io); >+ //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); >+ >+done: >+ if (h != NULL) { >+ smb2_util_close(tree1, *h); >+ } >+ >+ smb2_util_unlink(tree1, fname); >+ >+ talloc_free(tree1); >+ talloc_free(tree2); >+ >+ talloc_free(mem_ctx); >+ >+ return ret; >+} >+ > > struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) > { >@@ -2787,6 +3906,8 @@ struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) > test_durable_open_alloc_size); > torture_suite_add_1smb2_test(suite, "read-only", > test_durable_open_read_only); >+ torture_suite_add_2smb2_test(suite, "delaywrite1", >+ test_durable_open_delaywrite1); > > suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests"); > >-- >2.17.1 > > >From 18b68abbce9acd359d5ae08f51b9997d5b0209ae Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 15:16:21 +0200 >Subject: [PATCH 04/48] TODO source4/torture/smb2/durable_open.c > >--- > source4/torture/smb2/durable_open.c | 420 +++------------------------- > 1 file changed, 36 insertions(+), 384 deletions(-) > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 092294ff5341..58bbe3bf648f 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -2821,6 +2821,13 @@ done: > COMPARE_CREATE_TIME_EQUAL(given,correct); \ > } while (0) > >+#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >+ COMPARE_ACCESS_TIME_GREATER(given,correct); \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+} while (0) >+ > #define GET_INFO_FILE(tree, finfo) do { \ > struct timeval _atv; \ > struct timeval _wtv; \ >@@ -2889,366 +2896,6 @@ done: > } \ > } while (0) > >-#if 0 >-static bool test_delayed_write_update3(struct torture_context *tctx, >- struct smbcli_state *cli, >- struct smbcli_state *cli2) >-{ >- union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >- union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >- const char *fname = BASEDIR "\\torture_file3.txt"; >- int fnum1 = -1; >- bool ret = true; >- ssize_t written; >- struct timeval start; >- struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; >- >- torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >- >- torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >- >- torture_comment(tctx, "Open the file handle\n"); >- fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (fnum1 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >- >- finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- finfo0.basic_info.in.file.fnum = fnum1; >- finfo1 = finfo0; >- finfo2 = finfo0; >- finfo3 = finfo0; >- pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- pinfo0.basic_info.in.file.path = fname; >- pinfo1 = pinfo0; >- pinfo2 = pinfo0; >- pinfo3 = pinfo0; >- pinfo4 = pinfo0; >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo0,pinfo0); >- >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ >- start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_FILE(finfo1); >- >- if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(write time update delay == %.2f) (wrong!)\n", >- diff, used_delay / (double)1000000); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- break; >- } >- smb_msleep(0.5 * msec); >- } >- >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >- >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- >- if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- break; >- } >- smb_msleep(1 * msec); >- } >- >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >- if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update write_time (correct)\n"); >- } >- >- /* sleep */ >- smb_msleep(5 * msec); >- >- GET_INFO_BOTH(finfo3,pinfo3); >- COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >- >- /* >- * the close updates the write time to the time of the close >- * and not to the time of the last write! >- */ >- torture_comment(tctx, "Close the file handle\n"); >- smbcli_close(cli->tree, fnum1); >- fnum1 = -1; >- >- GET_INFO_PATH(pinfo4); >- COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); >- >- if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >- torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >- } >- >- done: >- if (fnum1 != -1) >- smbcli_close(cli->tree, fnum1); >- smbcli_unlink(cli->tree, fname); >- smbcli_deltree(cli->tree, BASEDIR); >- >- return ret; >-} >- >-/* >- * Show that a truncate write always updates the write time even >- * if an initial write has already updated the write time. >- */ >- >-static bool test_delayed_write_update3a(struct torture_context *tctx, >- struct smbcli_state *cli, >- struct smbcli_state *cli2) >-{ >- union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >- union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >- const char *fname = BASEDIR "\\torture_file3a.txt"; >- int fnum1 = -1; >- bool ret = true; >- ssize_t written; >- int i; >- struct timeval start; >- struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; >- >- torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); >- >- torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >- >- torture_comment(tctx, "Open the file handle\n"); >- fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (fnum1 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >- >- finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- finfo0.basic_info.in.file.fnum = fnum1; >- finfo1 = finfo0; >- finfo2 = finfo0; >- finfo3 = finfo0; >- pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- pinfo0.basic_info.in.file.path = fname; >- pinfo1 = pinfo0; >- pinfo2 = pinfo0; >- pinfo3 = pinfo0; >- pinfo4 = pinfo0; >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo0,pinfo0); >- >- /* >- * sleep some time, to demonstrate the handling of write times >- * doesn't depend on the time since the open >- */ >- smb_msleep(5 * msec); >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); >- >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ >- start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_FILE(finfo1); >- >- if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(1sec == %.2f) (wrong!)\n", >- diff, sec); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- break; >- } >- smb_msleep(0.5 * msec); >- } >- >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >- >- smb_msleep(3 * msec); >- >- /* >- * demonstrate that a truncate write always >- * updates the write time immediately >- */ >- for (i=0; i < 3; i++) { >- smb_msleep(2 * msec); >- /* do a write */ >- torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >- written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); >- if (written != 0) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >- finfo1 = finfo2; >- } >- >- smb_msleep(3 * msec); >- >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- >- if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- break; >- } >- smb_msleep(1 * msec); >- } >- >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >- if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update write_time (correct)\n"); >- } >- >- /* sleep */ >- smb_msleep(3 * msec); >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); >- >- /* >- * demonstrate that a truncate write always >- * updates the write time immediately >- */ >- for (i=0; i < 3; i++) { >- smb_msleep(2 * msec); >- /* do a write */ >- torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >- written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); >- if (written != 0) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >- finfo1 = finfo2; >- } >- >- /* sleep */ >- smb_msleep(3 * msec); >- >- GET_INFO_BOTH(finfo3,pinfo3); >- COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >- >- /* >- * the close doesn't update the write time >- */ >- torture_comment(tctx, "Close the file handle\n"); >- smbcli_close(cli->tree, fnum1); >- fnum1 = -1; >- >- GET_INFO_PATH(pinfo4); >- COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); >- >- if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); >- } >- >- done: >- if (fnum1 != -1) >- smbcli_close(cli->tree, fnum1); >- smbcli_unlink(cli->tree, fname); >- smbcli_deltree(cli->tree, BASEDIR); >- >- return ret; >-} >-#endif >- > static bool test_delay_writetime(struct torture_context *tctx, > double used_delay, > double normal_delay, >@@ -3264,7 +2911,11 @@ static bool test_delay_writetime(struct torture_context *tctx, > struct timeval start; > struct timeval end; > double sec = used_delay / normal_delay; >- int msec = 1000 * sec; >+ double msec = 1000 * sec; >+ double nsec = 1000 * msec; >+ double expected_delay = used_delay / nsec; >+ double min_delay = expected_delay * 0.1; >+ double max_delay = 5 * expected_delay; > bool ret = true; > bool ok; > >@@ -3278,13 +2929,13 @@ static bool test_delay_writetime(struct torture_context *tctx, > * Make sure the time doesn't change during the next 5 seconds > */ > start = timeval_current(); >- end = timeval_add(&start, 5 * sec, 0); >+ end = timeval_add(&start, max_delay * 1.25, 0); > while (!timeval_expired(&end)) { > smb_msleep(1 * msec); > torture_comment(tctx, "Check for no change\n"); > ok = get_basic_info_cb(private_data, &finfoT); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); > } > > ok = get_basic_info_cb(private_data, &finfoT); >@@ -3304,7 +2955,7 @@ static bool test_delay_writetime(struct torture_context *tctx, > (void)(&before_write == &after_write); > > start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >+ end = timeval_add(&start, max_delay * 2, 0); > while (!timeval_expired(&end)) { > struct timeval before_get; > struct timeval after_get; >@@ -3317,24 +2968,23 @@ static bool test_delay_writetime(struct torture_context *tctx, > (void)(&before_get == &after_get); > > if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- diff = timeval_elapsed2(&before_write, &after_get); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >- "(write time update delay == %.2f) (wrong!)\n", >- diff, used_delay / (double)1000000); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >+ double delayS = timeval_elapsed2(&after_write, &before_get); >+ double delayL = timeval_elapsed2(&before_write, &after_get); >+ >+ torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >+ "(min delay == %.2f, max delay == %.2f)\n", >+ delayS, delayL, min_delay, max_delay); >+ torture_assert(tctx, (delayL >= min_delay), >+ "Server updated write_time to early!"); >+ torture_assert(tctx, (delayS <= max_delay), >+ "Server didn't update write_time!"); >+ >+ COMPARE_WRITE_TIME_GREATER(finfoT, finfo0); > break; > } > >- COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >- smb_msleep(0.5 * msec); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >+ smb_msleep(0.01 * msec); > } > > ok = get_basic_info_cb(private_data, &finfo1); >@@ -3345,18 +2995,18 @@ static bool test_delay_writetime(struct torture_context *tctx, > * Make sure the time doesn't change during the next 5 seconds > */ > start = timeval_current(); >- end = timeval_add(&start, 5 * sec, 0); >+ end = timeval_add(&start, max_delay * 1.25, 0); > while (!timeval_expired(&end)) { > smb_msleep(1 * msec); >- torture_comment(tctx, "Check for no change\n"); >+ torture_comment(tctx, "Check for no additional change\n"); > ok = get_basic_info_cb(private_data, &finfoT); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); > } > > ok = get_basic_info_cb(private_data, &finfoT); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_WRITE_TIME_EQUAL(finfoT, finfo1); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); > #if 0 > start = timeval_current(); > end = timeval_add(&start, 7 * sec, 0); >@@ -3491,8 +3141,10 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > struct timeval start; > struct timeval end; > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); > double normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >+ //double normal_delay = 1000000; > //int normal_delay = 2000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; >-- >2.17.1 > > >From 1474b4c796ae6a7ae2f00e0142abe40b9670c2a7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 15:16:21 +0200 >Subject: [PATCH 05/48] TODO source4/torture/smb2/durable_open.c > >--- > source4/torture/smb2/durable_open.c | 41 +++++++++++++++++++---------- > 1 file changed, 27 insertions(+), 14 deletions(-) > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 58bbe3bf648f..61412558b35c 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -2793,20 +2793,22 @@ done: > COMPARE_WRITE_TIME_CMP(given,correct,!=) > #define COMPARE_WRITE_TIME_GREATER(given,correct) \ > COMPARE_WRITE_TIME_CMP(given,correct,<=) >-#define COMPARE_WRITE_TIME_LESS(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,>=) > > #define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ > COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ > } while (0) > #define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ > COMPARE_ACCESS_TIME_CMP(given,correct,!=) >+#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,<=) > > #define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ > COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ > } while (0) > #define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ > COMPARE_CHANGE_TIME_CMP(given,correct,!=) >+#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,<=) > > #define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ > COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >@@ -2815,17 +2817,27 @@ done: > COMPARE_CREATE_TIME_CMP(given,correct,!=) > > #define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ >- COMPARE_ACCESS_TIME_EQUAL(given,correct); \ > COMPARE_WRITE_TIME_EQUAL(given,correct); \ > COMPARE_CHANGE_TIME_EQUAL(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ > COMPARE_CREATE_TIME_EQUAL(given,correct); \ > } while (0) > > #define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >- COMPARE_ACCESS_TIME_GREATER(given,correct); \ > COMPARE_WRITE_TIME_GREATER(given,correct); \ > COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ > COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+} while (0) >+ >+#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_GREATER(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+ COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ > } while (0) > > #define GET_INFO_FILE(tree, finfo) do { \ >@@ -2914,7 +2926,7 @@ static bool test_delay_writetime(struct torture_context *tctx, > double msec = 1000 * sec; > double nsec = 1000 * msec; > double expected_delay = used_delay / nsec; >- double min_delay = expected_delay * 0.1; >+ double min_delay = expected_delay * 0.01; > double max_delay = 5 * expected_delay; > bool ret = true; > bool ok; >@@ -2942,11 +2954,6 @@ static bool test_delay_writetime(struct torture_context *tctx, > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); > COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); > >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ > torture_comment(tctx, "Do a write on the file handle\n"); > before_write = timeval_current(); > ok = write_data_cb(private_data); >@@ -2979,7 +2986,7 @@ static bool test_delay_writetime(struct torture_context *tctx, > torture_assert(tctx, (delayS <= max_delay), > "Server didn't update write_time!"); > >- COMPARE_WRITE_TIME_GREATER(finfoT, finfo0); >+ COMPARE_TIMES_AFTER_WRITE(finfoT, finfo0); > break; > } > >@@ -2989,7 +2996,7 @@ static bool test_delay_writetime(struct torture_context *tctx, > > ok = get_basic_info_cb(private_data, &finfo1); > torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); >- COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >+ COMPARE_TIMES_AFTER_WRITE(finfo1, finfo0); > > /* > * Make sure the time doesn't change during the next 5 seconds >@@ -3326,6 +3333,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > test_durable_open_delaywrite1_write_data, > &state); > torture_assert(tctx, ok, "test_delay_writetime"); >+goto close_handles; > goto done; > /* > * make sure the write time is updated 2 seconds later >@@ -3439,6 +3447,7 @@ goto done; > smb_msleep(0.1 * msec); > //smb_msleep(1 * msec); > } >+close_handles: > GET_INFO_BOTH(finfo3, c2finfo3); > //COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); > >@@ -3468,7 +3477,11 @@ goto done; > finfoCL.basic_info.out.write_time = cl.out.write_time; > finfoCL.basic_info.out.change_time = cl.out.change_time; > finfoCL.basic_info.out.attrib = cl.out.file_attr; >- COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); >+ //COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); >+ //COMPARE_TIMES_AFTER_CLOSE(finfoCL, finfo3); >+ >+ GET_INFO_FILE(tree2, c2finfo3); >+ COMPARE_ALL_TIMES_EQUAL(c2finfo3, finfoCL); > > ZERO_STRUCT(cl2); > cl2.in.file.handle = *h2; >@@ -3482,7 +3495,7 @@ goto done; > c2finfoCL.basic_info.out.write_time = cl2.out.write_time; > c2finfoCL.basic_info.out.change_time = cl2.out.change_time; > c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >- COMPARE_WRITE_TIME_EQUAL(c2finfoCL, finfoCL); >+ COMPARE_ALL_TIMES_EQUAL(c2finfoCL, finfoCL); > //struct { > // /* static body buffer 60 (0x3C) bytes */ > // /* uint16_t buffer_code; 0x3C */ >-- >2.17.1 > > >From e1f7c875d0ac0b7e0fd2cd5c13e597df173b8fcd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 15:16:21 +0200 >Subject: [PATCH 06/48] TODO source4/torture/smb2/durable_open.c > >--- > source4/torture/smb2/durable_open.c | 482 +++++++++------------------- > 1 file changed, 144 insertions(+), 338 deletions(-) > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 61412558b35c..0704fe4af8fd 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -2917,9 +2917,11 @@ static bool test_delay_writetime(struct torture_context *tctx, > bool (*write_data_cb)(void *private_data), > void *private_data) > { >- union smb_fileinfo finfo0, finfo1, finfoT; >+ union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; > struct timeval before_write; > struct timeval after_write; >+ struct timeval before_last_write; >+ struct timeval after_last_write; > struct timeval start; > struct timeval end; > double sec = used_delay / normal_delay; >@@ -2959,7 +2961,6 @@ static bool test_delay_writetime(struct torture_context *tctx, > ok = write_data_cb(private_data); > after_write = timeval_current(); > torture_assert(tctx, ok, "write_data_cb"); >- (void)(&before_write == &after_write); > > start = timeval_current(); > end = timeval_add(&start, max_delay * 2, 0); >@@ -2972,7 +2973,6 @@ static bool test_delay_writetime(struct torture_context *tctx, > ok = get_basic_info_cb(private_data, &finfoT); > after_get = timeval_current(); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- (void)(&before_get == &after_get); > > if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { > double delayS = timeval_elapsed2(&after_write, &before_get); >@@ -3014,50 +3014,81 @@ static bool test_delay_writetime(struct torture_context *tctx, > ok = get_basic_info_cb(private_data, &finfoT); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); > COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >-#if 0 >+ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ before_write = timeval_current(); >+ ok = write_data_cb(private_data); >+ after_write = timeval_current(); >+ torture_assert(tctx, ok, "write_data_cb"); >+ >+ ZERO_STRUCT(finfo2); >+ before_last_write = before_write; >+ after_last_write = after_write; > start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >+ end = timeval_add(&start, max_delay * 2, 0); > while (!timeval_expired(&end)) { >- union smb_fileinfo finfoT0; >- union smb_fileinfo finfoT1; >+ struct timeval before_get; >+ struct timeval after_get; > >- ok = get_basic_info_cb(private_data, &finfoT0); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT0"); >+ smb_msleep(0.01 * msec); > >- torture_comment(tctx, "Do a write on the file handle\n"); >- ok = write_data_cb(private_data); >- torture_assert_ntstatus_ok(tctx, status); >- >- ok = get_basic_info_cb(private_data, &finfoT1); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT1"); >- COMPARE_WRITE_TIME_EQUAL(finfoT1, finfoT0); >- >- if (finfo.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >- "(write time update delay == %.2f) (wrong!)\n", >- diff, used_delay / (double)1000000); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- changed = true; >+ torture_comment(tctx, "Wait for change\n"); >+ before_get = timeval_current(); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ after_get = timeval_current(); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ >+ if (finfoT.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double delayS = timeval_elapsed2(&after_write, &before_get); >+ double delayL = timeval_elapsed2(&before_write, &after_get); >+ >+ torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >+ "(min delay == %.2f, max delay == %.2f)\n", >+ delayS, delayL, min_delay, max_delay); >+ torture_assert(tctx, (delayL >= min_delay), >+ "Server updated write_time to early!"); >+ torture_assert(tctx, (delayS <= max_delay), >+ "Server didn't update write_time!"); >+ >+ COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); >+ before_write = before_last_write; >+ after_write = after_last_write; >+ finfo2 = finfoT; > break; > } >- ok = get_basic_info_cb(private_data, &finfo1); >- torture_assert_ntstatus_ok(tctx, status); > >- COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); >- smb_msleep(0.5 * msec); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >+ >+ torture_comment(tctx, "Write while waiting\n"); >+ before_last_write = timeval_current(); >+ ok = write_data_cb(private_data); >+ after_last_write = timeval_current(); >+ torture_assert(tctx, ok, "write_data_cb"); >+ } >+ >+ // We may get one additional change... >+ >+ ok = get_basic_info_cb(private_data, &finfo3); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); >+ COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); >+ >+ /* >+ * Make sure the time doesn't change during the next 5 seconds >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 1.25, 0); >+ while (!timeval_expired(&end)) { >+ smb_msleep(1 * msec); >+ torture_comment(tctx, "Check for no additional change\n"); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); > } >- changed = false; >- GET_INFO_BOTH(finfo1, c2finfo1); >- COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >-#endif >+ >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ > done: > return ret; > } >@@ -3092,6 +3123,13 @@ static bool test_durable_open_delaywrite1_get_info(void *private_data, > > GET_INFO_FILE(state->tree2, t2finfo); > GET_INFO_FILE(state->tree1, t1finfo); >+ if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { >+ /* >+ * There was a race, get it again on handle 2, >+ * but then they have to match. >+ */ >+ GET_INFO_FILE(state->tree2, t2finfo); >+ } > COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); > > finfo->basic_info.out = t1finfo.basic_info.out; >@@ -3133,20 +3171,16 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > NTSTATUS status; > TALLOC_CTX *mem_ctx = talloc_new(tctx); > char fname[256]; >- struct smb2_handle _h; >- struct smb2_handle *h = NULL; >+ struct smb2_handle _h1; >+ struct smb2_handle *h1 = NULL; > struct smb2_handle _h2; > struct smb2_handle *h2 = NULL; >- struct smb2_create cr; >+ struct smb2_create cr1; > struct smb2_create cr2; >- union smb_fileinfo finfoCR, finfo0, finfo1, finfo2, finfo3, finfo4, finfoT, finfoCL; >- union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfo4, c2finfoT, c2finfoCL; >- struct smb2_close cl; >+ union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; >+ union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; >+ struct smb2_close cl1; > struct smb2_close cl2; >- struct smb2_write wr; >- ssize_t written; >- struct timeval start; >- struct timeval end; > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); > double normal_delay = 1000000; >@@ -3156,7 +3190,6 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > bool ret = true; >- bool changed = false; > bool ok; > > /* Choose a random name in case the state is left a little funky. */ >@@ -3165,132 +3198,23 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > > smb2_util_unlink(tree1, fname); > >- smb2_oplock_create_share(&cr, fname, >+ smb2_oplock_create_share(&cr1, fname, > smb2_util_share_access(""), > smb2_util_oplock_level("b")); >- cr.in.durable_open = true; >+ cr1.in.durable_open = true; > >- status = smb2_create(tree1, mem_ctx, &cr); >+ status = smb2_create(tree1, mem_ctx, &cr1); > CHECK_STATUS(status, NT_STATUS_OK); >- _h = cr.out.file.handle; >- h = &_h; >- CHECK_CREATED(&cr, CREATED, FILE_ATTRIBUTE_ARCHIVE); >- CHECK_VAL(cr.out.oplock_level, smb2_util_oplock_level("b")); >- CHECK_VAL(cr.out.durable_open, true); >- CHECK_VAL(cr.out.durable_open_v2, false); >- CHECK_VAL(cr.out.persistent_open, false); >- //CHECK_VAL(io.out.timeout, io.in.timeout); >- >- // struct { >- // NTTIME create_time; >- // NTTIME access_time; >- // NTTIME write_time; >- // NTTIME change_time; >- // uint32_t attrib; >- // } out; >- //} basic_info; >- ZERO_STRUCT(finfoCR); >- finfoCR.basic_info.out.create_time = cr.out.create_time; >- finfoCR.basic_info.out.access_time = cr.out.access_time; >- finfoCR.basic_info.out.write_time = cr.out.write_time; >- finfoCR.basic_info.out.change_time = cr.out.change_time; >- finfoCR.basic_info.out.attrib = cr.out.file_attr; >- >- ZERO_STRUCT(finfo0); >- finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- finfo0.basic_info.in.file.handle = *h; >- finfo1 = finfo0; >- finfo2 = finfo0; >- finfo3 = finfo0; >- finfo4 = finfo0; >- finfoT = finfo0; >+ _h1 = cr1.out.file.handle; >+ h1 = &_h1; >+ CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); >+ CHECK_VAL(cr1.out.durable_open, true); >+ CHECK_VAL(cr1.out.durable_open_v2, false); >+ CHECK_VAL(cr1.out.persistent_open, false); > >- /* get the initial times */ >- GET_INFO_FILE(tree1, finfo0); >- COMPARE_WRITE_TIME_EQUAL(finfoCR, finfo0); >- >- ///* static body buffer 56 (0x38) bytes */ >- //uint8_t security_flags; /* SMB2_SECURITY_* */ >- //uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */ >- //uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */ >- //uint64_t create_flags; >- //uint64_t reserved; >- //uint32_t desired_access; >- //uint32_t file_attributes; >- //uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */ >- //uint32_t create_disposition; /* NTCREATEX_DISP_* */ >- //uint32_t create_options; /* NTCREATEX_OPTIONS_* */ >- >- ///* uint16_t fname_ofs */ >- ///* uint16_t fname_size */ >- ///* uint32_t blob_ofs; */ >- ///* uint32_t blob_size; */ >- >- ///* dynamic body */ >- //const char *fname; >- >- ///* now some optional parameters - encoded as tagged blobs */ >- //struct smb_ea_list eas; >- //uint64_t alloc_size; >- //struct security_descriptor *sec_desc; >- //bool durable_open; >- //struct smb2_handle *durable_handle; >- >- ///* data for durable handle v2 */ >- //bool durable_open_v2; >- //struct GUID create_guid; >- //bool persistent_open; >- //uint32_t timeout; >- //struct smb2_handle *durable_handle_v2; >- >- //bool query_maximal_access; >- //NTTIME timewarp; >- //bool query_on_disk_id; >- //struct smb2_lease *lease_request; >- //struct smb2_lease *lease_request_v2; >- >- //struct GUID *app_instance_id; >- >- ///* and any additional blobs the caller wants */ >- //struct smb2_create_blobs blobs; >- //} in; >- //struct {// >- //union smb_handle file; >- >- ///* static body buffer 88 (0x58) bytes */ >- ///* uint16_t buffer_code; 0x59 = 0x58 + 1 */ >- //uint8_t oplock_level; >- //uint8_t reserved; >- //uint32_t create_action; >- //NTTIME create_time; >- //NTTIME access_time; >- //NTTIME write_time; >- //NTTIME change_time; >- //uint64_t alloc_size; >- //uint64_t size; >- //uint32_t file_attr; >- //uint32_t reserved2; >- ///* struct smb2_handle handle;*/ >- ///* uint32_t blob_ofs; */ >- ///* uint32_t blob_size; */ >- >- ///* optional return values matching tagged values in the call */ >- //uint32_t maximal_access; >- //uint8_t on_disk_id[32]; >- //struct smb2_lease lease_response; >- //struct smb2_lease lease_response_v2; >- //bool durable_open; >- >- ///* durable handle v2 */ >- //bool durable_open_v2; >- //bool persistent_open; >- //uint32_t timeout; >- >- ///* tagged blobs in the reply */ >- //struct smb2_create_blobs blobs; >- //} out; >- cr2 = cr; >- cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE;//FILE_READ_ATTRIBUTES; >+ cr2 = cr1; >+ cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; > cr2.in.durable_open = false; > cr2.in.oplock_level = 0; > cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >@@ -3304,6 +3228,13 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > CHECK_VAL(cr2.out.durable_open_v2, false); > CHECK_VAL(cr2.out.persistent_open, false); > >+ ZERO_STRUCT(c1finfoCR); >+ c1finfoCR.basic_info.out.create_time = cr1.out.create_time; >+ c1finfoCR.basic_info.out.access_time = cr1.out.access_time; >+ c1finfoCR.basic_info.out.write_time = cr1.out.write_time; >+ c1finfoCR.basic_info.out.change_time = cr1.out.change_time; >+ c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; >+ > ZERO_STRUCT(c2finfoCR); > c2finfoCR.basic_info.out.create_time = cr2.out.create_time; > c2finfoCR.basic_info.out.access_time = cr2.out.access_time; >@@ -3311,153 +3242,50 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > c2finfoCR.basic_info.out.change_time = cr2.out.change_time; > c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; > >+ COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); >+ >+ ZERO_STRUCT(c1finfo0); >+ c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ c1finfo0.basic_info.in.file.handle = *h1; >+ c1finfo1 = c1finfo0; >+ c1finfo2 = c1finfo0; >+ > ZERO_STRUCT(c2finfo0); > c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; > c2finfo0.basic_info.in.file.handle = *h2; > c2finfo1 = c2finfo0; > c2finfo2 = c2finfo0; > c2finfo3 = c2finfo0; >- c2finfo4 = c2finfo0; >- c2finfoT = c2finfo0; > >- /* get the initial times */ >- GET_INFO_FILE(tree2, c2finfo0); >- COMPARE_WRITE_TIME_EQUAL(c2finfoCR, c2finfo0); >+ GET_INFO_BOTH(c1finfo0, c2finfo0); >+ COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); > >- state.h1 = h; >+ state.h1 = h1; > state.h2 = h2; > > ok = test_delay_writetime(tctx, used_delay, normal_delay, >- "some description", >+ "run1", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > &state); >- torture_assert(tctx, ok, "test_delay_writetime"); >-goto close_handles; >-goto done; >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ >- start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- GET_INFO_BOTH(finfoT, c2finfoT); >- ZERO_STRUCT(wr); >- wr.in.file.handle = *h; >- wr.in.offset = 0; >- wr.in.data = data_blob_const("x", 1); >- status = smb2_write(tree1, &wr); >- CHECK_STATUS(status, NT_STATUS_OK); >- written = wr.out.nwritten; >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo1, c2finfo1); >- if (changed) { >- COMPARE_WRITE_TIME_GREATER(finfo1, finfoT); >- } >- >- if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >- "(write time update delay == %.2f) (wrong!)\n", >- diff, used_delay / (double)1000000); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- changed = true; >- break; >- } >- COMPARE_WRITE_TIME_EQUAL(finfo1, finfoT); >- smb_msleep(0.5 * msec); >- } >- >- changed = false; >- GET_INFO_BOTH(finfo1, c2finfo1); >- COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >- >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- ZERO_STRUCT(wr); >- wr.in.file.handle = *h; >- wr.in.offset = 0; >- wr.in.data = data_blob_const("x", 1); >- status = smb2_write(tree1, &wr); >- CHECK_STATUS(status, NT_STATUS_OK); >- written = wr.out.nwritten; >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2, c2finfo2); >- >- if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- //break; >- } >- smb_msleep(0.1 * msec); >- //smb_msleep(1 * msec); >- } >- >- GET_INFO_BOTH(finfo2, c2finfo2); >- //COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >- COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >- if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update write_time (correct)\n"); >- } >+ torture_assert(tctx, ok, "test_delay_writetime(1)"); >+ ok = test_delay_writetime(tctx, used_delay, normal_delay, >+ "run2", >+ test_durable_open_delaywrite1_get_info, >+ test_durable_open_delaywrite1_write_data, >+ &state); >+ torture_assert(tctx, ok, "test_delay_writetime(2)"); > >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Check on both file handles\n"); >- GET_INFO_BOTH(finfo3, c2finfo3); >- >- if (finfo3.basic_info.out.write_time > finfo2.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, __location__": Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- break; >- } >- smb_msleep(0.1 * msec); >- //smb_msleep(1 * msec); >- } >-close_handles: >- GET_INFO_BOTH(finfo3, c2finfo3); >- //COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >+ GET_INFO_BOTH(c1finfo1, c2finfo1); >+ COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); > > /* sleep */ > torture_comment(tctx, "Sleep ...\n"); > smb_msleep(5 * msec); > torture_comment(tctx, "... continue\n"); > >- GET_INFO_BOTH(finfo4, c2finfo4); >- COMPARE_WRITE_TIME_EQUAL(finfo4, finfo3); >+ GET_INFO_BOTH(c1finfo2, c2finfo2); >+ COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); > > /* > * the close updates the write time to the time of the close >@@ -3465,23 +3293,22 @@ close_handles: > */ > torture_comment(tctx, "Close the file handle\n"); > >- ZERO_STRUCT(cl); >- cl.in.file.handle = *h; >- cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(tree1, &cl); >+ ZERO_STRUCT(cl1); >+ cl1.in.file.handle = *h1; >+ cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(tree1, &cl1); > CHECK_STATUS(status, NT_STATUS_OK); >- h = NULL; >- ZERO_STRUCT(finfoCL); >- finfoCL.basic_info.out.create_time = cl.out.create_time; >- finfoCL.basic_info.out.access_time = cl.out.access_time; >- finfoCL.basic_info.out.write_time = cl.out.write_time; >- finfoCL.basic_info.out.change_time = cl.out.change_time; >- finfoCL.basic_info.out.attrib = cl.out.file_attr; >- //COMPARE_WRITE_TIME_GREATER(finfoCL, finfo3); >- //COMPARE_TIMES_AFTER_CLOSE(finfoCL, finfo3); >+ h1 = NULL; >+ ZERO_STRUCT(c1finfoCL); >+ c1finfoCL.basic_info.out.create_time = cl1.out.create_time; >+ c1finfoCL.basic_info.out.access_time = cl1.out.access_time; >+ c1finfoCL.basic_info.out.write_time = cl1.out.write_time; >+ c1finfoCL.basic_info.out.change_time = cl1.out.change_time; >+ c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >+ COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); > > GET_INFO_FILE(tree2, c2finfo3); >- COMPARE_ALL_TIMES_EQUAL(c2finfo3, finfoCL); >+ COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); > > ZERO_STRUCT(cl2); > cl2.in.file.handle = *h2; >@@ -3495,35 +3322,14 @@ close_handles: > c2finfoCL.basic_info.out.write_time = cl2.out.write_time; > c2finfoCL.basic_info.out.change_time = cl2.out.change_time; > c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >- COMPARE_ALL_TIMES_EQUAL(c2finfoCL, finfoCL); >- //struct { >- // /* static body buffer 60 (0x3C) bytes */ >- // /* uint16_t buffer_code; 0x3C */ >- // uint16_t flags; >- // uint32_t _pad; >- // NTTIME create_time; >- // NTTIME access_time; >- // NTTIME write_time; >- // NTTIME change_time; >- // uint64_t alloc_size; >- // uint64_t size; >- // uint32_t file_attr; >- //} out; >- >- //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >- // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >- //} >- ///* try a durable reconnect while the file is still open */ >- //ZERO_STRUCT(io); >- //io.in.fname = ""; >- //io.in.durable_handle_v2 = h; >- //io.in.create_guid = create_guid; >- //status = smb2_create(tree1, mem_ctx, &io); >- //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); >+ COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); > > done: >- if (h != NULL) { >- smb2_util_close(tree1, *h); >+ if (h1 != NULL) { >+ smb2_util_close(tree1, *h1); >+ } >+ if (h2 != NULL) { >+ smb2_util_close(tree2, *h2); > } > > smb2_util_unlink(tree1, fname); >-- >2.17.1 > > >From 1c30035fc20bd918a20f77757e4c2fb7c26367e1 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 21:45:50 +0200 >Subject: [PATCH 07/48] smbd: SMB2 write time mode...??? > >--- > source3/smbd/fileio.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index 1fe806e058d2..c75b8a4dcef2 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -178,6 +178,10 @@ void fsp_flush_write_time_update(struct files_struct *fsp) > > /* Remove the timed event handler. */ > TALLOC_FREE(fsp->update_write_time_event); >+ if (fsp->conn->sconn->client->connections->protocol >= PROTOCOL_SMB2_02) { >+ fsp->update_write_time_triggered = false; >+ fsp->update_write_time_on_close = false; >+ } > } > > static void update_write_time_handler(struct tevent_context *ctx, >@@ -287,6 +291,7 @@ void mark_file_modified(files_struct *fsp) > int dosmode; > > if (fsp->modified) { >+ trigger_write_time_update(fsp); > return; > } > >-- >2.17.1 > > >From 37efff59337c94cb362185bcf222494148f1b58c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 14 Aug 2018 21:51:08 +0200 >Subject: [PATCH 08/48] revert source4/torture/smb2/durable_v2_open.c > >--- > source4/torture/smb2/durable_v2_open.c | 669 ------------------------- > 1 file changed, 669 deletions(-) > >diff --git a/source4/torture/smb2/durable_v2_open.c b/source4/torture/smb2/durable_v2_open.c >index df755bbe286b..0a928ec8c265 100644 >--- a/source4/torture/smb2/durable_v2_open.c >+++ b/source4/torture/smb2/durable_v2_open.c >@@ -2011,674 +2011,6 @@ bool test_persistent_open_lease(struct torture_context *tctx, > return ret; > } > >-#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >- uint64_t r = 10*1000*1000; \ >- NTTIME g = (given).basic_info.out.write_time; \ >- NTTIME gr = (g / r) * r; \ >- NTTIME _c = (correct).basic_info.out.write_time; \ >- NTTIME cr = (_c / r) * r; \ >- bool strict = torture_setting_bool(tctx, "strict mode", false); \ >- bool err = false; \ >- if (strict && (g cmp _c)) { \ >- err = true; \ >- } else if ((g cmp _c) && (gr cmp cr)) { \ >- /* handle filesystem without high resolution timestamps */ \ >- err = true; \ >- } \ >- if (err) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": wrong write_time (%s)%s(%llu) %s (%s)%s(%llu)", \ >- #given, nt_time_string(tctx, g), (unsigned long long)g, \ >- #cmp, #correct, nt_time_string(tctx, _c), (unsigned long long)_c); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >-#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,!=) >-#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,<=) >-#define COMPARE_WRITE_TIME_LESS(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,>=) >- >-#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >- NTTIME g = (given).basic_info.out.access_time; \ >- NTTIME c = (correct).basic_info.out.access_time; \ >- if (g cmp c) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": wrong access_time (%s)%s %s (%s)%s", \ >- #given, nt_time_string(tctx, g), \ >- #cmp, #correct, nt_time_string(tctx, c)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >-#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >- COMPARE_ACCESS_TIME_CMP(given,correct,!=) >- >-#define COMPARE_BOTH_TIMES_EQUAL(given,correct) do { \ >- COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >- COMPARE_WRITE_TIME_EQUAL(given,correct); \ >-} while (0) >- >-#define GET_INFO_FILE(finfo) do { \ >- NTSTATUS _status; \ >- _status = smb2_getinfo_file(tree, tctx, &finfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- ret = false; \ >- torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ >- nt_errstr(_status)); \ >- goto done; \ >- } \ >- torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ >- nt_time_string(tctx, finfo.basic_info.out.access_time), \ >- nt_time_string(tctx, finfo.basic_info.out.write_time)); \ >-} while (0) >- >-#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ >- NTSTATUS _status; \ >- union smb_setfileinfo sfinfo; \ >- sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >- sfinfo.basic_info.in.file.fnum = tfnum; \ >- sfinfo.basic_info.in.create_time = 0; \ >- sfinfo.basic_info.in.access_time = 0; \ >- unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >- sfinfo.basic_info.in.change_time = 0; \ >- sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >- _status = smb_raw_setfileinfo(tree, &sfinfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >- nt_errstr(_status)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >-#define SET_INFO_FILE(finfo, wrtime) \ >- SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) >- >-#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ >- NTSTATUS _status; \ >- union smb_setfileinfo sfinfo; \ >- sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >- sfinfo.basic_info.in.file.fnum = tfnum; \ >- sfinfo.basic_info.in.create_time = 0; \ >- sfinfo.basic_info.in.access_time = 0; \ >- unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >- sfinfo.basic_info.in.write_time += (ns); \ >- sfinfo.basic_info.in.change_time = 0; \ >- sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >- _status = smb_raw_setfileinfo(tree, &sfinfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >- nt_errstr(_status)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >- >-#if 0 >-static bool test_delayed_write_update3(struct torture_context *tctx, >- struct smbcli_state *cli, >- struct smbcli_state *cli2) >-{ >- union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >- union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >- const char *fname = BASEDIR "\\torture_file3.txt"; >- int fnum1 = -1; >- bool ret = true; >- ssize_t written; >- struct timeval start; >- struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; >- >- torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >- >- torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >- >- torture_comment(tctx, "Open the file handle\n"); >- fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (fnum1 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >- >- finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- finfo0.basic_info.in.file.fnum = fnum1; >- finfo1 = finfo0; >- finfo2 = finfo0; >- finfo3 = finfo0; >- pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- pinfo0.basic_info.in.file.path = fname; >- pinfo1 = pinfo0; >- pinfo2 = pinfo0; >- pinfo3 = pinfo0; >- pinfo4 = pinfo0; >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo0,pinfo0); >- >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ >- start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_FILE(finfo1); >- >- if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(write time update delay == %.2f) (wrong!)\n", >- diff, used_delay / (double)1000000); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- break; >- } >- smb_msleep(0.5 * msec); >- } >- >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >- >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- >- if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- break; >- } >- smb_msleep(1 * msec); >- } >- >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >- if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update write_time (correct)\n"); >- } >- >- /* sleep */ >- smb_msleep(5 * msec); >- >- GET_INFO_BOTH(finfo3,pinfo3); >- COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >- >- /* >- * the close updates the write time to the time of the close >- * and not to the time of the last write! >- */ >- torture_comment(tctx, "Close the file handle\n"); >- smbcli_close(cli->tree, fnum1); >- fnum1 = -1; >- >- GET_INFO_PATH(pinfo4); >- COMPARE_WRITE_TIME_GREATER(pinfo4, pinfo3); >- >- if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >- torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >- } >- >- done: >- if (fnum1 != -1) >- smbcli_close(cli->tree, fnum1); >- smbcli_unlink(cli->tree, fname); >- smbcli_deltree(cli->tree, BASEDIR); >- >- return ret; >-} >- >-/* >- * Show that a truncate write always updates the write time even >- * if an initial write has already updated the write time. >- */ >- >-static bool test_delayed_write_update3a(struct torture_context *tctx, >- struct smbcli_state *cli, >- struct smbcli_state *cli2) >-{ >- union smb_fileinfo finfo0, finfo1, finfo2, finfo3; >- union smb_fileinfo pinfo0, pinfo1, pinfo2, pinfo3, pinfo4; >- const char *fname = BASEDIR "\\torture_file3a.txt"; >- int fnum1 = -1; >- bool ret = true; >- ssize_t written; >- int i; >- struct timeval start; >- struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; >- >- torture_comment(tctx, "\nRunning test_delayed_write_update3a\n"); >- >- torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >- >- torture_comment(tctx, "Open the file handle\n"); >- fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (fnum1 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >- >- finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- finfo0.basic_info.in.file.fnum = fnum1; >- finfo1 = finfo0; >- finfo2 = finfo0; >- finfo3 = finfo0; >- pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- pinfo0.basic_info.in.file.path = fname; >- pinfo1 = pinfo0; >- pinfo2 = pinfo0; >- pinfo3 = pinfo0; >- pinfo4 = pinfo0; >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo0,pinfo0); >- >- /* >- * sleep some time, to demonstrate the handling of write times >- * doesn't depend on the time since the open >- */ >- smb_msleep(5 * msec); >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_EQUAL(finfo1, finfo0); >- >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ >- start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_FILE(finfo1); >- >- if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(1sec == %.2f) (wrong!)\n", >- diff, sec); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- break; >- } >- smb_msleep(0.5 * msec); >- } >- >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >- >- smb_msleep(3 * msec); >- >- /* >- * demonstrate that a truncate write always >- * updates the write time immediately >- */ >- for (i=0; i < 3; i++) { >- smb_msleep(2 * msec); >- /* do a write */ >- torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >- written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); >- if (written != 0) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >- finfo1 = finfo2; >- } >- >- smb_msleep(3 * msec); >- >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- >- if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- break; >- } >- smb_msleep(1 * msec); >- } >- >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >- if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update write_time (correct)\n"); >- } >- >- /* sleep */ >- smb_msleep(3 * msec); >- >- /* get the initial times */ >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_EQUAL(finfo1, finfo2); >- >- /* >- * demonstrate that a truncate write always >- * updates the write time immediately >- */ >- for (i=0; i < 3; i++) { >- smb_msleep(2 * msec); >- /* do a write */ >- torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); >- written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); >- if (written != 0) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 0", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_BOTH(finfo2,pinfo2); >- COMPARE_WRITE_TIME_GREATER(finfo2, finfo1); >- finfo1 = finfo2; >- } >- >- /* sleep */ >- smb_msleep(3 * msec); >- >- GET_INFO_BOTH(finfo3,pinfo3); >- COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >- >- /* >- * the close doesn't update the write time >- */ >- torture_comment(tctx, "Close the file handle\n"); >- smbcli_close(cli->tree, fnum1); >- fnum1 = -1; >- >- GET_INFO_PATH(pinfo4); >- COMPARE_WRITE_TIME_EQUAL(pinfo4, pinfo3); >- >- if (pinfo4.basic_info.out.write_time == pinfo3.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update the write_time on close (correct)\n"); >- } >- >- done: >- if (fnum1 != -1) >- smbcli_close(cli->tree, fnum1); >- smbcli_unlink(cli->tree, fname); >- smbcli_deltree(cli->tree, BASEDIR); >- >- return ret; >-} >-#endif >- >- >-static bool test_durable_v2_delaywrite1(struct torture_context *tctx, >- struct smb2_tree *tree) >-{ >- NTSTATUS status; >- TALLOC_CTX *mem_ctx = talloc_new(tctx); >- char fname[256]; >- struct smb2_handle _h; >- struct smb2_handle *h = NULL; >- struct smb2_create io; >- struct GUID create_guid = GUID_random(); >- union smb_fileinfo finfo0; >- union smb_fileinfo finfo1; >- union smb_fileinfo finfo2; >- union smb_fileinfo finfo3; >- struct smb2_close cl; >- struct smb2_write wr; >- ssize_t written; >- struct timeval start; >- struct timeval end; >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >- //int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; >- bool ret = true; >- >- /* Choose a random name in case the state is left a little funky. */ >- snprintf(fname, 256, "durable_v2_delaywrite1_%s.dat", >- generate_random_str(tctx, 8)); >- >- smb2_util_unlink(tree, fname); >- >- smb2_oplock_create_share(&io, fname, >- smb2_util_share_access(""), >- smb2_util_oplock_level("b")); >- io.in.durable_open = false; >- io.in.durable_open_v2 = true; >- io.in.persistent_open = false; >- io.in.create_guid = create_guid; >- io.in.timeout = UINT32_MAX; >- >- status = smb2_create(tree, mem_ctx, &io); >- CHECK_STATUS(status, NT_STATUS_OK); >- _h = io.out.file.handle; >- h = &_h; >- CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); >- CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b")); >- CHECK_VAL(io.out.durable_open, false); >- CHECK_VAL(io.out.durable_open_v2, true); >- CHECK_VAL(io.out.persistent_open, false); >- //CHECK_VAL(io.out.timeout, io.in.timeout); >- >- ZERO_STRUCT(finfo0); >- finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- finfo0.basic_info.in.file.handle = *h; >- finfo1 = finfo0; >- finfo2 = finfo0; >- finfo3 = finfo0; >- >- /* get the initial times */ >- GET_INFO_FILE(finfo0); >- >- /* >- * make sure the write time is updated 2 seconds later >- * calcuated from the first write >- * (but expect upto 5 seconds extra time for a busy server) >- */ >- start = timeval_current(); >- end = timeval_add(&start, 7 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- ZERO_STRUCT(wr); >- wr.in.file.handle = *h; >- wr.in.offset = 0; >- wr.in.data = data_blob_const("x", 1); >- status = smb2_write(tree, &wr); >- CHECK_STATUS(status, NT_STATUS_OK); >- written = wr.out.nwritten; >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_FILE(finfo1); >- >- if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(write time update delay == %.2f) (wrong!)\n", >- diff, used_delay / (double)1000000); >- ret = false; >- break; >- } >- >- torture_comment(tctx, "Server updated write_time after %.2f seconds " >- "(correct)\n", >- diff); >- break; >- } >- smb_msleep(0.5 * msec); >- } >- >- GET_INFO_FILE(finfo1); >- COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >- >- /* sure any further write doesn't update the write time */ >- start = timeval_current(); >- end = timeval_add(&start, 15 * sec, 0); >- while (!timeval_expired(&end)) { >- /* do a write */ >- torture_comment(tctx, "Do a write on the file handle\n"); >- ZERO_STRUCT(wr); >- wr.in.file.handle = *h; >- wr.in.offset = 0; >- wr.in.data = data_blob_const("x", 1); >- status = smb2_write(tree, &wr); >- CHECK_STATUS(status, NT_STATUS_OK); >- written = wr.out.nwritten; >- if (written != 1) { >- torture_result(tctx, TORTURE_FAIL, __location__": written gave %d - should have been 1", (int)written); >- ret = false; >- goto done; >- } >- /* get the times after the write */ >- GET_INFO_FILE(finfo2); >- >- if (finfo2.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double diff = timeval_elapsed(&start); >- torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " >- "(wrong!)\n", >- diff); >- ret = false; >- break; >- } >- smb_msleep(1 * msec); >- } >- >- GET_INFO_FILE(finfo2); >- COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); >- if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { >- torture_comment(tctx, "Server did not update write_time (correct)\n"); >- } >- >- /* sleep */ >- smb_msleep(5 * msec); >- >- GET_INFO_FILE(finfo3); >- COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); >- >- /* >- * the close updates the write time to the time of the close >- * and not to the time of the last write! >- */ >- torture_comment(tctx, "Close the file handle\n"); >- >- ZERO_STRUCT(cl); >- cl.in.file.handle = *h; >- cl.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(tree, &cl); >- CHECK_STATUS(status, NT_STATUS_OK); >- h = NULL; >- //struct { >- // /* static body buffer 60 (0x3C) bytes */ >- // /* uint16_t buffer_code; 0x3C */ >- // uint16_t flags; >- // uint32_t _pad; >- // NTTIME create_time; >- // NTTIME access_time; >- // NTTIME write_time; >- // NTTIME change_time; >- // uint64_t alloc_size; >- // uint64_t size; >- // uint32_t file_attr; >- //} out; >- >- //if (pinfo4.basic_info.out.write_time > pinfo3.basic_info.out.write_time) { >- // torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >- //} >- ///* try a durable reconnect while the file is still open */ >- //ZERO_STRUCT(io); >- //io.in.fname = ""; >- //io.in.durable_handle_v2 = h; >- //io.in.create_guid = create_guid; >- //status = smb2_create(tree, mem_ctx, &io); >- //CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); >- >-done: >- if (h != NULL) { >- smb2_util_close(tree, *h); >- } >- >- smb2_util_unlink(tree, fname); >- >- talloc_free(tree); >- >- talloc_free(mem_ctx); >- >- return ret; >-} >- > struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) > { > struct torture_suite *suite = >@@ -2698,7 +2030,6 @@ struct torture_suite *torture_smb2_durable_v2_open_init(TALLOC_CTX *ctx) > torture_suite_add_2smb2_test(suite, "app-instance", test_durable_v2_open_app_instance); > torture_suite_add_1smb2_test(suite, "persistent-open-oplock", test_persistent_open_oplock); > torture_suite_add_1smb2_test(suite, "persistent-open-lease", test_persistent_open_lease); >- torture_suite_add_1smb2_test(suite, "delaywrite1", test_durable_v2_delaywrite1); > > suite->description = talloc_strdup(suite, "SMB2-DURABLE-V2-OPEN tests"); > >-- >2.17.1 > > >From f519ffb5a23974e793817d8ae9e5f2bfa81cc02b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 08:06:55 +0200 >Subject: [PATCH 09/48] source4/torture/util_writetime.c > >--- > source4/torture/smb2/durable_open.c | 198 +----------------- > source4/torture/util.h | 8 + > source4/torture/util_writetime.c | 300 ++++++++++++++++++++++++++++ > source4/torture/wscript_build | 2 +- > 4 files changed, 315 insertions(+), 193 deletions(-) > create mode 100644 source4/torture/util_writetime.c > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 0704fe4af8fd..814f4944152d 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -25,9 +25,9 @@ > #include "libcli/smb2/smb2_calls.h" > #include "../libcli/smb/smbXcli_base.h" > #include "torture/torture.h" >+#include "torture/util.h" > #include "torture/smb2/proto.h" >-#include "../libcli/smb/smbXcli_base.h" >-#include "lib/util/time_basic.h" >+#include "../lib/util/time_basic.h" > > #define CHECK_VAL(v, correct) do { \ > if ((v) != (correct)) { \ >@@ -2908,191 +2908,6 @@ done: > } \ > } while (0) > >-static bool test_delay_writetime(struct torture_context *tctx, >- double used_delay, >- double normal_delay, >- const char *description, >- bool (*get_basic_info_cb)(void *private_data, >- union smb_fileinfo *finfo), >- bool (*write_data_cb)(void *private_data), >- void *private_data) >-{ >- union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; >- struct timeval before_write; >- struct timeval after_write; >- struct timeval before_last_write; >- struct timeval after_last_write; >- struct timeval start; >- struct timeval end; >- double sec = used_delay / normal_delay; >- double msec = 1000 * sec; >- double nsec = 1000 * msec; >- double expected_delay = used_delay / nsec; >- double min_delay = expected_delay * 0.01; >- double max_delay = 5 * expected_delay; >- bool ret = true; >- bool ok; >- >- torture_comment(tctx, "START: %s\n", description); >- >- /* get the initial times */ >- ok = get_basic_info_cb(private_data, &finfo0); >- torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); >- >- /* >- * Make sure the time doesn't change during the next 5 seconds >- */ >- start = timeval_current(); >- end = timeval_add(&start, max_delay * 1.25, 0); >- while (!timeval_expired(&end)) { >- smb_msleep(1 * msec); >- torture_comment(tctx, "Check for no change\n"); >- ok = get_basic_info_cb(private_data, &finfoT); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >- } >- >- ok = get_basic_info_cb(private_data, &finfoT); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >- >- torture_comment(tctx, "Do a write on the file handle\n"); >- before_write = timeval_current(); >- ok = write_data_cb(private_data); >- after_write = timeval_current(); >- torture_assert(tctx, ok, "write_data_cb"); >- >- start = timeval_current(); >- end = timeval_add(&start, max_delay * 2, 0); >- while (!timeval_expired(&end)) { >- struct timeval before_get; >- struct timeval after_get; >- >- torture_comment(tctx, "Wait for change\n"); >- before_get = timeval_current(); >- ok = get_basic_info_cb(private_data, &finfoT); >- after_get = timeval_current(); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- >- if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >- double delayS = timeval_elapsed2(&after_write, &before_get); >- double delayL = timeval_elapsed2(&before_write, &after_get); >- >- torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >- "(min delay == %.2f, max delay == %.2f)\n", >- delayS, delayL, min_delay, max_delay); >- torture_assert(tctx, (delayL >= min_delay), >- "Server updated write_time to early!"); >- torture_assert(tctx, (delayS <= max_delay), >- "Server didn't update write_time!"); >- >- COMPARE_TIMES_AFTER_WRITE(finfoT, finfo0); >- break; >- } >- >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >- smb_msleep(0.01 * msec); >- } >- >- ok = get_basic_info_cb(private_data, &finfo1); >- torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); >- COMPARE_TIMES_AFTER_WRITE(finfo1, finfo0); >- >- /* >- * Make sure the time doesn't change during the next 5 seconds >- */ >- start = timeval_current(); >- end = timeval_add(&start, max_delay * 1.25, 0); >- while (!timeval_expired(&end)) { >- smb_msleep(1 * msec); >- torture_comment(tctx, "Check for no additional change\n"); >- ok = get_basic_info_cb(private_data, &finfoT); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >- } >- >- ok = get_basic_info_cb(private_data, &finfoT); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >- >- torture_comment(tctx, "Do a write on the file handle\n"); >- before_write = timeval_current(); >- ok = write_data_cb(private_data); >- after_write = timeval_current(); >- torture_assert(tctx, ok, "write_data_cb"); >- >- ZERO_STRUCT(finfo2); >- before_last_write = before_write; >- after_last_write = after_write; >- start = timeval_current(); >- end = timeval_add(&start, max_delay * 2, 0); >- while (!timeval_expired(&end)) { >- struct timeval before_get; >- struct timeval after_get; >- >- smb_msleep(0.01 * msec); >- >- torture_comment(tctx, "Wait for change\n"); >- before_get = timeval_current(); >- ok = get_basic_info_cb(private_data, &finfoT); >- after_get = timeval_current(); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- >- if (finfoT.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >- double delayS = timeval_elapsed2(&after_write, &before_get); >- double delayL = timeval_elapsed2(&before_write, &after_get); >- >- torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >- "(min delay == %.2f, max delay == %.2f)\n", >- delayS, delayL, min_delay, max_delay); >- torture_assert(tctx, (delayL >= min_delay), >- "Server updated write_time to early!"); >- torture_assert(tctx, (delayS <= max_delay), >- "Server didn't update write_time!"); >- >- COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); >- before_write = before_last_write; >- after_write = after_last_write; >- finfo2 = finfoT; >- break; >- } >- >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >- >- torture_comment(tctx, "Write while waiting\n"); >- before_last_write = timeval_current(); >- ok = write_data_cb(private_data); >- after_last_write = timeval_current(); >- torture_assert(tctx, ok, "write_data_cb"); >- } >- >- // We may get one additional change... >- >- ok = get_basic_info_cb(private_data, &finfo3); >- torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); >- COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); >- >- /* >- * Make sure the time doesn't change during the next 5 seconds >- */ >- start = timeval_current(); >- end = timeval_add(&start, max_delay * 1.25, 0); >- while (!timeval_expired(&end)) { >- smb_msleep(1 * msec); >- torture_comment(tctx, "Check for no additional change\n"); >- ok = get_basic_info_cb(private_data, &finfoT); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >- } >- >- ok = get_basic_info_cb(private_data, &finfoT); >- torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >- >-done: >- return ret; >-} >- > struct test_durable_open_delaywrite1_state { > struct torture_context *tctx; > struct smb2_tree *tree1; >@@ -3263,18 +3078,18 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > state.h1 = h1; > state.h2 = h2; > >- ok = test_delay_writetime(tctx, used_delay, normal_delay, >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, > "run1", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > &state); >- torture_assert(tctx, ok, "test_delay_writetime(1)"); >- ok = test_delay_writetime(tctx, used_delay, normal_delay, >+ torture_assert(tctx, ok, "test_delay_writetime1(1)"); >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, > "run2", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > &state); >- torture_assert(tctx, ok, "test_delay_writetime(2)"); >+ torture_assert(tctx, ok, "test_delay_writetime2(2)"); > > GET_INFO_BOTH(c1finfo1, c2finfo1); > COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); >@@ -3342,7 +3157,6 @@ done: > return ret; > } > >- > struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) > { > struct torture_suite *suite = >diff --git a/source4/torture/util.h b/source4/torture/util.h >index 4695710faece..cd0a530be409 100644 >--- a/source4/torture/util.h >+++ b/source4/torture/util.h >@@ -107,5 +107,13 @@ NTSTATUS torture_check_privilege(struct smbcli_state *cli, > const char *sid_str, > const char *privilege); > >+bool test_delay_writetime1(struct torture_context *tctx, >+ double used_delay, >+ double normal_delay, >+ const char *description, >+ bool (*get_basic_info_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ bool (*write_data_cb)(void *private_data), >+ void *private_data); > > #endif /* _TORTURE_UTIL_H_ */ >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c >new file mode 100644 >index 000000000000..7ded582dd894 >--- /dev/null >+++ b/source4/torture/util_writetime.c >@@ -0,0 +1,300 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ test suite for delayed write time updates >+ >+ Copyright (C) Stefan Metzmacher 2018 >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include "../lib/util/time_basic.h" >+#include "../libcli/smb/smb_common.h" >+#include "../libcli/smb/smbXcli_base.h" >+#include "libcli/raw/libcliraw.h" >+#include "torture/torture.h" >+#include "torture/util.h" >+ >+#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ >+ const uint64_t _r = 10*1000*1000; \ >+ NTTIME _g = (given).basic_info.out.gelem; \ >+ NTTIME _gr = (_g / _r) * _r; \ >+ NTTIME _c = (correct).basic_info.out.celem; \ >+ NTTIME _cr = (_c / _r) * _r; \ >+ bool _strict = torture_setting_bool(tctx, "strict mode", false); \ >+ const char *_err = NULL; \ >+ if (_strict && (_g cmp _c)) { \ >+ _err = "strict"; \ >+ } else if ((_g cmp _c) && (_gr cmp _cr)) { \ >+ /* handle filesystem without high resolution timestamps */ \ >+ _err = "rounded"; \ >+ } \ >+ if (_err != NULL) { \ >+ struct timeval _gtv; \ >+ struct timeval _ctv; \ >+ struct timeval_buf _gtvb; \ >+ struct timeval_buf _ctvb; \ >+ nttime_to_timeval(&_gtv, _g); \ >+ nttime_to_timeval(&_ctv, _c); \ >+ torture_result(tctx, TORTURE_FAIL, \ >+ __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ >+ _err, \ >+ #given, #gelem, \ >+ timeval_str_buf(&_gtv, false, true, &_gtvb), \ >+ #cmp, \ >+ #correct, #celem, \ >+ timeval_str_buf(&_ctv, false, true, &_ctvb)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ >+} while (0) >+#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,!=) >+#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ >+} while (0) >+#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,!=) >+#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ >+} while (0) >+#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,!=) >+#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >+} while (0) >+#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ >+ COMPARE_CREATE_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ >+ COMPARE_WRITE_TIME_EQUAL(given,correct); \ >+ COMPARE_CHANGE_TIME_EQUAL(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+} while (0) >+ >+#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+} while (0) >+ >+#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_GREATER(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+ COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ >+} while (0) >+ >+bool test_delay_writetime1(struct torture_context *tctx, >+ double used_delay, >+ double normal_delay, >+ const char *description, >+ bool (*get_basic_info_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ bool (*write_data_cb)(void *private_data), >+ void *private_data) >+{ >+ union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; >+ struct timeval before_write; >+ struct timeval after_write; >+ struct timeval before_last_write; >+ struct timeval after_last_write; >+ struct timeval start; >+ struct timeval end; >+ double sec = used_delay / normal_delay; >+ double msec = 1000 * sec; >+ double nsec = 1000 * msec; >+ double expected_delay = used_delay / nsec; >+ double min_delay = expected_delay * 0.01; >+ double max_delay = 5 * expected_delay; >+ bool ret = true; >+ bool ok; >+ >+ torture_comment(tctx, "START: %s\n", description); >+ >+ /* get the initial times */ >+ ok = get_basic_info_cb(private_data, &finfo0); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); >+ >+ /* >+ * Make sure the time doesn't change during the next 5 seconds >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 1.25, 0); >+ while (!timeval_expired(&end)) { >+ smb_msleep(1 * msec); >+ torture_comment(tctx, "Check for no change\n"); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >+ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ before_write = timeval_current(); >+ ok = write_data_cb(private_data); >+ after_write = timeval_current(); >+ torture_assert(tctx, ok, "write_data_cb"); >+ >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 2, 0); >+ while (!timeval_expired(&end)) { >+ struct timeval before_get; >+ struct timeval after_get; >+ >+ torture_comment(tctx, "Wait for change\n"); >+ before_get = timeval_current(); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ after_get = timeval_current(); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ >+ if (finfoT.basic_info.out.write_time > finfo0.basic_info.out.write_time) { >+ double delayS = timeval_elapsed2(&after_write, &before_get); >+ double delayL = timeval_elapsed2(&before_write, &after_get); >+ >+ torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >+ "(min delay == %.2f, max delay == %.2f)\n", >+ delayS, delayL, min_delay, max_delay); >+ torture_assert(tctx, (delayL >= min_delay), >+ "Server updated write_time to early!"); >+ torture_assert(tctx, (delayS <= max_delay), >+ "Server didn't update write_time!"); >+ >+ COMPARE_TIMES_AFTER_WRITE(finfoT, finfo0); >+ break; >+ } >+ >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >+ smb_msleep(0.01 * msec); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfo1); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfo1"); >+ COMPARE_TIMES_AFTER_WRITE(finfo1, finfo0); >+ >+ /* >+ * Make sure the time doesn't change during the next 5 seconds >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 1.25, 0); >+ while (!timeval_expired(&end)) { >+ smb_msleep(1 * msec); >+ torture_comment(tctx, "Check for no additional change\n"); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >+ >+ torture_comment(tctx, "Do a write on the file handle\n"); >+ before_write = timeval_current(); >+ ok = write_data_cb(private_data); >+ after_write = timeval_current(); >+ torture_assert(tctx, ok, "write_data_cb"); >+ >+ ZERO_STRUCT(finfo2); >+ before_last_write = before_write; >+ after_last_write = after_write; >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 2, 0); >+ while (!timeval_expired(&end)) { >+ struct timeval before_get; >+ struct timeval after_get; >+ >+ smb_msleep(0.01 * msec); >+ >+ torture_comment(tctx, "Wait for change\n"); >+ before_get = timeval_current(); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ after_get = timeval_current(); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ >+ if (finfoT.basic_info.out.write_time > finfo1.basic_info.out.write_time) { >+ double delayS = timeval_elapsed2(&after_write, &before_get); >+ double delayL = timeval_elapsed2(&before_write, &after_get); >+ >+ torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >+ "(min delay == %.2f, max delay == %.2f)\n", >+ delayS, delayL, min_delay, max_delay); >+ torture_assert(tctx, (delayL >= min_delay), >+ "Server updated write_time to early!"); >+ torture_assert(tctx, (delayS <= max_delay), >+ "Server didn't update write_time!"); >+ >+ COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); >+ before_write = before_last_write; >+ after_write = after_last_write; >+ finfo2 = finfoT; >+ break; >+ } >+ >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >+ >+ torture_comment(tctx, "Write while waiting\n"); >+ before_last_write = timeval_current(); >+ ok = write_data_cb(private_data); >+ after_last_write = timeval_current(); >+ torture_assert(tctx, ok, "write_data_cb"); >+ } >+ >+ // We may get one additional change... >+ >+ ok = get_basic_info_cb(private_data, &finfo3); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); >+ COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); >+ >+ /* >+ * Make sure the time doesn't change during the next 5 seconds >+ */ >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 1.25, 0); >+ while (!timeval_expired(&end)) { >+ smb_msleep(1 * msec); >+ torture_comment(tctx, "Check for no additional change\n"); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ } >+ >+ ok = get_basic_info_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ >+done: >+ return ret; >+} >diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build >index aceededc9d83..fb9c324da051 100644 >--- a/source4/torture/wscript_build >+++ b/source4/torture/wscript_build >@@ -2,7 +2,7 @@ > > > bld.SAMBA_SUBSYSTEM('TORTURE_UTIL', >- source='util_smb.c', >+ source='util_smb.c util_writetime.c', > public_deps='torture popt POPT_CREDENTIALS', > deps='smbclient-raw' > ) >-- >2.17.1 > > >From 728dcb36ef11adbf915256699002082458ab7e39 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 08:40:54 +0200 >Subject: [PATCH 10/48] test_delaywrite_delaywrite1 SMB1 > >--- > source4/torture/basic/delaywrite.c | 438 +++++++++++++++++++++++++++++ > 1 file changed, 438 insertions(+) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index dd261d86d096..da69a5a6d126 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3074,6 +3074,443 @@ static bool test_directory_update8(struct torture_context *tctx, struct smbcli_s > return ret; > } > >+#undef COMPARE_WRITE_TIME_CMP >+#undef COMPARE_ACCESS_TIME_CMP >+ >+#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ >+ const uint64_t _r = 10*1000*1000; \ >+ NTTIME _g = (given).basic_info.out.gelem; \ >+ NTTIME _gr = (_g / _r) * _r; \ >+ NTTIME _c = (correct).basic_info.out.celem; \ >+ NTTIME _cr = (_c / _r) * _r; \ >+ bool _strict = torture_setting_bool(tctx, "strict mode", false); \ >+ const char *_err = NULL; \ >+ if (_strict && (_g cmp _c)) { \ >+ _err = "strict"; \ >+ } else if ((_g cmp _c) && (_gr cmp _cr)) { \ >+ /* handle filesystem without high resolution timestamps */ \ >+ _err = "rounded"; \ >+ } \ >+ if (_err != NULL) { \ >+ struct timeval _gtv; \ >+ struct timeval _ctv; \ >+ struct timeval_buf _gtvb; \ >+ struct timeval_buf _ctvb; \ >+ nttime_to_timeval(&_gtv, _g); \ >+ nttime_to_timeval(&_ctv, _c); \ >+ torture_result(tctx, TORTURE_FAIL, \ >+ __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ >+ _err, \ >+ #given, #gelem, \ >+ timeval_str_buf(&_gtv, false, true, &_gtvb), \ >+ #cmp, \ >+ #correct, #celem, \ >+ timeval_str_buf(&_ctv, false, true, &_ctvb)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ >+} while (0) >+#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,!=) >+#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ >+} while (0) >+#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,!=) >+#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ >+} while (0) >+#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,!=) >+#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >+} while (0) >+#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ >+ COMPARE_CREATE_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ >+ COMPARE_WRITE_TIME_EQUAL(given,correct); \ >+ COMPARE_CHANGE_TIME_EQUAL(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+} while (0) >+ >+#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+} while (0) >+ >+struct test_delaywrite_delaywrite1_state { >+ struct torture_context *tctx; >+ struct smbcli_state *cli1; >+ struct smbcli_state *cli2; >+ int fnum1; >+ int fnum2; >+ const char *fname; >+}; >+ >+static bool test_delaywrite_delaywrite1_get_info(void *private_data, >+ union smb_fileinfo *finfo) >+{ >+ struct test_delaywrite_delaywrite1_state *state = >+ (struct test_delaywrite_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ struct smbcli_state *cli = state->cli1; >+ struct smbcli_state *cli2 = state->cli2; >+ union smb_fileinfo t1finfo; >+ union smb_fileinfo t2finfo; >+ union smb_fileinfo t2pinfo; >+ bool ret = true; >+ >+ ZERO_STRUCTP(finfo); >+ >+ ZERO_STRUCT(t1finfo); >+ t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t1finfo.basic_info.in.file.fnum = state->fnum1; >+ >+ ZERO_STRUCT(t2finfo); >+ t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t2finfo.basic_info.in.file.fnum = state->fnum2; >+ ZERO_STRUCT(t2pinfo); >+ t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t2pinfo.basic_info.in.file.path = state->fname; >+ >+ GET_INFO_FILE2(t2finfo); >+ GET_INFO_PATH(t2pinfo); >+ GET_INFO_FILE(t1finfo); >+ if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { >+ /* >+ * There was a race, get it again on handle 2, >+ * but then they have to match. >+ */ >+ GET_INFO_FILE2(t2finfo); >+ GET_INFO_PATH(t2pinfo); >+ } >+ COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); >+ COMPARE_ALL_TIMES_EQUAL(t1finfo, t2pinfo); >+ >+ finfo->basic_info.out = t1finfo.basic_info.out; >+done: >+ return ret; >+} >+ >+static bool test_delaywrite_delaywrite1_write_data(void *private_data) >+{ >+ struct test_delaywrite_delaywrite1_state *state = >+ (struct test_delaywrite_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ bool ret = true; >+ ssize_t nwritten; >+ >+ nwritten = smbcli_write(state->cli1->tree, state->fnum1, 0, "x", 0, 1); >+ torture_assert_int_equal_goto(tctx, nwritten, 1, >+ ret, done, "smbcli_write"); >+ >+done: >+ return ret; >+} >+ >+static bool test_delaywrite_delaywrite1(struct torture_context *tctx, >+ struct smbcli_state *cli, >+ struct smbcli_state *cli2) >+{ >+ struct test_delaywrite_delaywrite1_state state = { >+ .tctx = tctx, >+ .cli1 = cli, >+ .cli2 = cli2, >+ }; >+ union smb_fileinfo c1finfo0, c1finfo1, c1finfo2; >+ union smb_fileinfo c2pinfo0, c2pinfo1, c2pinfo2, c2pinfo3; >+ const char *fname = BASEDIR "\\torture_file3.txt"; >+ int fnum1 = -1; >+ int fnum2 = -1; >+ bool ret = true; >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ double normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >+ //double normal_delay = 1000000; >+ //int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ bool ok; >+ >+ torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Open the file handle\n"); >+ fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (fnum1 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } >+ fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (fnum2 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } >+ >+ c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ c1finfo0.basic_info.in.file.fnum = fnum1; >+ c1finfo1 = c1finfo0; >+ c1finfo2 = c1finfo0; >+ c2pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ c2pinfo0.basic_info.in.file.path = fname; >+ c2pinfo1 = c2pinfo0; >+ c2pinfo2 = c2pinfo0; >+ c2pinfo3 = c2pinfo0; >+ >+ /* get the initial times */ >+ GET_INFO_BOTH(c1finfo0,c2pinfo0); >+ >+ state.fname = fname; >+ state.fnum1 = fnum1; >+ state.fnum2 = fnum2; >+ >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run1", >+ test_delaywrite_delaywrite1_get_info, >+ test_delaywrite_delaywrite1_write_data, >+ &state); >+ torture_assert(tctx, ok, "test_delay_writetime1(1)"); >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run2", >+ test_delaywrite_delaywrite1_get_info, >+ test_delaywrite_delaywrite1_write_data, >+ &state); >+ torture_assert(tctx, ok, "test_delay_writetime2(2)"); >+ >+ GET_INFO_BOTH(c1finfo1, c2pinfo1); >+ COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); >+ >+ /* sleep */ >+ torture_comment(tctx, "Sleep ...\n"); >+ smb_msleep(5 * msec); >+ torture_comment(tctx, "... continue\n"); >+ >+ GET_INFO_BOTH(c1finfo2, c2pinfo2); >+ COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ smbcli_close(cli->tree, fnum1); >+ fnum1 = -1; >+ >+ GET_INFO_PATH(c2pinfo3); >+ COMPARE_WRITE_TIME_GREATER(c2pinfo3, c2pinfo2); >+ >+ if (c2pinfo3.basic_info.out.write_time > c2pinfo2.basic_info.out.write_time) { >+ torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >+ } >+ >+ done: >+ if (fnum1 != -1) { >+ smbcli_close(cli->tree, fnum1); >+ } >+ if (fnum2 != -1) { >+ smbcli_close(cli2->tree, fnum2); >+ } >+ smbcli_unlink(cli->tree, fname); >+ smbcli_deltree(cli->tree, BASEDIR); >+ >+ return ret; >+} >+#if 0 >+ NTSTATUS status; >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ char fname[256]; >+ struct smb2_handle _h1; >+ struct smb2_handle *h1 = NULL; >+ struct smb2_handle _h2; >+ struct smb2_handle *h2 = NULL; >+ struct smb2_create cr1; >+ struct smb2_create cr2; >+ union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; >+ union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; >+ struct smb2_close cl1; >+ struct smb2_close cl2; >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ double normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >+ //double normal_delay = 1000000; >+ //int normal_delay = 2000000; >+ double sec = ((double)used_delay) / ((double)normal_delay); >+ int msec = 1000 * sec; >+ bool ret = true; >+ bool ok; >+ >+ /* Choose a random name in case the state is left a little funky. */ >+ snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", >+ generate_random_str(tctx, 8)); >+ >+ smb2_util_unlink(tree1, fname); >+ >+ smb2_oplock_create_share(&cr1, fname, >+ smb2_util_share_access(""), >+ smb2_util_oplock_level("b")); >+ cr1.in.durable_open = true; >+ >+ status = smb2_create(tree1, mem_ctx, &cr1); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h1 = cr1.out.file.handle; >+ h1 = &_h1; >+ CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); >+ CHECK_VAL(cr1.out.durable_open, true); >+ CHECK_VAL(cr1.out.durable_open_v2, false); >+ CHECK_VAL(cr1.out.persistent_open, false); >+ >+ cr2 = cr1; >+ cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; >+ cr2.in.durable_open = false; >+ cr2.in.oplock_level = 0; >+ cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >+ status = smb2_create(tree2, mem_ctx, &cr2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h2 = cr2.out.file.handle; >+ h2 = &_h2; >+ CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr2.out.oplock_level, 0); >+ CHECK_VAL(cr2.out.durable_open, false); >+ CHECK_VAL(cr2.out.durable_open_v2, false); >+ CHECK_VAL(cr2.out.persistent_open, false); >+ >+ ZERO_STRUCT(c1finfoCR); >+ c1finfoCR.basic_info.out.create_time = cr1.out.create_time; >+ c1finfoCR.basic_info.out.access_time = cr1.out.access_time; >+ c1finfoCR.basic_info.out.write_time = cr1.out.write_time; >+ c1finfoCR.basic_info.out.change_time = cr1.out.change_time; >+ c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; >+ >+ ZERO_STRUCT(c2finfoCR); >+ c2finfoCR.basic_info.out.create_time = cr2.out.create_time; >+ c2finfoCR.basic_info.out.access_time = cr2.out.access_time; >+ c2finfoCR.basic_info.out.write_time = cr2.out.write_time; >+ c2finfoCR.basic_info.out.change_time = cr2.out.change_time; >+ c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; >+ >+ COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); >+ >+ ZERO_STRUCT(c1finfo0); >+ c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ c1finfo0.basic_info.in.file.handle = *h1; >+ c1finfo1 = c1finfo0; >+ c1finfo2 = c1finfo0; >+ >+ ZERO_STRUCT(c2finfo0); >+ c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ c2finfo0.basic_info.in.file.handle = *h2; >+ c2finfo1 = c2finfo0; >+ c2finfo2 = c2finfo0; >+ c2finfo3 = c2finfo0; >+ >+ GET_INFO_BOTH(c1finfo0, c2finfo0); >+ COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); >+ >+ state.h1 = h1; >+ state.h2 = h2; >+ >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run1", >+ test_delaywrite_delaywrite1_get_info, >+ test_delaywrite_delaywrite1_write_data, >+ &state); >+ torture_assert(tctx, ok, "test_delay_writetime1(1)"); >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run2", >+ test_delaywrite_delaywrite1_get_info, >+ test_delaywrite_delaywrite1_write_data, >+ &state); >+ torture_assert(tctx, ok, "test_delay_writetime2(2)"); >+ >+ GET_INFO_BOTH(c1finfo1, c2finfo1); >+ COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); >+ >+ /* sleep */ >+ torture_comment(tctx, "Sleep ...\n"); >+ smb_msleep(5 * msec); >+ torture_comment(tctx, "... continue\n"); >+ >+ GET_INFO_BOTH(c1finfo2, c2finfo2); >+ COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ >+ ZERO_STRUCT(cl1); >+ cl1.in.file.handle = *h1; >+ cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(tree1, &cl1); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ h1 = NULL; >+ ZERO_STRUCT(c1finfoCL); >+ c1finfoCL.basic_info.out.create_time = cl1.out.create_time; >+ c1finfoCL.basic_info.out.access_time = cl1.out.access_time; >+ c1finfoCL.basic_info.out.write_time = cl1.out.write_time; >+ c1finfoCL.basic_info.out.change_time = cl1.out.change_time; >+ c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >+ COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); >+ >+ GET_INFO_FILE(tree2, c2finfo3); >+ COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); >+ >+ ZERO_STRUCT(cl2); >+ cl2.in.file.handle = *h2; >+ cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(tree2, &cl2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ h2 = NULL; >+ ZERO_STRUCT(c2finfoCL); >+ c2finfoCL.basic_info.out.create_time = cl2.out.create_time; >+ c2finfoCL.basic_info.out.access_time = cl2.out.access_time; >+ c2finfoCL.basic_info.out.write_time = cl2.out.write_time; >+ c2finfoCL.basic_info.out.change_time = cl2.out.change_time; >+ c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >+ COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); >+ >+done: >+ if (h1 != NULL) { >+ smb2_util_close(tree1, *h1); >+ } >+ if (h2 != NULL) { >+ smb2_util_close(tree2, *h2); >+ } >+ >+ smb2_util_unlink(tree1, fname); >+ >+ talloc_free(tree1); >+ talloc_free(tree2); >+ >+ talloc_free(mem_ctx); >+ >+ return ret; >+} >+#endif > /* > testing of delayed update of write_time > */ >@@ -3098,6 +3535,7 @@ struct torture_suite *torture_delay_write(TALLOC_CTX *ctx) > torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6); > torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7); > torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); >+ torture_suite_add_2smb_test(suite, "delaywrite1", test_delaywrite_delaywrite1); > > return suite; > } >-- >2.17.1 > > >From aceb3f9c545b5d5a5dfc917e10028f1e5c5346ec Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 09:39:36 +0200 >Subject: [PATCH 11/48] sq source4/torture/util_writetime.c > source4/torture/smb2/durable_open.c > >--- > source4/torture/smb2/durable_open.c | 140 ++++++++++++++-------------- > source4/torture/util.h | 2 + > source4/torture/util_writetime.c | 16 ++++ > 3 files changed, 86 insertions(+), 72 deletions(-) > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 814f4944152d..f5ace21de8a3 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -2974,6 +2974,62 @@ done: > return ret; > } > >+static bool test_durable_open_delaywrite1_close(void *private_data, >+ union smb_fileinfo *finfo) >+{ >+ struct test_durable_open_delaywrite1_state *state = >+ (struct test_durable_open_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ union smb_fileinfo t1finfoCL; >+ union smb_fileinfo t2finfoCL; >+ struct smb2_close cl1; >+ struct smb2_close cl2; >+ union smb_fileinfo t2finfo; >+ NTSTATUS status; >+ bool ret = true; >+ >+ ZERO_STRUCTP(finfo); >+ >+ ZERO_STRUCT(cl1); >+ cl1.in.file.handle = *state->h1; >+ cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(state->tree1, &cl1); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ state->h1 = NULL; >+ ZERO_STRUCT(t1finfoCL); >+ t1finfoCL.basic_info.out.create_time = cl1.out.create_time; >+ t1finfoCL.basic_info.out.access_time = cl1.out.access_time; >+ t1finfoCL.basic_info.out.write_time = cl1.out.write_time; >+ t1finfoCL.basic_info.out.change_time = cl1.out.change_time; >+ t1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >+ >+ ZERO_STRUCT(t2finfo); >+ t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t2finfo.basic_info.in.file.handle = *state->h2; >+ >+ GET_INFO_FILE(state->tree2, t2finfo); >+ COMPARE_ALL_TIMES_EQUAL(t2finfo, t1finfoCL); >+ >+ ZERO_STRUCT(cl2); >+ cl2.in.file.handle = *state->h2; >+ cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(state->tree2, &cl2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ state->h2 = NULL; >+ ZERO_STRUCT(t2finfoCL); >+ t2finfoCL.basic_info.out.create_time = cl2.out.create_time; >+ t2finfoCL.basic_info.out.access_time = cl2.out.access_time; >+ t2finfoCL.basic_info.out.write_time = cl2.out.write_time; >+ t2finfoCL.basic_info.out.change_time = cl2.out.change_time; >+ t2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >+ COMPARE_ALL_TIMES_EQUAL(t2finfoCL, t1finfoCL); >+ >+ finfo->basic_info.out = t1finfoCL.basic_info.out; >+ >+done: >+ return ret; >+} >+ > static bool test_durable_open_delaywrite1(struct torture_context *tctx, > struct smb2_tree *tree1, > struct smb2_tree *tree2) >@@ -2987,23 +3043,17 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > TALLOC_CTX *mem_ctx = talloc_new(tctx); > char fname[256]; > struct smb2_handle _h1; >- struct smb2_handle *h1 = NULL; > struct smb2_handle _h2; >- struct smb2_handle *h2 = NULL; > struct smb2_create cr1; > struct smb2_create cr2; >- union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; >- union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; >- struct smb2_close cl1; >- struct smb2_close cl2; >+ union smb_fileinfo c1finfoCR, c1finfo0; >+ union smb_fileinfo c2finfoCR, c2finfo0; > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); > double normal_delay = 1000000; > double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); > //double normal_delay = 1000000; > //int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; > bool ret = true; > bool ok; > >@@ -3021,7 +3071,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > status = smb2_create(tree1, mem_ctx, &cr1); > CHECK_STATUS(status, NT_STATUS_OK); > _h1 = cr1.out.file.handle; >- h1 = &_h1; >+ state.h1 = &_h1; > CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); > CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); > CHECK_VAL(cr1.out.durable_open, true); >@@ -3036,7 +3086,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > status = smb2_create(tree2, mem_ctx, &cr2); > CHECK_STATUS(status, NT_STATUS_OK); > _h2 = cr2.out.file.handle; >- h2 = &_h2; >+ state.h2 = &_h2; > CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); > CHECK_VAL(cr2.out.oplock_level, 0); > CHECK_VAL(cr2.out.durable_open, false); >@@ -3061,90 +3111,36 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > > ZERO_STRUCT(c1finfo0); > c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- c1finfo0.basic_info.in.file.handle = *h1; >- c1finfo1 = c1finfo0; >- c1finfo2 = c1finfo0; >+ c1finfo0.basic_info.in.file.handle = *state.h1; > > ZERO_STRUCT(c2finfo0); > c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- c2finfo0.basic_info.in.file.handle = *h2; >- c2finfo1 = c2finfo0; >- c2finfo2 = c2finfo0; >- c2finfo3 = c2finfo0; >+ c2finfo0.basic_info.in.file.handle = *state.h2; > > GET_INFO_BOTH(c1finfo0, c2finfo0); > COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); > >- state.h1 = h1; >- state.h2 = h2; >- > ok = test_delay_writetime1(tctx, used_delay, normal_delay, > "run1", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, >+ NULL, /* close_cb */ > &state); > torture_assert(tctx, ok, "test_delay_writetime1(1)"); > ok = test_delay_writetime1(tctx, used_delay, normal_delay, > "run2", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, >+ test_durable_open_delaywrite1_close, > &state); > torture_assert(tctx, ok, "test_delay_writetime2(2)"); > >- GET_INFO_BOTH(c1finfo1, c2finfo1); >- COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); >- >- /* sleep */ >- torture_comment(tctx, "Sleep ...\n"); >- smb_msleep(5 * msec); >- torture_comment(tctx, "... continue\n"); >- >- GET_INFO_BOTH(c1finfo2, c2finfo2); >- COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); >- >- /* >- * the close updates the write time to the time of the close >- * and not to the time of the last write! >- */ >- torture_comment(tctx, "Close the file handle\n"); >- >- ZERO_STRUCT(cl1); >- cl1.in.file.handle = *h1; >- cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(tree1, &cl1); >- CHECK_STATUS(status, NT_STATUS_OK); >- h1 = NULL; >- ZERO_STRUCT(c1finfoCL); >- c1finfoCL.basic_info.out.create_time = cl1.out.create_time; >- c1finfoCL.basic_info.out.access_time = cl1.out.access_time; >- c1finfoCL.basic_info.out.write_time = cl1.out.write_time; >- c1finfoCL.basic_info.out.change_time = cl1.out.change_time; >- c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >- COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); >- >- GET_INFO_FILE(tree2, c2finfo3); >- COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); >- >- ZERO_STRUCT(cl2); >- cl2.in.file.handle = *h2; >- cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(tree2, &cl2); >- CHECK_STATUS(status, NT_STATUS_OK); >- h2 = NULL; >- ZERO_STRUCT(c2finfoCL); >- c2finfoCL.basic_info.out.create_time = cl2.out.create_time; >- c2finfoCL.basic_info.out.access_time = cl2.out.access_time; >- c2finfoCL.basic_info.out.write_time = cl2.out.write_time; >- c2finfoCL.basic_info.out.change_time = cl2.out.change_time; >- c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >- COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); >- > done: >- if (h1 != NULL) { >- smb2_util_close(tree1, *h1); >+ if (state.h1 != NULL) { >+ smb2_util_close(tree1, *state.h1); > } >- if (h2 != NULL) { >- smb2_util_close(tree2, *h2); >+ if (state.h2 != NULL) { >+ smb2_util_close(tree2, *state.h2); > } > > smb2_util_unlink(tree1, fname); >diff --git a/source4/torture/util.h b/source4/torture/util.h >index cd0a530be409..05e983453d22 100644 >--- a/source4/torture/util.h >+++ b/source4/torture/util.h >@@ -114,6 +114,8 @@ bool test_delay_writetime1(struct torture_context *tctx, > bool (*get_basic_info_cb)(void *private_data, > union smb_fileinfo *finfo), > bool (*write_data_cb)(void *private_data), >+ bool (*close_cb)(void *private_data, >+ union smb_fileinfo *finfo), > void *private_data); > > #endif /* _TORTURE_UTIL_H_ */ >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c >index 7ded582dd894..c567280eb36b 100644 >--- a/source4/torture/util_writetime.c >+++ b/source4/torture/util_writetime.c >@@ -121,6 +121,8 @@ bool test_delay_writetime1(struct torture_context *tctx, > bool (*get_basic_info_cb)(void *private_data, > union smb_fileinfo *finfo), > bool (*write_data_cb)(void *private_data), >+ bool (*close_cb)(void *private_data, >+ union smb_fileinfo *finfo), > void *private_data) > { > union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; >@@ -295,6 +297,20 @@ bool test_delay_writetime1(struct torture_context *tctx, > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); > COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); > >+ if (close_cb == NULL) { >+ goto done; >+ } >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ >+ ok = close_cb(private_data, &finfoT); >+ torture_assert(tctx, ok, "close_cb: finfoT"); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ > done: > return ret; > } >-- >2.17.1 > > >From 3dc77fdf7a48009acd706f657116707ac2316b84 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 09:58:38 +0200 >Subject: [PATCH 12/48] works for SMB2, fails SMB1 > >SMB1: >no update at all. >What's the difference to 'delayed update of write time' test??? >--- > source4/torture/basic/delaywrite.c | 118 +++++++++++++--------------- > source4/torture/smb2/durable_open.c | 8 +- > source4/torture/util.h | 1 + > source4/torture/util_writetime.c | 14 +++- > 4 files changed, 72 insertions(+), 69 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index da69a5a6d126..c95d8ab518d2 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3225,6 +3225,48 @@ done: > return ret; > } > >+static bool test_delaywrite_delaywrite1_close(void *private_data, >+ union smb_fileinfo *finfo) >+{ >+ struct test_delaywrite_delaywrite1_state *state = >+ (struct test_delaywrite_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ struct smbcli_state *cli2 = state->cli2; >+ union smb_fileinfo t2finfo; >+ union smb_fileinfo t2pinfo; >+ bool ret = true; >+ >+ ZERO_STRUCTP(finfo); >+ >+ /* >+ * the close updates the write time to the time of the close >+ * and not to the time of the last write! >+ */ >+ torture_comment(tctx, "Close the file handle\n"); >+ smbcli_close(state->cli1->tree, state->fnum1); >+ state->fnum1 = -1; >+ >+ ZERO_STRUCT(t2finfo); >+ t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ t2finfo.basic_info.in.file.fnum = state->fnum2; >+ ZERO_STRUCT(t2pinfo); >+ t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ t2pinfo.basic_info.in.file.path = state->fname; >+ >+ GET_INFO_FILE2(t2finfo); >+ >+ smbcli_close(state->cli2->tree, state->fnum2); >+ state->fnum2 = -1; >+ >+ GET_INFO_PATH(t2pinfo); >+ COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo); >+ >+ finfo->basic_info.out = t2finfo.basic_info.out; >+ >+done: >+ return ret; >+} >+ > static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > struct smbcli_state *cli, > struct smbcli_state *cli2) >@@ -3233,12 +3275,10 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > .tctx = tctx, > .cli1 = cli, > .cli2 = cli2, >+ .fnum1 = -1, >+ .fnum2 = -1, > }; >- union smb_fileinfo c1finfo0, c1finfo1, c1finfo2; >- union smb_fileinfo c2pinfo0, c2pinfo1, c2pinfo2, c2pinfo3; > const char *fname = BASEDIR "\\torture_file3.txt"; >- int fnum1 = -1; >- int fnum2 = -1; > bool ret = true; > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); > //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >@@ -3246,8 +3286,6 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); > //double normal_delay = 1000000; > //int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; > bool ok; > > torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >@@ -3255,81 +3293,35 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); > > torture_comment(tctx, "Open the file handle\n"); >- fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (fnum1 == -1) { >+ state.fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (state.fnum1 == -1) { > ret = false; > torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); > goto done; > } >- fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (fnum2 == -1) { >+ state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (state.fnum2 == -1) { > ret = false; > torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); > goto done; > } > >- c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- c1finfo0.basic_info.in.file.fnum = fnum1; >- c1finfo1 = c1finfo0; >- c1finfo2 = c1finfo0; >- c2pinfo0.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- c2pinfo0.basic_info.in.file.path = fname; >- c2pinfo1 = c2pinfo0; >- c2pinfo2 = c2pinfo0; >- c2pinfo3 = c2pinfo0; >- >- /* get the initial times */ >- GET_INFO_BOTH(c1finfo0,c2pinfo0); >- > state.fname = fname; >- state.fnum1 = fnum1; >- state.fnum2 = fnum2; > > ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run1", >+ "run", true, /* smb1 */ > test_delaywrite_delaywrite1_get_info, > test_delaywrite_delaywrite1_write_data, >+ test_delaywrite_delaywrite1_close, > &state); >- torture_assert(tctx, ok, "test_delay_writetime1(1)"); >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run2", >- test_delaywrite_delaywrite1_get_info, >- test_delaywrite_delaywrite1_write_data, >- &state); >- torture_assert(tctx, ok, "test_delay_writetime2(2)"); >- >- GET_INFO_BOTH(c1finfo1, c2pinfo1); >- COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); >- >- /* sleep */ >- torture_comment(tctx, "Sleep ...\n"); >- smb_msleep(5 * msec); >- torture_comment(tctx, "... continue\n"); >- >- GET_INFO_BOTH(c1finfo2, c2pinfo2); >- COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); >- >- /* >- * the close updates the write time to the time of the close >- * and not to the time of the last write! >- */ >- torture_comment(tctx, "Close the file handle\n"); >- smbcli_close(cli->tree, fnum1); >- fnum1 = -1; >- >- GET_INFO_PATH(c2pinfo3); >- COMPARE_WRITE_TIME_GREATER(c2pinfo3, c2pinfo2); >- >- if (c2pinfo3.basic_info.out.write_time > c2pinfo2.basic_info.out.write_time) { >- torture_comment(tctx, "Server updated the write_time on close (correct)\n"); >- } >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); > > done: >- if (fnum1 != -1) { >- smbcli_close(cli->tree, fnum1); >+ if (state.fnum1 != -1) { >+ smbcli_close(cli->tree, state.fnum1); > } >- if (fnum2 != -1) { >- smbcli_close(cli2->tree, fnum2); >+ if (state.fnum2 != -1) { >+ smbcli_close(cli2->tree, state.fnum2); > } > smbcli_unlink(cli->tree, fname); > smbcli_deltree(cli->tree, BASEDIR); >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index f5ace21de8a3..a21fca2373d1 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -3121,19 +3121,19 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); > > ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run1", >+ "run1", false, /* smb1 */ > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > NULL, /* close_cb */ > &state); >- torture_assert(tctx, ok, "test_delay_writetime1(1)"); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); > ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run2", >+ "run2", false, /* smb1 */ > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > test_durable_open_delaywrite1_close, > &state); >- torture_assert(tctx, ok, "test_delay_writetime2(2)"); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); > > done: > if (state.h1 != NULL) { >diff --git a/source4/torture/util.h b/source4/torture/util.h >index 05e983453d22..f0b3e15c1ecc 100644 >--- a/source4/torture/util.h >+++ b/source4/torture/util.h >@@ -111,6 +111,7 @@ bool test_delay_writetime1(struct torture_context *tctx, > double used_delay, > double normal_delay, > const char *description, >+ bool smb1, > bool (*get_basic_info_cb)(void *private_data, > union smb_fileinfo *finfo), > bool (*write_data_cb)(void *private_data), >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c >index c567280eb36b..a6e42274466c 100644 >--- a/source4/torture/util_writetime.c >+++ b/source4/torture/util_writetime.c >@@ -118,6 +118,7 @@ bool test_delay_writetime1(struct torture_context *tctx, > double used_delay, > double normal_delay, > const char *description, >+ bool smb1, > bool (*get_basic_info_cb)(void *private_data, > union smb_fileinfo *finfo), > bool (*write_data_cb)(void *private_data), >@@ -229,6 +230,11 @@ bool test_delay_writetime1(struct torture_context *tctx, > after_write = timeval_current(); > torture_assert(tctx, ok, "write_data_cb"); > >+ if (smb1) { >+ finfo2 = finfo1; >+ goto no_change; >+ } >+ > ZERO_STRUCT(finfo2); > before_last_write = before_write; > after_last_write = after_write; >@@ -275,7 +281,7 @@ bool test_delay_writetime1(struct torture_context *tctx, > } > > // We may get one additional change... >- >+no_change: > ok = get_basic_info_cb(private_data, &finfo3); > torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); > COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); >@@ -309,7 +315,11 @@ bool test_delay_writetime1(struct torture_context *tctx, > > ok = close_cb(private_data, &finfoT); > torture_assert(tctx, ok, "close_cb: finfoT"); >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ if (smb1) { >+ COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); >+ } else { >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ } > > done: > return ret; >-- >2.17.1 > > >From be3fa262b08968001c370de62cfe22a418b3f4b9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 10:23:14 +0200 >Subject: [PATCH 13/48] works SMB1 > >--- > source4/torture/basic/delaywrite.c | 46 +++++++++++++++++++++--------- > source4/torture/util_writetime.c | 15 ++++++---- > 2 files changed, 41 insertions(+), 20 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index c95d8ab518d2..9e99298af51d 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3172,6 +3172,7 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, > struct torture_context *tctx = state->tctx; > struct smbcli_state *cli = state->cli1; > struct smbcli_state *cli2 = state->cli2; >+ struct smbcli_state *tmpcli = NULL; > union smb_fileinfo t1finfo; > union smb_fileinfo t2finfo; > union smb_fileinfo t2pinfo; >@@ -3190,20 +3191,30 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, > t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; > t2pinfo.basic_info.in.file.path = state->fname; > >- GET_INFO_FILE2(t2finfo); >- GET_INFO_PATH(t2pinfo); >+ if (state->fnum2 != -1) { >+ GET_INFO_FILE2(t2finfo); >+ } >+ tmpcli = cli2; >+ cli2 = cli; >+ if (0) GET_INFO_PATH(t2pinfo); >+ cli2 = tmpcli; > GET_INFO_FILE(t1finfo); >+if (0) { > if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { > /* > * There was a race, get it again on handle 2, > * but then they have to match. > */ >+ if (state->fnum2 != -1) { > GET_INFO_FILE2(t2finfo); >- GET_INFO_PATH(t2pinfo); > } >+ if (0) GET_INFO_PATH(t2pinfo); >+ } >+ if (state->fnum2 != -1) { > COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); >+ } > COMPARE_ALL_TIMES_EQUAL(t1finfo, t2pinfo); >- >+} > finfo->basic_info.out = t1finfo.basic_info.out; > done: > return ret; >@@ -3253,15 +3264,22 @@ static bool test_delaywrite_delaywrite1_close(void *private_data, > t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; > t2pinfo.basic_info.in.file.path = state->fname; > >- GET_INFO_FILE2(t2finfo); >+ if (state->fnum2 != -1) { >+ GET_INFO_FILE2(t2finfo); >+ } > >- smbcli_close(state->cli2->tree, state->fnum2); >- state->fnum2 = -1; >+ if (state->fnum2 != -1) { >+ smbcli_close(state->cli2->tree, state->fnum2); >+ state->fnum2 = -1; >+ } > > GET_INFO_PATH(t2pinfo); >+ if (state->fnum2 != -1) { > COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo); >+ } > > finfo->basic_info.out = t2finfo.basic_info.out; >+ finfo->basic_info.out = t2pinfo.basic_info.out; > > done: > return ret; >@@ -3299,12 +3317,12 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); > goto done; > } >- state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (state.fnum2 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >+ //state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ //if (state.fnum2 == -1) { >+ // ret = false; >+ // torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ // goto done; >+ //} > > state.fname = fname; > >@@ -3314,7 +3332,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > test_delaywrite_delaywrite1_write_data, > test_delaywrite_delaywrite1_close, > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1()"); > > done: > if (state.fnum1 != -1) { >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c >index a6e42274466c..c3e2cde75afb 100644 >--- a/source4/torture/util_writetime.c >+++ b/source4/torture/util_writetime.c >@@ -142,12 +142,13 @@ bool test_delay_writetime1(struct torture_context *tctx, > bool ret = true; > bool ok; > >+ smb1 = false; > torture_comment(tctx, "START: %s\n", description); > > /* get the initial times */ > ok = get_basic_info_cb(private_data, &finfo0); > torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); >- >+if (1 || !smb1) { > /* > * Make sure the time doesn't change during the next 5 seconds > */ >@@ -164,7 +165,7 @@ bool test_delay_writetime1(struct torture_context *tctx, > ok = get_basic_info_cb(private_data, &finfoT); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); > COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >- >+} > torture_comment(tctx, "Do a write on the file handle\n"); > before_write = timeval_current(); > ok = write_data_cb(private_data); >@@ -200,7 +201,8 @@ bool test_delay_writetime1(struct torture_context *tctx, > } > > COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >- smb_msleep(0.01 * msec); >+ //smb_msleep(0.01 * msec); >+ smb_msleep(1 * msec); > } > > ok = get_basic_info_cb(private_data, &finfo1); >@@ -231,8 +233,8 @@ bool test_delay_writetime1(struct torture_context *tctx, > torture_assert(tctx, ok, "write_data_cb"); > > if (smb1) { >- finfo2 = finfo1; >- goto no_change; >+ //finfo2 = finfo1; >+ if (0) goto no_change; > } > > ZERO_STRUCT(finfo2); >@@ -316,7 +318,8 @@ no_change: > ok = close_cb(private_data, &finfoT); > torture_assert(tctx, ok, "close_cb: finfoT"); > if (smb1) { >- COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >+ //COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); > } else { > COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); > } >-- >2.17.1 > > >From f8d5b924bd3cb54e1dec2977daa0af1ca5627ca3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 10:29:06 +0200 >Subject: [PATCH 14/48] still works SMB1 > >--- > source4/torture/basic/delaywrite.c | 47 +++++++----------------------- > 1 file changed, 11 insertions(+), 36 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 9e99298af51d..aca49bc80472 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3172,10 +3172,8 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, > struct torture_context *tctx = state->tctx; > struct smbcli_state *cli = state->cli1; > struct smbcli_state *cli2 = state->cli2; >- struct smbcli_state *tmpcli = NULL; > union smb_fileinfo t1finfo; > union smb_fileinfo t2finfo; >- union smb_fileinfo t2pinfo; > bool ret = true; > > ZERO_STRUCTP(finfo); >@@ -3187,34 +3185,18 @@ static bool test_delaywrite_delaywrite1_get_info(void *private_data, > ZERO_STRUCT(t2finfo); > t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; > t2finfo.basic_info.in.file.fnum = state->fnum2; >- ZERO_STRUCT(t2pinfo); >- t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- t2pinfo.basic_info.in.file.path = state->fname; > >- if (state->fnum2 != -1) { >- GET_INFO_FILE2(t2finfo); >- } >- tmpcli = cli2; >- cli2 = cli; >- if (0) GET_INFO_PATH(t2pinfo); >- cli2 = tmpcli; >+ GET_INFO_FILE2(t2finfo); > GET_INFO_FILE(t1finfo); >-if (0) { > if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { > /* > * There was a race, get it again on handle 2, > * but then they have to match. > */ >- if (state->fnum2 != -1) { > GET_INFO_FILE2(t2finfo); > } >- if (0) GET_INFO_PATH(t2pinfo); >- } >- if (state->fnum2 != -1) { > COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); >- } >- COMPARE_ALL_TIMES_EQUAL(t1finfo, t2pinfo); >-} >+ > finfo->basic_info.out = t1finfo.basic_info.out; > done: > return ret; >@@ -3264,21 +3246,14 @@ static bool test_delaywrite_delaywrite1_close(void *private_data, > t2pinfo.basic_info.level = RAW_FILEINFO_BASIC_INFO; > t2pinfo.basic_info.in.file.path = state->fname; > >- if (state->fnum2 != -1) { >- GET_INFO_FILE2(t2finfo); >- } >+ GET_INFO_FILE2(t2finfo); > >- if (state->fnum2 != -1) { >- smbcli_close(state->cli2->tree, state->fnum2); >- state->fnum2 = -1; >- } >+ smbcli_close(state->cli2->tree, state->fnum2); >+ state->fnum2 = -1; > > GET_INFO_PATH(t2pinfo); >- if (state->fnum2 != -1) { > COMPARE_ALL_TIMES_EQUAL(t2pinfo, t2finfo); >- } > >- finfo->basic_info.out = t2finfo.basic_info.out; > finfo->basic_info.out = t2pinfo.basic_info.out; > > done: >@@ -3317,12 +3292,12 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); > goto done; > } >- //state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- //if (state.fnum2 == -1) { >- // ret = false; >- // torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- // goto done; >- //} >+ state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ if (state.fnum2 == -1) { >+ ret = false; >+ torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >+ goto done; >+ } > > state.fname = fname; > >-- >2.17.1 > > >From 713123bda5075672afcb211a6742950ad968b146 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 10:43:20 +0200 >Subject: [PATCH 15/48] break test_delayed_write_update with a PATHINFO call... > >--- > source4/torture/basic/delaywrite.c | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index aca49bc80472..a38242b2fe62 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -37,6 +37,7 @@ > static bool test_delayed_write_update(struct torture_context *tctx, struct smbcli_state *cli) > { > union smb_fileinfo finfo1, finfo2; >+ union smb_fileinfo pinfo1; > const char *fname = BASEDIR "\\torture_file.txt"; > NTSTATUS status; > int fnum1 = -1; >@@ -71,6 +72,11 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > torture_assert_int_equal(tctx, written, 1, > "unexpected number of bytes written"); > >+ pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ pinfo1.basic_info.in.file.path = fname; >+ status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); >+ torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); >+ > start = timeval_current(); > end = timeval_add(&start, (120 * sec), 0); > while (!timeval_expired(&end)) { >-- >2.17.1 > > >From de084ad41c6455152ad798e70aa3903e79b7ee9c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 10:54:27 +0200 >Subject: [PATCH 16/48] works for SMB1 and SMB2 > >--- > source4/torture/basic/delaywrite.c | 11 +++++++++-- > source4/torture/smb2/durable_open.c | 6 +++--- > source4/torture/util.h | 1 - > source4/torture/util_writetime.c | 20 ++++---------------- > 4 files changed, 16 insertions(+), 22 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index a38242b2fe62..0f9fdfd7e5f1 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3308,12 +3308,19 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > state.fname = fname; > > ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run", true, /* smb1 */ >+ "run1", >+ test_delaywrite_delaywrite1_get_info, >+ test_delaywrite_delaywrite1_write_data, >+ NULL, /* close_cb */ >+ &state); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run2", > test_delaywrite_delaywrite1_get_info, > test_delaywrite_delaywrite1_write_data, > test_delaywrite_delaywrite1_close, > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1()"); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); > > done: > if (state.fnum1 != -1) { >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index a21fca2373d1..63eb7e99922a 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -3121,19 +3121,19 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); > > ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run1", false, /* smb1 */ >+ "run1", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > NULL, /* close_cb */ > &state); > torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); > ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run2", false, /* smb1 */ >+ "run2", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > test_durable_open_delaywrite1_close, > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime2(2)"); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); > > done: > if (state.h1 != NULL) { >diff --git a/source4/torture/util.h b/source4/torture/util.h >index f0b3e15c1ecc..05e983453d22 100644 >--- a/source4/torture/util.h >+++ b/source4/torture/util.h >@@ -111,7 +111,6 @@ bool test_delay_writetime1(struct torture_context *tctx, > double used_delay, > double normal_delay, > const char *description, >- bool smb1, > bool (*get_basic_info_cb)(void *private_data, > union smb_fileinfo *finfo), > bool (*write_data_cb)(void *private_data), >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c >index c3e2cde75afb..98d021b8d7f7 100644 >--- a/source4/torture/util_writetime.c >+++ b/source4/torture/util_writetime.c >@@ -118,7 +118,6 @@ bool test_delay_writetime1(struct torture_context *tctx, > double used_delay, > double normal_delay, > const char *description, >- bool smb1, > bool (*get_basic_info_cb)(void *private_data, > union smb_fileinfo *finfo), > bool (*write_data_cb)(void *private_data), >@@ -142,13 +141,12 @@ bool test_delay_writetime1(struct torture_context *tctx, > bool ret = true; > bool ok; > >- smb1 = false; > torture_comment(tctx, "START: %s\n", description); > > /* get the initial times */ > ok = get_basic_info_cb(private_data, &finfo0); > torture_assert(tctx, ok, "get_basic_info_cb: finfo0"); >-if (1 || !smb1) { >+ > /* > * Make sure the time doesn't change during the next 5 seconds > */ >@@ -165,7 +163,7 @@ if (1 || !smb1) { > ok = get_basic_info_cb(private_data, &finfoT); > torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); > COMPARE_WRITE_TIME_EQUAL(finfoT, finfo0); >-} >+ > torture_comment(tctx, "Do a write on the file handle\n"); > before_write = timeval_current(); > ok = write_data_cb(private_data); >@@ -232,11 +230,6 @@ if (1 || !smb1) { > after_write = timeval_current(); > torture_assert(tctx, ok, "write_data_cb"); > >- if (smb1) { >- //finfo2 = finfo1; >- if (0) goto no_change; >- } >- > ZERO_STRUCT(finfo2); > before_last_write = before_write; > after_last_write = after_write; >@@ -283,7 +276,7 @@ if (1 || !smb1) { > } > > // We may get one additional change... >-no_change: >+ > ok = get_basic_info_cb(private_data, &finfo3); > torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); > COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); >@@ -317,12 +310,7 @@ no_change: > > ok = close_cb(private_data, &finfoT); > torture_assert(tctx, ok, "close_cb: finfoT"); >- if (smb1) { >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >- //COMPARE_TIMES_AFTER_CLOSE(finfoT, finfo1); >- } else { >- COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); >- } >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo3); > > done: > return ret; >-- >2.17.1 > > >From 61e4fc83f45c701508fe3c34289f1c6be4636554 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:29:33 +0200 >Subject: [PATCH 17/48] source4/torture/smb2/timestamps.c > >--- > source4/torture/smb2/smb2.c | 2 + > source4/torture/smb2/timestamps.c | 459 +++++++++++++++++++++++++++++ > source4/torture/smb2/wscript_build | 1 + > 3 files changed, 462 insertions(+) > create mode 100644 source4/torture/smb2/timestamps.c > >diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c >index 344cf5a40a52..1f82a77ec22a 100644 >--- a/source4/torture/smb2/smb2.c >+++ b/source4/torture/smb2/smb2.c >@@ -187,6 +187,8 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) > > torture_suite_add_suite(suite, torture_smb2_doc_init(suite)); > >+ torture_suite_add_suite(suite, torture_smb2_timestamps_init(suite)); >+ > suite->description = talloc_strdup(suite, "SMB2-specific tests"); > > torture_register_suite(ctx, suite); >diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c >new file mode 100644 >index 000000000000..bb8e7325788b >--- /dev/null >+++ b/source4/torture/smb2/timestamps.c >@@ -0,0 +1,459 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ test suite for SMB2 timestamp handling >+ >+ Copyright (C) Stefan Metzmacher 2018 >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include "libcli/smb2/smb2.h" >+#include "libcli/smb2/smb2_calls.h" >+#include "../libcli/smb/smbXcli_base.h" >+#include "torture/torture.h" >+#include "torture/util.h" >+#include "torture/smb2/proto.h" >+#include "../lib/util/time_basic.h" >+ >+#define CHECK_VAL(v, correct) do { \ >+ torture_assert_int_equal_goto(tctx, v, correct, ret, done, __location__); \ >+} while (0) >+ >+#define CHECK_STATUS(status, correct) do { \ >+ torture_assert_ntstatus_equal_goto(tctx, status, correct, ret, done, __location__); \ >+} while (0) >+ >+#define CHECK_CREATED(__io, __created, __attribute) \ >+ do { \ >+ CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \ >+ CHECK_VAL((__io)->out.alloc_size, 0); \ >+ CHECK_VAL((__io)->out.size, 0); \ >+ CHECK_VAL((__io)->out.file_attr, (__attribute)); \ >+ CHECK_VAL((__io)->out.reserved2, 0); \ >+ } while(0) >+ >+#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ >+ const uint64_t _r = 10*1000*1000; \ >+ NTTIME _g = (given).basic_info.out.gelem; \ >+ NTTIME _gr = (_g / _r) * _r; \ >+ NTTIME _c = (correct).basic_info.out.celem; \ >+ NTTIME _cr = (_c / _r) * _r; \ >+ bool _strict = torture_setting_bool(tctx, "strict mode", false); \ >+ const char *_err = NULL; \ >+ if (_strict && (_g cmp _c)) { \ >+ _err = "strict"; \ >+ } else if ((_g cmp _c) && (_gr cmp _cr)) { \ >+ /* handle filesystem without high resolution timestamps */ \ >+ _err = "rounded"; \ >+ } \ >+ if (_err != NULL) { \ >+ struct timeval _gtv; \ >+ struct timeval _ctv; \ >+ struct timeval_buf _gtvb; \ >+ struct timeval_buf _ctvb; \ >+ nttime_to_timeval(&_gtv, _g); \ >+ nttime_to_timeval(&_ctv, _c); \ >+ torture_result(tctx, TORTURE_FAIL, \ >+ __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ >+ _err, \ >+ #given, #gelem, \ >+ timeval_str_buf(&_gtv, false, true, &_gtvb), \ >+ #cmp, \ >+ #correct, #celem, \ >+ timeval_str_buf(&_ctv, false, true, &_ctvb)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ >+} while (0) >+#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,!=) >+#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >+ COMPARE_WRITE_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ >+} while (0) >+#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,!=) >+#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ >+ COMPARE_ACCESS_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ >+} while (0) >+#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,!=) >+#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ >+ COMPARE_CHANGE_TIME_CMP(given,correct,<=) >+ >+#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ >+ COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >+} while (0) >+#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ >+ COMPARE_CREATE_TIME_CMP(given,correct,!=) >+ >+#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ >+ COMPARE_WRITE_TIME_EQUAL(given,correct); \ >+ COMPARE_CHANGE_TIME_EQUAL(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+} while (0) >+ >+#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+} while (0) >+ >+#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ >+ COMPARE_WRITE_TIME_GREATER(given,correct); \ >+ COMPARE_CHANGE_TIME_GREATER(given,correct); \ >+ COMPARE_ACCESS_TIME_GREATER(given,correct); \ >+ COMPARE_CREATE_TIME_EQUAL(given,correct); \ >+ COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >+ COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ >+} while (0) >+ >+#define GET_INFO_FILE(tree, finfo) do { \ >+ struct timeval _atv; \ >+ struct timeval _wtv; \ >+ struct timeval_buf _atvb; \ >+ struct timeval_buf _wtvb; \ >+ NTSTATUS _status; \ >+ _status = smb2_getinfo_file(tree, tctx, &finfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ ret = false; \ >+ torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ goto done; \ >+ } \ >+ nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ >+ nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ >+ torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ >+ #tree, #finfo, \ >+ timeval_str_buf(&_atv, false, true, &_atvb), \ >+ timeval_str_buf(&_wtv, false, true, &_wtvb)); \ >+} while (0) >+ >+#define GET_INFO_BOTH(finfo1, finfo2) do { \ >+ GET_INFO_FILE(tree2, finfo2); \ >+ GET_INFO_FILE(tree1, finfo1); \ >+ COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ >+} while (0) >+ >+#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ >+ NTSTATUS _status; \ >+ union smb_setfileinfo sfinfo; \ >+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >+ sfinfo.basic_info.in.file.fnum = tfnum; \ >+ sfinfo.basic_info.in.create_time = 0; \ >+ sfinfo.basic_info.in.access_time = 0; \ >+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >+ sfinfo.basic_info.in.change_time = 0; \ >+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >+ _status = smb_raw_setfileinfo(tree, &sfinfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+#define SET_INFO_FILE(finfo, wrtime) \ >+ SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) >+ >+#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ >+ NTSTATUS _status; \ >+ union smb_setfileinfo sfinfo; \ >+ sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >+ sfinfo.basic_info.in.file.fnum = tfnum; \ >+ sfinfo.basic_info.in.create_time = 0; \ >+ sfinfo.basic_info.in.access_time = 0; \ >+ unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >+ sfinfo.basic_info.in.write_time += (ns); \ >+ sfinfo.basic_info.in.change_time = 0; \ >+ sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >+ _status = smb_raw_setfileinfo(tree, &sfinfo); \ >+ if (!NT_STATUS_IS_OK(_status)) { \ >+ torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >+ nt_errstr(_status)); \ >+ ret = false; \ >+ goto done; \ >+ } \ >+} while (0) >+ >+struct test_durable_open_delaywrite1_state { >+ struct torture_context *tctx; >+ struct smb2_tree *tree1; >+ struct smb2_tree *tree2; >+ struct smb2_handle *h1; >+ struct smb2_handle *h2; >+}; >+ >+static bool test_durable_open_delaywrite1_get_info(void *private_data, >+ union smb_fileinfo *finfo) >+{ >+ struct test_durable_open_delaywrite1_state *state = >+ (struct test_durable_open_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ union smb_fileinfo t1finfo; >+ union smb_fileinfo t2finfo; >+ bool ret = true; >+ >+ ZERO_STRUCTP(finfo); >+ >+ ZERO_STRUCT(t1finfo); >+ t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t1finfo.basic_info.in.file.handle = *state->h1; >+ >+ ZERO_STRUCT(t2finfo); >+ t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t2finfo.basic_info.in.file.handle = *state->h2; >+ >+ GET_INFO_FILE(state->tree2, t2finfo); >+ GET_INFO_FILE(state->tree1, t1finfo); >+ if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { >+ /* >+ * There was a race, get it again on handle 2, >+ * but then they have to match. >+ */ >+ GET_INFO_FILE(state->tree2, t2finfo); >+ } >+ COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); >+ >+ finfo->basic_info.out = t1finfo.basic_info.out; >+done: >+ return ret; >+} >+ >+static bool test_durable_open_delaywrite1_write_data(void *private_data) >+{ >+ struct test_durable_open_delaywrite1_state *state = >+ (struct test_durable_open_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ struct smb2_write wr; >+ NTSTATUS status; >+ bool ret = true; >+ >+ ZERO_STRUCT(wr); >+ wr.in.file.handle = *state->h1; >+ wr.in.offset = 0; >+ wr.in.data = data_blob_const("x", 1); >+ status = smb2_write(state->tree1, &wr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ torture_assert_int_equal_goto(tctx, wr.out.nwritten, 1, >+ ret, done, "smb2_write"); >+ >+done: >+ return ret; >+} >+ >+static bool test_durable_open_delaywrite1_close(void *private_data, >+ union smb_fileinfo *finfo) >+{ >+ struct test_durable_open_delaywrite1_state *state = >+ (struct test_durable_open_delaywrite1_state *)private_data; >+ struct torture_context *tctx = state->tctx; >+ union smb_fileinfo t1finfoCL; >+ union smb_fileinfo t2finfoCL; >+ struct smb2_close cl1; >+ struct smb2_close cl2; >+ union smb_fileinfo t2finfo; >+ NTSTATUS status; >+ bool ret = true; >+ >+ ZERO_STRUCTP(finfo); >+ >+ ZERO_STRUCT(cl1); >+ cl1.in.file.handle = *state->h1; >+ cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(state->tree1, &cl1); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ state->h1 = NULL; >+ ZERO_STRUCT(t1finfoCL); >+ t1finfoCL.basic_info.out.create_time = cl1.out.create_time; >+ t1finfoCL.basic_info.out.access_time = cl1.out.access_time; >+ t1finfoCL.basic_info.out.write_time = cl1.out.write_time; >+ t1finfoCL.basic_info.out.change_time = cl1.out.change_time; >+ t1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >+ >+ ZERO_STRUCT(t2finfo); >+ t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ t2finfo.basic_info.in.file.handle = *state->h2; >+ >+ GET_INFO_FILE(state->tree2, t2finfo); >+ COMPARE_ALL_TIMES_EQUAL(t2finfo, t1finfoCL); >+ >+ ZERO_STRUCT(cl2); >+ cl2.in.file.handle = *state->h2; >+ cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >+ status = smb2_close(state->tree2, &cl2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ state->h2 = NULL; >+ ZERO_STRUCT(t2finfoCL); >+ t2finfoCL.basic_info.out.create_time = cl2.out.create_time; >+ t2finfoCL.basic_info.out.access_time = cl2.out.access_time; >+ t2finfoCL.basic_info.out.write_time = cl2.out.write_time; >+ t2finfoCL.basic_info.out.change_time = cl2.out.change_time; >+ t2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >+ COMPARE_ALL_TIMES_EQUAL(t2finfoCL, t1finfoCL); >+ >+ finfo->basic_info.out = t1finfoCL.basic_info.out; >+ >+done: >+ return ret; >+} >+ >+static bool test_durable_open_delaywrite1(struct torture_context *tctx, >+ struct smb2_tree *tree1, >+ struct smb2_tree *tree2) >+{ >+ struct test_durable_open_delaywrite1_state state = { >+ .tctx = tctx, >+ .tree1 = tree1, >+ .tree2 = tree2, >+ }; >+ NTSTATUS status; >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ char fname[256]; >+ struct smb2_handle _h1; >+ struct smb2_handle _h2; >+ struct smb2_create cr1; >+ struct smb2_create cr2; >+ union smb_fileinfo c1finfoCR, c1finfo0; >+ union smb_fileinfo c2finfoCR, c2finfo0; >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ double normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >+ //double normal_delay = 1000000; >+ //int normal_delay = 2000000; >+ bool ret = true; >+ bool ok; >+ >+ /* Choose a random name in case the state is left a little funky. */ >+ snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", >+ generate_random_str(tctx, 8)); >+ >+ smb2_util_unlink(tree1, fname); >+ >+ smb2_oplock_create_share(&cr1, fname, >+ smb2_util_share_access(""), >+ smb2_util_oplock_level("b")); >+ cr1.in.durable_open = true; >+ >+ status = smb2_create(tree1, mem_ctx, &cr1); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h1 = cr1.out.file.handle; >+ state.h1 = &_h1; >+ CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); >+ CHECK_VAL(cr1.out.durable_open, true); >+ CHECK_VAL(cr1.out.durable_open_v2, false); >+ CHECK_VAL(cr1.out.persistent_open, false); >+ >+ cr2 = cr1; >+ cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; >+ cr2.in.durable_open = false; >+ cr2.in.oplock_level = 0; >+ cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >+ status = smb2_create(tree2, mem_ctx, &cr2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ _h2 = cr2.out.file.handle; >+ state.h2 = &_h2; >+ CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr2.out.oplock_level, 0); >+ CHECK_VAL(cr2.out.durable_open, false); >+ CHECK_VAL(cr2.out.durable_open_v2, false); >+ CHECK_VAL(cr2.out.persistent_open, false); >+ >+ ZERO_STRUCT(c1finfoCR); >+ c1finfoCR.basic_info.out.create_time = cr1.out.create_time; >+ c1finfoCR.basic_info.out.access_time = cr1.out.access_time; >+ c1finfoCR.basic_info.out.write_time = cr1.out.write_time; >+ c1finfoCR.basic_info.out.change_time = cr1.out.change_time; >+ c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; >+ >+ ZERO_STRUCT(c2finfoCR); >+ c2finfoCR.basic_info.out.create_time = cr2.out.create_time; >+ c2finfoCR.basic_info.out.access_time = cr2.out.access_time; >+ c2finfoCR.basic_info.out.write_time = cr2.out.write_time; >+ c2finfoCR.basic_info.out.change_time = cr2.out.change_time; >+ c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; >+ >+ COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); >+ >+ ZERO_STRUCT(c1finfo0); >+ c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ c1finfo0.basic_info.in.file.handle = *state.h1; >+ >+ ZERO_STRUCT(c2finfo0); >+ c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >+ c2finfo0.basic_info.in.file.handle = *state.h2; >+ >+ GET_INFO_BOTH(c1finfo0, c2finfo0); >+ COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); >+ >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run1", >+ test_durable_open_delaywrite1_get_info, >+ test_durable_open_delaywrite1_write_data, >+ NULL, /* close_cb */ >+ &state); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); >+ ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ "run2", >+ test_durable_open_delaywrite1_get_info, >+ test_durable_open_delaywrite1_write_data, >+ test_durable_open_delaywrite1_close, >+ &state); >+ torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); >+ >+done: >+ if (state.h1 != NULL) { >+ smb2_util_close(tree1, *state.h1); >+ } >+ if (state.h2 != NULL) { >+ smb2_util_close(tree2, *state.h2); >+ } >+ >+ smb2_util_unlink(tree1, fname); >+ >+ talloc_free(tree1); >+ talloc_free(tree2); >+ >+ talloc_free(mem_ctx); >+ >+ return ret; >+} >+ >+struct torture_suite *torture_smb2_timestamps_init(TALLOC_CTX *ctx) >+{ >+ struct torture_suite *suite = >+ torture_suite_create(ctx, "timestamps"); >+ >+ torture_suite_add_2smb2_test(suite, "delaywrite1", >+ test_durable_open_delaywrite1); >+ >+ suite->description = talloc_strdup(suite, "SMB2-TIMESTAMPS tests"); >+ >+ return suite; >+} >diff --git a/source4/torture/smb2/wscript_build b/source4/torture/smb2/wscript_build >index 8b0060a2831b..209ea98a004c 100644 >--- a/source4/torture/smb2/wscript_build >+++ b/source4/torture/smb2/wscript_build >@@ -31,6 +31,7 @@ bld.SAMBA_MODULE('TORTURE_SMB2', > sharemode.c > smb2.c > streams.c >+ timestamps.c > util.c > ''', > subsystem='smbtorture', >-- >2.17.1 > > >From fafb38ee97ea0224d5ca6d4de3ffc8fbd8257abf Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:51:48 +0200 >Subject: [PATCH 18/48] source4/torture/util_writetime.c test_delay_writetime1 > >--- > source4/torture/util_writetime.c | 49 ++++++++++++++++++++++++++------ > 1 file changed, 40 insertions(+), 9 deletions(-) > >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_writetime.c >index 98d021b8d7f7..453bcd335c33 100644 >--- a/source4/torture/util_writetime.c >+++ b/source4/torture/util_writetime.c >@@ -1,7 +1,7 @@ > /* > Unix SMB/CIFS implementation. > >- test suite for delayed write time updates >+ test suite for SMB(1/2/3) timestamp handling > > Copyright (C) Stefan Metzmacher 2018 > >@@ -260,13 +260,12 @@ bool test_delay_writetime1(struct torture_context *tctx, > "Server didn't update write_time!"); > > COMPARE_TIMES_AFTER_WRITE(finfoT, finfo1); >- before_write = before_last_write; >- after_write = after_last_write; > finfo2 = finfoT; > break; > } > > COMPARE_ALL_TIMES_EQUAL(finfoT, finfo1); >+ finfo2 = finfoT; > > torture_comment(tctx, "Write while waiting\n"); > before_last_write = timeval_current(); >@@ -275,17 +274,49 @@ bool test_delay_writetime1(struct torture_context *tctx, > torture_assert(tctx, ok, "write_data_cb"); > } > >- // We may get one additional change... >+ before_write = before_last_write; >+ after_write = after_last_write; >+ ZERO_STRUCT(finfo3); >+ start = after_write; >+ end = timeval_add(&start, max_delay * 1.25, 0); >+ while (!timeval_expired(&end)) { >+ struct timeval before_get; >+ struct timeval after_get; >+ >+ smb_msleep(1 * msec); >+ >+ torture_comment(tctx, "Wait for change or no change\n"); >+ before_get = timeval_current(); >+ ok = get_basic_info_cb(private_data, &finfoT); >+ after_get = timeval_current(); >+ torture_assert(tctx, ok, "get_basic_info_cb: finfoT"); >+ >+ if (finfoT.basic_info.out.write_time > finfo2.basic_info.out.write_time) { >+ double delayS = timeval_elapsed2(&after_write, &before_get); >+ double delayL = timeval_elapsed2(&before_write, &after_get); > >- ok = get_basic_info_cb(private_data, &finfo3); >- torture_assert(tctx, ok, "get_basic_info_cb: finfo3"); >- COMPARE_ALL_TIMES_EQUAL(finfo3, finfo2); >+ torture_comment(tctx, "Server updated write_time after %.2f/%.2f seconds " >+ "(min delay == %.2f, max delay == %.2f)\n", >+ delayS, delayL, min_delay, max_delay); >+ torture_assert(tctx, (delayL >= min_delay), >+ "Server updated write_time to early!"); >+ torture_assert(tctx, (delayS <= max_delay), >+ "Server didn't update write_time!"); >+ >+ COMPARE_TIMES_AFTER_WRITE(finfoT, finfo2); >+ start = timeval_current(); >+ end = timeval_add(&start, max_delay * 1.25, 0); >+ finfo3 = finfoT; >+ break; >+ } >+ >+ COMPARE_ALL_TIMES_EQUAL(finfoT, finfo2); >+ finfo3 = finfoT; >+ } > > /* > * Make sure the time doesn't change during the next 5 seconds > */ >- start = timeval_current(); >- end = timeval_add(&start, max_delay * 1.25, 0); > while (!timeval_expired(&end)) { > smb_msleep(1 * msec); > torture_comment(tctx, "Check for no additional change\n"); >-- >2.17.1 > > >From bb18eaaa3870ec4f930a3a0bfe9fd6d85680cba5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:52:30 +0200 >Subject: [PATCH 19/48] sq source4/torture/smb2/timestamps.c > >--- > source4/torture/smb2/timestamps.c | 23 ----------------------- > 1 file changed, 23 deletions(-) > >diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c >index bb8e7325788b..44c7e9dab6e1 100644 >--- a/source4/torture/smb2/timestamps.c >+++ b/source4/torture/smb2/timestamps.c >@@ -83,24 +83,18 @@ > } while (0) > #define COMPARE_WRITE_TIME_EQUAL(given,correct) \ > COMPARE_WRITE_TIME_CMP(given,correct,!=) >-#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,<=) > > #define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ > COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ > } while (0) > #define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ > COMPARE_ACCESS_TIME_CMP(given,correct,!=) >-#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ >- COMPARE_ACCESS_TIME_CMP(given,correct,<=) > > #define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ > COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ > } while (0) > #define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ > COMPARE_CHANGE_TIME_CMP(given,correct,!=) >-#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ >- COMPARE_CHANGE_TIME_CMP(given,correct,<=) > > #define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ > COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >@@ -115,23 +109,6 @@ > COMPARE_CREATE_TIME_EQUAL(given,correct); \ > } while (0) > >-#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >- COMPARE_WRITE_TIME_GREATER(given,correct); \ >- COMPARE_CHANGE_TIME_GREATER(given,correct); \ >- COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >- COMPARE_CREATE_TIME_EQUAL(given,correct); \ >- COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >-} while (0) >- >-#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ >- COMPARE_WRITE_TIME_GREATER(given,correct); \ >- COMPARE_CHANGE_TIME_GREATER(given,correct); \ >- COMPARE_ACCESS_TIME_GREATER(given,correct); \ >- COMPARE_CREATE_TIME_EQUAL(given,correct); \ >- COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >- COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ >-} while (0) >- > #define GET_INFO_FILE(tree, finfo) do { \ > struct timeval _atv; \ > struct timeval _wtv; \ >-- >2.17.1 > > >From 40e2c7e3c94a48b27a79afbda7aad63b874004b9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:53:06 +0200 >Subject: [PATCH 20/48] sq source4/torture/basic/delaywrite.c > >--- > source4/torture/basic/delaywrite.c | 212 +++-------------------------- > 1 file changed, 18 insertions(+), 194 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 0f9fdfd7e5f1..5b4fbc2b6e3b 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -1314,50 +1314,48 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s > COMPARE_WRITE_TIME_EQUAL(given,correct); \ > } while (0) > >-#define GET_INFO_FILE(finfo) do { \ >+#define _DEBUG_BASIC_INFO(finfo, comment) do { \ > struct timeval atv; \ > struct timeval wtv; \ > struct timeval_buf atvb; \ > struct timeval_buf wtvb; \ >- NTSTATUS _status; \ >- _status = smb_raw_fileinfo(cli->tree, tctx, &finfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- ret = false; \ >- torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ >- nt_errstr(_status)); \ >- goto done; \ >- } \ > nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \ > nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \ >- torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ >+ torture_comment(tctx, "%s: Access(%s) Write(%s)\n", \ >+ comment, \ > timeval_str_buf(&atv, false, true, &atvb), \ > timeval_str_buf(&wtv, false, true, &wtvb)); \ > } while (0) >-#define GET_INFO_FILE2(finfo) do { \ >+#define _GET_INFO_FILE(tree, finfo) do { \ > NTSTATUS _status; \ >- _status = smb_raw_fileinfo(cli2->tree, tctx, &finfo); \ >+ _status = smb_raw_fileinfo(tree, tctx, &finfo); \ > if (!NT_STATUS_IS_OK(_status)) { \ > ret = false; \ > torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ > nt_errstr(_status)); \ > goto done; \ > } \ >- torture_comment(tctx, "fileinfo: Access(%s) Write(%s)\n", \ >- nt_time_string(tctx, finfo.basic_info.out.access_time), \ >- nt_time_string(tctx, finfo.basic_info.out.write_time)); \ >+ _DEBUG_BASIC_INFO(finfo, "fileinfo(" #tree ")"); \ > } while (0) >-#define GET_INFO_PATH(pinfo) do { \ >+#define _GET_INFO_PATH(tree, pinfo) do { \ > NTSTATUS _status; \ >- _status = smb_raw_pathinfo(cli2->tree, tctx, &pinfo); \ >+ _status = smb_raw_pathinfo(tree, tctx, &pinfo); \ > if (!NT_STATUS_IS_OK(_status)) { \ > torture_result(tctx, TORTURE_FAIL, __location__": pathinfo failed: %s", \ > nt_errstr(_status)); \ > ret = false; \ > goto done; \ > } \ >- torture_comment(tctx, "pathinfo: Access(%s) Write(%s)\n", \ >- nt_time_string(tctx, pinfo.basic_info.out.access_time), \ >- nt_time_string(tctx, pinfo.basic_info.out.write_time)); \ >+ _DEBUG_BASIC_INFO(pinfo, "pathinfo(" #tree ")"); \ >+} while (0) >+#define GET_INFO_FILE(finfo) do { \ >+ _GET_INFO_FILE(cli->tree, finfo); \ >+} while (0) >+#define GET_INFO_FILE2(finfo) do { \ >+ _GET_INFO_FILE(cli2->tree, finfo); \ >+} while (0) >+#define GET_INFO_PATH(pinfo) do { \ >+ _GET_INFO_PATH(cli2->tree, pinfo); \ > } while (0) > #define GET_INFO_BOTH(finfo,pinfo) do { \ > GET_INFO_FILE(finfo); \ >@@ -3334,181 +3332,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > > return ret; > } >-#if 0 >- NTSTATUS status; >- TALLOC_CTX *mem_ctx = talloc_new(tctx); >- char fname[256]; >- struct smb2_handle _h1; >- struct smb2_handle *h1 = NULL; >- struct smb2_handle _h2; >- struct smb2_handle *h2 = NULL; >- struct smb2_create cr1; >- struct smb2_create cr2; >- union smb_fileinfo c1finfoCR, c1finfo0, c1finfo1, c1finfo2, c1finfoCL; >- union smb_fileinfo c2finfoCR, c2finfo0, c2finfo1, c2finfo2, c2finfo3, c2finfoCL; >- struct smb2_close cl1; >- struct smb2_close cl2; >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- double normal_delay = 1000000; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >- //double normal_delay = 1000000; >- //int normal_delay = 2000000; >- double sec = ((double)used_delay) / ((double)normal_delay); >- int msec = 1000 * sec; >- bool ret = true; >- bool ok; >- >- /* Choose a random name in case the state is left a little funky. */ >- snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", >- generate_random_str(tctx, 8)); >- >- smb2_util_unlink(tree1, fname); >- >- smb2_oplock_create_share(&cr1, fname, >- smb2_util_share_access(""), >- smb2_util_oplock_level("b")); >- cr1.in.durable_open = true; >- >- status = smb2_create(tree1, mem_ctx, &cr1); >- CHECK_STATUS(status, NT_STATUS_OK); >- _h1 = cr1.out.file.handle; >- h1 = &_h1; >- CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); >- CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); >- CHECK_VAL(cr1.out.durable_open, true); >- CHECK_VAL(cr1.out.durable_open_v2, false); >- CHECK_VAL(cr1.out.persistent_open, false); >- >- cr2 = cr1; >- cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; >- cr2.in.durable_open = false; >- cr2.in.oplock_level = 0; >- cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >- status = smb2_create(tree2, mem_ctx, &cr2); >- CHECK_STATUS(status, NT_STATUS_OK); >- _h2 = cr2.out.file.handle; >- h2 = &_h2; >- CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); >- CHECK_VAL(cr2.out.oplock_level, 0); >- CHECK_VAL(cr2.out.durable_open, false); >- CHECK_VAL(cr2.out.durable_open_v2, false); >- CHECK_VAL(cr2.out.persistent_open, false); >- >- ZERO_STRUCT(c1finfoCR); >- c1finfoCR.basic_info.out.create_time = cr1.out.create_time; >- c1finfoCR.basic_info.out.access_time = cr1.out.access_time; >- c1finfoCR.basic_info.out.write_time = cr1.out.write_time; >- c1finfoCR.basic_info.out.change_time = cr1.out.change_time; >- c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; >- >- ZERO_STRUCT(c2finfoCR); >- c2finfoCR.basic_info.out.create_time = cr2.out.create_time; >- c2finfoCR.basic_info.out.access_time = cr2.out.access_time; >- c2finfoCR.basic_info.out.write_time = cr2.out.write_time; >- c2finfoCR.basic_info.out.change_time = cr2.out.change_time; >- c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; >- >- COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); >- >- ZERO_STRUCT(c1finfo0); >- c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- c1finfo0.basic_info.in.file.handle = *h1; >- c1finfo1 = c1finfo0; >- c1finfo2 = c1finfo0; >- >- ZERO_STRUCT(c2finfo0); >- c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- c2finfo0.basic_info.in.file.handle = *h2; >- c2finfo1 = c2finfo0; >- c2finfo2 = c2finfo0; >- c2finfo3 = c2finfo0; >- >- GET_INFO_BOTH(c1finfo0, c2finfo0); >- COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); >- >- state.h1 = h1; >- state.h2 = h2; >- >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run1", >- test_delaywrite_delaywrite1_get_info, >- test_delaywrite_delaywrite1_write_data, >- &state); >- torture_assert(tctx, ok, "test_delay_writetime1(1)"); >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run2", >- test_delaywrite_delaywrite1_get_info, >- test_delaywrite_delaywrite1_write_data, >- &state); >- torture_assert(tctx, ok, "test_delay_writetime2(2)"); > >- GET_INFO_BOTH(c1finfo1, c2finfo1); >- COMPARE_TIMES_AFTER_WRITE(c1finfo1, c1finfo0); >- >- /* sleep */ >- torture_comment(tctx, "Sleep ...\n"); >- smb_msleep(5 * msec); >- torture_comment(tctx, "... continue\n"); >- >- GET_INFO_BOTH(c1finfo2, c2finfo2); >- COMPARE_ALL_TIMES_EQUAL(c1finfo2, c1finfo1); >- >- /* >- * the close updates the write time to the time of the close >- * and not to the time of the last write! >- */ >- torture_comment(tctx, "Close the file handle\n"); >- >- ZERO_STRUCT(cl1); >- cl1.in.file.handle = *h1; >- cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(tree1, &cl1); >- CHECK_STATUS(status, NT_STATUS_OK); >- h1 = NULL; >- ZERO_STRUCT(c1finfoCL); >- c1finfoCL.basic_info.out.create_time = cl1.out.create_time; >- c1finfoCL.basic_info.out.access_time = cl1.out.access_time; >- c1finfoCL.basic_info.out.write_time = cl1.out.write_time; >- c1finfoCL.basic_info.out.change_time = cl1.out.change_time; >- c1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >- COMPARE_ALL_TIMES_EQUAL(c1finfoCL, c1finfo2); >- >- GET_INFO_FILE(tree2, c2finfo3); >- COMPARE_ALL_TIMES_EQUAL(c2finfo3, c1finfoCL); >- >- ZERO_STRUCT(cl2); >- cl2.in.file.handle = *h2; >- cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(tree2, &cl2); >- CHECK_STATUS(status, NT_STATUS_OK); >- h2 = NULL; >- ZERO_STRUCT(c2finfoCL); >- c2finfoCL.basic_info.out.create_time = cl2.out.create_time; >- c2finfoCL.basic_info.out.access_time = cl2.out.access_time; >- c2finfoCL.basic_info.out.write_time = cl2.out.write_time; >- c2finfoCL.basic_info.out.change_time = cl2.out.change_time; >- c2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >- COMPARE_ALL_TIMES_EQUAL(c2finfoCL, c1finfoCL); >- >-done: >- if (h1 != NULL) { >- smb2_util_close(tree1, *h1); >- } >- if (h2 != NULL) { >- smb2_util_close(tree2, *h2); >- } >- >- smb2_util_unlink(tree1, fname); >- >- talloc_free(tree1); >- talloc_free(tree2); >- >- talloc_free(mem_ctx); >- >- return ret; >-} >-#endif > /* > testing of delayed update of write_time > */ >-- >2.17.1 > > >From c666c2a9f1cd123ef4ba2c4d60ff63eb1bfaec2f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:53:17 +0200 >Subject: [PATCH 21/48] test_delayed_write_update TODO: research PATHINFO => > DEFER_CHANGE_ON_CLOSE > >--- > source4/torture/basic/delaywrite.c | 22 +++++++++++++++------- > 1 file changed, 15 insertions(+), 7 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 5b4fbc2b6e3b..b53ec0ada35e 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -72,13 +72,19 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > torture_assert_int_equal(tctx, written, 1, > "unexpected number of bytes written"); > >+ start = timeval_current(); >+ //smb_msleep(5 * msec); > pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; >+ pinfo1.basic_info.level = RAW_FILEINFO_MODE_INFORMATION; > pinfo1.basic_info.in.file.path = fname; > status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); > torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); > >- start = timeval_current(); >- end = timeval_add(&start, (120 * sec), 0); >+ //written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >+ //torture_assert_int_equal(tctx, written, 1, >+ // "unexpected number of bytes written"); >+ >+ end = timeval_add(&start, (30 * sec), 0); > while (!timeval_expired(&end)) { > status = smb_raw_fileinfo(cli->tree, tctx, &finfo2); > >@@ -107,14 +113,16 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > smb_msleep(1 * msec); > } > >- torture_assert_u64_not_equal(tctx, >- finfo2.basic_info.out.write_time, >- finfo1.basic_info.out.write_time, >- "Server did not update write time within " >- "120 seconds"); >+ //torture_assert_u64_not_equal(tctx, >+ // finfo2.basic_info.out.write_time, >+ // finfo1.basic_info.out.write_time, >+ // "Server did not update write time within " >+ // "120 seconds"); > > if (fnum1 != -1) > smbcli_close(cli->tree, fnum1); >+ status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); >+ torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); > smbcli_unlink(cli->tree, fname); > smbcli_deltree(cli->tree, BASEDIR); > >-- >2.17.1 > > >From ea4b58768d15880e1dac512d78073a96aa98c870 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:54:03 +0200 >Subject: [PATCH 22/48] Revert "test_delayed_write_update TODO: research > PATHINFO => DEFER_CHANGE_ON_CLOSE" > >This reverts commit c666c2a9f1cd123ef4ba2c4d60ff63eb1bfaec2f. >--- > source4/torture/basic/delaywrite.c | 22 +++++++--------------- > 1 file changed, 7 insertions(+), 15 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index b53ec0ada35e..5b4fbc2b6e3b 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -72,19 +72,13 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > torture_assert_int_equal(tctx, written, 1, > "unexpected number of bytes written"); > >- start = timeval_current(); >- //smb_msleep(5 * msec); > pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- pinfo1.basic_info.level = RAW_FILEINFO_MODE_INFORMATION; > pinfo1.basic_info.in.file.path = fname; > status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); > torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); > >- //written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); >- //torture_assert_int_equal(tctx, written, 1, >- // "unexpected number of bytes written"); >- >- end = timeval_add(&start, (30 * sec), 0); >+ start = timeval_current(); >+ end = timeval_add(&start, (120 * sec), 0); > while (!timeval_expired(&end)) { > status = smb_raw_fileinfo(cli->tree, tctx, &finfo2); > >@@ -113,16 +107,14 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > smb_msleep(1 * msec); > } > >- //torture_assert_u64_not_equal(tctx, >- // finfo2.basic_info.out.write_time, >- // finfo1.basic_info.out.write_time, >- // "Server did not update write time within " >- // "120 seconds"); >+ torture_assert_u64_not_equal(tctx, >+ finfo2.basic_info.out.write_time, >+ finfo1.basic_info.out.write_time, >+ "Server did not update write time within " >+ "120 seconds"); > > if (fnum1 != -1) > smbcli_close(cli->tree, fnum1); >- status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); >- torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); > smbcli_unlink(cli->tree, fname); > smbcli_deltree(cli->tree, BASEDIR); > >-- >2.17.1 > > >From fa2eeff50187202d8dd7d934c932829aec10166e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 19:57:53 +0200 >Subject: [PATCH 23/48] test_smb_timestamp_writetime1 > source4/torture/util_smb_timestamps.c > >--- > source4/torture/util.h | 20 +++++++++---------- > ...util_writetime.c => util_smb_timestamps.c} | 20 +++++++++---------- > source4/torture/wscript_build | 2 +- > 3 files changed, 21 insertions(+), 21 deletions(-) > rename source4/torture/{util_writetime.c => util_smb_timestamps.c} (96%) > >diff --git a/source4/torture/util.h b/source4/torture/util.h >index 05e983453d22..f3264f86fd8b 100644 >--- a/source4/torture/util.h >+++ b/source4/torture/util.h >@@ -107,15 +107,15 @@ NTSTATUS torture_check_privilege(struct smbcli_state *cli, > const char *sid_str, > const char *privilege); > >-bool test_delay_writetime1(struct torture_context *tctx, >- double used_delay, >- double normal_delay, >- const char *description, >- bool (*get_basic_info_cb)(void *private_data, >- union smb_fileinfo *finfo), >- bool (*write_data_cb)(void *private_data), >- bool (*close_cb)(void *private_data, >- union smb_fileinfo *finfo), >- void *private_data); >+bool test_smb_timestamp_writetime1(struct torture_context *tctx, >+ double used_delay, >+ double normal_delay, >+ const char *description, >+ bool (*get_basic_info_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ bool (*write_data_cb)(void *private_data), >+ bool (*close_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ void *private_data); > > #endif /* _TORTURE_UTIL_H_ */ >diff --git a/source4/torture/util_writetime.c b/source4/torture/util_smb_timestamps.c >similarity index 96% >rename from source4/torture/util_writetime.c >rename to source4/torture/util_smb_timestamps.c >index 453bcd335c33..7d1c0c6c64c0 100644 >--- a/source4/torture/util_writetime.c >+++ b/source4/torture/util_smb_timestamps.c >@@ -114,16 +114,16 @@ > COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ > } while (0) > >-bool test_delay_writetime1(struct torture_context *tctx, >- double used_delay, >- double normal_delay, >- const char *description, >- bool (*get_basic_info_cb)(void *private_data, >- union smb_fileinfo *finfo), >- bool (*write_data_cb)(void *private_data), >- bool (*close_cb)(void *private_data, >- union smb_fileinfo *finfo), >- void *private_data) >+bool test_smb_timestamp_writetime1(struct torture_context *tctx, >+ double used_delay, >+ double normal_delay, >+ const char *description, >+ bool (*get_basic_info_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ bool (*write_data_cb)(void *private_data), >+ bool (*close_cb)(void *private_data, >+ union smb_fileinfo *finfo), >+ void *private_data) > { > union smb_fileinfo finfo0, finfo1, finfo2, finfo3, finfoT; > struct timeval before_write; >diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build >index fb9c324da051..01f6caaec609 100644 >--- a/source4/torture/wscript_build >+++ b/source4/torture/wscript_build >@@ -2,7 +2,7 @@ > > > bld.SAMBA_SUBSYSTEM('TORTURE_UTIL', >- source='util_smb.c util_writetime.c', >+ source='util_smb.c util_smb_timestamps.c', > public_deps='torture popt POPT_CREDENTIALS', > deps='smbclient-raw' > ) >-- >2.17.1 > > >From cdd42744698edea532de52db34f6b418688a739a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:04:02 +0200 >Subject: [PATCH 24/48] revert source4/torture/smb2/durable_open.c > >--- > source4/torture/smb2/durable_open.c | 404 +--------------------------- > 1 file changed, 1 insertion(+), 403 deletions(-) > >diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c >index 63eb7e99922a..17b3b217b56e 100644 >--- a/source4/torture/smb2/durable_open.c >+++ b/source4/torture/smb2/durable_open.c >@@ -25,9 +25,8 @@ > #include "libcli/smb2/smb2_calls.h" > #include "../libcli/smb/smbXcli_base.h" > #include "torture/torture.h" >-#include "torture/util.h" > #include "torture/smb2/proto.h" >-#include "../lib/util/time_basic.h" >+#include "../libcli/smb/smbXcli_base.h" > > #define CHECK_VAL(v, correct) do { \ > if ((v) != (correct)) { \ >@@ -2753,405 +2752,6 @@ done: > return ret; > } > >-#define COMPARE_TIME_CMP(given, gelem, correct, celem, cmp) do { \ >- const uint64_t _r = 10*1000*1000; \ >- NTTIME _g = (given).basic_info.out.gelem; \ >- NTTIME _gr = (_g / _r) * _r; \ >- NTTIME _c = (correct).basic_info.out.celem; \ >- NTTIME _cr = (_c / _r) * _r; \ >- bool _strict = torture_setting_bool(tctx, "strict mode", false); \ >- const char *_err = NULL; \ >- if (_strict && (_g cmp _c)) { \ >- _err = "strict"; \ >- } else if ((_g cmp _c) && (_gr cmp _cr)) { \ >- /* handle filesystem without high resolution timestamps */ \ >- _err = "rounded"; \ >- } \ >- if (_err != NULL) { \ >- struct timeval _gtv; \ >- struct timeval _ctv; \ >- struct timeval_buf _gtvb; \ >- struct timeval_buf _ctvb; \ >- nttime_to_timeval(&_gtv, _g); \ >- nttime_to_timeval(&_ctv, _c); \ >- torture_result(tctx, TORTURE_FAIL, \ >- __location__": %s wrong (%s.%s)%s %s (%s.%s)%s", \ >- _err, \ >- #given, #gelem, \ >- timeval_str_buf(&_gtv, false, true, &_gtvb), \ >- #cmp, \ >- #correct, #celem, \ >- timeval_str_buf(&_ctv, false, true, &_ctvb)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >-#define COMPARE_WRITE_TIME_CMP(given, correct, cmp) do { \ >- COMPARE_TIME_CMP(given, write_time, correct, write_time, cmp); \ >-} while (0) >-#define COMPARE_WRITE_TIME_EQUAL(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,!=) >-#define COMPARE_WRITE_TIME_GREATER(given,correct) \ >- COMPARE_WRITE_TIME_CMP(given,correct,<=) >- >-#define COMPARE_ACCESS_TIME_CMP(given, correct, cmp) do { \ >- COMPARE_TIME_CMP(given, access_time, correct, access_time, cmp); \ >-} while (0) >-#define COMPARE_ACCESS_TIME_EQUAL(given,correct) \ >- COMPARE_ACCESS_TIME_CMP(given,correct,!=) >-#define COMPARE_ACCESS_TIME_GREATER(given,correct) \ >- COMPARE_ACCESS_TIME_CMP(given,correct,<=) >- >-#define COMPARE_CHANGE_TIME_CMP(given, correct, cmp) do { \ >- COMPARE_TIME_CMP(given, change_time, correct, change_time, cmp); \ >-} while (0) >-#define COMPARE_CHANGE_TIME_EQUAL(given,correct) \ >- COMPARE_CHANGE_TIME_CMP(given,correct,!=) >-#define COMPARE_CHANGE_TIME_GREATER(given,correct) \ >- COMPARE_CHANGE_TIME_CMP(given,correct,<=) >- >-#define COMPARE_CREATE_TIME_CMP(given, correct, cmp) do { \ >- COMPARE_TIME_CMP(given, create_time, correct, create_time, cmp); \ >-} while (0) >-#define COMPARE_CREATE_TIME_EQUAL(given,correct) \ >- COMPARE_CREATE_TIME_CMP(given,correct,!=) >- >-#define COMPARE_ALL_TIMES_EQUAL(given,correct) do { \ >- COMPARE_WRITE_TIME_EQUAL(given,correct); \ >- COMPARE_CHANGE_TIME_EQUAL(given,correct); \ >- COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >- COMPARE_CREATE_TIME_EQUAL(given,correct); \ >-} while (0) >- >-#define COMPARE_TIMES_AFTER_WRITE(given,correct) do { \ >- COMPARE_WRITE_TIME_GREATER(given,correct); \ >- COMPARE_CHANGE_TIME_GREATER(given,correct); \ >- COMPARE_ACCESS_TIME_EQUAL(given,correct); \ >- COMPARE_CREATE_TIME_EQUAL(given,correct); \ >- COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >-} while (0) >- >-#define COMPARE_TIMES_AFTER_CLOSE(given,correct) do { \ >- COMPARE_WRITE_TIME_GREATER(given,correct); \ >- COMPARE_CHANGE_TIME_GREATER(given,correct); \ >- COMPARE_ACCESS_TIME_GREATER(given,correct); \ >- COMPARE_CREATE_TIME_EQUAL(given,correct); \ >- COMPARE_TIME_CMP(given, change_time, given, write_time, !=); \ >- COMPARE_TIME_CMP(given, access_time, given, write_time, !=); \ >-} while (0) >- >-#define GET_INFO_FILE(tree, finfo) do { \ >- struct timeval _atv; \ >- struct timeval _wtv; \ >- struct timeval_buf _atvb; \ >- struct timeval_buf _wtvb; \ >- NTSTATUS _status; \ >- _status = smb2_getinfo_file(tree, tctx, &finfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- ret = false; \ >- torture_result(tctx, TORTURE_FAIL, __location__": fileinfo failed: %s", \ >- nt_errstr(_status)); \ >- goto done; \ >- } \ >- nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ >- nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ >- torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ >- #tree, #finfo, \ >- timeval_str_buf(&_atv, false, true, &_atvb), \ >- timeval_str_buf(&_wtv, false, true, &_wtvb)); \ >-} while (0) >- >-#define GET_INFO_BOTH(finfo1, finfo2) do { \ >- GET_INFO_FILE(tree2, finfo2); \ >- GET_INFO_FILE(tree1, finfo1); \ >- COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ >-} while (0) >- >-#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ >- NTSTATUS _status; \ >- union smb_setfileinfo sfinfo; \ >- sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >- sfinfo.basic_info.in.file.fnum = tfnum; \ >- sfinfo.basic_info.in.create_time = 0; \ >- sfinfo.basic_info.in.access_time = 0; \ >- unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >- sfinfo.basic_info.in.change_time = 0; \ >- sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >- _status = smb_raw_setfileinfo(tree, &sfinfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >- nt_errstr(_status)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >-#define SET_INFO_FILE(finfo, wrtime) \ >- SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) >- >-#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ >- NTSTATUS _status; \ >- union smb_setfileinfo sfinfo; \ >- sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >- sfinfo.basic_info.in.file.fnum = tfnum; \ >- sfinfo.basic_info.in.create_time = 0; \ >- sfinfo.basic_info.in.access_time = 0; \ >- unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >- sfinfo.basic_info.in.write_time += (ns); \ >- sfinfo.basic_info.in.change_time = 0; \ >- sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >- _status = smb_raw_setfileinfo(tree, &sfinfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >- nt_errstr(_status)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >- >-struct test_durable_open_delaywrite1_state { >- struct torture_context *tctx; >- struct smb2_tree *tree1; >- struct smb2_tree *tree2; >- struct smb2_handle *h1; >- struct smb2_handle *h2; >-}; >- >-static bool test_durable_open_delaywrite1_get_info(void *private_data, >- union smb_fileinfo *finfo) >-{ >- struct test_durable_open_delaywrite1_state *state = >- (struct test_durable_open_delaywrite1_state *)private_data; >- struct torture_context *tctx = state->tctx; >- union smb_fileinfo t1finfo; >- union smb_fileinfo t2finfo; >- bool ret = true; >- >- ZERO_STRUCTP(finfo); >- >- ZERO_STRUCT(t1finfo); >- t1finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- t1finfo.basic_info.in.file.handle = *state->h1; >- >- ZERO_STRUCT(t2finfo); >- t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- t2finfo.basic_info.in.file.handle = *state->h2; >- >- GET_INFO_FILE(state->tree2, t2finfo); >- GET_INFO_FILE(state->tree1, t1finfo); >- if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { >- /* >- * There was a race, get it again on handle 2, >- * but then they have to match. >- */ >- GET_INFO_FILE(state->tree2, t2finfo); >- } >- COMPARE_ALL_TIMES_EQUAL(t1finfo, t2finfo); >- >- finfo->basic_info.out = t1finfo.basic_info.out; >-done: >- return ret; >-} >- >-static bool test_durable_open_delaywrite1_write_data(void *private_data) >-{ >- struct test_durable_open_delaywrite1_state *state = >- (struct test_durable_open_delaywrite1_state *)private_data; >- struct torture_context *tctx = state->tctx; >- struct smb2_write wr; >- NTSTATUS status; >- bool ret = true; >- >- ZERO_STRUCT(wr); >- wr.in.file.handle = *state->h1; >- wr.in.offset = 0; >- wr.in.data = data_blob_const("x", 1); >- status = smb2_write(state->tree1, &wr); >- CHECK_STATUS(status, NT_STATUS_OK); >- torture_assert_int_equal_goto(tctx, wr.out.nwritten, 1, >- ret, done, "smb2_write"); >- >-done: >- return ret; >-} >- >-static bool test_durable_open_delaywrite1_close(void *private_data, >- union smb_fileinfo *finfo) >-{ >- struct test_durable_open_delaywrite1_state *state = >- (struct test_durable_open_delaywrite1_state *)private_data; >- struct torture_context *tctx = state->tctx; >- union smb_fileinfo t1finfoCL; >- union smb_fileinfo t2finfoCL; >- struct smb2_close cl1; >- struct smb2_close cl2; >- union smb_fileinfo t2finfo; >- NTSTATUS status; >- bool ret = true; >- >- ZERO_STRUCTP(finfo); >- >- ZERO_STRUCT(cl1); >- cl1.in.file.handle = *state->h1; >- cl1.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(state->tree1, &cl1); >- CHECK_STATUS(status, NT_STATUS_OK); >- state->h1 = NULL; >- ZERO_STRUCT(t1finfoCL); >- t1finfoCL.basic_info.out.create_time = cl1.out.create_time; >- t1finfoCL.basic_info.out.access_time = cl1.out.access_time; >- t1finfoCL.basic_info.out.write_time = cl1.out.write_time; >- t1finfoCL.basic_info.out.change_time = cl1.out.change_time; >- t1finfoCL.basic_info.out.attrib = cl1.out.file_attr; >- >- ZERO_STRUCT(t2finfo); >- t2finfo.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- t2finfo.basic_info.in.file.handle = *state->h2; >- >- GET_INFO_FILE(state->tree2, t2finfo); >- COMPARE_ALL_TIMES_EQUAL(t2finfo, t1finfoCL); >- >- ZERO_STRUCT(cl2); >- cl2.in.file.handle = *state->h2; >- cl2.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; >- status = smb2_close(state->tree2, &cl2); >- CHECK_STATUS(status, NT_STATUS_OK); >- state->h2 = NULL; >- ZERO_STRUCT(t2finfoCL); >- t2finfoCL.basic_info.out.create_time = cl2.out.create_time; >- t2finfoCL.basic_info.out.access_time = cl2.out.access_time; >- t2finfoCL.basic_info.out.write_time = cl2.out.write_time; >- t2finfoCL.basic_info.out.change_time = cl2.out.change_time; >- t2finfoCL.basic_info.out.attrib = cl2.out.file_attr; >- COMPARE_ALL_TIMES_EQUAL(t2finfoCL, t1finfoCL); >- >- finfo->basic_info.out = t1finfoCL.basic_info.out; >- >-done: >- return ret; >-} >- >-static bool test_durable_open_delaywrite1(struct torture_context *tctx, >- struct smb2_tree *tree1, >- struct smb2_tree *tree2) >-{ >- struct test_durable_open_delaywrite1_state state = { >- .tctx = tctx, >- .tree1 = tree1, >- .tree2 = tree2, >- }; >- NTSTATUS status; >- TALLOC_CTX *mem_ctx = talloc_new(tctx); >- char fname[256]; >- struct smb2_handle _h1; >- struct smb2_handle _h2; >- struct smb2_create cr1; >- struct smb2_create cr2; >- union smb_fileinfo c1finfoCR, c1finfo0; >- union smb_fileinfo c2finfoCR, c2finfo0; >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- double normal_delay = 1000000; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >- //double normal_delay = 1000000; >- //int normal_delay = 2000000; >- bool ret = true; >- bool ok; >- >- /* Choose a random name in case the state is left a little funky. */ >- snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", >- generate_random_str(tctx, 8)); >- >- smb2_util_unlink(tree1, fname); >- >- smb2_oplock_create_share(&cr1, fname, >- smb2_util_share_access(""), >- smb2_util_oplock_level("b")); >- cr1.in.durable_open = true; >- >- status = smb2_create(tree1, mem_ctx, &cr1); >- CHECK_STATUS(status, NT_STATUS_OK); >- _h1 = cr1.out.file.handle; >- state.h1 = &_h1; >- CHECK_CREATED(&cr1, CREATED, FILE_ATTRIBUTE_ARCHIVE); >- CHECK_VAL(cr1.out.oplock_level, smb2_util_oplock_level("b")); >- CHECK_VAL(cr1.out.durable_open, true); >- CHECK_VAL(cr1.out.durable_open_v2, false); >- CHECK_VAL(cr1.out.persistent_open, false); >- >- cr2 = cr1; >- cr2.in.desired_access = SEC_FILE_READ_ATTRIBUTE; >- cr2.in.durable_open = false; >- cr2.in.oplock_level = 0; >- cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >- status = smb2_create(tree2, mem_ctx, &cr2); >- CHECK_STATUS(status, NT_STATUS_OK); >- _h2 = cr2.out.file.handle; >- state.h2 = &_h2; >- CHECK_CREATED(&cr2, EXISTED, FILE_ATTRIBUTE_ARCHIVE); >- CHECK_VAL(cr2.out.oplock_level, 0); >- CHECK_VAL(cr2.out.durable_open, false); >- CHECK_VAL(cr2.out.durable_open_v2, false); >- CHECK_VAL(cr2.out.persistent_open, false); >- >- ZERO_STRUCT(c1finfoCR); >- c1finfoCR.basic_info.out.create_time = cr1.out.create_time; >- c1finfoCR.basic_info.out.access_time = cr1.out.access_time; >- c1finfoCR.basic_info.out.write_time = cr1.out.write_time; >- c1finfoCR.basic_info.out.change_time = cr1.out.change_time; >- c1finfoCR.basic_info.out.attrib = cr1.out.file_attr; >- >- ZERO_STRUCT(c2finfoCR); >- c2finfoCR.basic_info.out.create_time = cr2.out.create_time; >- c2finfoCR.basic_info.out.access_time = cr2.out.access_time; >- c2finfoCR.basic_info.out.write_time = cr2.out.write_time; >- c2finfoCR.basic_info.out.change_time = cr2.out.change_time; >- c2finfoCR.basic_info.out.attrib = cr2.out.file_attr; >- >- COMPARE_ALL_TIMES_EQUAL(c1finfoCR, c2finfoCR); >- >- ZERO_STRUCT(c1finfo0); >- c1finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- c1finfo0.basic_info.in.file.handle = *state.h1; >- >- ZERO_STRUCT(c2finfo0); >- c2finfo0.basic_info.level = RAW_FILEINFO_BASIC_INFORMATION; >- c2finfo0.basic_info.in.file.handle = *state.h2; >- >- GET_INFO_BOTH(c1finfo0, c2finfo0); >- COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); >- >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run1", >- test_durable_open_delaywrite1_get_info, >- test_durable_open_delaywrite1_write_data, >- NULL, /* close_cb */ >- &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >- "run2", >- test_durable_open_delaywrite1_get_info, >- test_durable_open_delaywrite1_write_data, >- test_durable_open_delaywrite1_close, >- &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); >- >-done: >- if (state.h1 != NULL) { >- smb2_util_close(tree1, *state.h1); >- } >- if (state.h2 != NULL) { >- smb2_util_close(tree2, *state.h2); >- } >- >- smb2_util_unlink(tree1, fname); >- >- talloc_free(tree1); >- talloc_free(tree2); >- >- talloc_free(mem_ctx); >- >- return ret; >-} > > struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) > { >@@ -3187,8 +2787,6 @@ struct torture_suite *torture_smb2_durable_open_init(TALLOC_CTX *ctx) > test_durable_open_alloc_size); > torture_suite_add_1smb2_test(suite, "read-only", > test_durable_open_read_only); >- torture_suite_add_2smb2_test(suite, "delaywrite1", >- test_durable_open_delaywrite1); > > suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests"); > >-- >2.17.1 > > >From 9c7d557e449d94e950d0b60ad2f52a0dd33bc7e8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:07:18 +0200 >Subject: [PATCH 25/48] sq test_delaywrite_delaywrite1 > source4/torture/basic/delaywrite.c > >--- > source4/torture/basic/delaywrite.c | 38 ++++++++++++++---------------- > 1 file changed, 18 insertions(+), 20 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 5b4fbc2b6e3b..1c11c9e26f89 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3277,48 +3277,46 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > }; > const char *fname = BASEDIR "\\torture_file3.txt"; > bool ret = true; >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); > double normal_delay = 1000000; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >- //double normal_delay = 1000000; >- //int normal_delay = 2000000; >+ double used_delay; > bool ok; > >+ used_delay = torture_setting_int(tctx, "writetimeupdatedelay", >+ normal_delay); >+ > torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); > >- torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), >+ "Failed to setup up test directory: " BASEDIR); > > torture_comment(tctx, "Open the file handle\n"); > state.fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (state.fnum1 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >+ torture_assert_int_not_equal_goto(tctx, state.fnum1, -1, >+ ret, done, >+ "unable to open fnum1"); > state.fnum2 = smbcli_open(cli2->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >- if (state.fnum2 == -1) { >- ret = false; >- torture_result(tctx, TORTURE_FAIL, __location__": unable to open %s", fname); >- goto done; >- } >+ torture_assert_int_not_equal_goto(tctx, state.fnum2, -1, >+ ret, done, >+ "unable to open fnum2"); > > state.fname = fname; > >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run1", > test_delaywrite_delaywrite1_get_info, > test_delaywrite_delaywrite1_write_data, > NULL, /* close_cb */ > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ torture_assert_goto(tctx, ok, ret, done, >+ "test_smb_timestamp_writetime1(1)"); >+ ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run2", > test_delaywrite_delaywrite1_get_info, > test_delaywrite_delaywrite1_write_data, > test_delaywrite_delaywrite1_close, > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); >+ torture_assert_goto(tctx, ok, ret, done, >+ "test_smb_timestamp_writetime1(2)"); > > done: > if (state.fnum1 != -1) { >-- >2.17.1 > > >From 67f9b259996c887158637dff8f5dc7e1d2f3e58d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:07:43 +0200 >Subject: [PATCH 26/48] sq test_durable_open_delaywrite1 > source4/torture/smb2/timestamps.c > >--- > source4/torture/smb2/timestamps.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > >diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c >index 44c7e9dab6e1..4cafec889a8d 100644 >--- a/source4/torture/smb2/timestamps.c >+++ b/source4/torture/smb2/timestamps.c >@@ -389,20 +389,22 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > GET_INFO_BOTH(c1finfo0, c2finfo0); > COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); > >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run1", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > NULL, /* close_cb */ > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(1)"); >- ok = test_delay_writetime1(tctx, used_delay, normal_delay, >+ torture_assert_goto(tctx, ok, ret, done, >+ "test_smb_timestamp_writetime1(1)"); >+ ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run2", > test_durable_open_delaywrite1_get_info, > test_durable_open_delaywrite1_write_data, > test_durable_open_delaywrite1_close, > &state); >- torture_assert_goto(tctx, ok, ret, done, "test_delay_writetime1(2)"); >+ torture_assert_goto(tctx, ok, ret, done, >+ "test_smb_timestamp_writetime1(2)"); > > done: > if (state.h1 != NULL) { >-- >2.17.1 > > >From ed114c60c63f8ae3ec6af3338a49a6c7e010a9a1 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:08:25 +0200 >Subject: [PATCH 27/48] Revert "break test_delayed_write_update with a PATHINFO > call..." > >This reverts commit 713123bda5075672afcb211a6742950ad968b146. >--- > source4/torture/basic/delaywrite.c | 6 ------ > 1 file changed, 6 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 1c11c9e26f89..4008df680eaa 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -37,7 +37,6 @@ > static bool test_delayed_write_update(struct torture_context *tctx, struct smbcli_state *cli) > { > union smb_fileinfo finfo1, finfo2; >- union smb_fileinfo pinfo1; > const char *fname = BASEDIR "\\torture_file.txt"; > NTSTATUS status; > int fnum1 = -1; >@@ -72,11 +71,6 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > torture_assert_int_equal(tctx, written, 1, > "unexpected number of bytes written"); > >- pinfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO; >- pinfo1.basic_info.in.file.path = fname; >- status = smb_raw_pathinfo(cli->tree, tctx, &pinfo1); >- torture_assert_ntstatus_ok(tctx, status, "pathinfo failed"); >- > start = timeval_current(); > end = timeval_add(&start, (120 * sec), 0); > while (!timeval_expired(&end)) { >-- >2.17.1 > > >From 65d9404157c0d17cc8ca188c9ec26ce6d9750f36 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:09:31 +0200 >Subject: [PATCH 28/48] revert test_delayed_write_update3 > >--- > source4/torture/basic/delaywrite.c | 4 +--- > 1 file changed, 1 insertion(+), 3 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 4008df680eaa..6f5bd2a8b6a9 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -1411,8 +1411,6 @@ static bool test_delayed_write_update3(struct torture_context *tctx, > struct timeval start; > struct timeval end; > double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- //int normal_delay = 1000000; > int normal_delay = 2000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; >@@ -1466,7 +1464,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, > if (finfo1.basic_info.out.write_time > finfo0.basic_info.out.write_time) { > double diff = timeval_elapsed(&start); > if (diff < (used_delay / (double)1000000)) { >- torture_result(tctx, TORTURE_FAIL, "111Server updated write_time after %.2f seconds " >+ torture_result(tctx, TORTURE_FAIL, "Server updated write_time after %.2f seconds " > "(write time update delay == %.2f) (wrong!)\n", > diff, used_delay / (double)1000000); > ret = false; >-- >2.17.1 > > >From 52063482e2a5ad1fd7a8abccbf7aff8d8fa631f3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:11:42 +0200 >Subject: [PATCH 29/48] sq source4/torture/smb2/timestamps.c > >--- > source4/torture/smb2/timestamps.c | 9 ++++----- > 1 file changed, 4 insertions(+), 5 deletions(-) > >diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c >index 4cafec889a8d..55c6b1694226 100644 >--- a/source4/torture/smb2/timestamps.c >+++ b/source4/torture/smb2/timestamps.c >@@ -317,15 +317,14 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > struct smb2_create cr2; > union smb_fileinfo c1finfoCR, c1finfo0; > union smb_fileinfo c2finfoCR, c2finfo0; >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- //double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); > double normal_delay = 1000000; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", normal_delay); >- //double normal_delay = 1000000; >- //int normal_delay = 2000000; >+ double used_delay; > bool ret = true; > bool ok; > >+ used_delay = torture_setting_int(tctx, "writetimeupdatedelay", >+ normal_delay); >+ > /* Choose a random name in case the state is left a little funky. */ > snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", > generate_random_str(tctx, 8)); >-- >2.17.1 > > >From b48f60349c5552c415db18ab4ffccc52c2822f49 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 20:22:07 +0200 >Subject: [PATCH 30/48] sq test_smb_timestamp_writetime1 > source4/torture/util_smb_timestamps.c > >--- > source4/torture/util_smb_timestamps.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > >diff --git a/source4/torture/util_smb_timestamps.c b/source4/torture/util_smb_timestamps.c >index 7d1c0c6c64c0..9d007a542ac7 100644 >--- a/source4/torture/util_smb_timestamps.c >+++ b/source4/torture/util_smb_timestamps.c >@@ -199,7 +199,6 @@ bool test_smb_timestamp_writetime1(struct torture_context *tctx, > } > > COMPARE_ALL_TIMES_EQUAL(finfoT, finfo0); >- //smb_msleep(0.01 * msec); > smb_msleep(1 * msec); > } > >@@ -239,8 +238,6 @@ bool test_smb_timestamp_writetime1(struct torture_context *tctx, > struct timeval before_get; > struct timeval after_get; > >- smb_msleep(0.01 * msec); >- > torture_comment(tctx, "Wait for change\n"); > before_get = timeval_current(); > ok = get_basic_info_cb(private_data, &finfoT); >@@ -272,6 +269,8 @@ bool test_smb_timestamp_writetime1(struct torture_context *tctx, > ok = write_data_cb(private_data); > after_last_write = timeval_current(); > torture_assert(tctx, ok, "write_data_cb"); >+ >+ smb_msleep(0.01 * msec); > } > > before_write = before_last_write; >-- >2.17.1 > > >From 682c0b0d335caa44a7e2202083dfa4e2f087c422 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 21:11:39 +0200 >Subject: [PATCH 31/48] sq source4/torture/smb2/timestamps.c > >--- > source4/torture/smb2/timestamps.c | 118 ++++++++++-------------------- > 1 file changed, 40 insertions(+), 78 deletions(-) > >diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c >index 55c6b1694226..259075ebc00a 100644 >--- a/source4/torture/smb2/timestamps.c >+++ b/source4/torture/smb2/timestamps.c >@@ -39,8 +39,6 @@ > #define CHECK_CREATED(__io, __created, __attribute) \ > do { \ > CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_ ## __created); \ >- CHECK_VAL((__io)->out.alloc_size, 0); \ >- CHECK_VAL((__io)->out.size, 0); \ > CHECK_VAL((__io)->out.file_attr, (__attribute)); \ > CHECK_VAL((__io)->out.reserved2, 0); \ > } while(0) >@@ -109,11 +107,19 @@ > COMPARE_CREATE_TIME_EQUAL(given,correct); \ > } while (0) > >+#define DEBUG_BASIC_INFO(finfo, comment) do { \ >+ struct timeval atv; \ >+ struct timeval wtv; \ >+ struct timeval_buf atvb; \ >+ struct timeval_buf wtvb; \ >+ nttime_to_timeval(&atv, finfo.basic_info.out.access_time); \ >+ nttime_to_timeval(&wtv, finfo.basic_info.out.write_time); \ >+ torture_comment(tctx, "%s: Access(%s) Write(%s)\n", \ >+ comment, \ >+ timeval_str_buf(&atv, false, true, &atvb), \ >+ timeval_str_buf(&wtv, false, true, &wtvb)); \ >+} while (0) > #define GET_INFO_FILE(tree, finfo) do { \ >- struct timeval _atv; \ >- struct timeval _wtv; \ >- struct timeval_buf _atvb; \ >- struct timeval_buf _wtvb; \ > NTSTATUS _status; \ > _status = smb2_getinfo_file(tree, tctx, &finfo); \ > if (!NT_STATUS_IS_OK(_status)) { \ >@@ -122,12 +128,7 @@ > nt_errstr(_status)); \ > goto done; \ > } \ >- nttime_to_timeval(&_atv, finfo.basic_info.out.access_time); \ >- nttime_to_timeval(&_wtv, finfo.basic_info.out.write_time); \ >- torture_comment(tctx, "fileinfo(%s,%s): Access(%s) Write(%s)\n", \ >- #tree, #finfo, \ >- timeval_str_buf(&_atv, false, true, &_atvb), \ >- timeval_str_buf(&_wtv, false, true, &_wtvb)); \ >+ DEBUG_BASIC_INFO(finfo, "fileinfo(" #tree ")"); \ > } while (0) > > #define GET_INFO_BOTH(finfo1, finfo2) do { \ >@@ -136,48 +137,7 @@ > COMPARE_ALL_TIMES_EQUAL(finfo1, finfo2); \ > } while (0) > >-#define SET_INFO_FILE_EX(finfo, wrtime, tree, tfnum) do { \ >- NTSTATUS _status; \ >- union smb_setfileinfo sfinfo; \ >- sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >- sfinfo.basic_info.in.file.fnum = tfnum; \ >- sfinfo.basic_info.in.create_time = 0; \ >- sfinfo.basic_info.in.access_time = 0; \ >- unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >- sfinfo.basic_info.in.change_time = 0; \ >- sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >- _status = smb_raw_setfileinfo(tree, &sfinfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >- nt_errstr(_status)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >-#define SET_INFO_FILE(finfo, wrtime) \ >- SET_INFO_FILE_EX(finfo, wrtime, cli->tree, fnum1) >- >-#define SET_INFO_FILE_NS(finfo, wrtime, ns, tree, tfnum) do { \ >- NTSTATUS _status; \ >- union smb_setfileinfo sfinfo; \ >- sfinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO; \ >- sfinfo.basic_info.in.file.fnum = tfnum; \ >- sfinfo.basic_info.in.create_time = 0; \ >- sfinfo.basic_info.in.access_time = 0; \ >- unix_to_nt_time(&sfinfo.basic_info.in.write_time, (wrtime)); \ >- sfinfo.basic_info.in.write_time += (ns); \ >- sfinfo.basic_info.in.change_time = 0; \ >- sfinfo.basic_info.in.attrib = finfo1.basic_info.out.attrib; \ >- _status = smb_raw_setfileinfo(tree, &sfinfo); \ >- if (!NT_STATUS_IS_OK(_status)) { \ >- torture_result(tctx, TORTURE_FAIL, __location__": setfileinfo failed: %s", \ >- nt_errstr(_status)); \ >- ret = false; \ >- goto done; \ >- } \ >-} while (0) >- >-struct test_durable_open_delaywrite1_state { >+struct test_timestamp_delaywrite1_state { > struct torture_context *tctx; > struct smb2_tree *tree1; > struct smb2_tree *tree2; >@@ -185,11 +145,11 @@ struct test_durable_open_delaywrite1_state { > struct smb2_handle *h2; > }; > >-static bool test_durable_open_delaywrite1_get_info(void *private_data, >+static bool test_timestamp_delaywrite1_get_info(void *private_data, > union smb_fileinfo *finfo) > { >- struct test_durable_open_delaywrite1_state *state = >- (struct test_durable_open_delaywrite1_state *)private_data; >+ struct test_timestamp_delaywrite1_state *state = >+ (struct test_timestamp_delaywrite1_state *)private_data; > struct torture_context *tctx = state->tctx; > union smb_fileinfo t1finfo; > union smb_fileinfo t2finfo; >@@ -221,10 +181,10 @@ done: > return ret; > } > >-static bool test_durable_open_delaywrite1_write_data(void *private_data) >+static bool test_timestamp_delaywrite1_write_data(void *private_data) > { >- struct test_durable_open_delaywrite1_state *state = >- (struct test_durable_open_delaywrite1_state *)private_data; >+ struct test_timestamp_delaywrite1_state *state = >+ (struct test_timestamp_delaywrite1_state *)private_data; > struct torture_context *tctx = state->tctx; > struct smb2_write wr; > NTSTATUS status; >@@ -243,11 +203,11 @@ done: > return ret; > } > >-static bool test_durable_open_delaywrite1_close(void *private_data, >+static bool test_timestamp_delaywrite1_close(void *private_data, > union smb_fileinfo *finfo) > { >- struct test_durable_open_delaywrite1_state *state = >- (struct test_durable_open_delaywrite1_state *)private_data; >+ struct test_timestamp_delaywrite1_state *state = >+ (struct test_timestamp_delaywrite1_state *)private_data; > struct torture_context *tctx = state->tctx; > union smb_fileinfo t1finfoCL; > union smb_fileinfo t2finfoCL; >@@ -299,11 +259,13 @@ done: > return ret; > } > >-static bool test_durable_open_delaywrite1(struct torture_context *tctx, >- struct smb2_tree *tree1, >- struct smb2_tree *tree2) >+static bool test_timestamp_delaywrite1x(struct torture_context *tctx, >+ struct smb2_tree *tree1, >+ struct smb2_tree *tree2, >+ const char *description, >+ bool reconnect) > { >- struct test_durable_open_delaywrite1_state state = { >+ struct test_timestamp_delaywrite1_state state = { > .tctx = tctx, > .tree1 = tree1, > .tree2 = tree2, >@@ -326,7 +288,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > normal_delay); > > /* Choose a random name in case the state is left a little funky. */ >- snprintf(fname, 256, "durable_open_delaywrite1_%s.dat", >+ snprintf(fname, 256, "%s_%s.dat", description, > generate_random_str(tctx, 8)); > > smb2_util_unlink(tree1, fname); >@@ -351,7 +313,7 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > cr2.in.durable_open = false; > cr2.in.oplock_level = 0; > cr2.in.create_disposition = NTCREATEX_DISP_OPEN; >- status = smb2_create(tree2, mem_ctx, &cr2); >+ status = smb2_create(state.tree2, mem_ctx, &cr2); > CHECK_STATUS(status, NT_STATUS_OK); > _h2 = cr2.out.file.handle; > state.h2 = &_h2; >@@ -390,17 +352,17 @@ static bool test_durable_open_delaywrite1(struct torture_context *tctx, > > ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run1", >- test_durable_open_delaywrite1_get_info, >- test_durable_open_delaywrite1_write_data, >+ test_timestamp_delaywrite1_get_info, >+ test_timestamp_delaywrite1_write_data, > NULL, /* close_cb */ > &state); > torture_assert_goto(tctx, ok, ret, done, > "test_smb_timestamp_writetime1(1)"); > ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run2", >- test_durable_open_delaywrite1_get_info, >- test_durable_open_delaywrite1_write_data, >- test_durable_open_delaywrite1_close, >+ test_timestamp_delaywrite1_get_info, >+ test_timestamp_delaywrite1_write_data, >+ test_timestamp_delaywrite1_close, > &state); > torture_assert_goto(tctx, ok, ret, done, > "test_smb_timestamp_writetime1(2)"); >@@ -413,10 +375,10 @@ done: > smb2_util_close(tree2, *state.h2); > } > >- smb2_util_unlink(tree1, fname); >+ smb2_util_unlink(tree2, fname); > >- talloc_free(tree1); >- talloc_free(tree2); >+ TALLOC_FREE(tree1); >+ TALLOC_FREE(tree2); > > talloc_free(mem_ctx); > >@@ -429,7 +391,7 @@ struct torture_suite *torture_smb2_timestamps_init(TALLOC_CTX *ctx) > torture_suite_create(ctx, "timestamps"); > > torture_suite_add_2smb2_test(suite, "delaywrite1", >- test_durable_open_delaywrite1); >+ test_timestamp_delaywrite1); > > suite->description = talloc_strdup(suite, "SMB2-TIMESTAMPS tests"); > >-- >2.17.1 > > >From 846d07c8c510bcebd6547e2e5b57ffcd6c7cf0a2 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 21:15:16 +0200 >Subject: [PATCH 32/48] test_timestamp_delaywrite1a/b durable-reconnect > >--- > source4/torture/smb2/timestamps.c | 84 +++++++++++++++++++++++++++++-- > 1 file changed, 81 insertions(+), 3 deletions(-) > >diff --git a/source4/torture/smb2/timestamps.c b/source4/torture/smb2/timestamps.c >index 259075ebc00a..2ecc203394f1 100644 >--- a/source4/torture/smb2/timestamps.c >+++ b/source4/torture/smb2/timestamps.c >@@ -140,9 +140,12 @@ > struct test_timestamp_delaywrite1_state { > struct torture_context *tctx; > struct smb2_tree *tree1; >+ struct smb2_tree **tree1ptr; > struct smb2_tree *tree2; > struct smb2_handle *h1; > struct smb2_handle *h2; >+ const char *fname; >+ bool reconnect; > }; > > static bool test_timestamp_delaywrite1_get_info(void *private_data, >@@ -166,7 +169,56 @@ static bool test_timestamp_delaywrite1_get_info(void *private_data, > t2finfo.basic_info.in.file.handle = *state->h2; > > GET_INFO_FILE(state->tree2, t2finfo); >- GET_INFO_FILE(state->tree1, t1finfo); >+ if (state->reconnect) { >+ struct smb2_create cr; >+ union smb_fileinfo finfoCR; >+ NTSTATUS status; >+ struct smb2_session *session = state->tree1->session; >+ uint64_t previous_session_id; >+ struct smbcli_options options; >+ struct smb2_handle *h = state->h1; >+ bool ok; >+ >+ previous_session_id = >+ smb2cli_session_current_id(session->smbXcli); >+ options = state->tree1->session->transport->options; >+ >+ state->h1 = NULL; >+ *state->tree1ptr = NULL; >+ TALLOC_FREE(state->tree1); >+ >+ ok = torture_smb2_connection_ext(tctx, previous_session_id, >+ &options, &state->tree1); >+ torture_assert_goto(tctx, ok, ret, done, "could not reconnect"); >+ *state->tree1ptr = state->tree1; >+ >+ ZERO_STRUCT(cr); >+ cr.in.fname = state->fname; >+ cr.in.durable_handle = h; >+ >+ status = smb2_create(state->tree1, tctx, &cr); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ CHECK_CREATED(&cr, EXISTED, FILE_ATTRIBUTE_ARCHIVE); >+ CHECK_VAL(cr.out.oplock_level, smb2_util_oplock_level("b")); >+ CHECK_VAL(cr.out.durable_open, false); >+ CHECK_VAL(cr.out.durable_open_v2, false); >+ CHECK_VAL(cr.out.persistent_open, false); >+ *h = cr.out.file.handle; >+ state->h1 = h; >+ >+ ZERO_STRUCT(finfoCR); >+ finfoCR.basic_info.out.create_time = cr.out.create_time; >+ finfoCR.basic_info.out.access_time = cr.out.access_time; >+ finfoCR.basic_info.out.write_time = cr.out.write_time; >+ finfoCR.basic_info.out.change_time = cr.out.change_time; >+ finfoCR.basic_info.out.attrib = cr.out.file_attr; >+ DEBUG_BASIC_INFO(finfoCR, "durable-reconnect"); \ >+ >+ t1finfo = finfoCR; >+ } else { >+ GET_INFO_FILE(state->tree1, t1finfo); >+ } >+ > if (t1finfo.basic_info.out.write_time != t2finfo.basic_info.out.write_time) { > /* > * There was a race, get it again on handle 2, >@@ -268,7 +320,9 @@ static bool test_timestamp_delaywrite1x(struct torture_context *tctx, > struct test_timestamp_delaywrite1_state state = { > .tctx = tctx, > .tree1 = tree1, >+ .tree1ptr = &tree1, > .tree2 = tree2, >+ .reconnect = reconnect, > }; > NTSTATUS status; > TALLOC_CTX *mem_ctx = talloc_new(tctx); >@@ -291,6 +345,8 @@ static bool test_timestamp_delaywrite1x(struct torture_context *tctx, > snprintf(fname, 256, "%s_%s.dat", description, > generate_random_str(tctx, 8)); > >+ torture_comment(tctx, "START: %s on %s", description, fname); >+ > smb2_util_unlink(tree1, fname); > > smb2_oplock_create_share(&cr1, fname, >@@ -350,6 +406,8 @@ static bool test_timestamp_delaywrite1x(struct torture_context *tctx, > GET_INFO_BOTH(c1finfo0, c2finfo0); > COMPARE_ALL_TIMES_EQUAL(c1finfo0, c1finfoCR); > >+ state.fname = fname; >+ > ok = test_smb_timestamp_writetime1(tctx, used_delay, normal_delay, > "run1", > test_timestamp_delaywrite1_get_info, >@@ -385,13 +443,33 @@ done: > return ret; > } > >+static bool test_timestamp_delaywrite1a(struct torture_context *tctx, >+ struct smb2_tree *tree1, >+ struct smb2_tree *tree2) >+{ >+ return test_timestamp_delaywrite1x(tctx, tree1, tree2, >+ __func__, >+ false); /* reconnect */ >+} >+ >+static bool test_timestamp_delaywrite1b(struct torture_context *tctx, >+ struct smb2_tree *tree1, >+ struct smb2_tree *tree2) >+{ >+ return test_timestamp_delaywrite1x(tctx, tree1, tree2, >+ __func__, >+ true); /* reconnect */ >+} >+ > struct torture_suite *torture_smb2_timestamps_init(TALLOC_CTX *ctx) > { > struct torture_suite *suite = > torture_suite_create(ctx, "timestamps"); > >- torture_suite_add_2smb2_test(suite, "delaywrite1", >- test_timestamp_delaywrite1); >+ torture_suite_add_2smb2_test(suite, "delaywrite1a", >+ test_timestamp_delaywrite1a); >+ torture_suite_add_2smb2_test(suite, "delaywrite1b", >+ test_timestamp_delaywrite1b); > > suite->description = talloc_strdup(suite, "SMB2-TIMESTAMPS tests"); > >-- >2.17.1 > > >From 5923ad11c0c7eabf0b19b9073ccad62a89c5cddc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 15 Aug 2018 21:22:03 +0200 >Subject: [PATCH 33/48] fix mark_file_modified for new Windows >= 2008R2 > behaviour > >--- > source3/smbd/fileio.c | 8 +++----- > 1 file changed, 3 insertions(+), 5 deletions(-) > >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index c75b8a4dcef2..833b50012e2c 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -178,10 +178,8 @@ void fsp_flush_write_time_update(struct files_struct *fsp) > > /* Remove the timed event handler. */ > TALLOC_FREE(fsp->update_write_time_event); >- if (fsp->conn->sconn->client->connections->protocol >= PROTOCOL_SMB2_02) { >- fsp->update_write_time_triggered = false; >- fsp->update_write_time_on_close = false; >- } >+ fsp->update_write_time_triggered = false; >+ fsp->update_write_time_on_close = false; > } > > static void update_write_time_handler(struct tevent_context *ctx, >@@ -291,7 +289,7 @@ void mark_file_modified(files_struct *fsp) > int dosmode; > > if (fsp->modified) { >- trigger_write_time_update(fsp); >+ trigger_write_time_update(fsp); > return; > } > >-- >2.17.1 > > >From dc156af622aaaa8b04456b18e05bd076a7193b00 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 16 Aug 2018 10:14:20 +0200 >Subject: [PATCH 34/48] TODO smbd: allow durable opens together with stat opens > >TODO: explicit tests >--- > source3/locking/locking.c | 27 +++++++++++++++++++++++---- > source3/locking/proto.h | 2 ++ > source3/smbd/durable.c | 29 +++-------------------------- > 3 files changed, 28 insertions(+), 30 deletions(-) > >diff --git a/source3/locking/locking.c b/source3/locking/locking.c >index 208f7e2081d0..833734cd37fa 100644 >--- a/source3/locking/locking.c >+++ b/source3/locking/locking.c >@@ -876,6 +876,29 @@ struct share_mode_entry *find_share_mode_entry( > return NULL; > } > >+struct share_mode_entry *find_share_mode_entry_durable( >+ struct share_mode_lock *lck, uint64_t persistent_fid) >+{ >+ struct share_mode_data *d = lck->data; >+ uint32_t i; >+ >+ for (i=0; i<d->num_share_modes; i++) { >+ struct share_mode_entry *e = &d->share_modes[i]; >+ >+ if (!server_id_is_disconnected(&e->pid)) { >+ continue; >+ } >+ if (!is_valid_share_mode_entry(e)) { >+ continue; >+ } >+ if (persistent_fid != e->share_file_id) { >+ continue; >+ } >+ return e; >+ } >+ return NULL; >+} >+ > /******************************************************************* > Del the share mode of a file for this process. Return the number of > entries left. >@@ -901,10 +924,6 @@ bool mark_share_mode_disconnected(struct share_mode_lock *lck, > { > struct share_mode_entry *e; > >- if (lck->data->num_share_modes != 1) { >- return false; >- } >- > if (fsp->op == NULL) { > return false; > } >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index b615a4ae6d0b..1e8ae049704e 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -178,6 +178,8 @@ bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, > uint32_t lease_idx); > struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck, > files_struct *fsp); >+struct share_mode_entry *find_share_mode_entry_durable( >+ struct share_mode_lock *lck, uint64_t persistent_fid); > void remove_stale_share_mode_entries(struct share_mode_data *d); > bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp); > bool mark_share_mode_disconnected(struct share_mode_lock *lck, >diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c >index 80392e2c6dbb..2a309a2aedd2 100644 >--- a/source3/smbd/durable.c >+++ b/source3/smbd/durable.c >@@ -617,33 +617,10 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, > return NT_STATUS_INTERNAL_DB_ERROR; > } > >- if (lck->data->num_share_modes > 1) { >- /* >- * It can't be durable if there is more than one handle >- * on the file. >- */ >- DEBUG(5, ("vfs_default_durable_reconnect: more than one " >- "share-mode entry - can not be durable\n")); >- TALLOC_FREE(lck); >- return NT_STATUS_OBJECT_NAME_NOT_FOUND; >- } >- >- e = &lck->data->share_modes[0]; >- >- if (!server_id_is_disconnected(&e->pid)) { >- DEBUG(5, ("vfs_default_durable_reconnect: denying durable " >- "reconnect for handle that was not marked " >- "disconnected (e.g. smbd or cluster node died)\n")); >- TALLOC_FREE(lck); >- return NT_STATUS_OBJECT_NAME_NOT_FOUND; >- } >- >- if (e->share_file_id != op->global->open_persistent_id) { >+ e = find_share_mode_entry_durable(lck, op->global->open_persistent_id); >+ if (e == NULL) { > DEBUG(5, ("vfs_default_durable_reconnect: denying durable " >- "share_file_id changed %llu != %llu" >- "(e.g. another client had opened the file)\n", >- (unsigned long long)e->share_file_id, >- (unsigned long long)op->global->open_persistent_id)); >+ "reconnect for handle - share mode not found\n")); > TALLOC_FREE(lck); > return NT_STATUS_OBJECT_NAME_NOT_FOUND; > } >-- >2.17.1 > > >From 9247020e0569322eeefd71ea18d7083da290bc46 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 16 Aug 2018 10:16:46 +0200 >Subject: [PATCH 35/48] s4:libcli: cleanup smbcli_deltree() > >We already have the 'status' of smbcli_unlink(), so >we can check that directly. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source4/libcli/clideltree.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c >index 7bce95c2a179..866b8c551388 100644 >--- a/source4/libcli/clideltree.c >+++ b/source4/libcli/clideltree.c >@@ -99,13 +99,13 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname) > > /* it might be a file */ > status = smbcli_unlink(tree, dname); >- if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) { >+ if (NT_STATUS_IS_OK(status)) { > return 1; > } >- if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) || >- NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) || >- NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE) || >- NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_DOS(ERRDOS, ERRbadfile))) { >+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) || >+ NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) || >+ NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE) || >+ NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRbadfile))) { > return 0; > } > if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { >-- >2.17.1 > > >From c739ee3c7c1f61aa1fe2a7dea5123da304ac12e1 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 16 Aug 2018 10:18:25 +0200 >Subject: [PATCH 36/48] sq smb2.timestamps > >--- > selftest/skip | 1 + > source3/selftest/tests.py | 4 ++-- > 2 files changed, 3 insertions(+), 2 deletions(-) > >diff --git a/selftest/skip b/selftest/skip >index dd60ab5a1fbe..be99bae40041 100644 >--- a/selftest/skip >+++ b/selftest/skip >@@ -92,6 +92,7 @@ > ^samba4.smb2.dir > ^samba4.smb2.session > ^samba4.smb2.compound >+^samba4.smb2.timestamps # this is tested as 'samba3.smb2.timestamps already > ^samba4.smb2.oplock.levelii501 # No test yet > # SMB2 in s4 does not seem to support rename correctly > ^samba4.smb2.rename.*\(ad_dc_ntvfs\)$ >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index d3c548703774..c0aa816eec28 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -435,8 +435,8 @@ vfs = ["vfs.fruit", "vfs.acl_xattr", "vfs.fruit_netatalk", "vfs.fruit_file_id", > tests= base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap + vfs > > for t in tests: >- if t == "base.delaywrite" or t == "base.deny1" or t == "base.deny2": >- plansmbtorture4testsuite(t, "fileserver", '//$SERVER/tmp -U$USERNAME%$PASSWORD --maximum-runtime=900') >+ if t == "base.delaywrite" or t == "base.deny1" or t == "base.deny2" or t == "smb2.timestamps": >+ plansmbtorture4testsuite(t, "fileserver", '//$SERVER/durable -U$USERNAME%$PASSWORD --maximum-runtime=900') > elif t == "base.createx_access": > plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD -k yes --maximum-runtime=900') > elif t == "rap.sam": >-- >2.17.1 > > >From 0c1861a74155df13b9ac579d7ccf7e4d26fe856b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 01:50:08 +0200 >Subject: [PATCH 37/48] MSG_SMB_FILE_PATHINFO > >--- > librpc/idl/messaging.idl | 6 ++++ > source3/locking/locking.c | 61 ++++++++++++++++++++++++++++++++++++--- > source3/locking/proto.h | 5 ++++ > source3/smbd/fileio.c | 58 ++++++++++++++++++++++++++++++++++++- > source3/smbd/process.c | 2 ++ > source3/smbd/proto.h | 5 ++++ > source3/smbd/trans2.c | 6 +++- > 7 files changed, 137 insertions(+), 6 deletions(-) > >diff --git a/librpc/idl/messaging.idl b/librpc/idl/messaging.idl >index c916768ccec7..2a2f67187d2f 100644 >--- a/librpc/idl/messaging.idl >+++ b/librpc/idl/messaging.idl >@@ -110,6 +110,12 @@ interface messaging > MSG_SMB_NOTIFY_REC_CHANGES = 0x031E, > MSG_SMB_NOTIFY_STARTED = 0x031F, > >+ /* >+ * Send to all open handles, if a >+ * SMB1 QUERY PATH INFO happened. >+ */ >+ MSG_SMB_FILE_PATHINFO = 0x0320, >+ > /* winbind messages */ > MSG_WINBIND_FINISHED = 0x0401, > MSG_WINBIND_FORGET_STATE = 0x0402, >diff --git a/source3/locking/locking.c b/source3/locking/locking.c >index 833734cd37fa..a5dec6c254d5 100644 >--- a/source3/locking/locking.c >+++ b/source3/locking/locking.c >@@ -600,12 +600,15 @@ bool rename_share_filename(struct messaging_context *msg_ctx, > return True; > } > >-void get_file_infos(struct file_id id, >- uint32_t name_hash, >- bool *delete_on_close, >- struct timespec *write_time) >+static void get_filepath_infos(struct file_id id, >+ struct messaging_context *pathinfo_msg_ctx, >+ uint32_t name_hash, >+ bool *delete_on_close, >+ struct timespec *write_time) > { > struct share_mode_lock *lck; >+ uint8_t msg[24] = {0, }; >+ uint32_t i; > > if (delete_on_close) { > *delete_on_close = false; >@@ -627,9 +630,59 @@ void get_file_infos(struct file_id id, > *write_time = get_share_mode_write_time(lck); > } > >+ if (pathinfo_msg_ctx == NULL) { >+ TALLOC_FREE(lck); >+ return; >+ } >+ >+ push_file_id_24((char *)msg, &id); >+ >+ for (i = 0; i < lck->data->num_share_modes; i++) { >+ struct share_mode_entry *e = &lck->data->share_modes[i]; >+ >+ if (!is_valid_share_mode_entry(e)) { >+ continue; >+ } >+ >+ if (!serverid_exists(&e->pid)) { >+ continue; >+ } >+ >+ messaging_send_buf(pathinfo_msg_ctx, >+ e->pid, >+ MSG_SMB_FILE_PATHINFO, >+ msg, >+ sizeof(msg)); >+ } >+ > TALLOC_FREE(lck); > } > >+void get_file_infos(struct file_id id, >+ uint32_t name_hash, >+ bool *delete_on_close, >+ struct timespec *write_time) >+{ >+ get_filepath_infos(id, >+ NULL, /* pathinfo_msg_ctx */ >+ name_hash, >+ delete_on_close, >+ write_time); >+} >+ >+void get_path_infos(struct file_id id, >+ struct messaging_context *msg_ctx, >+ uint32_t name_hash, >+ bool *delete_on_close, >+ struct timespec *write_time) >+{ >+ get_filepath_infos(id, >+ msg_ctx, >+ name_hash, >+ delete_on_close, >+ write_time); >+} >+ > bool is_valid_share_mode_entry(const struct share_mode_entry *e) > { > int num_props = 0; >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 1e8ae049704e..d06144f9f0bf 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -171,6 +171,11 @@ void get_file_infos(struct file_id id, > uint32_t name_hash, > bool *delete_on_close, > struct timespec *write_time); >+void get_path_infos(struct file_id id, >+ struct messaging_context *msg_ctx, >+ uint32_t name_hash, >+ bool *delete_on_close, >+ struct timespec *write_time); > bool is_valid_share_mode_entry(const struct share_mode_entry *e); > bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx); > bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index 833b50012e2c..d83efde6abb0 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -271,7 +271,7 @@ void trigger_write_time_update_immediate(struct files_struct *fsp) > fsp_str_dbg(fsp))); > > /* After an immediate update, reset the trigger. */ >- fsp->update_write_time_triggered = true; >+ fsp->update_write_time_triggered = true; // TODO: false??? > fsp->update_write_time_on_close = false; > > ZERO_STRUCT(ft); >@@ -316,6 +316,62 @@ void mark_file_modified(files_struct *fsp) > dosmode | FILE_ATTRIBUTE_ARCHIVE, NULL, false); > } > >+/**************************************************************************** >+ Receive notification that someone did a SMB1 QueryPathInfo on the file. >+ This changes the write time update behaviour on open handles. >+****************************************************************************/ >+ >+void msg_file_got_pathinfo(struct messaging_context *msg, >+ void *private_data, >+ uint32_t msg_type, >+ struct server_id server_id, >+ DATA_BLOB *data) >+{ >+ struct smbd_server_connection *sconn = >+ talloc_get_type_abort(private_data, >+ struct smbd_server_connection); >+ struct files_struct *fsp = NULL; >+ struct file_id id; >+ >+ if (data->data == NULL || data->length != 24) { >+ DBG_ERR("Got invalid msg len %zu\n", data->length); >+ return; >+ } >+ >+ /* Unpack the message. */ >+ pull_file_id_24((char *)data->data, &id); >+ >+ DBG_DEBUG("Got PATHINFO notification file_id %s\n", >+ file_id_string_tos(&id)); >+ >+ for(fsp = file_find_di_first(sconn, id); fsp; >+ fsp = file_find_di_next(fsp)) { >+ >+ if (fsp->write_time_forced) { >+ /* >+ * No point - "sticky" write times >+ * in effect. >+ */ >+ continue; >+ } >+ >+ if (!fsp->update_write_time_triggered) { >+ /* >+ * No write time update pending. >+ */ >+ continue; >+ } >+ >+ /* >+ * We cancel the timer, which means the write time update >+ * will happen on close. >+ */ >+ DBG_INFO("Defer write time updates to close on %s\n", >+ fsp_str_dbg(fsp)); >+ TALLOC_FREE(fsp->update_write_time_event); >+ } >+} >+ > /**************************************************************************** > Write to a file. > ****************************************************************************/ >diff --git a/source3/smbd/process.c b/source3/smbd/process.c >index 35b5f4df385d..c67d7eef7d5e 100644 >--- a/source3/smbd/process.c >+++ b/source3/smbd/process.c >@@ -4092,6 +4092,8 @@ void smbd_process(struct tevent_context *ev_ctx, > MSG_SMB_CLOSE_FILE, msg_close_file); > messaging_register(sconn->msg_ctx, sconn, > MSG_SMB_FILE_RENAME, msg_file_was_renamed); >+ messaging_register(sconn->msg_ctx, sconn, >+ MSG_SMB_FILE_PATHINFO, msg_file_got_pathinfo); > > id_cache_register_msgs(sconn->msg_ctx); > messaging_deregister(sconn->msg_ctx, ID_CACHE_KILL, NULL); >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index 2a41d9d251dd..45e39e9df37c 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -332,6 +332,11 @@ ssize_t read_file(files_struct *fsp,char *data,off_t pos,size_t n); > void fsp_flush_write_time_update(struct files_struct *fsp); > void trigger_write_time_update(struct files_struct *fsp); > void trigger_write_time_update_immediate(struct files_struct *fsp); >+void msg_file_got_pathinfo(struct messaging_context *msg, >+ void *private_data, >+ uint32_t msg_type, >+ struct server_id server_id, >+ DATA_BLOB *data); > void mark_file_modified(files_struct *fsp); > ssize_t write_file(struct smb_request *req, > files_struct *fsp, >diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c >index 0ec20fe6337f..a9d413bf3c3b 100644 >--- a/source3/smbd/trans2.c >+++ b/source3/smbd/trans2.c >@@ -5982,7 +5982,11 @@ static void call_trans2qfilepathinfo(connection_struct *conn, > } > > fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st); >- get_file_infos(fileid, name_hash, &delete_pending, &write_time_ts); >+ get_path_infos(fileid, >+ req->sconn->msg_ctx, >+ name_hash, >+ &delete_pending, >+ &write_time_ts); > if (delete_pending) { > reply_nterror(req, NT_STATUS_DELETE_PENDING); > return; >-- >2.17.1 > > >From 8d751a927ea95c7b9d1ae013237cdb1a049b7d1a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 01:50:41 +0200 >Subject: [PATCH 38/48] HACK w2k behaviour > >--- > source3/include/vfs.h | 2 ++ > source3/smbd/fileio.c | 9 +++++++++ > 2 files changed, 11 insertions(+) > >diff --git a/source3/include/vfs.h b/source3/include/vfs.h >index 4f3db6948964..efc9a99cdaf3 100644 >--- a/source3/include/vfs.h >+++ b/source3/include/vfs.h >@@ -334,6 +334,8 @@ typedef struct files_struct { > bool kernel_share_modes_taken; > > bool update_write_time_triggered; >+ uint64_t num_write_time_updates; >+ bool got_query_path_info; > struct tevent_timer *update_write_time_event; > bool update_write_time_on_close; > struct timespec close_write_time; >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index d83efde6abb0..9448ebe5d08c 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -178,8 +178,10 @@ void fsp_flush_write_time_update(struct files_struct *fsp) > > /* Remove the timed event handler. */ > TALLOC_FREE(fsp->update_write_time_event); >+ if (!fsp->got_query_path_info) { > fsp->update_write_time_triggered = false; > fsp->update_write_time_on_close = false; >+ } > } > > static void update_write_time_handler(struct tevent_context *ctx, >@@ -226,6 +228,7 @@ void trigger_write_time_update(struct files_struct *fsp) > return; > } > fsp->update_write_time_triggered = true; >+ fsp->num_write_time_updates++; > > delay = lp_parm_int(SNUM(fsp->conn), > "smbd", "writetimeupdatedelay", >@@ -362,6 +365,12 @@ void msg_file_got_pathinfo(struct messaging_context *msg, > continue; > } > >+ fsp->got_query_path_info = true; >+ >+ if (fsp->num_write_time_updates == 1) { >+ continue; >+ } >+ > /* > * We cancel the timer, which means the write time update > * will happen on close. >-- >2.17.1 > > >From 17c5d23284509ee2e70fc1bc642cbcbd75b8da49 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 01:50:54 +0200 >Subject: [PATCH 39/48] Revert "HACK w2k behaviour" > >This reverts commit 8d751a927ea95c7b9d1ae013237cdb1a049b7d1a. >--- > source3/include/vfs.h | 2 -- > source3/smbd/fileio.c | 9 --------- > 2 files changed, 11 deletions(-) > >diff --git a/source3/include/vfs.h b/source3/include/vfs.h >index efc9a99cdaf3..4f3db6948964 100644 >--- a/source3/include/vfs.h >+++ b/source3/include/vfs.h >@@ -334,8 +334,6 @@ typedef struct files_struct { > bool kernel_share_modes_taken; > > bool update_write_time_triggered; >- uint64_t num_write_time_updates; >- bool got_query_path_info; > struct tevent_timer *update_write_time_event; > bool update_write_time_on_close; > struct timespec close_write_time; >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index 9448ebe5d08c..d83efde6abb0 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -178,10 +178,8 @@ void fsp_flush_write_time_update(struct files_struct *fsp) > > /* Remove the timed event handler. */ > TALLOC_FREE(fsp->update_write_time_event); >- if (!fsp->got_query_path_info) { > fsp->update_write_time_triggered = false; > fsp->update_write_time_on_close = false; >- } > } > > static void update_write_time_handler(struct tevent_context *ctx, >@@ -228,7 +226,6 @@ void trigger_write_time_update(struct files_struct *fsp) > return; > } > fsp->update_write_time_triggered = true; >- fsp->num_write_time_updates++; > > delay = lp_parm_int(SNUM(fsp->conn), > "smbd", "writetimeupdatedelay", >@@ -365,12 +362,6 @@ void msg_file_got_pathinfo(struct messaging_context *msg, > continue; > } > >- fsp->got_query_path_info = true; >- >- if (fsp->num_write_time_updates == 1) { >- continue; >- } >- > /* > * We cancel the timer, which means the write time update > * will happen on close. >-- >2.17.1 > > >From 092f769e1c75012a51949694da06e3c31f33198e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 01:51:28 +0200 >Subject: [PATCH 40/48] test_delayed_write_update4 HACKS ... > >--- > source4/torture/basic/delaywrite.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 6f5bd2a8b6a9..7b981b06e5ef 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2187,7 +2187,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > goto done; > } > >- GET_INFO_BOTH(finfo1,pinfo1); >+ //GET_INFO_BOTH(finfo1,pinfo1); >+ GET_INFO_FILE(finfo1); > COMPARE_WRITE_TIME_EQUAL(finfo1,finfo0); > > /* >@@ -2219,8 +2220,9 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > smb_msleep(0.5 * msec); > } > >- GET_INFO_BOTH(finfo1,pinfo1); >- COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); >+ //GET_INFO_BOTH(finfo1,pinfo1); >+ GET_INFO_FILE(finfo1); >+ COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); > > /* sure any further write doesn't update the write time */ > start = timeval_current(); >@@ -2248,7 +2250,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > smb_msleep(1 * msec); > } > >- GET_INFO_BOTH(finfo2,pinfo2); >+ //GET_INFO_BOTH(finfo2,pinfo2); >+ GET_INFO_FILE(finfo2); > COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); > if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { > torture_comment(tctx, "Server did not updatewrite_time (correct)\n"); >@@ -2257,7 +2260,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > /* sleep */ > smb_msleep(5 * msec); > >- GET_INFO_BOTH(finfo3,pinfo3); >+ //GET_INFO_BOTH(finfo3,pinfo3); >+ GET_INFO_FILE(finfo3); > COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); > > /* >-- >2.17.1 > > >From 9995e9e6023c70d5fb9b5789cb70b5621978d238 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 01:51:46 +0200 >Subject: [PATCH 41/48] Revert "test_delayed_write_update4 HACKS ..." > >This reverts commit 092f769e1c75012a51949694da06e3c31f33198e. >--- > source4/torture/basic/delaywrite.c | 18 +++++++----------- > 1 file changed, 7 insertions(+), 11 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 7b981b06e5ef..6f5bd2a8b6a9 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >+ int normal_delay = 2000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2187,8 +2187,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > goto done; > } > >- //GET_INFO_BOTH(finfo1,pinfo1); >- GET_INFO_FILE(finfo1); >+ GET_INFO_BOTH(finfo1,pinfo1); > COMPARE_WRITE_TIME_EQUAL(finfo1,finfo0); > > /* >@@ -2220,9 +2219,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > smb_msleep(0.5 * msec); > } > >- //GET_INFO_BOTH(finfo1,pinfo1); >- GET_INFO_FILE(finfo1); >- COMPARE_WRITE_TIME_GREATER(finfo1, finfo0); >+ GET_INFO_BOTH(finfo1,pinfo1); >+ COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); > > /* sure any further write doesn't update the write time */ > start = timeval_current(); >@@ -2250,8 +2248,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > smb_msleep(1 * msec); > } > >- //GET_INFO_BOTH(finfo2,pinfo2); >- GET_INFO_FILE(finfo2); >+ GET_INFO_BOTH(finfo2,pinfo2); > COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); > if (finfo2.basic_info.out.write_time == finfo1.basic_info.out.write_time) { > torture_comment(tctx, "Server did not updatewrite_time (correct)\n"); >@@ -2260,8 +2257,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > /* sleep */ > smb_msleep(5 * msec); > >- //GET_INFO_BOTH(finfo3,pinfo3); >- GET_INFO_FILE(finfo3); >+ GET_INFO_BOTH(finfo3,pinfo3); > COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); > > /* >-- >2.17.1 > > >From 09f914311f1597068a06c248d4ba335c2ecdc10e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 02:24:52 +0200 >Subject: [PATCH 42/48] modern and legacy delaywrite => legacy works against > w2k > >legacy lower time to 1 sec? >--- > source4/torture/basic/base.c | 3 ++- > source4/torture/basic/delaywrite.c | 32 ++++++++++++++++++++++++++++-- > 2 files changed, 32 insertions(+), 3 deletions(-) > >diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c >index 314e8f2d131f..43b46d89a22a 100644 >--- a/source4/torture/basic/base.c >+++ b/source4/torture/basic/base.c >@@ -1972,7 +1972,8 @@ NTSTATUS torture_base_init(TALLOC_CTX *ctx) > torture_suite_add_1smb_test(suite, "chkpath", torture_chkpath_test); > torture_suite_add_1smb_test(suite, "secleak", torture_sec_leak); > torture_suite_add_simple_test(suite, "disconnect", torture_disconnect); >- torture_suite_add_suite(suite, torture_delay_write(suite)); >+ torture_suite_add_suite(suite, torture_delay_write_modern(suite)); >+ torture_suite_add_suite(suite, torture_delay_write_legacy(suite)); > torture_suite_add_simple_test(suite, "samba3error", torture_samba3_errorpaths); > torture_suite_add_1smb_test(suite, "casetable", torture_casetable); > torture_suite_add_1smb_test(suite, "utable", torture_utable); >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 6f5bd2a8b6a9..be75533243d1 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3326,9 +3326,9 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > /* > testing of delayed update of write_time > */ >-struct torture_suite *torture_delay_write(TALLOC_CTX *ctx) >+struct torture_suite *torture_delay_write_modern(TALLOC_CTX *ctx) > { >- struct torture_suite *suite = torture_suite_create(ctx, "delaywrite"); >+ struct torture_suite *suite = torture_suite_create(ctx, "delaywrite-modern"); > > torture_suite_add_2smb_test(suite, "finfo update on close", test_finfo_after_write); > torture_suite_add_1smb_test(suite, "delayed update of write time", test_delayed_write_update); >@@ -3349,5 +3349,33 @@ struct torture_suite *torture_delay_write(TALLOC_CTX *ctx) > torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); > torture_suite_add_2smb_test(suite, "delaywrite1", test_delaywrite_delaywrite1); > >+ suite->description = talloc_strdup(suite, "SMB1-DELAYWRITE tests modern >= w2k8r2 behaviour"); >+ >+ return suite; >+} >+struct torture_suite *torture_delay_write_legacy(TALLOC_CTX *ctx) >+{ >+ struct torture_suite *suite = torture_suite_create(ctx, "delaywrite-legacy"); >+ >+ torture_suite_add_2smb_test(suite, "finfo update on close", test_finfo_after_write); >+ torture_suite_add_1smb_test(suite, "delayed update of write time", test_delayed_write_update); >+ torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate", test_delayed_write_update1); >+ torture_suite_add_1smb_test(suite, "update of write time and SMBwrite truncate expand", test_delayed_write_update1a); >+ torture_suite_add_1smb_test(suite, "update of write time using SET_END_OF_FILE", test_delayed_write_update1b); >+ torture_suite_add_1smb_test(suite, "update of write time using SET_ALLOCATION_SIZE", test_delayed_write_update1c); >+ torture_suite_add_2smb_test(suite, "delayed update of write time using 2 connections", test_delayed_write_update2); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 3", test_delayed_write_update3); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 3a", test_delayed_write_update3a); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 3b", test_delayed_write_update3b); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 3c", test_delayed_write_update3c); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 4", test_delayed_write_update4); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 5", test_delayed_write_update5); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 5b", test_delayed_write_update5b); >+ torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6); >+ torture_suite_add_1smb_test(suite, "timestamp resolution test", test_delayed_write_update7); >+ torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); >+ >+ suite->description = talloc_strdup(suite, "SMB1-DELAYWRITE tests legacy w2k behaviour"); >+ > return suite; > } >-- >2.17.1 > > >From 55c8fbc733e9a1beef630e7cc3f7a300e2d1a850 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 02:24:52 +0200 >Subject: [PATCH 43/48] modern and legacy delaywrite > >--- > source4/torture/basic/delaywrite.c | 65 +++++++++++++++--------------- > 1 file changed, 32 insertions(+), 33 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index be75533243d1..42a00e30596d 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -44,8 +44,8 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -125,8 +125,8 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -291,8 +291,8 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -452,8 +452,8 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -612,8 +612,8 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -776,8 +776,8 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > union smb_flush flsh; >@@ -1134,8 +1134,8 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s > int fnum2; > bool ret = true; > ssize_t written; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1410,8 +1410,8 @@ static bool test_delayed_write_update3(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1562,8 +1562,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, > int i; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1773,8 +1773,8 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1937,8 +1937,8 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, > int i; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2300,8 +2300,8 @@ static bool test_delayed_write_update5(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2460,8 +2460,8 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2625,8 +2625,8 @@ static bool test_delayed_write_update6(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > bool first = true; >@@ -2989,8 +2989,8 @@ static bool test_directory_update8(struct torture_context *tctx, struct smbcli_s > int fnum1 = -1; > int fnum2 = -1; > bool ret = true; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); >- int normal_delay = 2000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >+ int normal_delay = 1000000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > TALLOC_CTX *mem_ctx = talloc_init("test_delayed_write_update8"); >@@ -3341,7 +3341,6 @@ struct torture_suite *torture_delay_write_modern(TALLOC_CTX *ctx) > torture_suite_add_2smb_test(suite, "delayed update of write time 3a", test_delayed_write_update3a); > torture_suite_add_2smb_test(suite, "delayed update of write time 3b", test_delayed_write_update3b); > torture_suite_add_2smb_test(suite, "delayed update of write time 3c", test_delayed_write_update3c); >- torture_suite_add_2smb_test(suite, "delayed update of write time 4", test_delayed_write_update4); > torture_suite_add_2smb_test(suite, "delayed update of write time 5", test_delayed_write_update5); > torture_suite_add_2smb_test(suite, "delayed update of write time 5b", test_delayed_write_update5b); > torture_suite_add_2smb_test(suite, "delayed update of write time 6", test_delayed_write_update6); >-- >2.17.1 > > >From 8ac8972497967262b73030b1e740996c132f34d3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 02:48:30 +0200 >Subject: [PATCH 44/48] sq test_delaywrite_delaywrite1 > >--- > source4/torture/basic/delaywrite.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index 42a00e30596d..bd34dc8e2618 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -3267,7 +3267,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > .fnum1 = -1, > .fnum2 = -1, > }; >- const char *fname = BASEDIR "\\torture_file3.txt"; >+ const char *fname = BASEDIR "\\torture_file_delaywrite1.txt"; > bool ret = true; > double normal_delay = 1000000; > double used_delay; >@@ -3276,7 +3276,7 @@ static bool test_delaywrite_delaywrite1(struct torture_context *tctx, > used_delay = torture_setting_int(tctx, "writetimeupdatedelay", > normal_delay); > >- torture_comment(tctx, "\nRunning test_delayed_write_update3\n"); >+ torture_comment(tctx, "\nRunning test_delaywrite_delaywrite1\n"); > > torture_assert(tctx, torture_setup_dir(cli, BASEDIR), > "Failed to setup up test directory: " BASEDIR); >-- >2.17.1 > > >From b831cf95b7a42935b4d164806220e90282a05ab4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 02:57:40 +0200 >Subject: [PATCH 45/48] sq modern and legacy delaywrite selftest > >--- > source3/selftest/tests.py | 8 +++++--- > 1 file changed, 5 insertions(+), 3 deletions(-) > >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index c0aa816eec28..5fe962ad36e1 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -381,13 +381,15 @@ plantestsuite("samba3.async_req", "nt4_dc", > > #smbtorture4 tests > >-base = ["base.attr", "base.charset", "base.chkpath", "base.createx_access", "base.defer_open", "base.delaywrite", "base.delete", >+base = ["base.attr", "base.charset", "base.chkpath", "base.createx_access", "base.defer_open", "base.delete", > "base.deny1", "base.deny2", "base.deny3", "base.denydos", "base.dir1", "base.dir2", > "base.disconnect", "base.fdpass", "base.lock", > "base.mangle", "base.negnowait", "base.ntdeny1", > "base.ntdeny2", "base.open", "base.openattr", "base.properties", "base.rename", "base.rw1", > "base.secleak", "base.tcon", "base.tcondev", "base.trans2", "base.unlink", "base.vuid", >- "base.xcopy", "base.samba3error"] >+ "base.xcopy", "base.samba3error", >+ "base.delaywrite-modern", >+ ] > > raw = ["raw.acls", "raw.chkpath", "raw.close", "raw.composite", "raw.context", "raw.eas", > "raw.ioctl", "raw.lock", "raw.mkdir", "raw.mux", "raw.notify", "raw.open", "raw.oplock", >@@ -435,7 +437,7 @@ vfs = ["vfs.fruit", "vfs.acl_xattr", "vfs.fruit_netatalk", "vfs.fruit_file_id", > tests= base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap + vfs > > for t in tests: >- if t == "base.delaywrite" or t == "base.deny1" or t == "base.deny2" or t == "smb2.timestamps": >+ if t == "base.delaywrite-modern" or t == "base.deny1" or t == "base.deny2" or t == "smb2.timestamps": > plansmbtorture4testsuite(t, "fileserver", '//$SERVER/durable -U$USERNAME%$PASSWORD --maximum-runtime=900') > elif t == "base.createx_access": > plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD -k yes --maximum-runtime=900') >-- >2.17.1 > > >From 3be8e1f8fe502ee056d505f1c8ad43c262fab07c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 11:35:41 +0200 >Subject: [PATCH 46/48] TODO: smb2_server: set req->do_encryption = true > earlier > >TODO: tests > >https://blogs.msdn.microsoft.com/openspecification/2012/10/05/encryption-in-smb-3-0-a-protocol-perspective/ > >The sender encrypts the message if any of the following conditions is >satisfied: > > If the sender is sending a response to an encrypted request. > If Session.EncryptData is TRUE and the request or response being >sent is not NEGOTIATE. > If Session.EncryptData is FALSE, the request or response being sent >is not NEGOTIATE or SESSION_SETUP or TREE_CONNECT, and ><TreeConnect|Share>.EncryptData is TRUE. > >[MS-SMB2] 3.3.4.1.4 Encrypting the Message > > If Connection.Dialect belongs to the SMB 3.x dialect family and > Connection.ClientCapabilities includes the SMB2_GLOBAL_CAP_ENCRYPTION > bit, the server MUST encrypt the message before sending, if any of the > following conditions are satisfied: > > - If the message being sent is any response to a client request for which > Request.IsEncrypted is TRUE. > > - If Session.EncryptData is TRUE and the response being sent is not > SMB2_NEGOTIATE or SMB2 SESSION_SETUP. > > - If Session.EncryptData is FALSE, the response being sent is not > SMB2_NEGOTIATE or SMB2 SESSION_SETUP or SMB2 TREE_CONNECT, and > Share.EncryptData for the share associated with the TreeId in the SMB2 > header of the response is TRUE. > > The server MUST encrypt the message as specified in section 3.1.4.3, > before sending it to the client. >--- > source3/smbd/smb2_server.c | 15 ++++++++++----- > 1 file changed, 10 insertions(+), 5 deletions(-) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index 229f8ab0e856..e36db1e55f5e 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -2359,7 +2359,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) > > req->async_internal = false; > req->do_signing = false; >- req->do_encryption = false; >+ if (opcode != SMB2_OP_SESSSETUP) { >+ req->do_encryption = encryption_desired; >+ } else { >+ req->do_encryption = false; >+ } > req->was_encrypted = false; > if (intf_v->iov_len == SMB2_TF_HDR_SIZE) { > const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req); >@@ -2383,9 +2387,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) > } > > req->was_encrypted = true; >+ req->do_encryption = true; > } > > if (encryption_required && !req->was_encrypted) { >+ req->do_encryption = true; > return smbd_smb2_request_error(req, > NT_STATUS_ACCESS_DENIED); > } >@@ -2523,8 +2529,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) > encryption_required = true; > } > if (encryption_required && !req->was_encrypted) { >+ req->do_encryption = true; > return smbd_smb2_request_error(req, > NT_STATUS_ACCESS_DENIED); >+ } else if (encryption_desired) { >+ req->do_encryption = true; > } > } else if (call->need_session) { > struct auth_session_info *session_info = NULL; >@@ -2544,10 +2553,6 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) > session_info->info->domain_name); > } > >- if (req->was_encrypted || encryption_desired) { >- req->do_encryption = true; >- } >- > if (req->session) { > bool update_session_global = false; > bool update_tcon_global = false; >-- >2.17.1 > > >From 329ac5e104bdee2010451fa3a0455812556e9158 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 12:25:17 +0200 >Subject: [PATCH 47/48] modern and legacy delaywrite => 0.5 sec delay > >--- > source4/torture/basic/delaywrite.c | 64 +++++++++++++++--------------- > 1 file changed, 32 insertions(+), 32 deletions(-) > >diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c >index bd34dc8e2618..b66ff09b7583 100644 >--- a/source4/torture/basic/delaywrite.c >+++ b/source4/torture/basic/delaywrite.c >@@ -44,8 +44,8 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -125,8 +125,8 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -291,8 +291,8 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -452,8 +452,8 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -612,8 +612,8 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > char buf[2048]; >@@ -776,8 +776,8 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > union smb_flush flsh; >@@ -1134,8 +1134,8 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s > int fnum2; > bool ret = true; > ssize_t written; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1410,8 +1410,8 @@ static bool test_delayed_write_update3(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1562,8 +1562,8 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, > int i; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1773,8 +1773,8 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -1937,8 +1937,8 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, > int i; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2143,8 +2143,8 @@ static bool test_delayed_write_update4(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2300,8 +2300,8 @@ static bool test_delayed_write_update5(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2460,8 +2460,8 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > >@@ -2625,8 +2625,8 @@ static bool test_delayed_write_update6(struct torture_context *tctx, > ssize_t written; > struct timeval start; > struct timeval end; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > bool first = true; >@@ -2989,8 +2989,8 @@ static bool test_directory_update8(struct torture_context *tctx, struct smbcli_s > int fnum1 = -1; > int fnum2 = -1; > bool ret = true; >- double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 1000000); >- int normal_delay = 1000000; >+ double used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 500000); >+ int normal_delay = 500000; > double sec = ((double)used_delay) / ((double)normal_delay); > int msec = 1000 * sec; > TALLOC_CTX *mem_ctx = talloc_init("test_delayed_write_update8"); >-- >2.17.1 > > >From 58ce7c981b96c7f84685d1e3064a535353e4eac7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 17 Aug 2018 15:19:25 +0200 >Subject: [PATCH 48/48] Output examples > >bin/smbtorture //172.31.9.192/torture -Uadministrator%geheim 'base.delaywrite-legacy' 2>&1 | tee out.legacy-192 >bin/smbtorture //172.31.9.219/torture -Uadministrator%A1b2C3d4 'base.delaywrite-modern' 2>&1 | tee out.modern-219 >bin/smbtorture //172.31.9.187/torture -Uadministrator%A1b2C3d4 'base.delaywrite-modern' 2>&1 | tee out.modern-187 > >172.31.9.192 is Windows 2000 SP4 >172.31.9.219 is Windows 2008 R2 >172.31.9.187 is Windows 2016 >--- > out.legacy-192 | 1086 +++++++++++++++++++++++ > out.modern-187 | 2297 ++++++++++++++++++++++++++++++++++++++++++++++++ > out.modern-219 | 1787 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 5170 insertions(+) > create mode 100644 out.legacy-192 > create mode 100644 out.modern-187 > create mode 100644 out.modern-219 > >diff --git a/out.legacy-192 b/out.legacy-192 >new file mode 100644 >index 000000000000..b57ecf6ced32 >--- /dev/null >+++ b/out.legacy-192 >@@ -0,0 +1,1086 @@ >+smbtorture 4.10.0pre1-DEVELOPERBUILD >+Using seed 1534511438 >+time: 2018-08-17 13:10:38.915952 >+progress: 17 >+test: finfo update on close >+time: 2018-08-17 13:10:38.916111 >+ >+Running test_finfo_after_write >+time: 2018-08-17 13:10:39.932646 >+success: finfo update on close >+test: delayed update of write time >+time: 2018-08-17 13:10:39.932686 >+ >+Running test_delayed_write_update >+Initial write time Fri Aug 17 15:10:40 2018 CEST >+write time Fri Aug 17 15:10:40 2018 CEST >+write time Fri Aug 17 15:10:40 2018 CEST >+write time Fri Aug 17 15:10:40 2018 CEST >+write time Fri Aug 17 15:10:42 2018 CEST >+Server updated write_time after 3.00 seconds (correct) >+time: 2018-08-17 13:10:42.950208 >+success: delayed update of write time >+test: update of write time and SMBwrite truncate >+time: 2018-08-17 13:10:42.950251 >+ >+Running test_delayed_write_update1 >+Initial write time Fri Aug 17 15:10:43 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+write time Fri Aug 17 15:10:49 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 13:11:02.988284 >+success: update of write time and SMBwrite truncate >+test: update of write time and SMBwrite truncate expand >+time: 2018-08-17 13:11:02.988328 >+ >+Running test_delayed_write_update1a >+Initial write time Fri Aug 17 15:11:03 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+write time Fri Aug 17 15:11:06 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 13:11:18.021734 >+success: update of write time and SMBwrite truncate expand >+test: update of write time using SET_END_OF_FILE >+time: 2018-08-17 13:11:18.021753 >+ >+Running test_delayed_write_update1b >+Initial write time Fri Aug 17 15:11:18 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+write time Fri Aug 17 15:11:21 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 13:11:33.054125 >+success: update of write time using SET_END_OF_FILE >+test: update of write time using SET_ALLOCATION_SIZE >+time: 2018-08-17 13:11:33.054165 >+ >+Running test_delayed_write_update1c >+Initial write time Fri Aug 17 15:11:33 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+write time Fri Aug 17 15:11:36 2018 CEST >+Server did not update write time within 10 seconds. Good! >+time: 2018-08-17 13:11:48.090610 >+success: update of write time using SET_ALLOCATION_SIZE >+test: delayed update of write time using 2 connections >+time: 2018-08-17 13:11:48.090656 >+ >+Running test_delayed_write_update2 >+Initial write time Fri Aug 17 15:11:48 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+Server updated write_time (correct) >+Modified write time Fri Aug 17 06:51:51 2018 CEST >+Doing a 10 byte write to extend the file and see if this changes the last write time. >+Doing flush after write >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+Server did not update write time (correct) >+Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. >+write time Fri Aug 17 06:51:51 2018 CEST >+Closing the first fd to see if write time updated. >+Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+write time Fri Aug 17 06:51:51 2018 CEST >+Server did not update write time (correct) >+Closing second fd to see if write time updated. >+Second open initial write time Fri Aug 17 15:12:23 2018 CEST >+Doing a 10 byte write to extend the file to see if this changes the last write time. >+write time Fri Aug 17 15:12:23 2018 CEST >+write time Fri Aug 17 15:12:23 2018 CEST >+write time Fri Aug 17 15:12:23 2018 CEST >+write time Fri Aug 17 15:12:34 2018 CEST >+Server updated write_time after 2.00 seconds(correct) >+time: 2018-08-17 13:12:35.189016 >+success: delayed update of write time using 2 connections >+test: delayed update of write time 3 >+time: 2018-08-17 13:12:35.189044 >+ >+Running test_delayed_write_update3 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:35.102404) Write(2018/08/17 15:12:35.102404) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Server updated write_time after 1.51 seconds (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:36.284103) Write(2018/08/17 15:12:36.284103) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:12:56.663407) Write(2018/08/17 15:12:56.663407) >+Server updated the write_time on close (correct) >+time: 2018-08-17 13:12:56.760420 >+success: delayed update of write time 3 >+test: delayed update of write time 3a >+time: 2018-08-17 13:12:56.760456 >+ >+Running test_delayed_write_update3a >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+pathinfo(cli2->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:12:56.673422) Write(2018/08/17 15:12:56.673422) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:03.322983) Write(2018/08/17 15:13:03.322983) >+Server updated write_time after 2.01 seconds (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:13:03.322983) Write(2018/08/17 15:13:03.322983) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:03.322983) Write(2018/08/17 15:13:03.322983) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:08.700716) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:08.700716) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:10.703596) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:10.703596) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:08.700716) Write(2018/08/17 15:13:12.706476) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:35.769639) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:35.769639) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:37.772519) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:37.772519) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) >+fileinfo(cli->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:13:35.769639) Write(2018/08/17 15:13:39.775399) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 13:13:42.871875 >+success: delayed update of write time 3a >+test: delayed update of write time 3b >+time: 2018-08-17 13:13:42.871895 >+ >+Running test_delayed_write_update3b >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:42.779719) Write(2018/08/17 15:13:42.779719) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Server updated write_time after 2.01 seconds (write time update delay == 0.50) (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+pathinfo(cli2->tree): Access(2018/08/17 15:13:49.389223) Write(2018/08/17 15:13:49.389223) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.848643) Write(2018/08/17 15:14:09.848643) >+Server updated the write_time on close (correct) >+time: 2018-08-17 13:14:09.951853 >+success: delayed update of write time 3b >+test: delayed update of write time 3c >+time: 2018-08-17 13:14:09.951883 >+ >+Running test_delayed_write_update3c >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:09.868671) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:16.878751) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:16.878751) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:18.881631) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:18.881631) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:09.868671) Write(2018/08/17 15:14:20.884511) >+Do a truncate write [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:34.914686) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:34.914686) >+Do a truncate write [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:36.907551) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:36.907551) >+Do a truncate write [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+pathinfo(cli2->tree): Access(2018/08/17 15:14:34.914686) Write(2018/08/17 15:14:38.920446) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:15:03.976475) Write(2018/08/17 15:15:03.976475) >+Server updated the write_time on close (correct) >+time: 2018-08-17 13:15:04.075559 >+success: delayed update of write time 3c >+test: delayed update of write time 4 >+time: 2018-08-17 13:15:04.075597 >+ >+Running test_delayed_write_update4 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+fileinfo(cli->tree): Access(2018/08/17 15:15:03.996503) Write(2018/08/17 15:15:03.996503) >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Server updated write_time after 1.51 seconds (write time update delay == 0.50) (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Server did not updatewrite_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:10.505863) Write(2018/08/17 15:15:10.505863) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.554692) Write(2018/08/17 15:15:30.554692) >+Server updated the write_time on close (correct) >+time: 2018-08-17 13:15:30.655585 >+success: delayed update of write time 4 >+test: delayed update of write time 5 >+time: 2018-08-17 13:15:30.655608 >+ >+Running test_delayed_write_update5 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/17 15:15:30.574721) >+Set write time in the future on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/18 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/18 15:15:30.000000) >+Set write time in the past on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:15:30.574721) Write(2018/08/16 15:15:30.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.665179) Write(2018/08/16 15:15:30.000000) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 13:16:05.765388 >+success: delayed update of write time 5 >+test: delayed update of write time 5b >+time: 2018-08-17 13:16:05.765418 >+ >+Running test_delayed_write_update5b >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/17 15:16:05.685207) >+Set write time in the future on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/18 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/18 15:16:05.000000) >+Set write time in the past on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Server did not update write_time (correct) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:16:05.685207) Write(2018/08/16 15:16:05.000000) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 13:16:40.866349 >+success: delayed update of write time 5b >+test: delayed update of write time 6 >+time: 2018-08-17 13:16:40.866374 >+ >+Running test_delayed_write_update6 >+Open the file handle >+Open the 2nd file handle on 2nd connection >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/17 15:16:40.785679) >+Set write time in the future on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/18 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/18 15:16:40.000000) >+Set write time in the past on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:16:40.785679) Write(2018/08/16 15:16:40.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Server updated the write_time on close (correct) >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Have we lost the sticky write time ? >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:05.841708) Write(2018/08/17 15:17:05.841708) >+Set write time in the future on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/18 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/18 15:17:28.000000) >+Set write time in the past on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:28.904871) Write(2018/08/16 15:17:28.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Server updated the write_time on close (correct) >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Have we lost the sticky write time ? >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+pathinfo(cli2->tree): Access(2018/08/17 15:17:53.960900) Write(2018/08/17 15:17:53.960900) >+Close the 2nd file handle >+pathinfo(cli2->tree): Access(2018/08/17 15:18:17.014049) Write(2018/08/17 15:17:53.960900) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 13:18:17.112115 >+success: delayed update of write time 6 >+test: timestamp resolution test >+time: 2018-08-17 13:18:17.112135 >+ >+Running test_delayed_write_update7 (timestamp resolution test) >+time: 2018-08-17 13:18:17.121007 >+success: timestamp resolution test >+test: directory timestamp update test >+time: 2018-08-17 13:18:17.121025 >+ >+Running test directory write update >+Initial write time Fri Aug 17 15:18:17 2018 CEST >+Updated write time Fri Aug 17 15:18:20 2018 CEST >+time: 2018-08-17 13:18:20.134425 >+success: directory timestamp update test >diff --git a/out.modern-187 b/out.modern-187 >new file mode 100644 >index 000000000000..bdac1a55b6ef >--- /dev/null >+++ b/out.modern-187 >@@ -0,0 +1,2297 @@ >+smbtorture 4.10.0pre1-DEVELOPERBUILD >+Using seed 1534501266 >+time: 2018-08-17 10:21:06.655675 >+progress: 17 >+test: finfo update on close >+time: 2018-08-17 10:21:06.655833 >+ >+Running test_finfo_after_write >+time: 2018-08-17 10:21:07.676713 >+success: finfo update on close >+test: delayed update of write time >+time: 2018-08-17 10:21:07.676756 >+ >+Running test_delayed_write_update >+Initial write time Fri Aug 17 12:21:08 2018 CEST >+write time Fri Aug 17 12:21:08 2018 CEST >+write time Fri Aug 17 12:21:08 2018 CEST >+write time Fri Aug 17 12:21:10 2018 CEST >+Server updated write_time after 2.00 seconds (correct) >+time: 2018-08-17 10:21:09.692169 >+success: delayed update of write time >+test: update of write time and SMBwrite truncate >+time: 2018-08-17 10:21:09.692208 >+ >+Running test_delayed_write_update1 >+Initial write time Fri Aug 17 12:21:10 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+write time Fri Aug 17 12:21:16 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 10:21:29.741022 >+success: update of write time and SMBwrite truncate >+test: update of write time and SMBwrite truncate expand >+time: 2018-08-17 10:21:29.741063 >+ >+Running test_delayed_write_update1a >+Initial write time Fri Aug 17 12:21:30 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+write time Fri Aug 17 12:21:33 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 10:21:44.794855 >+success: update of write time and SMBwrite truncate expand >+test: update of write time using SET_END_OF_FILE >+time: 2018-08-17 10:21:44.794884 >+ >+Running test_delayed_write_update1b >+Initial write time Fri Aug 17 12:21:45 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+write time Fri Aug 17 12:21:48 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 10:21:59.848678 >+success: update of write time using SET_END_OF_FILE >+test: update of write time using SET_ALLOCATION_SIZE >+time: 2018-08-17 10:21:59.848707 >+ >+Running test_delayed_write_update1c >+Initial write time Fri Aug 17 12:22:00 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+write time Fri Aug 17 12:22:03 2018 CEST >+Server did not update write time within 10 seconds. Good! >+time: 2018-08-17 10:22:14.889942 >+success: update of write time using SET_ALLOCATION_SIZE >+test: delayed update of write time using 2 connections >+time: 2018-08-17 10:22:14.889983 >+ >+Running test_delayed_write_update2 >+Initial write time Fri Aug 17 12:22:15 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+Server updated write_time (correct) >+Modified write time Fri Aug 17 04:02:17 2018 CEST >+Doing a 10 byte write to extend the file and see if this changes the last write time. >+Doing flush after write >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+Server did not update write time (correct) >+Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. >+write time Fri Aug 17 04:02:17 2018 CEST >+Closing the first fd to see if write time updated. >+Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+write time Fri Aug 17 04:02:17 2018 CEST >+Server did not update write time (correct) >+Closing second fd to see if write time updated. >+Second open initial write time Fri Aug 17 12:22:50 2018 CEST >+Doing a 10 byte write to extend the file to see if this changes the last write time. >+write time Fri Aug 17 12:22:50 2018 CEST >+write time Fri Aug 17 12:22:50 2018 CEST >+write time Fri Aug 17 12:22:50 2018 CEST >+write time Fri Aug 17 12:22:50 2018 CEST >+write time Fri Aug 17 12:23:03 2018 CEST >+Server updated write_time after 3.01 seconds(correct) >+time: 2018-08-17 10:23:03.004249 >+success: delayed update of write time using 2 connections >+test: delayed update of write time 3 >+time: 2018-08-17 10:23:03.004310 >+ >+Running test_delayed_write_update3 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:02.968606) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Server updated write_time after 2.01 seconds (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:04.499640) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:23:02.968606) Write(2018/08/17 12:23:25.030595) >+Server updated the write_time on close (correct) >+time: 2018-08-17 10:23:25.085565 >+success: delayed update of write time 3 >+test: delayed update of write time 3a >+time: 2018-08-17 10:23:25.085579 >+ >+Running test_delayed_write_update3a >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:25.046529) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:30.498815) >+Server updated write_time after 0.50 seconds (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:30.498815) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:30.498815) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:35.561499) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:35.561499) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:37.577115) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:37.577115) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:23:39.592449) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:02.810789) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:02.810789) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:04.810696) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:04.810696) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) >+fileinfo(cli->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:23:25.046529) Write(2018/08/17 12:24:06.826559) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:24:09.882712 >+success: delayed update of write time 3a >+test: delayed update of write time 3b >+time: 2018-08-17 10:24:09.882744 >+ >+Running test_delayed_write_update3b >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:09.842148) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Server updated write_time after 0.50 seconds (write time update delay == 0.50) (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:14.873369) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:24:09.842148) Write(2018/08/17 12:24:35.419315) >+Server updated the write_time on close (correct) >+time: 2018-08-17 10:24:35.467659 >+success: delayed update of write time 3b >+test: delayed update of write time 3c >+time: 2018-08-17 10:24:35.467721 >+ >+Running test_delayed_write_update3c >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:35.434994) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:42.435487) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:42.435487) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:44.450742) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:44.450742) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:24:46.450692) >+Do a truncate write [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:00.481998) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:00.481998) >+Do a truncate write [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:02.497410) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:02.497410) >+Do a truncate write [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:04.497007) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:24:35.434994) Write(2018/08/17 12:25:29.590701) >+Server updated the write_time on close (correct) >+time: 2018-08-17 10:25:29.657002 >+success: delayed update of write time 3c >+test: delayed update of write time 5 >+time: 2018-08-17 10:25:29.657021 >+ >+Running test_delayed_write_update5 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/17 12:25:29.621994) >+Set write time in the future on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/18 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/18 12:25:29.000000) >+Set write time in the past on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:25:29.621994) Write(2018/08/16 12:25:29.000000) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:26:04.774051 >+success: delayed update of write time 5 >+test: delayed update of write time 5b >+time: 2018-08-17 10:26:04.774088 >+ >+Running test_delayed_write_update5b >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/17 12:26:04.731354) >+Set write time in the future on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/18 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/18 12:26:04.000000) >+Set write time in the past on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Server did not update write_time (correct) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:26:04.731354) Write(2018/08/16 12:26:04.000000) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:26:39.928555 >+success: delayed update of write time 5b >+test: delayed update of write time 6 >+time: 2018-08-17 10:26:39.928575 >+ >+Running test_delayed_write_update6 >+Open the file handle >+Open the 2nd file handle on 2nd connection >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:26:39.887346) >+Set write time in the future on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:26:39.000000) >+Set write time in the past on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:26:39.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Server updated the write_time on close (correct) >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Have we lost the sticky write time ? >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:04.964048) >+Set write time in the future on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/18 12:27:28.000000) >+Set write time in the past on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/16 12:27:28.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Server updated the write_time on close (correct) >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Have we lost the sticky write time ? >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Close the 2nd file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:26:39.887346) Write(2018/08/17 12:27:53.104346) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:28:16.218644 >+success: delayed update of write time 6 >+test: timestamp resolution test >+time: 2018-08-17 10:28:16.218678 >+ >+Running test_delayed_write_update7 (timestamp resolution test) >+time: 2018-08-17 10:28:16.233498 >+success: timestamp resolution test >+test: directory timestamp update test >+time: 2018-08-17 10:28:16.233519 >+ >+Running test directory write update >+Initial write time Fri Aug 17 12:28:16 2018 CEST >+Updated write time Fri Aug 17 12:28:19 2018 CEST >+time: 2018-08-17 10:28:19.248341 >+success: directory timestamp update test >+test: delaywrite1 >+time: 2018-08-17 10:28:19.248394 >+ >+Running test_delaywrite_delaywrite1 >+Open the file handle >+START: run1 >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:19.213229) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Server updated write_time after 1.00/1.01 seconds (min delay == 0.01, max delay == 5.00) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:25.244496) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Server updated write_time after 0.38/0.38 seconds (min delay == 0.01, max delay == 5.00) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+START: run2 >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:32.635303) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Server updated write_time after 3.01/3.01 seconds (min delay == 0.01, max delay == 5.00) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:47.681320) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Server updated write_time after 3.00/3.00 seconds (min delay == 0.01, max delay == 5.00) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+fileinfo(cli->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+Close the file handle >+Close the file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+pathinfo(cli2->tree): Access(2018/08/17 12:28:19.213229) Write(2018/08/17 12:28:56.704135) >+time: 2018-08-17 10:29:02.779445 >+success: delaywrite1 >diff --git a/out.modern-219 b/out.modern-219 >new file mode 100644 >index 000000000000..6445e89c07ae >--- /dev/null >+++ b/out.modern-219 >@@ -0,0 +1,1787 @@ >+smbtorture 4.10.0pre1-DEVELOPERBUILD >+Using seed 1534500791 >+time: 2018-08-17 10:13:11.988198 >+progress: 17 >+test: finfo update on close >+time: 2018-08-17 10:13:11.988352 >+ >+Running test_finfo_after_write >+time: 2018-08-17 10:13:13.005181 >+success: finfo update on close >+test: delayed update of write time >+time: 2018-08-17 10:13:13.005212 >+ >+Running test_delayed_write_update >+Initial write time Fri Aug 17 12:13:13 2018 CEST >+write time Fri Aug 17 12:13:13 2018 CEST >+write time Fri Aug 17 12:13:13 2018 CEST >+write time Fri Aug 17 12:13:15 2018 CEST >+Server updated write_time after 2.00 seconds (correct) >+time: 2018-08-17 10:13:15.020529 >+success: delayed update of write time >+test: update of write time and SMBwrite truncate >+time: 2018-08-17 10:13:15.020563 >+ >+Running test_delayed_write_update1 >+Initial write time Fri Aug 17 12:13:15 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+write time Fri Aug 17 12:13:21 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 10:13:35.065108 >+success: update of write time and SMBwrite truncate >+test: update of write time and SMBwrite truncate expand >+time: 2018-08-17 10:13:35.065151 >+ >+Running test_delayed_write_update1a >+Initial write time Fri Aug 17 12:13:35 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+write time Fri Aug 17 12:13:38 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 10:13:50.102264 >+success: update of write time and SMBwrite truncate expand >+test: update of write time using SET_END_OF_FILE >+time: 2018-08-17 10:13:50.102291 >+ >+Running test_delayed_write_update1b >+Initial write time Fri Aug 17 12:13:50 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+write time Fri Aug 17 12:13:53 2018 CEST >+Server did not update write time within 10 seconds. Good! >+Server updated write time on close (correct) >+time: 2018-08-17 10:14:05.142073 >+success: update of write time using SET_END_OF_FILE >+test: update of write time using SET_ALLOCATION_SIZE >+time: 2018-08-17 10:14:05.142110 >+ >+Running test_delayed_write_update1c >+Initial write time Fri Aug 17 12:14:05 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+Server updated write time immediately. Good! >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+write time Fri Aug 17 12:14:08 2018 CEST >+Server did not update write time within 10 seconds. Good! >+time: 2018-08-17 10:14:20.178262 >+success: update of write time using SET_ALLOCATION_SIZE >+test: delayed update of write time using 2 connections >+time: 2018-08-17 10:14:20.178301 >+ >+Running test_delayed_write_update2 >+Initial write time Fri Aug 17 12:14:20 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+Server updated write_time (correct) >+Modified write time Fri Aug 17 03:54:23 2018 CEST >+Doing a 10 byte write to extend the file and see if this changes the last write time. >+Doing flush after write >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+Server did not update write time (correct) >+Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. >+write time Fri Aug 17 03:54:23 2018 CEST >+Closing the first fd to see if write time updated. >+Doing a 10 byte write to extend the file via second fd and see if this changes the last write time. >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+write time Fri Aug 17 03:54:23 2018 CEST >+Server did not update write time (correct) >+Closing second fd to see if write time updated. >+Second open initial write time Fri Aug 17 12:14:55 2018 CEST >+Doing a 10 byte write to extend the file to see if this changes the last write time. >+write time Fri Aug 17 12:14:55 2018 CEST >+write time Fri Aug 17 12:14:55 2018 CEST >+write time Fri Aug 17 12:14:55 2018 CEST >+write time Fri Aug 17 12:14:55 2018 CEST >+write time Fri Aug 17 12:15:08 2018 CEST >+Server updated write_time after 3.01 seconds(correct) >+time: 2018-08-17 10:15:08.271634 >+success: delayed update of write time using 2 connections >+test: delayed update of write time 3 >+time: 2018-08-17 10:15:08.271665 >+ >+Running test_delayed_write_update3 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:08.178131) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Server updated write_time after 1.51 seconds (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:09.475006) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:15:08.178131) Write(2018/08/17 12:15:29.740631) >+Server updated the write_time on close (correct) >+time: 2018-08-17 10:15:29.846089 >+success: delayed update of write time 3 >+test: delayed update of write time 3a >+time: 2018-08-17 10:15:29.846124 >+ >+Running test_delayed_write_update3a >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:29.756256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:35.475006) >+Server updated write_time after 1.01 seconds (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:35.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:35.475006) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:40.771881) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:40.771881) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:42.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:42.787506) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:15:44.787506) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:07.850006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:07.850006) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:09.850006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:09.850006) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) >+fileinfo(cli->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:15:29.756256) Write(2018/08/17 12:16:11.850006) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:16:14.960060 >+success: delayed update of write time 3a >+test: delayed update of write time 3b >+time: 2018-08-17 10:16:14.960105 >+ >+Running test_delayed_write_update3b >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:14.881256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Server updated write_time after 1.01 seconds (write time update delay == 0.50) (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:20.475006) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:16:14.881256) Write(2018/08/17 12:16:40.943756) >+Server updated the write_time on close (correct) >+time: 2018-08-17 10:16:41.040859 >+success: delayed update of write time 3b >+test: delayed update of write time 3c >+time: 2018-08-17 10:16:41.040895 >+ >+Running test_delayed_write_update3c >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:40.959381) >+Do a truncate SMBwrite [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:47.959381) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:47.959381) >+Do a truncate SMBwrite [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:49.959381) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:49.959381) >+Do a truncate SMBwrite [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:16:51.975006) >+Do a truncate write [0] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:05.990631) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:05.990631) >+Do a truncate write [1] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:07.990631) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:07.990631) >+Do a truncate write [2] on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:10.006256) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:16:40.959381) Write(2018/08/17 12:17:35.053131) >+Server updated the write_time on close (correct) >+time: 2018-08-17 10:17:35.154560 >+success: delayed update of write time 3c >+test: delayed update of write time 5 >+time: 2018-08-17 10:17:35.154582 >+ >+Running test_delayed_write_update5 >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/17 12:17:35.068756) >+Set write time in the future on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/18 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/18 12:17:35.000000) >+Set write time in the past on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:17:35.068756) Write(2018/08/16 12:17:35.000000) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:18:10.267297 >+success: delayed update of write time 5 >+test: delayed update of write time 5b >+time: 2018-08-17 10:18:10.267338 >+ >+Running test_delayed_write_update5b >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/17 12:18:10.178131) >+Set write time in the future on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/18 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/18 12:18:10.000000) >+Set write time in the past on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Server did not update write_time (correct) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Do a truncate write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:18:10.178131) Write(2018/08/16 12:18:10.000000) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:18:45.375869 >+success: delayed update of write time 5b >+test: delayed update of write time 6 >+time: 2018-08-17 10:18:45.375909 >+ >+Running test_delayed_write_update6 >+Open the file handle >+Open the 2nd file handle on 2nd connection >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:18:45.287506) >+Set write time in the future on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:18:45.000000) >+Set write time in the past on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:18:45.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Server updated the write_time on close (correct) >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Have we lost the sticky write time ? >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Open the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:10.350006) >+Set write time in the future on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/18 12:19:33.000000) >+Set write time in the past on the 2nd file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Server did not update write_time (correct) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Do a write on the file handle >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Server did not update write_time (correct) >+fileinfo(cli->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/16 12:19:33.000000) >+Close the file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Server updated the write_time on close (correct) >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Have we lost the sticky write time ? >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Do a truncate write on the second file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Close the 2nd file handle >+pathinfo(cli2->tree): Access(2018/08/17 12:18:45.287506) Write(2018/08/17 12:19:58.475006) >+Server did not update the write_time on close (correct) >+time: 2018-08-17 10:20:21.632961 >+success: delayed update of write time 6 >+test: timestamp resolution test >+time: 2018-08-17 10:20:21.632986 >+ >+Running test_delayed_write_update7 (timestamp resolution test) >+time: 2018-08-17 10:20:21.646111 >+success: timestamp resolution test >+test: directory timestamp update test >+time: 2018-08-17 10:20:21.646136 >+ >+Running test directory write update >+Initial write time Fri Aug 17 12:20:22 2018 CEST >+Updated write time Fri Aug 17 12:20:25 2018 CEST >+time: 2018-08-17 10:20:24.658805 >+success: directory timestamp update test >+test: delaywrite1 >+time: 2018-08-17 10:20:24.658851 >+ >+Running test_delaywrite_delaywrite1 >+Open the file handle >+START: run1 >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:24.568756) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Server updated write_time after 1.00/1.00 seconds (min delay == 0.01, max delay == 5.00) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:31.475006) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Server updated write_time after 0.86/0.86 seconds (min delay == 0.01, max delay == 5.00) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+START: run2 >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Check for no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:38.475006) >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Server updated write_time after 3.01/3.01 seconds (min delay == 0.01, max delay == 5.00) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Check for no additional change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Do a write on the file handle >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:20:53.506256) >+Write while waiting >+Wait for change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Server updated write_time after 0.94/0.94 seconds (min delay == 0.01, max delay == 5.00) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Wait for change or no change >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+fileinfo(cli->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+Close the file handle >+Close the file handle >+fileinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+pathinfo(cli2->tree): Access(2018/08/17 12:20:24.568756) Write(2018/08/17 12:21:00.475006) >+time: 2018-08-17 10:21:06.592228 >+success: delaywrite1 >-- >2.17.1 >
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 13541
:
14351
| 14429