2 Unix SMB/CIFS implementation.
6 Copyright (C) Christof Schmitt 2016
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libcli/smb2/smb2.h"
24 #include "libcli/smb2/smb2_calls.h"
26 #include "torture/torture.h"
27 #include "torture/smb2/proto.h"
29 bool torture_smb2_maxfid(struct torture_context *tctx)
33 struct smb2_tree *tree = NULL;
34 const char *dname = "smb2_maxfid";
36 struct smb2_handle *handles, dir_handle = { };
37 const size_t max_handles = 0x41000; /* Windows 8.1 allowed 0x40000 */
39 if (!torture_smb2_connection(tctx, &tree)) {
43 handles = talloc_array(tctx, struct smb2_handle, max_handles);
45 torture_fail(tctx, "Could not allocate handles array.\n");
49 smb2_deltree(tree, dname);
51 status = torture_smb2_testdir(tree, dname, &dir_handle);
52 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
53 "torture_smb2_testdir failed");
54 smb2_util_close(tree, dir_handle);
56 torture_comment(tctx, "Creating subdirectories\n");
58 for (i = 0; i < max_handles; i += 1000) {
60 struct smb2_create create = { };
61 struct smb2_close close = { };
63 name = talloc_asprintf(tctx, "%s\\%d", dname, i / 1000);
64 torture_assert_goto(tctx, (name != NULL), ret, done,
65 "no memory for directory name\n");
67 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
68 create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
69 create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
70 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
71 NTCREATEX_SHARE_ACCESS_WRITE |
72 NTCREATEX_SHARE_ACCESS_DELETE;
73 create.in.create_disposition = NTCREATEX_DISP_CREATE;
74 create.in.fname = name;
76 status = smb2_create(tree, tctx, &create);
79 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
80 "CREATE directory failed\n");
82 close.in.file.handle = create.out.file.handle;
83 status = smb2_close(tree, &close);
84 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
85 "CLOSE directory failed\n");
88 torture_comment(tctx, "Testing maximum number of open files\n");
90 for (i = 0; i < max_handles; i++) {
92 struct smb2_create create = { };
94 name = talloc_asprintf(tctx, "%s\\%d\\%d", dname, i / 1000, i);
95 torture_assert_goto(tctx, (name != NULL), ret, done,
96 "no memory for file name\n");
98 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
99 create.in.create_options = 0;
100 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
101 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
102 NTCREATEX_SHARE_ACCESS_WRITE |
103 NTCREATEX_SHARE_ACCESS_DELETE;
104 create.in.create_disposition = NTCREATEX_DISP_CREATE;
105 create.in.fname = name;
107 status = smb2_create(tree, tctx, &create);
108 if (!NT_STATUS_IS_OK(status)) {
109 torture_comment(tctx, "create of %s failed: %s\n",
110 name, nt_errstr(status));
116 handles[i] = create.out.file.handle;
120 torture_comment(tctx, "Maximum number of open files: %d\n", maxfid);
122 torture_comment(tctx, "Cleanup open files\n");
124 for (i = 0; i < maxfid; i++) {
125 union smb_setfileinfo sfinfo = { };
127 sfinfo.disposition_info.in.delete_on_close = 1;
128 sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
129 sfinfo.generic.in.file.handle = handles[i];
131 status = smb2_setinfo_file(tree, &sfinfo);
132 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
135 status = smb2_util_close(tree, handles[i]);
136 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
141 smb2_deltree(tree, dname);
142 talloc_free(handles);