s3: Fix bug #9085.
[Samba.git] / source4 / torture / raw / write.c
blob5d3628ca86ff866bfd9afa28f8fd5a2b4ffd5f00
1 /*
2 Unix SMB/CIFS implementation.
3 test suite for various write operations
5 Copyright (C) Andrew Tridgell 2003
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "torture/torture.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "libcli/raw/raw_proto.h"
25 #include "system/time.h"
26 #include "system/filesys.h"
27 #include "libcli/libcli.h"
28 #include "torture/util.h"
30 #define CHECK_STATUS(status, correct) do { \
31 if (!NT_STATUS_EQUAL(status, correct)) { \
32 printf("(%s) Incorrect status %s - should be %s\n", \
33 __location__, nt_errstr(status), nt_errstr(correct)); \
34 ret = false; \
35 goto done; \
36 }} while (0)
38 #define CHECK_VALUE(v, correct) do { \
39 if ((v) != (correct)) { \
40 printf("(%s) Incorrect value %s=%d - should be %d\n", \
41 __location__, #v, v, correct); \
42 ret = false; \
43 goto done; \
44 }} while (0)
46 #define CHECK_BUFFER(buf, seed, len) do { \
47 if (!check_buffer(buf, seed, len, __location__)) { \
48 ret = false; \
49 goto done; \
50 }} while (0)
52 #define CHECK_ALL_INFO(v, field) do { \
53 finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
54 finfo.all_info.in.file.path = fname; \
55 status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
56 CHECK_STATUS(status, NT_STATUS_OK); \
57 if ((v) != finfo.all_info.out.field) { \
58 printf("(%s) wrong value for field %s %.0f - %.0f\n", \
59 __location__, #field, (double)v, (double)finfo.all_info.out.field); \
60 dump_all_info(tctx, &finfo); \
61 ret = false; \
62 }} while (0)
65 #define BASEDIR "\\testwrite"
69 setup a random buffer based on a seed
71 static void setup_buffer(uint8_t *buf, uint_t seed, int len)
73 int i;
74 srandom(seed);
75 for (i=0;i<len;i++) buf[i] = random();
79 check a random buffer based on a seed
81 static bool check_buffer(uint8_t *buf, uint_t seed, int len, const char *location)
83 int i;
84 srandom(seed);
85 for (i=0;i<len;i++) {
86 uint8_t v = random();
87 if (buf[i] != v) {
88 printf("Buffer incorrect at %s! ofs=%d buf=0x%x correct=0x%x\n",
89 location, i, buf[i], v);
90 return false;
93 return true;
97 test write ops
99 static bool test_write(struct torture_context *tctx,
100 struct smbcli_state *cli)
102 union smb_write io;
103 NTSTATUS status;
104 bool ret = true;
105 int fnum;
106 uint8_t *buf;
107 const int maxsize = 90000;
108 const char *fname = BASEDIR "\\test.txt";
109 uint_t seed = time(NULL);
110 union smb_fileinfo finfo;
112 buf = talloc_zero_array(tctx, uint8_t, maxsize);
114 if (!torture_setup_dir(cli, BASEDIR)) {
115 return false;
118 printf("Testing RAW_WRITE_WRITE\n");
119 io.generic.level = RAW_WRITE_WRITE;
121 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
122 if (fnum == -1) {
123 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
124 ret = false;
125 goto done;
128 printf("Trying zero write\n");
129 io.write.in.file.fnum = fnum;
130 io.write.in.count = 0;
131 io.write.in.offset = 0;
132 io.write.in.remaining = 0;
133 io.write.in.data = buf;
134 status = smb_raw_write(cli->tree, &io);
135 CHECK_STATUS(status, NT_STATUS_OK);
136 CHECK_VALUE(io.write.out.nwritten, 0);
138 setup_buffer(buf, seed, maxsize);
140 printf("Trying small write\n");
141 io.write.in.count = 9;
142 io.write.in.offset = 4;
143 io.write.in.data = buf;
144 status = smb_raw_write(cli->tree, &io);
145 CHECK_STATUS(status, NT_STATUS_OK);
146 CHECK_VALUE(io.write.out.nwritten, io.write.in.count);
148 memset(buf, 0, maxsize);
149 if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
150 printf("read failed at %s\n", __location__);
151 ret = false;
152 goto done;
154 CHECK_BUFFER(buf+4, seed, 9);
155 CHECK_VALUE(IVAL(buf,0), 0);
157 setup_buffer(buf, seed, maxsize);
159 printf("Trying large write\n");
160 io.write.in.count = 4000;
161 io.write.in.offset = 0;
162 io.write.in.data = buf;
163 status = smb_raw_write(cli->tree, &io);
164 CHECK_STATUS(status, NT_STATUS_OK);
165 CHECK_VALUE(io.write.out.nwritten, 4000);
167 memset(buf, 0, maxsize);
168 if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
169 printf("read failed at %s\n", __location__);
170 ret = false;
171 goto done;
173 CHECK_BUFFER(buf, seed, 4000);
175 printf("Trying bad fnum\n");
176 io.write.in.file.fnum = fnum+1;
177 io.write.in.count = 4000;
178 io.write.in.offset = 0;
179 io.write.in.data = buf;
180 status = smb_raw_write(cli->tree, &io);
181 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
183 printf("Setting file as sparse\n");
184 status = torture_set_sparse(cli->tree, fnum);
185 CHECK_STATUS(status, NT_STATUS_OK);
187 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
188 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
189 goto done;
192 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
193 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
194 goto done;
197 printf("Trying 2^32 offset\n");
198 setup_buffer(buf, seed, maxsize);
199 io.write.in.file.fnum = fnum;
200 io.write.in.count = 4000;
201 io.write.in.offset = 0xFFFFFFFF - 2000;
202 io.write.in.data = buf;
203 status = smb_raw_write(cli->tree, &io);
204 CHECK_STATUS(status, NT_STATUS_OK);
205 CHECK_VALUE(io.write.out.nwritten, 4000);
206 CHECK_ALL_INFO(io.write.in.count + (uint64_t)io.write.in.offset, size);
208 memset(buf, 0, maxsize);
209 if (smbcli_read(cli->tree, fnum, buf, io.write.in.offset, 4000) != 4000) {
210 printf("read failed at %s\n", __location__);
211 ret = false;
212 goto done;
214 CHECK_BUFFER(buf, seed, 4000);
216 done:
217 smbcli_close(cli->tree, fnum);
218 smb_raw_exit(cli->session);
219 smbcli_deltree(cli->tree, BASEDIR);
220 return ret;
225 test writex ops
227 static bool test_writex(struct torture_context *tctx,
228 struct smbcli_state *cli)
230 union smb_write io;
231 NTSTATUS status;
232 bool ret = true;
233 int fnum, i;
234 uint8_t *buf;
235 const int maxsize = 90000;
236 const char *fname = BASEDIR "\\test.txt";
237 uint_t seed = time(NULL);
238 union smb_fileinfo finfo;
239 int max_bits=63;
241 if (!torture_setting_bool(tctx, "dangerous", false)) {
242 max_bits=33;
243 torture_comment(tctx, "dangerous not set - limiting range of test to 2^%d\n", max_bits);
246 buf = talloc_zero_array(tctx, uint8_t, maxsize);
248 if (!torture_setup_dir(cli, BASEDIR)) {
249 return false;
252 printf("Testing RAW_WRITE_WRITEX\n");
253 io.generic.level = RAW_WRITE_WRITEX;
255 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
256 if (fnum == -1) {
257 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
258 ret = false;
259 goto done;
262 printf("Trying zero write\n");
263 io.writex.in.file.fnum = fnum;
264 io.writex.in.offset = 0;
265 io.writex.in.wmode = 0;
266 io.writex.in.remaining = 0;
267 io.writex.in.count = 0;
268 io.writex.in.data = buf;
269 status = smb_raw_write(cli->tree, &io);
270 CHECK_STATUS(status, NT_STATUS_OK);
271 CHECK_VALUE(io.writex.out.nwritten, 0);
273 setup_buffer(buf, seed, maxsize);
275 printf("Trying small write\n");
276 io.writex.in.count = 9;
277 io.writex.in.offset = 4;
278 io.writex.in.data = buf;
279 status = smb_raw_write(cli->tree, &io);
280 CHECK_STATUS(status, NT_STATUS_OK);
281 CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
283 memset(buf, 0, maxsize);
284 if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
285 printf("read failed at %s\n", __location__);
286 ret = false;
287 goto done;
289 CHECK_BUFFER(buf+4, seed, 9);
290 CHECK_VALUE(IVAL(buf,0), 0);
292 setup_buffer(buf, seed, maxsize);
294 printf("Trying large write\n");
295 io.writex.in.count = 4000;
296 io.writex.in.offset = 0;
297 io.writex.in.data = buf;
298 status = smb_raw_write(cli->tree, &io);
299 CHECK_STATUS(status, NT_STATUS_OK);
300 CHECK_VALUE(io.writex.out.nwritten, 4000);
302 memset(buf, 0, maxsize);
303 if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
304 printf("read failed at %s\n", __location__);
305 ret = false;
306 goto done;
308 CHECK_BUFFER(buf, seed, 4000);
310 printf("Trying bad fnum\n");
311 io.writex.in.file.fnum = fnum+1;
312 io.writex.in.count = 4000;
313 io.writex.in.offset = 0;
314 io.writex.in.data = buf;
315 status = smb_raw_write(cli->tree, &io);
316 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
318 printf("Testing wmode\n");
319 io.writex.in.file.fnum = fnum;
320 io.writex.in.count = 1;
321 io.writex.in.offset = 0;
322 io.writex.in.wmode = 1;
323 io.writex.in.data = buf;
324 status = smb_raw_write(cli->tree, &io);
325 CHECK_STATUS(status, NT_STATUS_OK);
326 CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
328 io.writex.in.wmode = 2;
329 status = smb_raw_write(cli->tree, &io);
330 CHECK_STATUS(status, NT_STATUS_OK);
331 CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count);
334 printf("Trying locked region\n");
335 cli->session->pid++;
336 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 3, 1, 0, WRITE_LOCK))) {
337 printf("Failed to lock file at %s\n", __location__);
338 ret = false;
339 goto done;
341 cli->session->pid--;
342 io.writex.in.wmode = 0;
343 io.writex.in.count = 4;
344 io.writex.in.offset = 0;
345 status = smb_raw_write(cli->tree, &io);
346 CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
348 printf("Setting file as sparse\n");
349 status = torture_set_sparse(cli->tree, fnum);
350 CHECK_STATUS(status, NT_STATUS_OK);
352 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
353 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
354 goto done;
357 printf("Trying 2^32 offset\n");
358 setup_buffer(buf, seed, maxsize);
359 io.writex.in.file.fnum = fnum;
360 io.writex.in.count = 4000;
361 io.writex.in.offset = 0xFFFFFFFF - 2000;
362 io.writex.in.data = buf;
363 status = smb_raw_write(cli->tree, &io);
364 CHECK_STATUS(status, NT_STATUS_OK);
365 CHECK_VALUE(io.writex.out.nwritten, 4000);
366 CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
368 memset(buf, 0, maxsize);
369 if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
370 printf("read failed at %s\n", __location__);
371 ret = false;
372 goto done;
374 CHECK_BUFFER(buf, seed, 4000);
376 for (i=33;i<max_bits;i++) {
377 printf("Trying 2^%d offset\n", i);
378 setup_buffer(buf, seed+1, maxsize);
379 io.writex.in.file.fnum = fnum;
380 io.writex.in.count = 4000;
381 io.writex.in.offset = ((uint64_t)1) << i;
382 io.writex.in.data = buf;
383 status = smb_raw_write(cli->tree, &io);
384 if (i>33 &&
385 NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
386 break;
388 CHECK_STATUS(status, NT_STATUS_OK);
389 CHECK_VALUE(io.writex.out.nwritten, 4000);
390 CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size);
392 memset(buf, 0, maxsize);
393 if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) {
394 printf("read failed at %s\n", __location__);
395 ret = false;
396 goto done;
398 CHECK_BUFFER(buf, seed+1, 4000);
400 printf("limit is 2^%d\n", i);
402 setup_buffer(buf, seed, maxsize);
404 done:
405 smbcli_close(cli->tree, fnum);
406 smb_raw_exit(cli->session);
407 smbcli_deltree(cli->tree, BASEDIR);
408 return ret;
413 test write unlock ops
415 static bool test_writeunlock(struct torture_context *tctx,
416 struct smbcli_state *cli)
418 union smb_write io;
419 NTSTATUS status;
420 bool ret = true;
421 int fnum;
422 uint8_t *buf;
423 const int maxsize = 90000;
424 const char *fname = BASEDIR "\\test.txt";
425 uint_t seed = time(NULL);
426 union smb_fileinfo finfo;
428 buf = talloc_zero_array(tctx, uint8_t, maxsize);
430 if (!torture_setup_dir(cli, BASEDIR)) {
431 return false;
434 printf("Testing RAW_WRITE_WRITEUNLOCK\n");
435 io.generic.level = RAW_WRITE_WRITEUNLOCK;
437 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
438 if (fnum == -1) {
439 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
440 ret = false;
441 goto done;
444 printf("Trying zero write\n");
445 io.writeunlock.in.file.fnum = fnum;
446 io.writeunlock.in.count = 0;
447 io.writeunlock.in.offset = 0;
448 io.writeunlock.in.remaining = 0;
449 io.writeunlock.in.data = buf;
450 status = smb_raw_write(cli->tree, &io);
451 CHECK_STATUS(status, NT_STATUS_OK);
452 CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
454 setup_buffer(buf, seed, maxsize);
456 printf("Trying small write\n");
457 io.writeunlock.in.count = 9;
458 io.writeunlock.in.offset = 4;
459 io.writeunlock.in.data = buf;
460 status = smb_raw_write(cli->tree, &io);
461 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
462 if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
463 printf("read failed at %s\n", __location__);
464 ret = false;
465 goto done;
467 CHECK_BUFFER(buf+4, seed, 9);
468 CHECK_VALUE(IVAL(buf,0), 0);
470 setup_buffer(buf, seed, maxsize);
471 smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count,
472 0, WRITE_LOCK);
473 status = smb_raw_write(cli->tree, &io);
474 CHECK_STATUS(status, NT_STATUS_OK);
475 CHECK_VALUE(io.writeunlock.out.nwritten, io.writeunlock.in.count);
477 memset(buf, 0, maxsize);
478 if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
479 printf("read failed at %s\n", __location__);
480 ret = false;
481 goto done;
483 CHECK_BUFFER(buf+4, seed, 9);
484 CHECK_VALUE(IVAL(buf,0), 0);
486 setup_buffer(buf, seed, maxsize);
488 printf("Trying large write\n");
489 io.writeunlock.in.count = 4000;
490 io.writeunlock.in.offset = 0;
491 io.writeunlock.in.data = buf;
492 smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count,
493 0, WRITE_LOCK);
494 status = smb_raw_write(cli->tree, &io);
495 CHECK_STATUS(status, NT_STATUS_OK);
496 CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
498 status = smb_raw_write(cli->tree, &io);
499 CHECK_STATUS(status, NT_STATUS_RANGE_NOT_LOCKED);
501 memset(buf, 0, maxsize);
502 if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
503 printf("read failed at %s\n", __location__);
504 ret = false;
505 goto done;
507 CHECK_BUFFER(buf, seed, 4000);
509 printf("Trying bad fnum\n");
510 io.writeunlock.in.file.fnum = fnum+1;
511 io.writeunlock.in.count = 4000;
512 io.writeunlock.in.offset = 0;
513 io.writeunlock.in.data = buf;
514 status = smb_raw_write(cli->tree, &io);
515 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
517 printf("Setting file as sparse\n");
518 status = torture_set_sparse(cli->tree, fnum);
519 CHECK_STATUS(status, NT_STATUS_OK);
521 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
522 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
523 goto done;
526 printf("Trying 2^32 offset\n");
527 setup_buffer(buf, seed, maxsize);
528 io.writeunlock.in.file.fnum = fnum;
529 io.writeunlock.in.count = 4000;
530 io.writeunlock.in.offset = 0xFFFFFFFF - 2000;
531 io.writeunlock.in.data = buf;
532 smbcli_lock(cli->tree, fnum, io.writeunlock.in.offset, io.writeunlock.in.count,
533 0, WRITE_LOCK);
534 status = smb_raw_write(cli->tree, &io);
535 CHECK_STATUS(status, NT_STATUS_OK);
536 CHECK_VALUE(io.writeunlock.out.nwritten, 4000);
537 CHECK_ALL_INFO(io.writeunlock.in.count + (uint64_t)io.writeunlock.in.offset, size);
539 memset(buf, 0, maxsize);
540 if (smbcli_read(cli->tree, fnum, buf, io.writeunlock.in.offset, 4000) != 4000) {
541 printf("read failed at %s\n", __location__);
542 ret = false;
543 goto done;
545 CHECK_BUFFER(buf, seed, 4000);
547 done:
548 smbcli_close(cli->tree, fnum);
549 smb_raw_exit(cli->session);
550 smbcli_deltree(cli->tree, BASEDIR);
551 return ret;
556 test write close ops
558 static bool test_writeclose(struct torture_context *tctx,
559 struct smbcli_state *cli)
561 union smb_write io;
562 NTSTATUS status;
563 bool ret = true;
564 int fnum;
565 uint8_t *buf;
566 const int maxsize = 90000;
567 const char *fname = BASEDIR "\\test.txt";
568 uint_t seed = time(NULL);
569 union smb_fileinfo finfo;
571 buf = talloc_zero_array(tctx, uint8_t, maxsize);
573 if (!torture_setup_dir(cli, BASEDIR)) {
574 return false;
577 printf("Testing RAW_WRITE_WRITECLOSE\n");
578 io.generic.level = RAW_WRITE_WRITECLOSE;
580 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
581 if (fnum == -1) {
582 printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree));
583 ret = false;
584 goto done;
587 printf("Trying zero write\n");
588 io.writeclose.in.file.fnum = fnum;
589 io.writeclose.in.count = 0;
590 io.writeclose.in.offset = 0;
591 io.writeclose.in.mtime = 0;
592 io.writeclose.in.data = buf;
593 status = smb_raw_write(cli->tree, &io);
594 CHECK_STATUS(status, NT_STATUS_OK);
595 CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
597 status = smb_raw_write(cli->tree, &io);
598 CHECK_STATUS(status, NT_STATUS_OK);
599 CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
601 setup_buffer(buf, seed, maxsize);
603 printf("Trying small write\n");
604 io.writeclose.in.count = 9;
605 io.writeclose.in.offset = 4;
606 io.writeclose.in.data = buf;
607 status = smb_raw_write(cli->tree, &io);
608 CHECK_STATUS(status, NT_STATUS_OK);
610 status = smb_raw_write(cli->tree, &io);
611 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
613 fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
614 io.writeclose.in.file.fnum = fnum;
616 if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
617 printf("read failed at %s\n", __location__);
618 ret = false;
619 goto done;
621 CHECK_BUFFER(buf+4, seed, 9);
622 CHECK_VALUE(IVAL(buf,0), 0);
624 setup_buffer(buf, seed, maxsize);
625 status = smb_raw_write(cli->tree, &io);
626 CHECK_STATUS(status, NT_STATUS_OK);
627 CHECK_VALUE(io.writeclose.out.nwritten, io.writeclose.in.count);
629 fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
630 io.writeclose.in.file.fnum = fnum;
632 memset(buf, 0, maxsize);
633 if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) {
634 printf("read failed at %s\n", __location__);
635 ret = false;
636 goto done;
638 CHECK_BUFFER(buf+4, seed, 9);
639 CHECK_VALUE(IVAL(buf,0), 0);
641 setup_buffer(buf, seed, maxsize);
643 printf("Trying large write\n");
644 io.writeclose.in.count = 4000;
645 io.writeclose.in.offset = 0;
646 io.writeclose.in.data = buf;
647 status = smb_raw_write(cli->tree, &io);
648 CHECK_STATUS(status, NT_STATUS_OK);
649 CHECK_VALUE(io.writeclose.out.nwritten, 4000);
651 status = smb_raw_write(cli->tree, &io);
652 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
654 fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
655 io.writeclose.in.file.fnum = fnum;
657 memset(buf, 0, maxsize);
658 if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) {
659 printf("read failed at %s\n", __location__);
660 ret = false;
661 goto done;
663 CHECK_BUFFER(buf, seed, 4000);
665 printf("Trying bad fnum\n");
666 io.writeclose.in.file.fnum = fnum+1;
667 io.writeclose.in.count = 4000;
668 io.writeclose.in.offset = 0;
669 io.writeclose.in.data = buf;
670 status = smb_raw_write(cli->tree, &io);
671 CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
673 printf("Setting file as sparse\n");
674 status = torture_set_sparse(cli->tree, fnum);
675 CHECK_STATUS(status, NT_STATUS_OK);
677 if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) {
678 printf("skipping large file tests - CAP_LARGE_FILES not set\n");
679 goto done;
682 printf("Trying 2^32 offset\n");
683 setup_buffer(buf, seed, maxsize);
684 io.writeclose.in.file.fnum = fnum;
685 io.writeclose.in.count = 4000;
686 io.writeclose.in.offset = 0xFFFFFFFF - 2000;
687 io.writeclose.in.data = buf;
688 status = smb_raw_write(cli->tree, &io);
689 CHECK_STATUS(status, NT_STATUS_OK);
690 CHECK_VALUE(io.writeclose.out.nwritten, 4000);
691 CHECK_ALL_INFO(io.writeclose.in.count + (uint64_t)io.writeclose.in.offset, size);
693 fnum = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
694 io.writeclose.in.file.fnum = fnum;
696 memset(buf, 0, maxsize);
697 if (smbcli_read(cli->tree, fnum, buf, io.writeclose.in.offset, 4000) != 4000) {
698 printf("read failed at %s\n", __location__);
699 ret = false;
700 goto done;
702 CHECK_BUFFER(buf, seed, 4000);
704 done:
705 smbcli_close(cli->tree, fnum);
706 smb_raw_exit(cli->session);
707 smbcli_deltree(cli->tree, BASEDIR);
708 return ret;
712 basic testing of write calls
714 struct torture_suite *torture_raw_write(TALLOC_CTX *mem_ctx)
716 struct torture_suite *suite = torture_suite_create(mem_ctx, "WRITE");
718 torture_suite_add_1smb_test(suite, "write", test_write);
719 torture_suite_add_1smb_test(suite, "write unlock", test_writeunlock);
720 torture_suite_add_1smb_test(suite, "write close", test_writeclose);
721 torture_suite_add_1smb_test(suite, "writex", test_writex);
723 return suite;