📄 vfs_nbench.c
字号:
/* 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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -