root/source4/ntvfs/nbench/vfs_nbench.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nbench_log
  2. nbench_ntvfs_handle_string
  3. nbench_connect
  4. nbench_disconnect
  5. nbench_unlink_send
  6. nbench_unlink
  7. nbench_ioctl_send
  8. nbench_ioctl
  9. nbench_chkpath_send
  10. nbench_chkpath
  11. nbench_qpathinfo_send
  12. nbench_qpathinfo
  13. nbench_qfileinfo_send
  14. nbench_qfileinfo
  15. nbench_setpathinfo_send
  16. nbench_setpathinfo
  17. nbench_open_send
  18. nbench_open
  19. nbench_mkdir_send
  20. nbench_mkdir
  21. nbench_rmdir_send
  22. nbench_rmdir
  23. nbench_rename_send
  24. nbench_rename
  25. nbench_copy_send
  26. nbench_copy
  27. nbench_read_send
  28. nbench_read
  29. nbench_write_send
  30. nbench_write
  31. nbench_seek_send
  32. nbench_seek
  33. nbench_flush_send
  34. nbench_flush
  35. nbench_close_send
  36. nbench_close
  37. nbench_exit_send
  38. nbench_exit
  39. nbench_logoff_send
  40. nbench_logoff
  41. nbench_async_setup_send
  42. nbench_async_setup
  43. nbench_cancel_send
  44. nbench_cancel
  45. nbench_lock_send
  46. nbench_lock
  47. nbench_setfileinfo_send
  48. nbench_setfileinfo
  49. nbench_fsinfo_send
  50. nbench_fsinfo
  51. nbench_lpq_send
  52. nbench_lpq
  53. nbench_search_first_send
  54. nbench_search_first
  55. nbench_search_next_send
  56. nbench_search_next
  57. nbench_search_close_send
  58. nbench_search_close
  59. nbench_trans_send
  60. nbench_trans
  61. ntvfs_nbench_init

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

/* [<][>][^][v][top][bottom][index][help] */