source: trunk/server/source4/ntvfs/nbench/vfs_nbench.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 23.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 a pass-thru NTVFS module to record a NBENCH load file
5
6 Copyright (C) Andrew Tridgell 2004
7
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.
12
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.
17
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/>.
20*/
21
22/*
23 "passthru" in this module refers to the next level of NTVFS being used
24*/
25
26#include "includes.h"
27#include "ntvfs/ntvfs.h"
28#include "system/filesys.h"
29
30/* this is stored in ntvfs_private */
31struct nbench_private {
32 int log_fd;
33};
34
35/*
36 log one request to the nbench log
37*/
38static void nbench_log(struct ntvfs_request *req,
39 const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
40
41static void nbench_log(struct ntvfs_request *req,
42 const char *format, ...)
43{
44 struct nbench_private *nprivates = req->async_states->ntvfs->private_data;
45 va_list ap;
46 char *s = NULL;
47
48 va_start(ap, format);
49 vasprintf(&s, format, ap);
50 va_end(ap);
51
52 write(nprivates->log_fd, s, strlen(s));
53 free(s);
54}
55
56static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_handle *h)
57{
58 DATA_BLOB key;
59 uint16_t fnum = 0;
60
61 key = ntvfs_handle_get_wire_key(h, req);
62
63 switch (key.length) {
64 case 2: /* SMB fnum */
65 fnum = SVAL(key.data, 0);
66 break;
67 default:
68 DEBUG(0,("%s: invalid wire handle size: %u\n",
69 __FUNCTION__, (unsigned)key.length));
70 break;
71 }
72
73 return talloc_asprintf(req, "%u", fnum);
74}
75
76/*
77 this pass through macro operates on request contexts, and disables
78 async calls.
79
80 async calls are a pain for the nbench module as it makes pulling the
81 status code and any result parameters much harder.
82*/
83#define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \
84 status = ntvfs_async_state_push(ntvfs, req, par1, nbench_##op##_send); \
85 if (!NT_STATUS_IS_OK(status)) { \
86 return status; \
87 } \
88} while (0)
89
90#define PASS_THRU_REQ_POST_ASYNC(req) do { \
91 req->async_states->status = status; \
92 if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
93 req->async_states->send_fn(req); \
94 } \
95} while (0)
96
97#define PASS_THRU_REQ(ntvfs, req, op, par1, args) do { \
98 PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1); \
99 status = ntvfs_next_##op args; \
100 PASS_THRU_REQ_POST_ASYNC(req); \
101} while (0)
102
103#define PASS_THRU_REP_POST(req) do { \
104 ntvfs_async_state_pop(req); \
105 if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \
106 req->async_states->send_fn(req); \
107 } \
108} while (0)
109
110/*
111 connect to a share - used when a tree_connect operation comes in.
112*/
113static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs,
114 struct ntvfs_request *req,
115 union smb_tcon* con)
116{
117 struct nbench_private *nprivates;
118 NTSTATUS status;
119 char *logname = NULL;
120
121 nprivates = talloc(ntvfs, struct nbench_private);
122 if (!nprivates) {
123 return NT_STATUS_NO_MEMORY;
124 }
125
126 logname = talloc_asprintf(req, "/tmp/nbenchlog%d.%u", ntvfs->depth,
127 getpid());
128 NT_STATUS_HAVE_NO_MEMORY(logname);
129 nprivates->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644);
130 talloc_free(logname);
131
132 if (nprivates->log_fd == -1) {
133 DEBUG(0,("Failed to open nbench log\n"));
134 return NT_STATUS_UNSUCCESSFUL;
135 }
136
137 ntvfs->private_data = nprivates;
138
139 status = ntvfs_next_connect(ntvfs, req, con);
140
141 return status;
142}
143
144/*
145 disconnect from a share
146*/
147static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs)
148{
149 struct nbench_private *nprivates = ntvfs->private_data;
150 NTSTATUS status;
151
152 close(nprivates->log_fd);
153
154 status = ntvfs_next_disconnect(ntvfs);
155
156 return status;
157}
158
159/*
160 delete a file - the dirtype specifies the file types to include in the search.
161 The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
162*/
163static void nbench_unlink_send(struct ntvfs_request *req)
164{
165 union smb_unlink *unl = req->async_states->private_data;
166
167 nbench_log(req, "Unlink \"%s\" 0x%x %s\n",
168 unl->unlink.in.pattern, unl->unlink.in.attrib,
169 get_nt_error_c_code(req->async_states->status));
170
171 PASS_THRU_REP_POST(req);
172}
173
174static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs,
175 struct ntvfs_request *req,
176 union smb_unlink *unl)
177{
178 NTSTATUS status;
179
180 PASS_THRU_REQ(ntvfs, req, unlink, unl, (ntvfs, req, unl));
181
182 return status;
183}
184
185/*
186 ioctl interface
187*/
188static void nbench_ioctl_send(struct ntvfs_request *req)
189{
190 nbench_log(req, "Ioctl - NOT HANDLED\n");
191
192 PASS_THRU_REP_POST(req);
193}
194
195static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs,
196 struct ntvfs_request *req, union smb_ioctl *io)
197{
198 NTSTATUS status;
199
200 PASS_THRU_REQ(ntvfs, req, ioctl, io, (ntvfs, req, io));
201
202 return status;
203}
204
205/*
206 check if a directory exists
207*/
208static void nbench_chkpath_send(struct ntvfs_request *req)
209{
210 union smb_chkpath *cp = req->async_states->private_data;
211
212 nbench_log(req, "Chkpath \"%s\" %s\n",
213 cp->chkpath.in.path,
214 get_nt_error_c_code(req->async_states->status));
215
216 PASS_THRU_REP_POST(req);
217}
218
219static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs,
220 struct ntvfs_request *req,
221 union smb_chkpath *cp)
222{
223 NTSTATUS status;
224
225 PASS_THRU_REQ(ntvfs, req, chkpath, cp, (ntvfs, req, cp));
226
227 return status;
228}
229
230/*
231 return info on a pathname
232*/
233static void nbench_qpathinfo_send(struct ntvfs_request *req)
234{
235 union smb_fileinfo *info = req->async_states->private_data;
236
237 nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n",
238 info->generic.in.file.path,
239 info->generic.level,
240 get_nt_error_c_code(req->async_states->status));
241
242 PASS_THRU_REP_POST(req);
243}
244
245static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs,
246 struct ntvfs_request *req, union smb_fileinfo *info)
247{
248 NTSTATUS status;
249
250 PASS_THRU_REQ(ntvfs, req, qpathinfo, info, (ntvfs, req, info));
251
252 return status;
253}
254
255/*
256 query info on a open file
257*/
258static void nbench_qfileinfo_send(struct ntvfs_request *req)
259{
260 union smb_fileinfo *info = req->async_states->private_data;
261
262 nbench_log(req, "QUERY_FILE_INFORMATION %s %d %s\n",
263 nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs),
264 info->generic.level,
265 get_nt_error_c_code(req->async_states->status));
266
267 PASS_THRU_REP_POST(req);
268}
269
270static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs,
271 struct ntvfs_request *req, union smb_fileinfo *info)
272{
273 NTSTATUS status;
274
275 PASS_THRU_REQ(ntvfs, req, qfileinfo, info, (ntvfs, req, info));
276
277 return status;
278}
279
280/*
281 set info on a pathname
282*/
283static void nbench_setpathinfo_send(struct ntvfs_request *req)
284{
285 union smb_setfileinfo *st = req->async_states->private_data;
286
287 nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n",
288 st->generic.in.file.path,
289 st->generic.level,
290 get_nt_error_c_code(req->async_states->status));
291
292 PASS_THRU_REP_POST(req);
293}
294
295static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs,
296 struct ntvfs_request *req, union smb_setfileinfo *st)
297{
298 NTSTATUS status;
299
300 PASS_THRU_REQ(ntvfs, req, setpathinfo, st, (ntvfs, req, st));
301
302 return status;
303}
304
305/*
306 open a file
307*/
308static void nbench_open_send(struct ntvfs_request *req)
309{
310 union smb_open *io = req->async_states->private_data;
311
312 switch (io->generic.level) {
313 case RAW_OPEN_NTCREATEX:
314 if (!NT_STATUS_IS_OK(req->async_states->status)) {
315 ZERO_STRUCT(io->ntcreatex.out);
316 }
317 nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %s %s\n",
318 io->ntcreatex.in.fname,
319 io->ntcreatex.in.create_options,
320 io->ntcreatex.in.open_disposition,
321 nbench_ntvfs_handle_string(req, io->ntcreatex.out.file.ntvfs),
322 get_nt_error_c_code(req->async_states->status));
323 break;
324
325 default:
326 nbench_log(req, "Open-%d - NOT HANDLED\n",
327 io->generic.level);
328 break;
329 }
330
331 PASS_THRU_REP_POST(req);
332}
333
334static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs,
335 struct ntvfs_request *req, union smb_open *io)
336{
337 NTSTATUS status;
338
339#undef open /* AIX defines open to be open64 */
340 PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io));
341
342 return status;
343}
344
345/*
346 create a directory
347*/
348static void nbench_mkdir_send(struct ntvfs_request *req)
349{
350 nbench_log(req, "Mkdir - NOT HANDLED\n");
351
352 PASS_THRU_REP_POST(req);
353}
354
355static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs,
356 struct ntvfs_request *req, union smb_mkdir *md)
357{
358 NTSTATUS status;
359
360 PASS_THRU_REQ(ntvfs, req, mkdir, md, (ntvfs, req, md));
361
362 return status;
363}
364
365/*
366 remove a directory
367*/
368static void nbench_rmdir_send(struct ntvfs_request *req)
369{
370 struct smb_rmdir *rd = req->async_states->private_data;
371
372 nbench_log(req, "Rmdir \"%s\" %s\n",
373 rd->in.path,
374 get_nt_error_c_code(req->async_states->status));
375
376 PASS_THRU_REP_POST(req);
377}
378
379static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs,
380 struct ntvfs_request *req, struct smb_rmdir *rd)
381{
382 NTSTATUS status;
383
384 PASS_THRU_REQ(ntvfs, req, rmdir, rd, (ntvfs, req, rd));
385
386 return status;
387}
388
389/*
390 rename a set of files
391*/
392static void nbench_rename_send(struct ntvfs_request *req)
393{
394 union smb_rename *ren = req->async_states->private_data;
395
396 switch (ren->generic.level) {
397 case RAW_RENAME_RENAME:
398 nbench_log(req, "Rename \"%s\" \"%s\" %s\n",
399 ren->rename.in.pattern1,
400 ren->rename.in.pattern2,
401 get_nt_error_c_code(req->async_states->status));
402 break;
403
404 default:
405 nbench_log(req, "Rename-%d - NOT HANDLED\n",
406 ren->generic.level);
407 break;
408 }
409
410 PASS_THRU_REP_POST(req);
411}
412
413static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs,
414 struct ntvfs_request *req, union smb_rename *ren)
415{
416 NTSTATUS status;
417
418 PASS_THRU_REQ(ntvfs, req, rename, ren, (ntvfs, req, ren));
419
420 return status;
421}
422
423/*
424 copy a set of files
425*/
426static void nbench_copy_send(struct ntvfs_request *req)
427{
428 nbench_log(req, "Copy - NOT HANDLED\n");
429
430 PASS_THRU_REP_POST(req);
431}
432
433static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs,
434 struct ntvfs_request *req, struct smb_copy *cp)
435{
436 NTSTATUS status;
437
438 PASS_THRU_REQ(ntvfs, req, copy, cp, (ntvfs, req, cp));
439
440 return status;
441}
442
443/*
444 read from a file
445*/
446static void nbench_read_send(struct ntvfs_request *req)
447{
448 union smb_read *rd = req->async_states->private_data;
449
450 switch (rd->generic.level) {
451 case RAW_READ_READX:
452 if (!NT_STATUS_IS_OK(req->async_states->status)) {
453 ZERO_STRUCT(rd->readx.out);
454 }
455 nbench_log(req, "ReadX %s %d %d %d %s\n",
456 nbench_ntvfs_handle_string(req, rd->readx.in.file.ntvfs),
457 (int)rd->readx.in.offset,
458 rd->readx.in.maxcnt,
459 rd->readx.out.nread,
460 get_nt_error_c_code(req->async_states->status));
461 break;
462 default:
463 nbench_log(req, "Read-%d - NOT HANDLED\n",
464 rd->generic.level);
465 break;
466 }
467
468 PASS_THRU_REP_POST(req);
469}
470
471static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs,
472 struct ntvfs_request *req, union smb_read *rd)
473{
474 NTSTATUS status;
475
476 PASS_THRU_REQ(ntvfs, req, read, rd, (ntvfs, req, rd));
477
478 return status;
479}
480
481/*
482 write to a file
483*/
484static void nbench_write_send(struct ntvfs_request *req)
485{
486 union smb_write *wr = req->async_states->private_data;
487
488 switch (wr->generic.level) {
489 case RAW_WRITE_WRITEX:
490 if (!NT_STATUS_IS_OK(req->async_states->status)) {
491 ZERO_STRUCT(wr->writex.out);
492 }
493 nbench_log(req, "WriteX %s %d %d %d %s\n",
494 nbench_ntvfs_handle_string(req, wr->writex.in.file.ntvfs),
495 (int)wr->writex.in.offset,
496 wr->writex.in.count,
497 wr->writex.out.nwritten,
498 get_nt_error_c_code(req->async_states->status));
499 break;
500
501 case RAW_WRITE_WRITE:
502 if (!NT_STATUS_IS_OK(req->async_states->status)) {
503 ZERO_STRUCT(wr->write.out);
504 }
505 nbench_log(req, "Write %s %d %d %d %s\n",
506 nbench_ntvfs_handle_string(req, wr->write.in.file.ntvfs),
507 wr->write.in.offset,
508 wr->write.in.count,
509 wr->write.out.nwritten,
510 get_nt_error_c_code(req->async_states->status));
511 break;
512
513 default:
514 nbench_log(req, "Write-%d - NOT HANDLED\n",
515 wr->generic.level);
516 break;
517 }
518
519 PASS_THRU_REP_POST(req);
520}
521
522static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs,
523 struct ntvfs_request *req, union smb_write *wr)
524{
525 NTSTATUS status;
526
527 PASS_THRU_REQ(ntvfs, req, write, wr, (ntvfs, req, wr));
528
529 return status;
530}
531
532/*
533 seek in a file
534*/
535static void nbench_seek_send(struct ntvfs_request *req)
536{
537 nbench_log(req, "Seek - NOT HANDLED\n");
538
539 PASS_THRU_REP_POST(req);
540}
541
542static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs,
543 struct ntvfs_request *req,
544 union smb_seek *io)
545{
546 NTSTATUS status;
547
548 PASS_THRU_REQ(ntvfs, req, seek, io, (ntvfs, req, io));
549
550 return status;
551}
552
553/*
554 flush a file
555*/
556static void nbench_flush_send(struct ntvfs_request *req)
557{
558 union smb_flush *io = req->async_states->private_data;
559
560 switch (io->generic.level) {
561 case RAW_FLUSH_FLUSH:
562 nbench_log(req, "Flush %s %s\n",
563 nbench_ntvfs_handle_string(req, io->flush.in.file.ntvfs),
564 get_nt_error_c_code(req->async_states->status));
565 break;
566 case RAW_FLUSH_ALL:
567 nbench_log(req, "Flush %d %s\n",
568 0xFFFF,
569 get_nt_error_c_code(req->async_states->status));
570 break;
571 default:
572 nbench_log(req, "Flush-%d - NOT HANDLED\n",
573 io->generic.level);
574 break;
575 }
576
577 PASS_THRU_REP_POST(req);
578}
579
580static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs,
581 struct ntvfs_request *req,
582 union smb_flush *io)
583{
584 NTSTATUS status;
585
586 PASS_THRU_REQ(ntvfs, req, flush, io, (ntvfs, req, io));
587
588 return status;
589}
590
591/*
592 close a file
593*/
594static void nbench_close_send(struct ntvfs_request *req)
595{
596 union smb_close *io = req->async_states->private_data;
597
598 switch (io->generic.level) {
599 case RAW_CLOSE_CLOSE:
600 nbench_log(req, "Close %s %s\n",
601 nbench_ntvfs_handle_string(req, io->close.in.file.ntvfs),
602 get_nt_error_c_code(req->async_states->status));
603 break;
604
605 default:
606 nbench_log(req, "Close-%d - NOT HANDLED\n",
607 io->generic.level);
608 break;
609 }
610
611 PASS_THRU_REP_POST(req);
612}
613
614static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs,
615 struct ntvfs_request *req, union smb_close *io)
616{
617 NTSTATUS status;
618
619 PASS_THRU_REQ(ntvfs, req, close, io, (ntvfs, req, io));
620
621 return status;
622}
623
624/*
625 exit - closing files
626*/
627static void nbench_exit_send(struct ntvfs_request *req)
628{
629 nbench_log(req, "Exit - NOT HANDLED\n");
630
631 PASS_THRU_REP_POST(req);
632}
633
634static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs,
635 struct ntvfs_request *req)
636{
637 NTSTATUS status;
638
639 PASS_THRU_REQ(ntvfs, req, exit, NULL, (ntvfs, req));
640
641 return status;
642}
643
644/*
645 logoff - closing files
646*/
647static void nbench_logoff_send(struct ntvfs_request *req)
648{
649 nbench_log(req, "Logoff - NOT HANDLED\n");
650
651 PASS_THRU_REP_POST(req);
652}
653
654static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs,
655 struct ntvfs_request *req)
656{
657 NTSTATUS status;
658
659 PASS_THRU_REQ(ntvfs, req, logoff, NULL, (ntvfs, req));
660
661 return status;
662}
663
664/*
665 async_setup - send fn
666*/
667static void nbench_async_setup_send(struct ntvfs_request *req)
668{
669 PASS_THRU_REP_POST(req);
670}
671
672/*
673 async setup
674*/
675static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs,
676 struct ntvfs_request *req,
677 void *private_data)
678{
679 NTSTATUS status;
680
681 PASS_THRU_REQ(ntvfs, req, async_setup, NULL, (ntvfs, req, private_data));
682
683 return status;
684}
685
686
687static void nbench_cancel_send(struct ntvfs_request *req)
688{
689 PASS_THRU_REP_POST(req);
690}
691
692/*
693 cancel an existing async request
694*/
695static NTSTATUS nbench_cancel(struct ntvfs_module_context *ntvfs,
696 struct ntvfs_request *req)
697{
698 NTSTATUS status;
699
700 PASS_THRU_REQ(ntvfs, req, cancel, NULL, (ntvfs, req));
701
702 return status;
703}
704
705/*
706 lock a byte range
707*/
708static void nbench_lock_send(struct ntvfs_request *req)
709{
710 union smb_lock *lck = req->async_states->private_data;
711
712 if (lck->generic.level == RAW_LOCK_LOCKX &&
713 lck->lockx.in.lock_cnt == 1 &&
714 lck->lockx.in.ulock_cnt == 0) {
715 nbench_log(req, "LockX %s %d %d %s\n",
716 nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs),
717 (int)lck->lockx.in.locks[0].offset,
718 (int)lck->lockx.in.locks[0].count,
719 get_nt_error_c_code(req->async_states->status));
720 } else if (lck->generic.level == RAW_LOCK_LOCKX &&
721 lck->lockx.in.ulock_cnt == 1) {
722 nbench_log(req, "UnlockX %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->async_states->status));
727 } else {
728 nbench_log(req, "Lock-%d - NOT HANDLED\n", lck->generic.level);
729 }
730
731 PASS_THRU_REP_POST(req);
732}
733
734static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs,
735 struct ntvfs_request *req, union smb_lock *lck)
736{
737 NTSTATUS status;
738
739 PASS_THRU_REQ(ntvfs, req, lock, lck, (ntvfs, req, lck));
740
741 return status;
742}
743
744/*
745 set info on a open file
746*/
747static void nbench_setfileinfo_send(struct ntvfs_request *req)
748{
749 union smb_setfileinfo *info = req->async_states->private_data;
750
751 nbench_log(req, "SET_FILE_INFORMATION %s %d %s\n",
752 nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs),
753 info->generic.level,
754 get_nt_error_c_code(req->async_states->status));
755
756 PASS_THRU_REP_POST(req);
757}
758
759static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs,
760 struct ntvfs_request *req,
761 union smb_setfileinfo *info)
762{
763 NTSTATUS status;
764
765 PASS_THRU_REQ(ntvfs, req, setfileinfo, info, (ntvfs, req, info));
766
767 return status;
768}
769
770/*
771 return filesystem space info
772*/
773static void nbench_fsinfo_send(struct ntvfs_request *req)
774{
775 union smb_fsinfo *fs = req->async_states->private_data;
776
777 nbench_log(req, "QUERY_FS_INFORMATION %d %s\n",
778 fs->generic.level,
779 get_nt_error_c_code(req->async_states->status));
780
781 PASS_THRU_REP_POST(req);
782}
783
784static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs,
785 struct ntvfs_request *req, union smb_fsinfo *fs)
786{
787 NTSTATUS status;
788
789 PASS_THRU_REQ(ntvfs, req, fsinfo, fs, (ntvfs, req, fs));
790
791 return status;
792}
793
794/*
795 return print queue info
796*/
797static void nbench_lpq_send(struct ntvfs_request *req)
798{
799 union smb_lpq *lpq = req->async_states->private_data;
800
801 nbench_log(req, "Lpq-%d - NOT HANDLED\n", lpq->generic.level);
802
803 PASS_THRU_REP_POST(req);
804}
805
806static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs,
807 struct ntvfs_request *req, union smb_lpq *lpq)
808{
809 NTSTATUS status;
810
811 PASS_THRU_REQ(ntvfs, req, lpq, lpq, (ntvfs, req, lpq));
812
813 return status;
814}
815
816/*
817 list files in a directory matching a wildcard pattern
818*/
819static void nbench_search_first_send(struct ntvfs_request *req)
820{
821 union smb_search_first *io = req->async_states->private_data;
822
823 switch (io->generic.level) {
824 case RAW_SEARCH_TRANS2:
825 if (NT_STATUS_IS_ERR(req->async_states->status)) {
826 ZERO_STRUCT(io->t2ffirst.out);
827 }
828 nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n",
829 io->t2ffirst.in.pattern,
830 io->t2ffirst.data_level,
831 io->t2ffirst.in.max_count,
832 io->t2ffirst.out.count,
833 get_nt_error_c_code(req->async_states->status));
834 break;
835
836 default:
837 nbench_log(req, "Search-%d - NOT HANDLED\n", io->generic.level);
838 break;
839 }
840
841 PASS_THRU_REP_POST(req);
842}
843
844static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs,
845 struct ntvfs_request *req, union smb_search_first *io,
846 void *search_private,
847 bool (*callback)(void *, const union smb_search_data *))
848{
849 NTSTATUS status;
850
851 PASS_THRU_REQ(ntvfs, req, search_first, io, (ntvfs, req, io, search_private, callback));
852
853 return status;
854}
855
856/* continue a search */
857static void nbench_search_next_send(struct ntvfs_request *req)
858{
859 union smb_search_next *io = req->async_states->private_data;
860
861 nbench_log(req, "Searchnext-%d - NOT HANDLED\n", io->generic.level);
862
863 PASS_THRU_REP_POST(req);
864}
865
866static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs,
867 struct ntvfs_request *req, union smb_search_next *io,
868 void *search_private,
869 bool (*callback)(void *, const union smb_search_data *))
870{
871 NTSTATUS status;
872
873 PASS_THRU_REQ(ntvfs, req, search_next, io, (ntvfs, req, io, search_private, callback));
874
875 return status;
876}
877
878/* close a search */
879static void nbench_search_close_send(struct ntvfs_request *req)
880{
881 union smb_search_close *io = req->async_states->private_data;
882
883 nbench_log(req, "Searchclose-%d - NOT HANDLED\n", io->generic.level);
884
885 PASS_THRU_REP_POST(req);
886}
887
888static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs,
889 struct ntvfs_request *req, union smb_search_close *io)
890{
891 NTSTATUS status;
892
893 PASS_THRU_REQ(ntvfs, req, search_close, io, (ntvfs, req, io));
894
895 return status;
896}
897
898/* SMBtrans - not used on file shares */
899static void nbench_trans_send(struct ntvfs_request *req)
900{
901 nbench_log(req, "Trans - NOT HANDLED\n");
902
903 PASS_THRU_REP_POST(req);
904}
905
906static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs,
907 struct ntvfs_request *req, struct smb_trans2 *trans2)
908{
909 NTSTATUS status;
910
911 PASS_THRU_REQ(ntvfs, req, trans, trans2, (ntvfs, req, trans2));
912
913 return status;
914}
915
916/*
917 initialise the nbench backend, registering ourselves with the ntvfs subsystem
918 */
919NTSTATUS ntvfs_nbench_init(void)
920{
921 NTSTATUS ret;
922 struct ntvfs_ops ops;
923 NTVFS_CURRENT_CRITICAL_SIZES(vers);
924
925 ZERO_STRUCT(ops);
926
927 /* fill in the name and type */
928 ops.name = "nbench";
929 ops.type = NTVFS_DISK;
930
931 /* fill in all the operations */
932 ops.connect = nbench_connect;
933 ops.disconnect = nbench_disconnect;
934 ops.unlink = nbench_unlink;
935 ops.chkpath = nbench_chkpath;
936 ops.qpathinfo = nbench_qpathinfo;
937 ops.setpathinfo = nbench_setpathinfo;
938 ops.open = nbench_open;
939 ops.mkdir = nbench_mkdir;
940 ops.rmdir = nbench_rmdir;
941 ops.rename = nbench_rename;
942 ops.copy = nbench_copy;
943 ops.ioctl = nbench_ioctl;
944 ops.read = nbench_read;
945 ops.write = nbench_write;
946 ops.seek = nbench_seek;
947 ops.flush = nbench_flush;
948 ops.close = nbench_close;
949 ops.exit = nbench_exit;
950 ops.lock = nbench_lock;
951 ops.setfileinfo = nbench_setfileinfo;
952 ops.qfileinfo = nbench_qfileinfo;
953 ops.fsinfo = nbench_fsinfo;
954 ops.lpq = nbench_lpq;
955 ops.search_first = nbench_search_first;
956 ops.search_next = nbench_search_next;
957 ops.search_close = nbench_search_close;
958 ops.trans = nbench_trans;
959 ops.logoff = nbench_logoff;
960 ops.async_setup = nbench_async_setup;
961 ops.cancel = nbench_cancel;
962
963 /* we don't register a trans2 handler as we want to be able to
964 log individual trans2 requests */
965 ops.trans2 = NULL;
966
967 /* register ourselves with the NTVFS subsystem. */
968 ret = ntvfs_register(&ops, &vers);
969
970 if (!NT_STATUS_IS_OK(ret)) {
971 DEBUG(0,("Failed to register nbench backend!\n"));
972 }
973
974 return ret;
975}
Note: See TracBrowser for help on using the repository browser.