smbtorture: New torture test for bug #9870.
authorJeremy Allison <jra@samba.org>
Wed, 4 Dec 2013 01:26:26 +0000 (17:26 -0800)
committerKarolin Seeger <kseeger@samba.org>
Tue, 10 Dec 2013 19:19:07 +0000 (20:19 +0100)
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 <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
Autobuild-User(master): Volker Lendecke <vl@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-1-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-1-test): Tue Dec 10 20:19:08 CET 2013 on sn-devel-104

selftest/knownfail
source4/torture/basic/delaywrite.c

index 258694767215c3c9e5a73b2c57a5b93d1c42991e..54b74561abd96be5e404f9fbbd8d5c905e4a31ed 100644 (file)
 ^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
index 23a17d5a7a32896c2de76593f5f7cf53ae94d07e..da03b72d431078efba439fb738bc789fd6ae768a 100644 (file)
@@ -3058,6 +3058,100 @@ static bool test_delayed_write_update7(struct torture_context *tctx, struct smbc
        return ret;
 }
 
+/*
+   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
 */
@@ -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;
 }