diff options
Diffstat (limited to 'source4/ntvfs/nbench/vfs_nbench.c')
-rw-r--r-- | source4/ntvfs/nbench/vfs_nbench.c | 972 |
1 files changed, 972 insertions, 0 deletions
diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c new file mode 100644 index 0000000000..987227a0b7 --- /dev/null +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -0,0 +1,972 @@ +/* + Unix SMB/CIFS implementation. + + a pass-thru NTVFS module to record a NBENCH load file + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* + "passthru" in this module refers to the next level of NTVFS being used +*/ + +#include "includes.h" +#include "ntvfs/ntvfs.h" +#include "system/filesys.h" + +/* this is stored in ntvfs_private */ +struct nbench_private { + int log_fd; +}; + +/* + log one request to the nbench log +*/ +static void nbench_log(struct ntvfs_request *req, + const char *format, ...) PRINTF_ATTRIBUTE(2, 3); + +static void nbench_log(struct ntvfs_request *req, + const char *format, ...) +{ + struct nbench_private *private = req->async_states->ntvfs->private_data; + va_list ap; + char *s = NULL; + + va_start(ap, format); + vasprintf(&s, format, ap); + va_end(ap); + + write(private->log_fd, s, strlen(s)); + free(s); +} + +static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_handle *h) +{ + DATA_BLOB key; + uint16_t fnum = 0; + + key = ntvfs_handle_get_wire_key(h, req); + + switch (key.length) { + case 2: /* SMB fnum */ + fnum = SVAL(key.data, 0); + break; + default: + DEBUG(0,("%s: invalid wire handle size: %u\n", + __FUNCTION__, (unsigned)key.length)); + break; + } + + return talloc_asprintf(req, "%u", fnum); +} + +/* + this pass through macro operates on request contexts, and disables + async calls. + + async calls are a pain for the nbench module as it makes pulling the + status code and any result parameters much harder. +*/ +#define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \ + status = ntvfs_async_state_push(ntvfs, req, par1, nbench_##op##_send); \ + if (!NT_STATUS_IS_OK(status)) { \ + return status; \ + } \ +} while (0) + +#define PASS_THRU_REQ_POST_ASYNC(req) do { \ + req->async_states->status = status; \ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \ + req->async_states->send_fn(req); \ + } \ +} while (0) + +#define PASS_THRU_REQ(ntvfs, req, op, par1, args) do { \ + PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1); \ + status = ntvfs_next_##op args; \ + PASS_THRU_REQ_POST_ASYNC(req); \ +} while (0) + +#define PASS_THRU_REP_POST(req) do { \ + ntvfs_async_state_pop(req); \ + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \ + req->async_states->send_fn(req); \ + } \ +} while (0) + +/* + connect to a share - used when a tree_connect operation comes in. +*/ +static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const char *sharename) +{ + struct nbench_private *nprivates; + NTSTATUS status; + char *logname = NULL; + + nprivates = talloc(ntvfs, struct nbench_private); + if (!nprivates) { + return NT_STATUS_NO_MEMORY; + } + + asprintf(&logname, "/tmp/nbenchlog%d.%u", ntvfs->depth, getpid()); + nprivates->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); + free(logname); + + if (nprivates->log_fd == -1) { + DEBUG(0,("Failed to open nbench log\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + ntvfs->private_data = nprivates; + + status = ntvfs_next_connect(ntvfs, req, sharename); + + return status; +} + +/* + disconnect from a share +*/ +static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs) +{ + struct nbench_private *nprivates = ntvfs->private_data; + NTSTATUS status; + + close(nprivates->log_fd); + + status = ntvfs_next_disconnect(ntvfs); + + return status; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static void nbench_unlink_send(struct ntvfs_request *req) +{ + union smb_unlink *unl = req->async_states->private_data; + + nbench_log(req, "Unlink \"%s\" 0x%x %s\n", + unl->unlink.in.pattern, unl->unlink.in.attrib, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_unlink *unl) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, unlink, unl, (ntvfs, req, unl)); + + return status; +} + +/* + ioctl interface +*/ +static void nbench_ioctl_send(struct ntvfs_request *req) +{ + nbench_log(req, "Ioctl - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, ioctl, io, (ntvfs, req, io)); + + return status; +} + +/* + check if a directory exists +*/ +static void nbench_chkpath_send(struct ntvfs_request *req) +{ + union smb_chkpath *cp = req->async_states->private_data; + + nbench_log(req, "Chkpath \"%s\" %s\n", + cp->chkpath.in.path, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_chkpath *cp) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, chkpath, cp, (ntvfs, req, cp)); + + return status; +} + +/* + return info on a pathname +*/ +static void nbench_qpathinfo_send(struct ntvfs_request *req) +{ + union smb_fileinfo *info = req->async_states->private_data; + + nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", + info->generic.in.file.path, + info->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, qpathinfo, info, (ntvfs, req, info)); + + return status; +} + +/* + query info on a open file +*/ +static void nbench_qfileinfo_send(struct ntvfs_request *req) +{ + union smb_fileinfo *info = req->async_states->private_data; + + nbench_log(req, "QUERY_FILE_INFORMATION %s %d %s\n", + nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs), + info->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, qfileinfo, info, (ntvfs, req, info)); + + return status; +} + +/* + set info on a pathname +*/ +static void nbench_setpathinfo_send(struct ntvfs_request *req) +{ + union smb_setfileinfo *st = req->async_states->private_data; + + nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n", + st->generic.in.file.path, + st->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_setfileinfo *st) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, setpathinfo, st, (ntvfs, req, st)); + + return status; +} + +/* + open a file +*/ +static void nbench_open_send(struct ntvfs_request *req) +{ + union smb_open *io = req->async_states->private_data; + + switch (io->generic.level) { + case RAW_OPEN_NTCREATEX: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(io->ntcreatex.out); + } + nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %s %s\n", + io->ntcreatex.in.fname, + io->ntcreatex.in.create_options, + io->ntcreatex.in.open_disposition, + nbench_ntvfs_handle_string(req, io->ntcreatex.out.file.ntvfs), + get_nt_error_c_code(req->async_states->status)); + break; + + default: + nbench_log(req, "Open-%d - NOT HANDLED\n", + io->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) +{ + NTSTATUS status; + +#undef open /* AIX defines open to be open64 */ + PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); + + return status; +} + +/* + create a directory +*/ +static void nbench_mkdir_send(struct ntvfs_request *req) +{ + nbench_log(req, "Mkdir - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_mkdir *md) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, mkdir, md, (ntvfs, req, md)); + + return status; +} + +/* + remove a directory +*/ +static void nbench_rmdir_send(struct ntvfs_request *req) +{ + struct smb_rmdir *rd = req->async_states->private_data; + + nbench_log(req, "Rmdir \"%s\" %s\n", + rd->in.path, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_rmdir *rd) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, rmdir, rd, (ntvfs, req, rd)); + + return status; +} + +/* + rename a set of files +*/ +static void nbench_rename_send(struct ntvfs_request *req) +{ + union smb_rename *ren = req->async_states->private_data; + + switch (ren->generic.level) { + case RAW_RENAME_RENAME: + nbench_log(req, "Rename \"%s\" \"%s\" %s\n", + ren->rename.in.pattern1, + ren->rename.in.pattern2, + get_nt_error_c_code(req->async_states->status)); + break; + + default: + nbench_log(req, "Rename-%d - NOT HANDLED\n", + ren->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_rename *ren) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, rename, ren, (ntvfs, req, ren)); + + return status; +} + +/* + copy a set of files +*/ +static void nbench_copy_send(struct ntvfs_request *req) +{ + nbench_log(req, "Copy - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_copy *cp) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, copy, cp, (ntvfs, req, cp)); + + return status; +} + +/* + read from a file +*/ +static void nbench_read_send(struct ntvfs_request *req) +{ + union smb_read *rd = req->async_states->private_data; + + switch (rd->generic.level) { + case RAW_READ_READX: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(rd->readx.out); + } + nbench_log(req, "ReadX %s %d %d %d %s\n", + nbench_ntvfs_handle_string(req, rd->readx.in.file.ntvfs), + (int)rd->readx.in.offset, + rd->readx.in.maxcnt, + rd->readx.out.nread, + get_nt_error_c_code(req->async_states->status)); + break; + default: + nbench_log(req, "Read-%d - NOT HANDLED\n", + rd->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_read *rd) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, read, rd, (ntvfs, req, rd)); + + return status; +} + +/* + write to a file +*/ +static void nbench_write_send(struct ntvfs_request *req) +{ + union smb_write *wr = req->async_states->private_data; + + switch (wr->generic.level) { + case RAW_WRITE_WRITEX: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(wr->writex.out); + } + nbench_log(req, "WriteX %s %d %d %d %s\n", + nbench_ntvfs_handle_string(req, wr->writex.in.file.ntvfs), + (int)wr->writex.in.offset, + wr->writex.in.count, + wr->writex.out.nwritten, + get_nt_error_c_code(req->async_states->status)); + break; + + case RAW_WRITE_WRITE: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(wr->write.out); + } + nbench_log(req, "Write %s %d %d %d %s\n", + nbench_ntvfs_handle_string(req, wr->write.in.file.ntvfs), + wr->write.in.offset, + wr->write.in.count, + wr->write.out.nwritten, + get_nt_error_c_code(req->async_states->status)); + break; + + default: + nbench_log(req, "Write-%d - NOT HANDLED\n", + wr->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_write *wr) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, write, wr, (ntvfs, req, wr)); + + return status; +} + +/* + seek in a file +*/ +static void nbench_seek_send(struct ntvfs_request *req) +{ + nbench_log(req, "Seek - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_seek *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, seek, io, (ntvfs, req, io)); + + return status; +} + +/* + flush a file +*/ +static void nbench_flush_send(struct ntvfs_request *req) +{ + union smb_flush *io = req->async_states->private_data; + + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + nbench_log(req, "Flush %s %s\n", + nbench_ntvfs_handle_string(req, io->flush.in.file.ntvfs), + get_nt_error_c_code(req->async_states->status)); + break; + case RAW_FLUSH_ALL: + nbench_log(req, "Flush %d %s\n", + 0xFFFF, + get_nt_error_c_code(req->async_states->status)); + break; + default: + nbench_log(req, "Flush-%d - NOT HANDLED\n", + io->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_flush *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, flush, io, (ntvfs, req, io)); + + return status; +} + +/* + close a file +*/ +static void nbench_close_send(struct ntvfs_request *req) +{ + union smb_close *io = req->async_states->private_data; + + switch (io->generic.level) { + case RAW_CLOSE_CLOSE: + nbench_log(req, "Close %s %s\n", + nbench_ntvfs_handle_string(req, io->close.in.file.ntvfs), + get_nt_error_c_code(req->async_states->status)); + break; + + default: + nbench_log(req, "Close-%d - NOT HANDLED\n", + io->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_close *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, close, io, (ntvfs, req, io)); + + return status; +} + +/* + exit - closing files +*/ +static void nbench_exit_send(struct ntvfs_request *req) +{ + nbench_log(req, "Exit - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, exit, NULL, (ntvfs, req)); + + return status; +} + +/* + logoff - closing files +*/ +static void nbench_logoff_send(struct ntvfs_request *req) +{ + nbench_log(req, "Logoff - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, logoff, NULL, (ntvfs, req)); + + return status; +} + +/* + async_setup - send fn +*/ +static void nbench_async_setup_send(struct ntvfs_request *req) +{ + PASS_THRU_REP_POST(req); +} + +/* + async setup +*/ +static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, async_setup, NULL, (ntvfs, req, private)); + + return status; +} + + +static void nbench_cancel_send(struct ntvfs_request *req) +{ + PASS_THRU_REP_POST(req); +} + +/* + cancel an existing async request +*/ +static NTSTATUS nbench_cancel(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, cancel, NULL, (ntvfs, req)); + + return status; +} + +/* + lock a byte range +*/ +static void nbench_lock_send(struct ntvfs_request *req) +{ + union smb_lock *lck = req->async_states->private_data; + + if (lck->generic.level == RAW_LOCK_LOCKX && + lck->lockx.in.lock_cnt == 1 && + lck->lockx.in.ulock_cnt == 0) { + nbench_log(req, "LockX %s %d %d %s\n", + nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs), + (int)lck->lockx.in.locks[0].offset, + (int)lck->lockx.in.locks[0].count, + get_nt_error_c_code(req->async_states->status)); + } else if (lck->generic.level == RAW_LOCK_LOCKX && + lck->lockx.in.ulock_cnt == 1) { + nbench_log(req, "UnlockX %s %d %d %s\n", + nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs), + (int)lck->lockx.in.locks[0].offset, + (int)lck->lockx.in.locks[0].count, + get_nt_error_c_code(req->async_states->status)); + } else { + nbench_log(req, "Lock-%d - NOT HANDLED\n", lck->generic.level); + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lock *lck) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, lock, lck, (ntvfs, req, lck)); + + return status; +} + +/* + set info on a open file +*/ +static void nbench_setfileinfo_send(struct ntvfs_request *req) +{ + union smb_setfileinfo *info = req->async_states->private_data; + + nbench_log(req, "SET_FILE_INFORMATION %s %d %s\n", + nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs), + info->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, setfileinfo, info, (ntvfs, req, info)); + + return status; +} + +/* + return filesystem space info +*/ +static void nbench_fsinfo_send(struct ntvfs_request *req) +{ + union smb_fsinfo *fs = req->async_states->private_data; + + nbench_log(req, "QUERY_FS_INFORMATION %d %s\n", + fs->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsinfo *fs) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, fsinfo, fs, (ntvfs, req, fs)); + + return status; +} + +/* + return print queue info +*/ +static void nbench_lpq_send(struct ntvfs_request *req) +{ + union smb_lpq *lpq = req->async_states->private_data; + + nbench_log(req, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lpq *lpq) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, lpq, lpq, (ntvfs, req, lpq)); + + return status; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static void nbench_search_first_send(struct ntvfs_request *req) +{ + union smb_search_first *io = req->async_states->private_data; + + switch (io->generic.level) { + case RAW_SEARCH_TRANS2: + if (NT_STATUS_IS_ERR(req->async_states->status)) { + ZERO_STRUCT(io->t2ffirst.out); + } + nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n", + io->t2ffirst.in.pattern, + io->t2ffirst.data_level, + io->t2ffirst.in.max_count, + io->t2ffirst.out.count, + get_nt_error_c_code(req->async_states->status)); + break; + + default: + nbench_log(req, "Search-%d - NOT HANDLED\n", io->generic.level); + break; + } + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + bool (*callback)(void *, const union smb_search_data *)) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_first, io, (ntvfs, req, io, search_private, callback)); + + return status; +} + +/* continue a search */ +static void nbench_search_next_send(struct ntvfs_request *req) +{ + union smb_search_next *io = req->async_states->private_data; + + nbench_log(req, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + bool (*callback)(void *, const union smb_search_data *)) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_next, io, (ntvfs, req, io, search_private, callback)); + + return status; +} + +/* close a search */ +static void nbench_search_close_send(struct ntvfs_request *req) +{ + union smb_search_close *io = req->async_states->private_data; + + nbench_log(req, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_close *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_close, io, (ntvfs, req, io)); + + return status; +} + +/* SMBtrans - not used on file shares */ +static void nbench_trans_send(struct ntvfs_request *req) +{ + nbench_log(req, "Trans - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_trans2 *trans2) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, trans, trans2, (ntvfs, req, trans2)); + + return status; +} + +/* + initialise the nbench backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_nbench_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); + + ZERO_STRUCT(ops); + + /* fill in the name and type */ + ops.name = "nbench"; + ops.type = NTVFS_DISK; + + /* fill in all the operations */ + ops.connect = nbench_connect; + ops.disconnect = nbench_disconnect; + ops.unlink = nbench_unlink; + ops.chkpath = nbench_chkpath; + ops.qpathinfo = nbench_qpathinfo; + ops.setpathinfo = nbench_setpathinfo; + ops.open = nbench_open; + ops.mkdir = nbench_mkdir; + ops.rmdir = nbench_rmdir; + ops.rename = nbench_rename; + ops.copy = nbench_copy; + ops.ioctl = nbench_ioctl; + ops.read = nbench_read; + ops.write = nbench_write; + ops.seek = nbench_seek; + ops.flush = nbench_flush; + ops.close = nbench_close; + ops.exit = nbench_exit; + ops.lock = nbench_lock; + ops.setfileinfo = nbench_setfileinfo; + ops.qfileinfo = nbench_qfileinfo; + ops.fsinfo = nbench_fsinfo; + ops.lpq = nbench_lpq; + ops.search_first = nbench_search_first; + ops.search_next = nbench_search_next; + ops.search_close = nbench_search_close; + ops.trans = nbench_trans; + ops.logoff = nbench_logoff; + ops.async_setup = nbench_async_setup; + ops.cancel = nbench_cancel; + + /* we don't register a trans2 handler as we want to be able to + log individual trans2 requests */ + ops.trans2 = NULL; + + /* register ourselves with the NTVFS subsystem. */ + ret = ntvfs_register(&ops, &vers); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register nbench backend!\n")); + } + + return ret; +} |