The branch, v4-0-test has been updated via eca8433 smbtorture: New torture test for bug #9870. via df348b8 smbd - allow updates on directory write times on open handles. from 717edc2 smbd: Fix a panic when a smb2 brlock times out
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test - Log ----------------------------------------------------------------- commit eca84335d65299553993c0cb282186f76072dfab Author: Jeremy Allison <j...@samba.org> Date: Tue Dec 3 17:26:26 2013 -0800 smbtorture: New torture test for bug #9870. Not fetching the latest modification time on a folder if we have read locks on it. Prove we should just rely on the mtime value from the underlying filesystem, even with an open handle. BUG: https://bugzilla.samba.org/show_bug.cgi?id=9870 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> Autobuild-User(master): Volker Lendecke <v...@samba.org> Autobuild-Date(master): Thu Dec 5 10:05:06 CET 2013 on sn-devel-104 BUG: https://bugzilla.samba.org/show_bug.cgi?id=9870 Not fetching the latest modification time on a folder if we have read locks on it. Autobuild-User(v4-0-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-0-test): Tue Dec 10 20:24:01 CET 2013 on sn-devel-104 commit df348b8d6b571f3f72ccd6ef3248eb63fd9b02b9 Author: Jeremy Allison <j...@samba.org> Date: Tue Dec 3 17:22:19 2013 -0800 smbd - allow updates on directory write times on open handles. If we set a non-null 'old timestamp' in the share mode database when creating a directory handle, this prevents mtime (write time) updates from being seen by clients, as we will always return the timestamp stored in the database whilst the handle is open. For files this is ok, as we update the stored timestamp ourselves when we write to the handle. For directories we should just rely on the mtime value from the underlying filesystem. Torture test to follow. BUG: https://bugzilla.samba.org/show_bug.cgi?id=9870 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Volker Lendecke <v...@samba.org> ----------------------------------------------------------------------- Summary of changes: selftest/knownfail | 1 + source3/smbd/open.c | 9 +++- source4/torture/basic/delaywrite.c | 95 ++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletions(-) Changeset truncated at 500 lines: diff --git a/selftest/knownfail b/selftest/knownfail index e393635..1889a6e 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -116,6 +116,7 @@ ^samba4.*base.delaywrite.*delayed update of write time 3c\(.*\)$ ^samba4.*base.delaywrite.*update of write time using SET_END_OF_FILE\(.*\)$ ^samba4.*base.delaywrite.*update of write time using SET_ALLOCATION_SIZE\(.*\)$ +^samba4.*base.delaywrite.*directory timestamp update test\(.*\)$ ^samba4.ldap.python \(dc\).Test add_ldif\(\) with BASE64 security descriptor input using WRONG domain SID\(.*\)$ # some operations don't work over the CIFS NTVFS backend yet (eg. root_fid) ^samba4.ntvfs.cifs.*.base.createx_sharemodes_dir diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 0282722..a41d3d5 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3154,7 +3154,14 @@ static NTSTATUS open_directory(connection_struct *conn, return status; } - mtimespec = smb_dname->st.st_ex_mtime; + /* Don't store old timestamps for directory + handles in the internal database. We don't + update them in there if new objects + are creaded in the directory. Currently + we only update timestamps on file writes. + See bug #9870. + */ + ZERO_STRUCT(mtimespec); #ifdef O_DIRECTORY status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0); diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 15482d8..90ad667 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -3059,6 +3059,100 @@ static bool test_delayed_write_update7(struct torture_context *tctx, struct smbc } /* + Test if creating a file in a directory with an open handle updates the + write timestamp (it should). +*/ +static bool test_directory_update8(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_fileinfo dir_info1, dir_info2; + union smb_open open_parms; + const char *fname = BASEDIR "\\torture_file.txt"; + NTSTATUS status; + int fnum1 = -1; + int fnum2 = -1; + bool ret = true; + int used_delay = torture_setting_int(tctx, "writetimeupdatedelay", 2000000); + int normal_delay = 2000000; + double sec = ((double)used_delay) / ((double)normal_delay); + int msec = 1000 * sec; + TALLOC_CTX *mem_ctx = talloc_init("test_delayed_write_update8"); + + if (!mem_ctx) return false; + + torture_comment(tctx, "\nRunning test directory write update\n"); + + torture_assert(tctx, torture_setup_dir(cli, BASEDIR), "Failed to setup up test directory: " BASEDIR); + + /* Open a handle on the directory - and leave it open. */ + ZERO_STRUCT(open_parms); + open_parms.ntcreatex.level = RAW_OPEN_NTCREATEX; + open_parms.ntcreatex.in.flags = 0; + open_parms.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_READ; + open_parms.ntcreatex.in.file_attr = 0; + open_parms.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; + open_parms.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + open_parms.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + open_parms.ntcreatex.in.fname = BASEDIR; + + status = smb_raw_open(cli->tree, mem_ctx, &open_parms); + talloc_free(mem_ctx); + + if (!NT_STATUS_IS_OK(status)) { + torture_result(tctx, TORTURE_FAIL, + "failed to open directory handle"); + ret = false; + goto done; + } + + fnum1 = open_parms.ntcreatex.out.file.fnum; + + /* Store the returned write time. */ + ZERO_STRUCT(dir_info1); + dir_info1.basic_info.out.write_time = open_parms.ntcreatex.out.write_time; + + torture_comment(tctx, "Initial write time %s\n", + nt_time_string(tctx, dir_info1.basic_info.out.write_time)); + + /* sleep */ + smb_msleep(3 * msec); + + /* Now create a file within the directory. */ + fnum2 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum2 == -1) { + torture_result(tctx, TORTURE_FAIL, "Failed to open %s", fname); + ret = false; + goto done; + } + smbcli_close(cli->tree, fnum2); + + /* Read the directory write time again. */ + ZERO_STRUCT(dir_info2); + dir_info2.basic_info.level = RAW_FILEINFO_BASIC_INFO; + dir_info2.basic_info.in.file.fnum = fnum1; + + status = smb_raw_fileinfo(cli->tree, tctx, &dir_info2); + + torture_assert_ntstatus_ok(tctx, status, "fileinfo failed"); + + /* Ensure it's been incremented. */ + COMPARE_WRITE_TIME_GREATER(dir_info2, dir_info1); + + torture_comment(tctx, "Updated write time %s\n", + nt_time_string(tctx, dir_info2.basic_info.out.write_time)); + + done: + + if (fnum1 != -1) + smbcli_close(cli->tree, fnum1); + smbcli_unlink(cli->tree, fname); + smbcli_deltree(cli->tree, BASEDIR); + + return ret; +} + +/* testing of delayed update of write_time */ struct torture_suite *torture_delay_write(void) @@ -3082,6 +3176,7 @@ struct torture_suite *torture_delay_write(void) 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, "timestamp resolution test", test_delayed_write_update7); + torture_suite_add_1smb_test(suite, "directory timestamp update test", test_directory_update8); return suite; } -- Samba Shared Repository