mirror of
https://github.com/samba-team/samba.git
synced 2025-09-11 09:44:19 +03:00
ntvfs: Remove unused nbench vfs module
A pass-though NTVFS module to write nbench files is a cute idea, but this is untested and almost certainly unused. Found by looking at the LCOV results. Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
This commit is contained in:
committed by
Gary Lockyer
parent
5b957f816c
commit
2017e291a2
@@ -1,13 +0,0 @@
|
|||||||
This module provides a way to capture file sharing loads for the
|
|
||||||
NBENCH benchmark client. It also servers as an example of a NTVFS
|
|
||||||
filter module.
|
|
||||||
|
|
||||||
Here is an example config that passes through to the CIFS NTVFS backend.
|
|
||||||
|
|
||||||
[bench]
|
|
||||||
ntvfs handler = nbench cifs
|
|
||||||
cifs:server = myserver
|
|
||||||
cifs:user = myuser
|
|
||||||
cifs:password = mypass
|
|
||||||
cifs:domain = MYDOMAIN
|
|
||||||
cifs:share = bench
|
|
@@ -1,982 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
#include "lib/util/sys_rw.h"
|
|
||||||
|
|
||||||
NTSTATUS ntvfs_nbench_init(TALLOC_CTX *);
|
|
||||||
|
|
||||||
/* 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 *nprivates = req->async_states->ntvfs->private_data;
|
|
||||||
va_list ap;
|
|
||||||
char *s = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
ret = vasprintf(&s, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (ret == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sys_write_v(nprivates->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,
|
|
||||||
union smb_tcon* con)
|
|
||||||
{
|
|
||||||
struct nbench_private *nprivates;
|
|
||||||
NTSTATUS status;
|
|
||||||
char *logname = NULL;
|
|
||||||
|
|
||||||
nprivates = talloc(ntvfs, struct nbench_private);
|
|
||||||
if (!nprivates) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
logname = talloc_asprintf(req, "/tmp/nbenchlog%d.%u", ntvfs->depth,
|
|
||||||
(unsigned int)getpid());
|
|
||||||
NT_STATUS_HAVE_NO_MEMORY(logname);
|
|
||||||
nprivates->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644);
|
|
||||||
talloc_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, con);
|
|
||||||
|
|
||||||
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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, req->async_states->status));
|
|
||||||
break;
|
|
||||||
case RAW_FLUSH_ALL:
|
|
||||||
nbench_log(req, "Flush %d %s\n",
|
|
||||||
0xFFFF,
|
|
||||||
get_nt_error_c_code(req, 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, 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_data)
|
|
||||||
{
|
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
PASS_THRU_REQ(ntvfs, req, async_setup, NULL, (ntvfs, req, private_data));
|
|
||||||
|
|
||||||
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, 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, 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, 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, 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, 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(TALLOC_CTX *ctx)
|
|
||||||
{
|
|
||||||
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_fn = nbench_connect;
|
|
||||||
ops.disconnect_fn = nbench_disconnect;
|
|
||||||
ops.unlink_fn = nbench_unlink;
|
|
||||||
ops.chkpath_fn = nbench_chkpath;
|
|
||||||
ops.qpathinfo_fn = nbench_qpathinfo;
|
|
||||||
ops.setpathinfo_fn = nbench_setpathinfo;
|
|
||||||
ops.open_fn = nbench_open;
|
|
||||||
ops.mkdir_fn = nbench_mkdir;
|
|
||||||
ops.rmdir_fn = nbench_rmdir;
|
|
||||||
ops.rename_fn = nbench_rename;
|
|
||||||
ops.copy_fn = nbench_copy;
|
|
||||||
ops.ioctl_fn = nbench_ioctl;
|
|
||||||
ops.read_fn = nbench_read;
|
|
||||||
ops.write_fn = nbench_write;
|
|
||||||
ops.seek_fn = nbench_seek;
|
|
||||||
ops.flush_fn = nbench_flush;
|
|
||||||
ops.close_fn = nbench_close;
|
|
||||||
ops.exit_fn = nbench_exit;
|
|
||||||
ops.lock_fn = nbench_lock;
|
|
||||||
ops.setfileinfo_fn = nbench_setfileinfo;
|
|
||||||
ops.qfileinfo_fn = nbench_qfileinfo;
|
|
||||||
ops.fsinfo_fn = nbench_fsinfo;
|
|
||||||
ops.lpq_fn = nbench_lpq;
|
|
||||||
ops.search_first_fn = nbench_search_first;
|
|
||||||
ops.search_next_fn = nbench_search_next;
|
|
||||||
ops.search_close_fn = nbench_search_close;
|
|
||||||
ops.trans_fn = nbench_trans;
|
|
||||||
ops.logoff_fn = nbench_logoff;
|
|
||||||
ops.async_setup_fn = nbench_async_setup;
|
|
||||||
ops.cancel_fn = nbench_cancel;
|
|
||||||
|
|
||||||
/* we don't register a trans2 handler as we want to be able to
|
|
||||||
log individual trans2 requests */
|
|
||||||
ops.trans2_fn = 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;
|
|
||||||
}
|
|
@@ -63,13 +63,3 @@ if bld.CONFIG_SET('WITH_NTVFS_FILESERVER'):
|
|||||||
init_function='ntvfs_ipc_init',
|
init_function='ntvfs_ipc_init',
|
||||||
deps='NDR_NAMED_PIPE_AUTH npa_tstream gssapi samba-credentials DCERPC_SHARE'
|
deps='NDR_NAMED_PIPE_AUTH npa_tstream gssapi samba-credentials DCERPC_SHARE'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
bld.SAMBA_MODULE('ntvfs_nbench',
|
|
||||||
source='nbench/vfs_nbench.c',
|
|
||||||
subsystem='ntvfs',
|
|
||||||
init_function='ntvfs_nbench_init',
|
|
||||||
deps='talloc'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user