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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 "passthru" in this module refers to the next level of NTVFS being used
28 #include "smb_server/smb_server.h"
30 /* this is stored in ntvfs_private */
31 struct nbench_private
{
36 log one request to the nbench log
38 static void nbench_log(struct smbsrv_request
*req
,
39 const char *format
, ...) PRINTF_ATTRIBUTE(2, 3);
41 static void nbench_log(struct smbsrv_request
*req
,
42 const char *format
, ...)
44 struct nbench_private
*private = req
->async_states
->ntvfs
->private_data
;
49 vasprintf(&s
, format
, ap
);
52 write(private->log_fd
, s
, strlen(s
));
57 this pass through macro operates on request contexts, and disables
60 async calls are a pain for the nbench module as it makes pulling the
61 status code and any result parameters much harder.
63 #define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \
64 status = ntvfs_async_state_push(req, par1, nbench_##op##_send, ntvfs); \
65 if (!NT_STATUS_IS_OK(status)) { \
70 #define PASS_THRU_REQ_POST_ASYNC(req) do { \
71 req->async_states->status = status; \
72 if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
73 req->async_states->send_fn(req); \
77 #define PASS_THRU_REQ(ntvfs, req, op, par1, args) do { \
78 PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1); \
79 status = ntvfs_next_##op args; \
80 PASS_THRU_REQ_POST_ASYNC(req); \
83 #define PASS_THRU_REP_POST(req) do { \
84 ntvfs_async_state_pop(req); \
85 if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \
86 req->async_states->send_fn(req); \
91 connect to a share - used when a tree_connect operation comes in.
93 static NTSTATUS
nbench_connect(struct ntvfs_module_context
*ntvfs
,
94 struct smbsrv_request
*req
, const char *sharename
)
96 struct nbench_private
*nprivates
;
100 nprivates
= talloc_p(req
->tcon
, struct nbench_private
);
102 return NT_STATUS_NO_MEMORY
;
105 asprintf(&logname
, "/tmp/nbenchlog%d.%u", ntvfs
->depth
, getpid());
106 nprivates
->log_fd
= open(logname
, O_WRONLY
|O_CREAT
|O_APPEND
, 0644);
109 if (nprivates
->log_fd
== -1) {
110 DEBUG(0,("Failed to open nbench log\n"));
111 return NT_STATUS_UNSUCCESSFUL
;
114 ntvfs
->private_data
= nprivates
;
116 status
= ntvfs_next_connect(ntvfs
, req
, sharename
);
122 disconnect from a share
124 static NTSTATUS
nbench_disconnect(struct ntvfs_module_context
*ntvfs
,
125 struct smbsrv_tcon
*tcon
)
127 struct nbench_private
*nprivates
= ntvfs
->private_data
;
130 close(nprivates
->log_fd
);
132 status
= ntvfs_next_disconnect(ntvfs
, tcon
);
138 delete a file - the dirtype specifies the file types to include in the search.
139 The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
141 static void nbench_unlink_send(struct smbsrv_request
*req
)
143 struct smb_unlink
*unl
= req
->async_states
->private_data
;
145 nbench_log(req
, "Unlink \"%s\" 0x%x %s\n",
146 unl
->in
.pattern
, unl
->in
.attrib
,
147 get_nt_error_c_code(req
->async_states
->status
));
149 PASS_THRU_REP_POST(req
);
152 static NTSTATUS
nbench_unlink(struct ntvfs_module_context
*ntvfs
,
153 struct smbsrv_request
*req
, struct smb_unlink
*unl
)
157 PASS_THRU_REQ(ntvfs
, req
, unlink
, unl
, (ntvfs
, req
, unl
));
165 static void nbench_ioctl_send(struct smbsrv_request
*req
)
167 nbench_log(req
, "Ioctl - NOT HANDLED\n");
169 PASS_THRU_REP_POST(req
);
172 static NTSTATUS
nbench_ioctl(struct ntvfs_module_context
*ntvfs
,
173 struct smbsrv_request
*req
, union smb_ioctl
*io
)
177 PASS_THRU_REQ(ntvfs
, req
, ioctl
, io
, (ntvfs
, req
, io
));
183 check if a directory exists
185 static void nbench_chkpath_send(struct smbsrv_request
*req
)
187 struct smb_chkpath
*cp
= req
->async_states
->private_data
;
189 nbench_log(req
, "Chkpath \"%s\" %s\n",
191 get_nt_error_c_code(req
->async_states
->status
));
193 PASS_THRU_REP_POST(req
);
196 static NTSTATUS
nbench_chkpath(struct ntvfs_module_context
*ntvfs
,
197 struct smbsrv_request
*req
, struct smb_chkpath
*cp
)
201 PASS_THRU_REQ(ntvfs
, req
, chkpath
, cp
, (ntvfs
, req
, cp
));
207 return info on a pathname
209 static void nbench_qpathinfo_send(struct smbsrv_request
*req
)
211 union smb_fileinfo
*info
= req
->async_states
->private_data
;
213 nbench_log(req
, "QUERY_PATH_INFORMATION \"%s\" %d %s\n",
214 info
->generic
.in
.fname
,
216 get_nt_error_c_code(req
->async_states
->status
));
218 PASS_THRU_REP_POST(req
);
221 static NTSTATUS
nbench_qpathinfo(struct ntvfs_module_context
*ntvfs
,
222 struct smbsrv_request
*req
, union smb_fileinfo
*info
)
226 PASS_THRU_REQ(ntvfs
, req
, qpathinfo
, info
, (ntvfs
, req
, info
));
232 query info on a open file
234 static void nbench_qfileinfo_send(struct smbsrv_request
*req
)
236 union smb_fileinfo
*info
= req
->async_states
->private_data
;
238 nbench_log(req
, "QUERY_FILE_INFORMATION %d %d %s\n",
239 info
->generic
.in
.fnum
,
241 get_nt_error_c_code(req
->async_states
->status
));
243 PASS_THRU_REP_POST(req
);
246 static NTSTATUS
nbench_qfileinfo(struct ntvfs_module_context
*ntvfs
,
247 struct smbsrv_request
*req
, union smb_fileinfo
*info
)
251 PASS_THRU_REQ(ntvfs
, req
, qfileinfo
, info
, (ntvfs
, req
, info
));
257 set info on a pathname
259 static void nbench_setpathinfo_send(struct smbsrv_request
*req
)
261 union smb_setfileinfo
*st
= req
->async_states
->private_data
;
263 nbench_log(req
, "SET_PATH_INFORMATION \"%s\" %d %s\n",
264 st
->generic
.file
.fname
,
266 get_nt_error_c_code(req
->async_states
->status
));
268 PASS_THRU_REP_POST(req
);
271 static NTSTATUS
nbench_setpathinfo(struct ntvfs_module_context
*ntvfs
,
272 struct smbsrv_request
*req
, union smb_setfileinfo
*st
)
276 PASS_THRU_REQ(ntvfs
, req
, setpathinfo
, st
, (ntvfs
, req
, st
));
284 static void nbench_openfile_send(struct smbsrv_request
*req
)
286 union smb_open
*io
= req
->async_states
->private_data
;
288 switch (io
->generic
.level
) {
289 case RAW_OPEN_NTCREATEX
:
290 if (!NT_STATUS_IS_OK(req
->async_states
->status
)) {
291 ZERO_STRUCT(io
->ntcreatex
.out
);
293 nbench_log(req
, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n",
294 io
->ntcreatex
.in
.fname
,
295 io
->ntcreatex
.in
.create_options
,
296 io
->ntcreatex
.in
.open_disposition
,
297 io
->ntcreatex
.out
.fnum
,
298 get_nt_error_c_code(req
->async_states
->status
));
302 nbench_log(req
, "Open-%d - NOT HANDLED\n",
307 PASS_THRU_REP_POST(req
);
310 static NTSTATUS
nbench_openfile(struct ntvfs_module_context
*ntvfs
,
311 struct smbsrv_request
*req
, union smb_open
*io
)
315 PASS_THRU_REQ(ntvfs
, req
, openfile
, io
, (ntvfs
, req
, io
));
323 static void nbench_mkdir_send(struct smbsrv_request
*req
)
325 nbench_log(req
, "Mkdir - NOT HANDLED\n");
327 PASS_THRU_REP_POST(req
);
330 static NTSTATUS
nbench_mkdir(struct ntvfs_module_context
*ntvfs
,
331 struct smbsrv_request
*req
, union smb_mkdir
*md
)
335 PASS_THRU_REQ(ntvfs
, req
, mkdir
, md
, (ntvfs
, req
, md
));
343 static void nbench_rmdir_send(struct smbsrv_request
*req
)
345 struct smb_rmdir
*rd
= req
->async_states
->private_data
;
347 nbench_log(req
, "Rmdir \"%s\" %s\n",
349 get_nt_error_c_code(req
->async_states
->status
));
351 PASS_THRU_REP_POST(req
);
354 static NTSTATUS
nbench_rmdir(struct ntvfs_module_context
*ntvfs
,
355 struct smbsrv_request
*req
, struct smb_rmdir
*rd
)
359 PASS_THRU_REQ(ntvfs
, req
, rmdir
, rd
, (ntvfs
, req
, rd
));
365 rename a set of files
367 static void nbench_rename_send(struct smbsrv_request
*req
)
369 union smb_rename
*ren
= req
->async_states
->private_data
;
371 switch (ren
->generic
.level
) {
372 case RAW_RENAME_RENAME
:
373 nbench_log(req
, "Rename \"%s\" \"%s\" %s\n",
374 ren
->rename
.in
.pattern1
,
375 ren
->rename
.in
.pattern2
,
376 get_nt_error_c_code(req
->async_states
->status
));
380 nbench_log(req
, "Rename-%d - NOT HANDLED\n",
385 PASS_THRU_REP_POST(req
);
388 static NTSTATUS
nbench_rename(struct ntvfs_module_context
*ntvfs
,
389 struct smbsrv_request
*req
, union smb_rename
*ren
)
393 PASS_THRU_REQ(ntvfs
, req
, rename
, ren
, (ntvfs
, req
, ren
));
401 static void nbench_copy_send(struct smbsrv_request
*req
)
403 nbench_log(req
, "Copy - NOT HANDLED\n");
405 PASS_THRU_REP_POST(req
);
408 static NTSTATUS
nbench_copy(struct ntvfs_module_context
*ntvfs
,
409 struct smbsrv_request
*req
, struct smb_copy
*cp
)
413 PASS_THRU_REQ(ntvfs
, req
, copy
, cp
, (ntvfs
, req
, cp
));
421 static void nbench_read_send(struct smbsrv_request
*req
)
423 union smb_read
*rd
= req
->async_states
->private_data
;
425 switch (rd
->generic
.level
) {
427 if (!NT_STATUS_IS_OK(req
->async_states
->status
)) {
428 ZERO_STRUCT(rd
->readx
.out
);
430 nbench_log(req
, "ReadX %d %d %d %d %s\n",
432 (int)rd
->readx
.in
.offset
,
435 get_nt_error_c_code(req
->async_states
->status
));
438 nbench_log(req
, "Read-%d - NOT HANDLED\n",
443 PASS_THRU_REP_POST(req
);
446 static NTSTATUS
nbench_read(struct ntvfs_module_context
*ntvfs
,
447 struct smbsrv_request
*req
, union smb_read
*rd
)
451 PASS_THRU_REQ(ntvfs
, req
, read
, rd
, (ntvfs
, req
, rd
));
459 static void nbench_write_send(struct smbsrv_request
*req
)
461 union smb_write
*wr
= req
->async_states
->private_data
;
463 switch (wr
->generic
.level
) {
464 case RAW_WRITE_WRITEX
:
465 if (!NT_STATUS_IS_OK(req
->async_states
->status
)) {
466 ZERO_STRUCT(wr
->writex
.out
);
468 nbench_log(req
, "WriteX %d %d %d %d %s\n",
470 (int)wr
->writex
.in
.offset
,
472 wr
->writex
.out
.nwritten
,
473 get_nt_error_c_code(req
->async_states
->status
));
476 case RAW_WRITE_WRITE
:
477 if (!NT_STATUS_IS_OK(req
->async_states
->status
)) {
478 ZERO_STRUCT(wr
->write
.out
);
480 nbench_log(req
, "Write %d %d %d %d %s\n",
484 wr
->write
.out
.nwritten
,
485 get_nt_error_c_code(req
->async_states
->status
));
489 nbench_log(req
, "Write-%d - NOT HANDLED\n",
494 PASS_THRU_REP_POST(req
);
497 static NTSTATUS
nbench_write(struct ntvfs_module_context
*ntvfs
,
498 struct smbsrv_request
*req
, union smb_write
*wr
)
502 PASS_THRU_REQ(ntvfs
, req
, write
, wr
, (ntvfs
, req
, wr
));
510 static void nbench_seek_send(struct smbsrv_request
*req
)
512 nbench_log(req
, "Seek - NOT HANDLED\n");
514 PASS_THRU_REP_POST(req
);
517 static NTSTATUS
nbench_seek(struct ntvfs_module_context
*ntvfs
,
518 struct smbsrv_request
*req
, struct smb_seek
*io
)
522 PASS_THRU_REQ(ntvfs
, req
, seek
, io
, (ntvfs
, req
, io
));
530 static void nbench_flush_send(struct smbsrv_request
*req
)
532 struct smb_flush
*io
= req
->async_states
->private_data
;
534 nbench_log(req
, "Flush %d %s\n",
536 get_nt_error_c_code(req
->async_states
->status
));
538 PASS_THRU_REP_POST(req
);
541 static NTSTATUS
nbench_flush(struct ntvfs_module_context
*ntvfs
,
542 struct smbsrv_request
*req
, struct smb_flush
*io
)
546 PASS_THRU_REQ(ntvfs
, req
, flush
, io
, (ntvfs
, req
, io
));
554 static void nbench_close_send(struct smbsrv_request
*req
)
556 union smb_close
*io
= req
->async_states
->private_data
;
558 switch (io
->generic
.level
) {
559 case RAW_CLOSE_CLOSE
:
560 nbench_log(req
, "Close %d %s\n",
562 get_nt_error_c_code(req
->async_states
->status
));
566 nbench_log(req
, "Close-%d - NOT HANDLED\n",
571 PASS_THRU_REP_POST(req
);
574 static NTSTATUS
nbench_close(struct ntvfs_module_context
*ntvfs
,
575 struct smbsrv_request
*req
, union smb_close
*io
)
579 PASS_THRU_REQ(ntvfs
, req
, close
, io
, (ntvfs
, req
, io
));
587 static void nbench_exit_send(struct smbsrv_request
*req
)
589 nbench_log(req
, "Exit - NOT HANDLED\n");
591 PASS_THRU_REP_POST(req
);
594 static NTSTATUS
nbench_exit(struct ntvfs_module_context
*ntvfs
,
595 struct smbsrv_request
*req
)
599 PASS_THRU_REQ(ntvfs
, req
, exit
, NULL
, (ntvfs
, req
));
605 logoff - closing files
607 static void nbench_logoff_send(struct smbsrv_request
*req
)
609 nbench_log(req
, "Logoff - NOT HANDLED\n");
611 PASS_THRU_REP_POST(req
);
614 static NTSTATUS
nbench_logoff(struct ntvfs_module_context
*ntvfs
,
615 struct smbsrv_request
*req
)
619 PASS_THRU_REQ(ntvfs
, req
, logoff
, NULL
, (ntvfs
, req
));
625 async_setup - send fn
627 static void nbench_async_setup_send(struct smbsrv_request
*req
)
629 PASS_THRU_REP_POST(req
);
635 static NTSTATUS
nbench_async_setup(struct ntvfs_module_context
*ntvfs
,
636 struct smbsrv_request
*req
,
641 PASS_THRU_REQ(ntvfs
, req
, async_setup
, NULL
, (ntvfs
, req
, private));
647 static void nbench_cancel_send(struct smbsrv_request
*req
)
649 PASS_THRU_REP_POST(req
);
653 cancel an existing async request
655 static NTSTATUS
nbench_cancel(struct ntvfs_module_context
*ntvfs
,
656 struct smbsrv_request
*req
)
660 PASS_THRU_REQ(ntvfs
, req
, cancel
, NULL
, (ntvfs
, req
));
668 static void nbench_lock_send(struct smbsrv_request
*req
)
670 union smb_lock
*lck
= req
->async_states
->private_data
;
672 if (lck
->generic
.level
== RAW_LOCK_LOCKX
&&
673 lck
->lockx
.in
.lock_cnt
== 1 &&
674 lck
->lockx
.in
.ulock_cnt
== 0) {
675 nbench_log(req
, "LockX %d %d %d %s\n",
677 (int)lck
->lockx
.in
.locks
[0].offset
,
678 (int)lck
->lockx
.in
.locks
[0].count
,
679 get_nt_error_c_code(req
->async_states
->status
));
680 } else if (lck
->generic
.level
== RAW_LOCK_LOCKX
&&
681 lck
->lockx
.in
.ulock_cnt
== 1) {
682 nbench_log(req
, "UnlockX %d %d %d %s\n",
684 (int)lck
->lockx
.in
.locks
[0].offset
,
685 (int)lck
->lockx
.in
.locks
[0].count
,
686 get_nt_error_c_code(req
->async_states
->status
));
688 nbench_log(req
, "Lock-%d - NOT HANDLED\n", lck
->generic
.level
);
691 PASS_THRU_REP_POST(req
);
694 static NTSTATUS
nbench_lock(struct ntvfs_module_context
*ntvfs
,
695 struct smbsrv_request
*req
, union smb_lock
*lck
)
699 PASS_THRU_REQ(ntvfs
, req
, lock
, lck
, (ntvfs
, req
, lck
));
705 set info on a open file
707 static void nbench_setfileinfo_send(struct smbsrv_request
*req
)
709 union smb_setfileinfo
*info
= req
->async_states
->private_data
;
711 nbench_log(req
, "SET_FILE_INFORMATION %d %d %s\n",
712 info
->generic
.file
.fnum
,
714 get_nt_error_c_code(req
->async_states
->status
));
716 PASS_THRU_REP_POST(req
);
719 static NTSTATUS
nbench_setfileinfo(struct ntvfs_module_context
*ntvfs
,
720 struct smbsrv_request
*req
,
721 union smb_setfileinfo
*info
)
725 PASS_THRU_REQ(ntvfs
, req
, setfileinfo
, info
, (ntvfs
, req
, info
));
731 return filesystem space info
733 static void nbench_fsinfo_send(struct smbsrv_request
*req
)
735 union smb_fsinfo
*fs
= req
->async_states
->private_data
;
737 nbench_log(req
, "QUERY_FS_INFORMATION %d %s\n",
739 get_nt_error_c_code(req
->async_states
->status
));
741 PASS_THRU_REP_POST(req
);
744 static NTSTATUS
nbench_fsinfo(struct ntvfs_module_context
*ntvfs
,
745 struct smbsrv_request
*req
, union smb_fsinfo
*fs
)
749 PASS_THRU_REQ(ntvfs
, req
, fsinfo
, fs
, (ntvfs
, req
, fs
));
755 return print queue info
757 static void nbench_lpq_send(struct smbsrv_request
*req
)
759 union smb_lpq
*lpq
= req
->async_states
->private_data
;
761 nbench_log(req
, "Lpq-%d - NOT HANDLED\n", lpq
->generic
.level
);
763 PASS_THRU_REP_POST(req
);
766 static NTSTATUS
nbench_lpq(struct ntvfs_module_context
*ntvfs
,
767 struct smbsrv_request
*req
, union smb_lpq
*lpq
)
771 PASS_THRU_REQ(ntvfs
, req
, lpq
, lpq
, (ntvfs
, req
, lpq
));
777 list files in a directory matching a wildcard pattern
779 static void nbench_search_first_send(struct smbsrv_request
*req
)
781 union smb_search_first
*io
= req
->async_states
->private_data
;
783 switch (io
->generic
.level
) {
784 case RAW_SEARCH_BOTH_DIRECTORY_INFO
:
785 if (NT_STATUS_IS_ERR(req
->async_states
->status
)) {
786 ZERO_STRUCT(io
->t2ffirst
.out
);
788 nbench_log(req
, "FIND_FIRST \"%s\" %d %d %d %s\n",
789 io
->t2ffirst
.in
.pattern
,
791 io
->t2ffirst
.in
.max_count
,
792 io
->t2ffirst
.out
.count
,
793 get_nt_error_c_code(req
->async_states
->status
));
797 nbench_log(req
, "Search-%d - NOT HANDLED\n", io
->generic
.level
);
801 PASS_THRU_REP_POST(req
);
804 static NTSTATUS
nbench_search_first(struct ntvfs_module_context
*ntvfs
,
805 struct smbsrv_request
*req
, union smb_search_first
*io
,
806 void *search_private
,
807 BOOL (*callback
)(void *, union smb_search_data
*))
811 PASS_THRU_REQ(ntvfs
, req
, search_first
, io
, (ntvfs
, req
, io
, search_private
, callback
));
816 /* continue a search */
817 static void nbench_search_next_send(struct smbsrv_request
*req
)
819 union smb_search_next
*io
= req
->async_states
->private_data
;
821 nbench_log(req
, "Searchnext-%d - NOT HANDLED\n", io
->generic
.level
);
823 PASS_THRU_REP_POST(req
);
826 static NTSTATUS
nbench_search_next(struct ntvfs_module_context
*ntvfs
,
827 struct smbsrv_request
*req
, union smb_search_next
*io
,
828 void *search_private
,
829 BOOL (*callback
)(void *, union smb_search_data
*))
833 PASS_THRU_REQ(ntvfs
, req
, search_next
, io
, (ntvfs
, req
, io
, search_private
, callback
));
839 static void nbench_search_close_send(struct smbsrv_request
*req
)
841 union smb_search_close
*io
= req
->async_states
->private_data
;
843 nbench_log(req
, "Searchclose-%d - NOT HANDLED\n", io
->generic
.level
);
845 PASS_THRU_REP_POST(req
);
848 static NTSTATUS
nbench_search_close(struct ntvfs_module_context
*ntvfs
,
849 struct smbsrv_request
*req
, union smb_search_close
*io
)
853 PASS_THRU_REQ(ntvfs
, req
, search_close
, io
, (ntvfs
, req
, io
));
858 /* SMBtrans - not used on file shares */
859 static void nbench_trans_send(struct smbsrv_request
*req
)
861 nbench_log(req
, "Trans - NOT HANDLED\n");
863 PASS_THRU_REP_POST(req
);
866 static NTSTATUS
nbench_trans(struct ntvfs_module_context
*ntvfs
,
867 struct smbsrv_request
*req
, struct smb_trans2
*trans2
)
871 PASS_THRU_REQ(ntvfs
, req
, trans
, trans2
, (ntvfs
, req
, trans2
));
877 initialise the nbench backend, registering ourselves with the ntvfs subsystem
879 NTSTATUS
ntvfs_nbench_init(void)
882 struct ntvfs_ops ops
;
886 /* fill in the name and type */
888 ops
.type
= NTVFS_DISK
;
890 /* fill in all the operations */
891 ops
.connect
= nbench_connect
;
892 ops
.disconnect
= nbench_disconnect
;
893 ops
.unlink
= nbench_unlink
;
894 ops
.chkpath
= nbench_chkpath
;
895 ops
.qpathinfo
= nbench_qpathinfo
;
896 ops
.setpathinfo
= nbench_setpathinfo
;
897 ops
.openfile
= nbench_openfile
;
898 ops
.mkdir
= nbench_mkdir
;
899 ops
.rmdir
= nbench_rmdir
;
900 ops
.rename
= nbench_rename
;
901 ops
.copy
= nbench_copy
;
902 ops
.ioctl
= nbench_ioctl
;
903 ops
.read
= nbench_read
;
904 ops
.write
= nbench_write
;
905 ops
.seek
= nbench_seek
;
906 ops
.flush
= nbench_flush
;
907 ops
.close
= nbench_close
;
908 ops
.exit
= nbench_exit
;
909 ops
.lock
= nbench_lock
;
910 ops
.setfileinfo
= nbench_setfileinfo
;
911 ops
.qfileinfo
= nbench_qfileinfo
;
912 ops
.fsinfo
= nbench_fsinfo
;
913 ops
.lpq
= nbench_lpq
;
914 ops
.search_first
= nbench_search_first
;
915 ops
.search_next
= nbench_search_next
;
916 ops
.search_close
= nbench_search_close
;
917 ops
.trans
= nbench_trans
;
918 ops
.logoff
= nbench_logoff
;
919 ops
.async_setup
= nbench_async_setup
;
920 ops
.cancel
= nbench_cancel
;
922 /* we don't register a trans2 handler as we want to be able to
923 log individual trans2 requests */
926 /* register ourselves with the NTVFS subsystem. */
927 ret
= ntvfs_register(&ops
);
929 if (!NT_STATUS_IS_OK(ret
)) {
930 DEBUG(0,("Failed to register nbench backend!\n"));