dbcheck: add a dict where we remember attributes with duplicate links
[Samba.git] / source4 / ntvfs / nbench / vfs_nbench.c
blob0b2ccf2cb567e31e7a2de69d55c572bd1031663b
1 /*
2 Unix SMB/CIFS implementation.
4 a pass-thru NTVFS module to record a NBENCH load file
6 Copyright (C) Andrew Tridgell 2004
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 "passthru" in this module refers to the next level of NTVFS being used
26 #include "includes.h"
27 #include "ntvfs/ntvfs.h"
28 #include "system/filesys.h"
29 #include "lib/util/sys_rw.h"
31 NTSTATUS ntvfs_nbench_init(TALLOC_CTX *);
33 /* this is stored in ntvfs_private */
34 struct nbench_private {
35 int log_fd;
39 log one request to the nbench log
41 static void nbench_log(struct ntvfs_request *req,
42 const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
44 static void nbench_log(struct ntvfs_request *req,
45 const char *format, ...)
47 struct nbench_private *nprivates = req->async_states->ntvfs->private_data;
48 va_list ap;
49 char *s = NULL;
50 int ret;
52 va_start(ap, format);
53 ret = vasprintf(&s, format, ap);
54 va_end(ap);
56 if (ret == -1) {
57 return;
60 sys_write_v(nprivates->log_fd, s, strlen(s));
61 free(s);
64 static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_handle *h)
66 DATA_BLOB key;
67 uint16_t fnum = 0;
69 key = ntvfs_handle_get_wire_key(h, req);
71 switch (key.length) {
72 case 2: /* SMB fnum */
73 fnum = SVAL(key.data, 0);
74 break;
75 default:
76 DEBUG(0,("%s: invalid wire handle size: %u\n",
77 __FUNCTION__, (unsigned)key.length));
78 break;
81 return talloc_asprintf(req, "%u", fnum);
85 this pass through macro operates on request contexts, and disables
86 async calls.
88 async calls are a pain for the nbench module as it makes pulling the
89 status code and any result parameters much harder.
91 #define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \
92 status = ntvfs_async_state_push(ntvfs, req, par1, nbench_##op##_send); \
93 if (!NT_STATUS_IS_OK(status)) { \
94 return status; \
95 } \
96 } while (0)
98 #define PASS_THRU_REQ_POST_ASYNC(req) do { \
99 req->async_states->status = status; \
100 if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
101 req->async_states->send_fn(req); \
103 } while (0)
105 #define PASS_THRU_REQ(ntvfs, req, op, par1, args) do { \
106 PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1); \
107 status = ntvfs_next_##op args; \
108 PASS_THRU_REQ_POST_ASYNC(req); \
109 } while (0)
111 #define PASS_THRU_REP_POST(req) do { \
112 ntvfs_async_state_pop(req); \
113 if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \
114 req->async_states->send_fn(req); \
116 } while (0)
119 connect to a share - used when a tree_connect operation comes in.
121 static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs,
122 struct ntvfs_request *req,
123 union smb_tcon* con)
125 struct nbench_private *nprivates;
126 NTSTATUS status;
127 char *logname = NULL;
129 nprivates = talloc(ntvfs, struct nbench_private);
130 if (!nprivates) {
131 return NT_STATUS_NO_MEMORY;
134 logname = talloc_asprintf(req, "/tmp/nbenchlog%d.%u", ntvfs->depth,
135 (unsigned int)getpid());
136 NT_STATUS_HAVE_NO_MEMORY(logname);
137 nprivates->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644);
138 talloc_free(logname);
140 if (nprivates->log_fd == -1) {
141 DEBUG(0,("Failed to open nbench log\n"));
142 return NT_STATUS_UNSUCCESSFUL;
145 ntvfs->private_data = nprivates;
147 status = ntvfs_next_connect(ntvfs, req, con);
149 return status;
153 disconnect from a share
155 static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs)
157 struct nbench_private *nprivates = ntvfs->private_data;
158 NTSTATUS status;
160 close(nprivates->log_fd);
162 status = ntvfs_next_disconnect(ntvfs);
164 return status;
168 delete a file - the dirtype specifies the file types to include in the search.
169 The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
171 static void nbench_unlink_send(struct ntvfs_request *req)
173 union smb_unlink *unl = req->async_states->private_data;
174 nbench_log(req, "Unlink \"%s\" 0x%x %s\n",
175 unl->unlink.in.pattern, unl->unlink.in.attrib,
176 get_nt_error_c_code(req, req->async_states->status));
178 PASS_THRU_REP_POST(req);
181 static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs,
182 struct ntvfs_request *req,
183 union smb_unlink *unl)
185 NTSTATUS status;
187 PASS_THRU_REQ(ntvfs, req, unlink, unl, (ntvfs, req, unl));
189 return status;
193 ioctl interface
195 static void nbench_ioctl_send(struct ntvfs_request *req)
197 nbench_log(req, "Ioctl - NOT HANDLED\n");
199 PASS_THRU_REP_POST(req);
202 static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs,
203 struct ntvfs_request *req, union smb_ioctl *io)
205 NTSTATUS status;
207 PASS_THRU_REQ(ntvfs, req, ioctl, io, (ntvfs, req, io));
209 return status;
213 check if a directory exists
215 static void nbench_chkpath_send(struct ntvfs_request *req)
217 union smb_chkpath *cp = req->async_states->private_data;
219 nbench_log(req, "Chkpath \"%s\" %s\n",
220 cp->chkpath.in.path,
221 get_nt_error_c_code(req, req->async_states->status));
223 PASS_THRU_REP_POST(req);
226 static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs,
227 struct ntvfs_request *req,
228 union smb_chkpath *cp)
230 NTSTATUS status;
232 PASS_THRU_REQ(ntvfs, req, chkpath, cp, (ntvfs, req, cp));
234 return status;
238 return info on a pathname
240 static void nbench_qpathinfo_send(struct ntvfs_request *req)
242 union smb_fileinfo *info = req->async_states->private_data;
244 nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n",
245 info->generic.in.file.path,
246 info->generic.level,
247 get_nt_error_c_code(req, req->async_states->status));
249 PASS_THRU_REP_POST(req);
252 static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs,
253 struct ntvfs_request *req, union smb_fileinfo *info)
255 NTSTATUS status;
257 PASS_THRU_REQ(ntvfs, req, qpathinfo, info, (ntvfs, req, info));
259 return status;
263 query info on a open file
265 static void nbench_qfileinfo_send(struct ntvfs_request *req)
267 union smb_fileinfo *info = req->async_states->private_data;
269 nbench_log(req, "QUERY_FILE_INFORMATION %s %d %s\n",
270 nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs),
271 info->generic.level,
272 get_nt_error_c_code(req, req->async_states->status));
274 PASS_THRU_REP_POST(req);
277 static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs,
278 struct ntvfs_request *req, union smb_fileinfo *info)
280 NTSTATUS status;
282 PASS_THRU_REQ(ntvfs, req, qfileinfo, info, (ntvfs, req, info));
284 return status;
288 set info on a pathname
290 static void nbench_setpathinfo_send(struct ntvfs_request *req)
292 union smb_setfileinfo *st = req->async_states->private_data;
294 nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n",
295 st->generic.in.file.path,
296 st->generic.level,
297 get_nt_error_c_code(req, req->async_states->status));
299 PASS_THRU_REP_POST(req);
302 static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs,
303 struct ntvfs_request *req, union smb_setfileinfo *st)
305 NTSTATUS status;
307 PASS_THRU_REQ(ntvfs, req, setpathinfo, st, (ntvfs, req, st));
309 return status;
313 open a file
315 static void nbench_open_send(struct ntvfs_request *req)
317 union smb_open *io = req->async_states->private_data;
319 switch (io->generic.level) {
320 case RAW_OPEN_NTCREATEX:
321 if (!NT_STATUS_IS_OK(req->async_states->status)) {
322 ZERO_STRUCT(io->ntcreatex.out);
324 nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %s %s\n",
325 io->ntcreatex.in.fname,
326 io->ntcreatex.in.create_options,
327 io->ntcreatex.in.open_disposition,
328 nbench_ntvfs_handle_string(req, io->ntcreatex.out.file.ntvfs),
329 get_nt_error_c_code(req, req->async_states->status));
330 break;
332 default:
333 nbench_log(req, "Open-%d - NOT HANDLED\n",
334 io->generic.level);
335 break;
338 PASS_THRU_REP_POST(req);
341 static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs,
342 struct ntvfs_request *req, union smb_open *io)
344 NTSTATUS status;
346 #undef open /* AIX defines open to be open64 */
347 PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io));
349 return status;
353 create a directory
355 static void nbench_mkdir_send(struct ntvfs_request *req)
357 nbench_log(req, "Mkdir - NOT HANDLED\n");
359 PASS_THRU_REP_POST(req);
362 static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs,
363 struct ntvfs_request *req, union smb_mkdir *md)
365 NTSTATUS status;
367 PASS_THRU_REQ(ntvfs, req, mkdir, md, (ntvfs, req, md));
369 return status;
373 remove a directory
375 static void nbench_rmdir_send(struct ntvfs_request *req)
377 struct smb_rmdir *rd = req->async_states->private_data;
379 nbench_log(req, "Rmdir \"%s\" %s\n",
380 rd->in.path,
381 get_nt_error_c_code(req, req->async_states->status));
383 PASS_THRU_REP_POST(req);
386 static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs,
387 struct ntvfs_request *req, struct smb_rmdir *rd)
389 NTSTATUS status;
391 PASS_THRU_REQ(ntvfs, req, rmdir, rd, (ntvfs, req, rd));
393 return status;
397 rename a set of files
399 static void nbench_rename_send(struct ntvfs_request *req)
401 union smb_rename *ren = req->async_states->private_data;
403 switch (ren->generic.level) {
404 case RAW_RENAME_RENAME:
405 nbench_log(req, "Rename \"%s\" \"%s\" %s\n",
406 ren->rename.in.pattern1,
407 ren->rename.in.pattern2,
408 get_nt_error_c_code(req, req->async_states->status));
409 break;
411 default:
412 nbench_log(req, "Rename-%d - NOT HANDLED\n",
413 ren->generic.level);
414 break;
417 PASS_THRU_REP_POST(req);
420 static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs,
421 struct ntvfs_request *req, union smb_rename *ren)
423 NTSTATUS status;
425 PASS_THRU_REQ(ntvfs, req, rename, ren, (ntvfs, req, ren));
427 return status;
431 copy a set of files
433 static void nbench_copy_send(struct ntvfs_request *req)
435 nbench_log(req, "Copy - NOT HANDLED\n");
437 PASS_THRU_REP_POST(req);
440 static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs,
441 struct ntvfs_request *req, struct smb_copy *cp)
443 NTSTATUS status;
445 PASS_THRU_REQ(ntvfs, req, copy, cp, (ntvfs, req, cp));
447 return status;
451 read from a file
453 static void nbench_read_send(struct ntvfs_request *req)
455 union smb_read *rd = req->async_states->private_data;
457 switch (rd->generic.level) {
458 case RAW_READ_READX:
459 if (!NT_STATUS_IS_OK(req->async_states->status)) {
460 ZERO_STRUCT(rd->readx.out);
462 nbench_log(req, "ReadX %s %d %d %d %s\n",
463 nbench_ntvfs_handle_string(req, rd->readx.in.file.ntvfs),
464 (int)rd->readx.in.offset,
465 rd->readx.in.maxcnt,
466 rd->readx.out.nread,
467 get_nt_error_c_code(req, req->async_states->status));
468 break;
469 default:
470 nbench_log(req, "Read-%d - NOT HANDLED\n",
471 rd->generic.level);
472 break;
475 PASS_THRU_REP_POST(req);
478 static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs,
479 struct ntvfs_request *req, union smb_read *rd)
481 NTSTATUS status;
483 PASS_THRU_REQ(ntvfs, req, read, rd, (ntvfs, req, rd));
485 return status;
489 write to a file
491 static void nbench_write_send(struct ntvfs_request *req)
493 union smb_write *wr = req->async_states->private_data;
495 switch (wr->generic.level) {
496 case RAW_WRITE_WRITEX:
497 if (!NT_STATUS_IS_OK(req->async_states->status)) {
498 ZERO_STRUCT(wr->writex.out);
500 nbench_log(req, "WriteX %s %d %d %d %s\n",
501 nbench_ntvfs_handle_string(req, wr->writex.in.file.ntvfs),
502 (int)wr->writex.in.offset,
503 wr->writex.in.count,
504 wr->writex.out.nwritten,
505 get_nt_error_c_code(req, req->async_states->status));
506 break;
508 case RAW_WRITE_WRITE:
509 if (!NT_STATUS_IS_OK(req->async_states->status)) {
510 ZERO_STRUCT(wr->write.out);
512 nbench_log(req, "Write %s %d %d %d %s\n",
513 nbench_ntvfs_handle_string(req, wr->write.in.file.ntvfs),
514 wr->write.in.offset,
515 wr->write.in.count,
516 wr->write.out.nwritten,
517 get_nt_error_c_code(req, req->async_states->status));
518 break;
520 default:
521 nbench_log(req, "Write-%d - NOT HANDLED\n",
522 wr->generic.level);
523 break;
526 PASS_THRU_REP_POST(req);
529 static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs,
530 struct ntvfs_request *req, union smb_write *wr)
532 NTSTATUS status;
534 PASS_THRU_REQ(ntvfs, req, write, wr, (ntvfs, req, wr));
536 return status;
540 seek in a file
542 static void nbench_seek_send(struct ntvfs_request *req)
544 nbench_log(req, "Seek - NOT HANDLED\n");
546 PASS_THRU_REP_POST(req);
549 static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs,
550 struct ntvfs_request *req,
551 union smb_seek *io)
553 NTSTATUS status;
555 PASS_THRU_REQ(ntvfs, req, seek, io, (ntvfs, req, io));
557 return status;
561 flush a file
563 static void nbench_flush_send(struct ntvfs_request *req)
565 union smb_flush *io = req->async_states->private_data;
567 switch (io->generic.level) {
568 case RAW_FLUSH_FLUSH:
569 nbench_log(req, "Flush %s %s\n",
570 nbench_ntvfs_handle_string(req, io->flush.in.file.ntvfs),
571 get_nt_error_c_code(req, req->async_states->status));
572 break;
573 case RAW_FLUSH_ALL:
574 nbench_log(req, "Flush %d %s\n",
575 0xFFFF,
576 get_nt_error_c_code(req, req->async_states->status));
577 break;
578 default:
579 nbench_log(req, "Flush-%d - NOT HANDLED\n",
580 io->generic.level);
581 break;
584 PASS_THRU_REP_POST(req);
587 static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs,
588 struct ntvfs_request *req,
589 union smb_flush *io)
591 NTSTATUS status;
593 PASS_THRU_REQ(ntvfs, req, flush, io, (ntvfs, req, io));
595 return status;
599 close a file
601 static void nbench_close_send(struct ntvfs_request *req)
603 union smb_close *io = req->async_states->private_data;
605 switch (io->generic.level) {
606 case RAW_CLOSE_CLOSE:
607 nbench_log(req, "Close %s %s\n",
608 nbench_ntvfs_handle_string(req, io->close.in.file.ntvfs),
609 get_nt_error_c_code(req, req->async_states->status));
610 break;
612 default:
613 nbench_log(req, "Close-%d - NOT HANDLED\n",
614 io->generic.level);
615 break;
618 PASS_THRU_REP_POST(req);
621 static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs,
622 struct ntvfs_request *req, union smb_close *io)
624 NTSTATUS status;
626 PASS_THRU_REQ(ntvfs, req, close, io, (ntvfs, req, io));
628 return status;
632 exit - closing files
634 static void nbench_exit_send(struct ntvfs_request *req)
636 nbench_log(req, "Exit - NOT HANDLED\n");
638 PASS_THRU_REP_POST(req);
641 static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs,
642 struct ntvfs_request *req)
644 NTSTATUS status;
646 PASS_THRU_REQ(ntvfs, req, exit, NULL, (ntvfs, req));
648 return status;
652 logoff - closing files
654 static void nbench_logoff_send(struct ntvfs_request *req)
656 nbench_log(req, "Logoff - NOT HANDLED\n");
658 PASS_THRU_REP_POST(req);
661 static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs,
662 struct ntvfs_request *req)
664 NTSTATUS status;
666 PASS_THRU_REQ(ntvfs, req, logoff, NULL, (ntvfs, req));
668 return status;
672 async_setup - send fn
674 static void nbench_async_setup_send(struct ntvfs_request *req)
676 PASS_THRU_REP_POST(req);
680 async setup
682 static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs,
683 struct ntvfs_request *req,
684 void *private_data)
686 NTSTATUS status;
688 PASS_THRU_REQ(ntvfs, req, async_setup, NULL, (ntvfs, req, private_data));
690 return status;
694 static void nbench_cancel_send(struct ntvfs_request *req)
696 PASS_THRU_REP_POST(req);
700 cancel an existing async request
702 static NTSTATUS nbench_cancel(struct ntvfs_module_context *ntvfs,
703 struct ntvfs_request *req)
705 NTSTATUS status;
707 PASS_THRU_REQ(ntvfs, req, cancel, NULL, (ntvfs, req));
709 return status;
713 lock a byte range
715 static void nbench_lock_send(struct ntvfs_request *req)
717 union smb_lock *lck = req->async_states->private_data;
719 if (lck->generic.level == RAW_LOCK_LOCKX &&
720 lck->lockx.in.lock_cnt == 1 &&
721 lck->lockx.in.ulock_cnt == 0) {
722 nbench_log(req, "LockX %s %d %d %s\n",
723 nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs),
724 (int)lck->lockx.in.locks[0].offset,
725 (int)lck->lockx.in.locks[0].count,
726 get_nt_error_c_code(req, req->async_states->status));
727 } else if (lck->generic.level == RAW_LOCK_LOCKX &&
728 lck->lockx.in.ulock_cnt == 1) {
729 nbench_log(req, "UnlockX %s %d %d %s\n",
730 nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs),
731 (int)lck->lockx.in.locks[0].offset,
732 (int)lck->lockx.in.locks[0].count,
733 get_nt_error_c_code(req, req->async_states->status));
734 } else {
735 nbench_log(req, "Lock-%d - NOT HANDLED\n", lck->generic.level);
738 PASS_THRU_REP_POST(req);
741 static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs,
742 struct ntvfs_request *req, union smb_lock *lck)
744 NTSTATUS status;
746 PASS_THRU_REQ(ntvfs, req, lock, lck, (ntvfs, req, lck));
748 return status;
752 set info on a open file
754 static void nbench_setfileinfo_send(struct ntvfs_request *req)
756 union smb_setfileinfo *info = req->async_states->private_data;
758 nbench_log(req, "SET_FILE_INFORMATION %s %d %s\n",
759 nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs),
760 info->generic.level,
761 get_nt_error_c_code(req, req->async_states->status));
763 PASS_THRU_REP_POST(req);
766 static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs,
767 struct ntvfs_request *req,
768 union smb_setfileinfo *info)
770 NTSTATUS status;
772 PASS_THRU_REQ(ntvfs, req, setfileinfo, info, (ntvfs, req, info));
774 return status;
778 return filesystem space info
780 static void nbench_fsinfo_send(struct ntvfs_request *req)
782 union smb_fsinfo *fs = req->async_states->private_data;
784 nbench_log(req, "QUERY_FS_INFORMATION %d %s\n",
785 fs->generic.level,
786 get_nt_error_c_code(req, req->async_states->status));
788 PASS_THRU_REP_POST(req);
791 static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs,
792 struct ntvfs_request *req, union smb_fsinfo *fs)
794 NTSTATUS status;
796 PASS_THRU_REQ(ntvfs, req, fsinfo, fs, (ntvfs, req, fs));
798 return status;
802 return print queue info
804 static void nbench_lpq_send(struct ntvfs_request *req)
806 union smb_lpq *lpq = req->async_states->private_data;
808 nbench_log(req, "Lpq-%d - NOT HANDLED\n", lpq->generic.level);
810 PASS_THRU_REP_POST(req);
813 static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs,
814 struct ntvfs_request *req, union smb_lpq *lpq)
816 NTSTATUS status;
818 PASS_THRU_REQ(ntvfs, req, lpq, lpq, (ntvfs, req, lpq));
820 return status;
824 list files in a directory matching a wildcard pattern
826 static void nbench_search_first_send(struct ntvfs_request *req)
828 union smb_search_first *io = req->async_states->private_data;
830 switch (io->generic.level) {
831 case RAW_SEARCH_TRANS2:
832 if (NT_STATUS_IS_ERR(req->async_states->status)) {
833 ZERO_STRUCT(io->t2ffirst.out);
835 nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n",
836 io->t2ffirst.in.pattern,
837 io->t2ffirst.data_level,
838 io->t2ffirst.in.max_count,
839 io->t2ffirst.out.count,
840 get_nt_error_c_code(req, req->async_states->status));
841 break;
843 default:
844 nbench_log(req, "Search-%d - NOT HANDLED\n", io->generic.level);
845 break;
848 PASS_THRU_REP_POST(req);
851 static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs,
852 struct ntvfs_request *req, union smb_search_first *io,
853 void *search_private,
854 bool (*callback)(void *, const union smb_search_data *))
856 NTSTATUS status;
858 PASS_THRU_REQ(ntvfs, req, search_first, io, (ntvfs, req, io, search_private, callback));
860 return status;
863 /* continue a search */
864 static void nbench_search_next_send(struct ntvfs_request *req)
866 union smb_search_next *io = req->async_states->private_data;
868 nbench_log(req, "Searchnext-%d - NOT HANDLED\n", io->generic.level);
870 PASS_THRU_REP_POST(req);
873 static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs,
874 struct ntvfs_request *req, union smb_search_next *io,
875 void *search_private,
876 bool (*callback)(void *, const union smb_search_data *))
878 NTSTATUS status;
880 PASS_THRU_REQ(ntvfs, req, search_next, io, (ntvfs, req, io, search_private, callback));
882 return status;
885 /* close a search */
886 static void nbench_search_close_send(struct ntvfs_request *req)
888 union smb_search_close *io = req->async_states->private_data;
890 nbench_log(req, "Searchclose-%d - NOT HANDLED\n", io->generic.level);
892 PASS_THRU_REP_POST(req);
895 static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs,
896 struct ntvfs_request *req, union smb_search_close *io)
898 NTSTATUS status;
900 PASS_THRU_REQ(ntvfs, req, search_close, io, (ntvfs, req, io));
902 return status;
905 /* SMBtrans - not used on file shares */
906 static void nbench_trans_send(struct ntvfs_request *req)
908 nbench_log(req, "Trans - NOT HANDLED\n");
910 PASS_THRU_REP_POST(req);
913 static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs,
914 struct ntvfs_request *req, struct smb_trans2 *trans2)
916 NTSTATUS status;
918 PASS_THRU_REQ(ntvfs, req, trans, trans2, (ntvfs, req, trans2));
920 return status;
924 initialise the nbench backend, registering ourselves with the ntvfs subsystem
926 NTSTATUS ntvfs_nbench_init(TALLOC_CTX *ctx)
928 NTSTATUS ret;
929 struct ntvfs_ops ops;
930 NTVFS_CURRENT_CRITICAL_SIZES(vers);
932 ZERO_STRUCT(ops);
934 /* fill in the name and type */
935 ops.name = "nbench";
936 ops.type = NTVFS_DISK;
938 /* fill in all the operations */
939 ops.connect_fn = nbench_connect;
940 ops.disconnect_fn = nbench_disconnect;
941 ops.unlink_fn = nbench_unlink;
942 ops.chkpath_fn = nbench_chkpath;
943 ops.qpathinfo_fn = nbench_qpathinfo;
944 ops.setpathinfo_fn = nbench_setpathinfo;
945 ops.open_fn = nbench_open;
946 ops.mkdir_fn = nbench_mkdir;
947 ops.rmdir_fn = nbench_rmdir;
948 ops.rename_fn = nbench_rename;
949 ops.copy_fn = nbench_copy;
950 ops.ioctl_fn = nbench_ioctl;
951 ops.read_fn = nbench_read;
952 ops.write_fn = nbench_write;
953 ops.seek_fn = nbench_seek;
954 ops.flush_fn = nbench_flush;
955 ops.close_fn = nbench_close;
956 ops.exit_fn = nbench_exit;
957 ops.lock_fn = nbench_lock;
958 ops.setfileinfo_fn = nbench_setfileinfo;
959 ops.qfileinfo_fn = nbench_qfileinfo;
960 ops.fsinfo_fn = nbench_fsinfo;
961 ops.lpq_fn = nbench_lpq;
962 ops.search_first_fn = nbench_search_first;
963 ops.search_next_fn = nbench_search_next;
964 ops.search_close_fn = nbench_search_close;
965 ops.trans_fn = nbench_trans;
966 ops.logoff_fn = nbench_logoff;
967 ops.async_setup_fn = nbench_async_setup;
968 ops.cancel_fn = nbench_cancel;
970 /* we don't register a trans2 handler as we want to be able to
971 log individual trans2 requests */
972 ops.trans2_fn = NULL;
974 /* register ourselves with the NTVFS subsystem. */
975 ret = ntvfs_register(&ops, &vers);
977 if (!NT_STATUS_IS_OK(ret)) {
978 DEBUG(0,("Failed to register nbench backend!\n"));
981 return ret;