source: branches/samba-3.5.x/source4/ntvfs/nbench/vfs_nbench.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 16 years ago

Samba 3.5.0: Initial import

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