diff options
author | Stefan Metzmacher <metze@samba.org> | 2004-10-28 21:48:53 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:04:57 -0500 |
commit | 019719595778e0bd0a00781b33407554d1943985 (patch) | |
tree | dd54db0a15f72d5fe4a63a5104d120bcae735fba /source4 | |
parent | 94c0b939c4735866945aea8b7a0377be4d814125 (diff) | |
download | samba-019719595778e0bd0a00781b33407554d1943985.tar.gz samba-019719595778e0bd0a00781b33407554d1943985.tar.xz samba-019719595778e0bd0a00781b33407554d1943985.zip |
r3336: use a struct ntvfs_async_state to be able to do async chaning of ntvfs modules
the idea is that a passthru module can use ntvfs_async_state_push() before
calling ntvfs_next_*() and in the _send function it calls
ntvfs_async_state_pop() and then call the upper layer send_fn itself
- ntvfs_nbench is now fully async
- the ntvfs_map_*() functions and the trans(2) mapping functions are not converted yet
metze
(This used to be commit fde64c0dc142b53d128c8ba09af048dc58d8ef3a)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/include/smb.h | 6 | ||||
-rw-r--r-- | source4/ntvfs/cifs/vfs_cifs.c | 78 | ||||
-rw-r--r-- | source4/ntvfs/nbench/vfs_nbench.c | 565 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs.h | 33 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs_base.c | 2 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs_generic.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs_util.c | 38 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_lock.c | 14 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_wait.c | 2 | ||||
-rw-r--r-- | source4/smb_server/reply.c | 304 | ||||
-rw-r--r-- | source4/smb_server/request.c | 9 | ||||
-rw-r--r-- | source4/smb_server/search.c | 16 | ||||
-rw-r--r-- | source4/smb_server/smb_server.c | 7 | ||||
-rw-r--r-- | source4/smb_server/smb_server.h | 28 |
14 files changed, 687 insertions, 423 deletions
diff --git a/source4/include/smb.h b/source4/include/smb.h index 4354eae862..ccb245ccdd 100644 --- a/source4/include/smb.h +++ b/source4/include/smb.h @@ -575,12 +575,6 @@ typedef struct nt_user_token { #define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14 - -/* a set of flags to control handling of request structures */ -#define REQ_CONTROL_LARGE (1<<1) /* allow replies larger than max_xmit */ -#define REQ_CONTROL_ASYNC (1<<2) /* the backend will answer this one later */ -#define REQ_CONTROL_MAY_ASYNC (1<<3) /* the backend is allowed to answer async */ - /* passed to br lock code */ enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_READ_LOCK, PENDING_WRITE_LOCK}; diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 1a0f1f2f71..9c5cfd9584 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -182,8 +182,8 @@ static void async_simple(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smbcli_request_simple_recv(c_req); - req->async.send_fn(req); + req->async_states->status = smbcli_request_simple_recv(c_req); + req->async_states->send_fn(req); } @@ -199,7 +199,7 @@ static void async_simple(struct smbcli_request *c_req) c_req->async.private = async; \ } \ c_req->async.fn = async_fn; \ - req->control_flags |= REQ_CONTROL_ASYNC; \ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ return NT_STATUS_OK; \ } while (0) @@ -219,7 +219,7 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, /* see if the front end will allow us to perform this function asynchronously. */ - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_unlink(private->tree, unl); } @@ -235,8 +235,8 @@ static void async_ioctl(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_ioctl_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -252,7 +252,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, /* see if the front end will allow us to perform this function asynchronously. */ - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_ioctl(private->tree, req, io); } @@ -272,7 +272,7 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_chkpath(private->tree, cp); } @@ -288,8 +288,8 @@ static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_pathinfo_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -303,7 +303,7 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_pathinfo(private->tree, req, info); } @@ -319,8 +319,8 @@ static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_fileinfo_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -334,7 +334,7 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fileinfo(private->tree, req, info); } @@ -355,7 +355,7 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setpathinfo(private->tree, st); } @@ -372,8 +372,8 @@ static void async_open(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_open_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_open_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -392,7 +392,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(req, io, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_open(private->tree, req, io); } @@ -412,7 +412,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_mkdir(private->tree, md); } @@ -432,7 +432,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rmdir(private->tree, rd); } c_req = smb_raw_rmdir_send(private->tree, rd); @@ -451,7 +451,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rename(private->tree, ren); } @@ -476,8 +476,8 @@ static void async_read(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_read_recv(c_req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_read_recv(c_req, async->parms); + req->async_states->send_fn(req); } /* @@ -496,7 +496,7 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(req, rd, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_read(private->tree, rd); } @@ -512,8 +512,8 @@ static void async_write(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_write_recv(c_req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_write_recv(c_req, async->parms); + req->async_states->send_fn(req); } /* @@ -532,7 +532,7 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(req, wr, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_write(private->tree, wr); } @@ -552,7 +552,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_seek(private->tree, io); } @@ -572,7 +572,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_flush(private->tree, io); } @@ -597,7 +597,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(req, io, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_close(private->tree, io); } @@ -617,7 +617,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_exit(private->tree->session); } @@ -662,7 +662,7 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, return ntvfs_map_lock(req, lck, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_lock(private->tree, lck); } @@ -682,7 +682,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setfileinfo(private->tree, info); } c_req = smb_raw_setfileinfo_send(private->tree, info); @@ -698,8 +698,8 @@ static void async_fsinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_fsinfo_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -713,7 +713,7 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fsinfo(private->tree, req, fs); } @@ -777,8 +777,8 @@ static void async_trans2(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_trans2_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* raw trans2 */ @@ -790,7 +790,7 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_trans2(private->tree, req, trans2); } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 482f0208a2..ab2d7af7b1 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -47,7 +47,7 @@ static void nbench_log(struct nbench_private *private, vasprintf(&s, format, ap); va_end(ap); - write(private->log_fd, s, strlen(s)); + //write(private->log_fd, s, strlen(s)); free(s); } @@ -58,11 +58,39 @@ static void nbench_log(struct nbench_private *private, 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(ntvfs, req, op, args) do { \ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; \ +#define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \ + status = ntvfs_async_state_push(req, par1, nbench_##op##_send, ntvfs); \ + 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)) { \ +DEBUG(0,("NBENCH S 0x%04X: %s: %s 0x%X\n", req->mid, __FUNCTION__, nt_errstr(status),req->async_states->state)); \ + req->async_states->send_fn(req); \ + } else { \ +DEBUG(0,("NBENCH A 0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(status))); \ + } \ +} 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) { \ +DEBUG(0,("NBENCH A0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(req->async_states->status))); \ + req->async_states->send_fn(req); \ + } \ +} while (0) + +#define PASS_THRU_REP_PRE(req) \ + struct nbench_private *nprivates = req->async_states->ntvfs->private_data /* connect to a share - used when a tree_connect operation comes in. @@ -70,25 +98,25 @@ static void nbench_log(struct nbench_private *private, static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) { - struct nbench_private *private; + struct nbench_private *nprivates; NTSTATUS status; char *logname = NULL; - private = talloc_p(req->tcon, struct nbench_private); - if (!private) { + nprivates = talloc_p(req->tcon, struct nbench_private); + if (!nprivates) { return NT_STATUS_NO_MEMORY; } - +#if 0 asprintf(&logname, "/tmp/nbenchlog%d.%u", ntvfs->depth, getpid()); - private->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); + nprivates->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logname); - if (private->log_fd == -1) { + if (nprivates->log_fd == -1) { DEBUG(0,("Failed to open nbench log\n")); return NT_STATUS_UNSUCCESSFUL; } - - ntvfs->private_data = private; +#endif + ntvfs->private_data = nprivates; status = ntvfs_next_connect(ntvfs, req, sharename); @@ -101,13 +129,13 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, struct smbsrv_tcon *tcon) { - struct nbench_private *private = ntvfs->private_data; + struct nbench_private *nprivates = ntvfs->private_data; NTSTATUS status; - close(private->log_fd); + close(nprivates->log_fd); status = ntvfs_next_disconnect(ntvfs, tcon); - + return status; } @@ -115,17 +143,24 @@ static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, 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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_unlink *unl = req->async_states->private_data; + + nbench_log(nprivates, "Unlink \"%s\" 0x%x %s\n", + unl->in.pattern, unl->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 smbsrv_request *req, struct smb_unlink *unl) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, unlink, (ntvfs, req, unl)); - - nbench_log(private, "Unlink \"%s\" 0x%x %s\n", - unl->in.pattern, unl->in.attrib, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, unlink, unl, (ntvfs, req, unl)); return status; } @@ -133,15 +168,21 @@ static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, /* ioctl interface */ +static void nbench_ioctl_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Ioctl - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_ioctl *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, ioctl, (ntvfs, req, io)); - - nbench_log(private, "Ioctl - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, ioctl, io, (ntvfs, req, io)); return status; } @@ -149,17 +190,24 @@ static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, /* check if a directory exists */ +static void nbench_chkpath_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_chkpath *cp = req->async_states->private_data; + + nbench_log(nprivates, "Chkpath \"%s\" %s\n", + cp->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 smbsrv_request *req, struct smb_chkpath *cp) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, chkpath, (ntvfs, req, cp)); - - nbench_log(private, "Chkpath \"%s\" %s\n", - cp->in.path, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, chkpath, cp, (ntvfs, req, cp)); return status; } @@ -167,18 +215,25 @@ static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, /* return info on a pathname */ +static void nbench_qpathinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_fileinfo *info = req->async_states->private_data; + + nbench_log(nprivates, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", + info->generic.in.fname, + 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 smbsrv_request *req, union smb_fileinfo *info) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, qpathinfo, (ntvfs, req, info)); - - nbench_log(private, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", - info->generic.in.fname, - info->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, qpathinfo, info, (ntvfs, req, info)); return status; } @@ -186,38 +241,51 @@ static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, /* query info on a open file */ +static void nbench_qfileinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_fileinfo *info = req->async_states->private_data; + + nbench_log(nprivates, "QUERY_FILE_INFORMATION %d %d %s\n", + info->generic.in.fnum, + 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 smbsrv_request *req, union smb_fileinfo *info) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, qfileinfo, (ntvfs, req, info)); - - nbench_log(private, "QUERY_FILE_INFORMATION %d %d %s\n", - info->generic.in.fnum, - info->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, qfileinfo, info, (ntvfs, req, info)); return status; } - /* set info on a pathname */ +static void nbench_setpathinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_setfileinfo *st = req->async_states->private_data; + + nbench_log(nprivates, "SET_PATH_INFORMATION \"%s\" %d %s\n", + st->generic.file.fname, + 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 smbsrv_request *req, union smb_setfileinfo *st) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, setpathinfo, (ntvfs, req, st)); - - nbench_log(private, "SET_PATH_INFORMATION \"%s\" %d %s\n", - st->generic.file.fname, - st->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, setpathinfo, st, (ntvfs, req, st)); return status; } @@ -225,47 +293,58 @@ static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, /* open a file */ -static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) +static void nbench_open_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io)); - - DEBUG(0,("%d: %s\n", ntvfs->depth, get_nt_error_c_code(status))); + PASS_THRU_REP_PRE(req); + union smb_open *io = req->async_states->private_data; switch (io->generic.level) { case RAW_OPEN_NTCREATEX: - nbench_log(private, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", + nbench_log(nprivates, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", io->ntcreatex.in.fname, io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, io->ntcreatex.out.fnum, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Open-%d - NOT HANDLED\n", + nbench_log(nprivates, "Open-%d - NOT HANDLED\n", io->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); + return status; } /* create a directory */ +static void nbench_mkdir_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Mkdir - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_mkdir *md) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, mkdir, (ntvfs, req, md)); - - nbench_log(private, "Mkdir - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, mkdir, md, (ntvfs, req, md)); return status; } @@ -273,17 +352,24 @@ static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, /* remove a directory */ +static void nbench_rmdir_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_rmdir *rd = req->async_states->private_data; + + nbench_log(nprivates, "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 smbsrv_request *req, struct smb_rmdir *rd) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, rmdir, (ntvfs, req, rd)); - - nbench_log(private, "Rmdir \"%s\" %s\n", - rd->in.path, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, rmdir, rd, (ntvfs, req, rd)); return status; } @@ -291,43 +377,56 @@ static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, /* rename a set of files */ -static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) +static void nbench_rename_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, rename, (ntvfs, req, ren)); + PASS_THRU_REP_PRE(req); + union smb_rename *ren = req->async_states->private_data; switch (ren->generic.level) { case RAW_RENAME_RENAME: - nbench_log(private, "Rename \"%s\" \"%s\" %s\n", + nbench_log(nprivates, "Rename \"%s\" \"%s\" %s\n", ren->rename.in.pattern1, ren->rename.in.pattern2, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Rename-%d - NOT HANDLED\n", + nbench_log(nprivates, "Rename-%d - NOT HANDLED\n", ren->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Copy - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_copy *cp) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, copy, (ntvfs, req, cp)); - - nbench_log(private, "Copy - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, copy, cp, (ntvfs, req, cp)); return status; } @@ -335,83 +434,103 @@ static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, /* read from a file */ -static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) +static void nbench_read_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, read, (ntvfs, req, rd)); + PASS_THRU_REP_PRE(req); + union smb_read *rd = req->async_states->private_data; switch (rd->generic.level) { case RAW_READ_READX: - nbench_log(private, "ReadX %d %d %d %d %s\n", + nbench_log(nprivates, "ReadX %d %d %d %d %s\n", rd->readx.in.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, rd->readx.out.nread, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Read-%d - NOT HANDLED\n", + nbench_log(nprivates, "Read-%d - NOT HANDLED\n", rd->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_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 NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) +static void nbench_write_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, write, (ntvfs, req, wr)); + PASS_THRU_REP_PRE(req); + union smb_write *wr = req->async_states->private_data; switch (wr->generic.level) { case RAW_WRITE_WRITEX: - nbench_log(private, "WriteX %d %d %d %d %s\n", + nbench_log(nprivates, "WriteX %d %d %d %d %s\n", wr->writex.in.fnum, (int)wr->writex.in.offset, wr->writex.in.count, wr->writex.out.nwritten, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; case RAW_WRITE_WRITE: - nbench_log(private, "Write %d %d %d %d %s\n", + nbench_log(nprivates, "Write %d %d %d %d %s\n", wr->write.in.fnum, wr->write.in.offset, wr->write.in.count, wr->write.out.nwritten, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Write-%d - NOT HANDLED\n", + nbench_log(nprivates, "Write-%d - NOT HANDLED\n", wr->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Seek - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_seek *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, seek, (ntvfs, req, io)); - - nbench_log(private, "Seek - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, seek, io, (ntvfs, req, io)); return status; } @@ -419,17 +538,24 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, /* flush a file */ +static void nbench_flush_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_flush *io = req->async_states->private_data; + + nbench_log(nprivates, "Flush %d %s\n", + io->in.fnum, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_flush *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, flush, (ntvfs, req, io)); - - nbench_log(private, "Flush %d %s\n", - io->in.fnum, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, flush, io, (ntvfs, req, io)); return status; } @@ -437,39 +563,55 @@ static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, /* close a file */ -static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) +static void nbench_close_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, close, (ntvfs, req, io)); + PASS_THRU_REP_PRE(req); + union smb_close *io = req->async_states->private_data; switch (io->generic.level) { case RAW_CLOSE_CLOSE: - nbench_log(private, "Close %d %s\n", + nbench_log(nprivates, "Close %d %s\n", io->close.in.fnum, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Close-%d - NOT HANDLED\n", + nbench_log(nprivates, "Close-%d - NOT HANDLED\n", io->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Exit - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, exit, (ntvfs, req)); + PASS_THRU_REQ(ntvfs, req, exit, NULL, (ntvfs, req)); return status; } @@ -477,12 +619,21 @@ static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, /* logoff - closing files */ +static void nbench_logoff_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Logoff - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req)); + PASS_THRU_REQ(ntvfs, req, logoff, NULL, (ntvfs, req)); return status; } @@ -500,71 +651,91 @@ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, /* lock a byte range */ -static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) +static void nbench_lock_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, lock, (ntvfs, req, lck)); + PASS_THRU_REP_PRE(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(private, "LockX %d %d %d %s\n", + nbench_log(nprivates, "LockX %d %d %d %s\n", lck->lockx.in.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, - get_nt_error_c_code(status)); + 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(private, "UnlockX %d %d %d %s\n", + nbench_log(nprivates, "UnlockX %d %d %d %s\n", lck->lockx.in.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); } else { - nbench_log(private, "Lock-%d - NOT HANDLED\n", lck->generic.level); + nbench_log(nprivates, "Lock-%d - NOT HANDLED\n", lck->generic.level); } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_setfileinfo *info = req->async_states->private_data; + + nbench_log(nprivates, "SET_FILE_INFORMATION %d %d %s\n", + info->generic.file.fnum, + 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 smbsrv_request *req, union smb_setfileinfo *info) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, setfileinfo, (ntvfs, req, info)); - - nbench_log(private, "SET_FILE_INFORMATION %d %d %s\n", - info->generic.file.fnum, - info->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, setfileinfo, info, (ntvfs, req, info)); return status; } - /* return filesystem space info */ +static void nbench_fsinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_fsinfo *fs = req->async_states->private_data; + + nbench_log(nprivates, "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 smbsrv_request *req, union smb_fsinfo *fs) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, fsinfo, (ntvfs, req, fs)); - - nbench_log(private, "QUERY_FS_INFORMATION %d %s\n", - fs->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, fsinfo, fs, (ntvfs, req, fs)); return status; } @@ -572,15 +743,22 @@ static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, /* return print queue info */ +static void nbench_lpq_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_lpq *lpq = req->async_states->private_data; + + nbench_log(nprivates, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_lpq *lpq) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, lpq, (ntvfs, req, lpq)); - - nbench_log(private, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + PASS_THRU_REQ(ntvfs, req, lpq, lpq, (ntvfs, req, lpq)); return status; } @@ -588,74 +766,101 @@ static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, /* list files in a directory matching a wildcard pattern */ -static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) +static void nbench_search_first_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, search_first, (ntvfs, req, io, search_private, callback)); - + PASS_THRU_REP_PRE(req); + union smb_search_first *io = req->async_states->private_data; + switch (io->generic.level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: - nbench_log(private, "FIND_FIRST \"%s\" %d %d %d %s\n", + nbench_log(nprivates, "FIND_FIRST \"%s\" %d %d %d %s\n", io->t2ffirst.in.pattern, io->generic.level, io->t2ffirst.in.max_count, io->t2ffirst.out.count, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Search-%d - NOT HANDLED\n", io->generic.level); + nbench_log(nprivates, "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 smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, 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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_search_next *io = req->async_states->private_data; + + nbench_log(nprivates, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, search_next, (ntvfs, req, io, search_private, callback)); - - nbench_log(private, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + 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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_search_close *io = req->async_states->private_data; + + nbench_log(nprivates, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_search_close *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, search_close, (ntvfs, req, io)); - - nbench_log(private, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + 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 smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Trans - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans2) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, trans, (ntvfs, req, trans2)); - - nbench_log(private, "Trans - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, trans, trans2, (ntvfs, req, trans2)); return status; } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index c9fe276f54..04e9b871c7 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -134,12 +134,45 @@ struct ntvfs_context { struct ntvfs_module_context *modules; }; + +/* a set of flags to control handling of request structures */ +#define NTVFS_ASYNC_STATE_ASYNC (1<<1) /* the backend will answer this one later */ +#define NTVFS_ASYNC_STATE_MAY_ASYNC (1<<2) /* the backend is allowed to answer async */ + +/* the ntvfs_async_state structure allows backend functions to + delay replying to requests. To use this, the front end must + set send_fn to a function to be called by the backend + when the reply is finally ready to be sent. The backend + must set status to the status it wants in the + reply. The backend must set the NTVFS_ASYNC_STATE_ASYNC + control_flag on the request to indicate that it wishes to + delay the reply + + If NTVFS_ASYNC_STATE_MAY_ASYNC is not set then the backend cannot + ask for a delayed reply for this request + + note that the private_data pointer is private to the layer which alloced this struct +*/ +struct ntvfs_async_state { + struct ntvfs_async_state *prev, *next; + /* the async handling infos */ + unsigned state; + void *private_data; + void (*send_fn)(struct smbsrv_request *); + NTSTATUS status; + + /* the passthru module's per session private data */ + struct ntvfs_module_context *ntvfs; +}; + /* this structure is used by backends to determine the size of some critical types */ struct ntvfs_critical_sizes { int interface_version; + int sizeof_ntvfs_critical_sizes; int sizeof_ntvfs_context; int sizeof_ntvfs_module_context; int sizeof_ntvfs_ops; + int sizeof_ntvfs_async_state; int sizeof_smbsrv_tcon; int sizeof_smbsrv_request; }; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index acbd02d915..17900b3dfc 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -100,9 +100,11 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { static const struct ntvfs_critical_sizes critical_sizes = { NTVFS_INTERFACE_VERSION, + sizeof(struct ntvfs_critical_sizes), sizeof(struct ntvfs_context), sizeof(struct ntvfs_module_context), sizeof(struct ntvfs_ops), + sizeof(struct ntvfs_async_state), sizeof(struct smbsrv_tcon), sizeof(struct smbsrv_request), }; diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 452273cbdb..2639b5ae39 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -71,7 +71,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, /* must be synchronous, or we won't be called to do the translation */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; switch (io->generic.level) { case RAW_OPEN_GENERIC: @@ -692,7 +692,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf /* must be synchronous, or we won't be called to do the translation */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; status = ntvfs->ops->qpathinfo(ntvfs, req, info2); if (!NT_STATUS_IS_OK(status)) { @@ -768,7 +768,7 @@ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, wr2->generic.level = RAW_WRITE_GENERIC; /* we can't map asynchronously */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; switch (wr->generic.level) { case RAW_WRITE_WRITEX: @@ -874,7 +874,7 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, rd2->generic.level = RAW_READ_GENERIC; /* we can't map asynchronously */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; switch (rd->generic.level) { case RAW_READ_READX: diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 4036fb0935..929ec037de 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. NTVFS utility code - Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan Metzmacher 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 @@ -23,4 +23,40 @@ #include "includes.h" +NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, + void *private_data, + void (*send_fn)(struct smbsrv_request *), + struct ntvfs_module_context *ntvfs) +{ + struct ntvfs_async_state *async; + async = talloc_p(req, struct ntvfs_async_state); + if (!async) { + return NT_STATUS_NO_MEMORY; + } + + async->state = req->async_states->state; + async->private_data = private_data; + async->send_fn = send_fn; + async->status = NT_STATUS_INTERNAL_ERROR; + + async->ntvfs = ntvfs; + + DLIST_ADD(req->async_states, async); + + return NT_STATUS_OK; +} + +void ntvfs_async_state_pop(struct smbsrv_request *req) +{ + struct ntvfs_async_state *async; + + async = req->async_states; + + DLIST_REMOVE(req->async_states, async); + + req->async_states->state = async->state; + req->async_states->status = async->status; + + talloc_free(async); +} diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 4a4da34b60..3835c9319b 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -77,8 +77,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, locks[i].count); f->lock_count--; } - req->async.status = status; - req->async.send_fn(req); + req->async_states->status = status; + req->async_states->send_fn(req); } @@ -192,8 +192,8 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) } /* we've managed to get all the locks. Tell the client */ - req->async.status = NT_STATUS_OK; - req->async.send_fn(req); + req->async_states->status = NT_STATUS_OK; + req->async_states->send_fn(req); } @@ -217,8 +217,8 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) next = p->next; DLIST_REMOVE(f->pending_list, p); talloc_free(p->wait_handle); - p->req->async.status = NT_STATUS_RANGE_NOT_LOCKED; - p->req->async.send_fn(p->req); + p->req->async_states->status = NT_STATUS_RANGE_NOT_LOCKED; + p->req->async_states->send_fn(p->req); } } @@ -287,7 +287,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } if (lck->lockx.in.timeout != 0 && - (req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { pending = talloc_p(req, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 071ecbce15..2a8cbbbe0d 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -149,7 +149,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, /* tell the main smb server layer that we will be replying asynchronously */ - req->control_flags |= REQ_CONTROL_ASYNC; + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; /* make sure we cleanup the timer and message handler */ talloc_set_destructor(pwait, pvfs_wait_destructor); diff --git a/source4/smb_server/reply.c b/source4/smb_server/reply.c index fbf683e381..dd1df29573 100644 --- a/source4/smb_server/reply.c +++ b/source4/smb_server/reply.c @@ -34,10 +34,10 @@ return; \ }} while (0) -/* check req->async.status and if not OK then send an error reply */ +/* check req->async_states->status and if not OK then send an error reply */ #define CHECK_ASYNC_STATUS do { \ - if (!NT_STATUS_IS_OK(req->async.status)) { \ - req_reply_error(req, req->async.status); \ + if (!NT_STATUS_IS_OK(req->async_states->status)) { \ + req_reply_error(req, req->async_states->status); \ return; \ }} while (0) @@ -55,8 +55,8 @@ immediately */ #define REQ_ASYNC_TAIL do { \ - if (!(req->control_flags & REQ_CONTROL_ASYNC)) { \ - req->async.send_fn(req); \ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \ + req->async_states->send_fn(req); \ }} while (0) /* zero out some reserved fields in a reply */ @@ -206,7 +206,7 @@ void reply_unknown(struct smbsrv_request *req) ****************************************************************************/ static void reply_ioctl_send(struct smbsrv_request *req) { - union smb_ioctl *io = req->async.private; + union smb_ioctl *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -236,12 +236,12 @@ void reply_ioctl(struct smbsrv_request *req) io->ioctl.in.fnum = req_fnum(req, req->in.vwv, VWV(0)); io->ioctl.in.request = IVAL(req->in.vwv, VWV(1)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_ioctl_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_ioctl_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_ioctl(req, io); + req->async_states->status = ntvfs_ioctl(req, io); REQ_ASYNC_TAIL; } @@ -258,10 +258,10 @@ void reply_chkpth(struct smbsrv_request *req) req_pull_ascii4(req, &io->in.path, req->in.data, STR_TERMINATE); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; - req->async.status = ntvfs_chkpath(req, io); + req->async_states->status = ntvfs_chkpath(req, io); REQ_ASYNC_TAIL; } @@ -271,7 +271,7 @@ void reply_chkpth(struct smbsrv_request *req) ****************************************************************************/ static void reply_getatr_send(struct smbsrv_request *req) { - union smb_fileinfo *st = req->async.private; + union smb_fileinfo *st = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -306,12 +306,12 @@ void reply_getatr(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_getatr_send; - req->async.private = st; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_getatr_send; + req->async_states->private_data = st; /* call backend */ - req->async.status = ntvfs_qpathinfo(req, st); + req->async_states->status = ntvfs_qpathinfo(req, st); REQ_ASYNC_TAIL; } @@ -339,11 +339,11 @@ void reply_setatr(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_setpathinfo(req, st); + req->async_states->status = ntvfs_setpathinfo(req, st); REQ_ASYNC_TAIL; } @@ -354,7 +354,7 @@ void reply_setatr(struct smbsrv_request *req) ****************************************************************************/ static void reply_dskattr_send(struct smbsrv_request *req) { - union smb_fsinfo *fs = req->async.private; + union smb_fsinfo *fs = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -383,12 +383,12 @@ void reply_dskattr(struct smbsrv_request *req) fs->dskattr.level = RAW_QFS_DSKATTR; - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_dskattr_send; - req->async.private = fs; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_dskattr_send; + req->async_states->private_data = fs; /* call backend */ - req->async.status = ntvfs_fsinfo(req, fs); + req->async_states->status = ntvfs_fsinfo(req, fs); REQ_ASYNC_TAIL; } @@ -400,7 +400,7 @@ void reply_dskattr(struct smbsrv_request *req) ****************************************************************************/ static void reply_open_send(struct smbsrv_request *req) { - union smb_open *oi = req->async.private; + union smb_open *oi = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -438,12 +438,12 @@ void reply_open(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_open_send; - req->async.private = oi; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_open_send; + req->async_states->private_data = oi; /* call backend */ - req->async.status = ntvfs_open(req, oi); + req->async_states->status = ntvfs_open(req, oi); REQ_ASYNC_TAIL; } @@ -454,7 +454,7 @@ void reply_open(struct smbsrv_request *req) ****************************************************************************/ static void reply_open_and_X_send(struct smbsrv_request *req) { - union smb_open *oi = req->async.private; + union smb_open *oi = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -514,12 +514,12 @@ void reply_open_and_X(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_open_and_X_send; - req->async.private = oi; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_open_and_X_send; + req->async_states->private_data = oi; /* call the backend */ - req->async.status = ntvfs_open(req, oi); + req->async_states->status = ntvfs_open(req, oi); REQ_ASYNC_TAIL; } @@ -530,7 +530,7 @@ void reply_open_and_X(struct smbsrv_request *req) ****************************************************************************/ static void reply_mknew_send(struct smbsrv_request *req) { - union smb_open *oi = req->async.private; + union smb_open *oi = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -565,12 +565,12 @@ void reply_mknew(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_mknew_send; - req->async.private = oi; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_mknew_send; + req->async_states->private_data = oi; /* call the backend */ - req->async.status = ntvfs_open(req, oi); + req->async_states->status = ntvfs_open(req, oi); REQ_ASYNC_TAIL; } @@ -580,7 +580,7 @@ void reply_mknew(struct smbsrv_request *req) ****************************************************************************/ static void reply_ctemp_send(struct smbsrv_request *req) { - union smb_open *oi = req->async.private; + union smb_open *oi = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -619,12 +619,12 @@ void reply_ctemp(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_ctemp_send; - req->async.private = oi; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_ctemp_send; + req->async_states->private_data = oi; /* call the backend */ - req->async.status = ntvfs_open(req, oi); + req->async_states->status = ntvfs_open(req, oi); REQ_ASYNC_TAIL; } @@ -645,11 +645,11 @@ void reply_unlink(struct smbsrv_request *req) req_pull_ascii4(req, &unl->in.pattern, req->in.data, STR_TERMINATE); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_unlink(req, unl); + req->async_states->status = ntvfs_unlink(req, unl); REQ_ASYNC_TAIL; } @@ -724,7 +724,7 @@ failed: ****************************************************************************/ static void reply_lockread_send(struct smbsrv_request *req) { - union smb_read *io = req->async.private; + union smb_read *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -768,12 +768,12 @@ void reply_lockread(struct smbsrv_request *req) /* tell the backend where to put the data */ io->lockread.out.data = req->out.data + 3; - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_lockread_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_lockread_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_read(req, io); + req->async_states->status = ntvfs_read(req, io); REQ_ASYNC_TAIL; } @@ -785,7 +785,7 @@ void reply_lockread(struct smbsrv_request *req) ****************************************************************************/ static void reply_read_send(struct smbsrv_request *req) { - union smb_read *io = req->async.private; + union smb_read *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -827,12 +827,12 @@ void reply_read(struct smbsrv_request *req) /* tell the backend where to put the data */ io->read.out.data = req->out.data + 3; - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_read_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_read_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_read(req, io); + req->async_states->status = ntvfs_read(req, io); REQ_ASYNC_TAIL; } @@ -844,7 +844,7 @@ void reply_read(struct smbsrv_request *req) ****************************************************************************/ static void reply_read_and_X_send(struct smbsrv_request *req) { - union smb_read *io = req->async.private; + union smb_read *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -910,12 +910,12 @@ void reply_read_and_X(struct smbsrv_request *req) io->readx.out.data = req->out.data; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_read_and_X_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_read_and_X_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_read(req, io); + req->async_states->status = ntvfs_read(req, io); REQ_ASYNC_TAIL; } @@ -936,7 +936,7 @@ void reply_writebraw(struct smbsrv_request *req) ****************************************************************************/ static void reply_writeunlock_send(struct smbsrv_request *req) { - union smb_write *io = req->async.private; + union smb_write *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -977,12 +977,12 @@ void reply_writeunlock(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_writeunlock_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_writeunlock_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_write(req, io); + req->async_states->status = ntvfs_write(req, io); REQ_ASYNC_TAIL; } @@ -994,7 +994,7 @@ void reply_writeunlock(struct smbsrv_request *req) ****************************************************************************/ static void reply_write_send(struct smbsrv_request *req) { - union smb_write *io = req->async.private; + union smb_write *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1035,12 +1035,12 @@ void reply_write(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_write_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_write_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_write(req, io); + req->async_states->status = ntvfs_write(req, io); REQ_ASYNC_TAIL; } @@ -1051,7 +1051,7 @@ void reply_write(struct smbsrv_request *req) ****************************************************************************/ static void reply_write_and_X_send(struct smbsrv_request *req) { - union smb_write *io = req->async.private; + union smb_write *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1102,12 +1102,12 @@ void reply_write_and_X(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_write_and_X_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_write_and_X_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_write(req, io); + req->async_states->status = ntvfs_write(req, io); REQ_ASYNC_TAIL; } @@ -1118,7 +1118,7 @@ void reply_write_and_X(struct smbsrv_request *req) ****************************************************************************/ static void reply_lseek_send(struct smbsrv_request *req) { - struct smb_seek *io = req->async.private; + struct smb_seek *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1144,12 +1144,12 @@ void reply_lseek(struct smbsrv_request *req) io->in.mode = SVAL(req->in.vwv, VWV(1)); io->in.offset = IVALS(req->in.vwv, VWV(2)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_lseek_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_lseek_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_seek(req, io); + req->async_states->status = ntvfs_seek(req, io); REQ_ASYNC_TAIL; } @@ -1167,11 +1167,11 @@ void reply_flush(struct smbsrv_request *req) io->in.fnum = req_fnum(req, req->in.vwv, VWV(0)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_flush(req, io); + req->async_states->status = ntvfs_flush(req, io); REQ_ASYNC_TAIL; } @@ -1218,11 +1218,11 @@ void reply_close(struct smbsrv_request *req) io->close.in.fnum = req_fnum(req, req->in.vwv, VWV(0)); io->close.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_close(req, io); + req->async_states->status = ntvfs_close(req, io); REQ_ASYNC_TAIL; } @@ -1234,7 +1234,7 @@ void reply_close(struct smbsrv_request *req) ****************************************************************************/ static void reply_writeclose_send(struct smbsrv_request *req) { - union smb_write *io = req->async.private; + union smb_write *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1273,12 +1273,12 @@ void reply_writeclose(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_writeclose_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_writeclose_send; + req->async_states->private_data = io; /* call backend */ - req->async.status = ntvfs_write(req, io); + req->async_states->status = ntvfs_write(req, io); REQ_ASYNC_TAIL; } @@ -1299,11 +1299,11 @@ void reply_lock(struct smbsrv_request *req) lck->lock.in.count = IVAL(req->in.vwv, VWV(1)); lck->lock.in.offset = IVAL(req->in.vwv, VWV(3)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_lock(req, lck); + req->async_states->status = ntvfs_lock(req, lck); REQ_ASYNC_TAIL; } @@ -1325,11 +1325,11 @@ void reply_unlock(struct smbsrv_request *req) lck->unlock.in.count = IVAL(req->in.vwv, VWV(1)); lck->unlock.in.offset = IVAL(req->in.vwv, VWV(3)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_lock(req, lck); + req->async_states->status = ntvfs_lock(req, lck); REQ_ASYNC_TAIL; } @@ -1385,7 +1385,7 @@ void reply_echo(struct smbsrv_request *req) ****************************************************************************/ static void reply_printopen_send(struct smbsrv_request *req) { - union smb_open *oi = req->async.private; + union smb_open *oi = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1414,12 +1414,12 @@ void reply_printopen(struct smbsrv_request *req) req_pull_ascii4(req, &oi->splopen.in.ident, req->in.data, STR_TERMINATE); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_printopen_send; - req->async.private = oi; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_printopen_send; + req->async_states->private_data = oi; /* call backend */ - req->async.status = ntvfs_open(req, oi); + req->async_states->status = ntvfs_open(req, oi); REQ_ASYNC_TAIL; } @@ -1438,11 +1438,11 @@ void reply_printclose(struct smbsrv_request *req) io->splclose.level = RAW_CLOSE_SPLCLOSE; io->splclose.in.fnum = req_fnum(req, req->in.vwv, VWV(0)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_close(req, io); + req->async_states->status = ntvfs_close(req, io); REQ_ASYNC_TAIL; } @@ -1452,7 +1452,7 @@ void reply_printclose(struct smbsrv_request *req) ****************************************************************************/ void reply_printqueue_send(struct smbsrv_request *req) { - union smb_lpq *lpq = req->async.private; + union smb_lpq *lpq = req->async_states->private_data; int i, maxcount; const uint_t el_size = 28; @@ -1507,12 +1507,12 @@ void reply_printqueue(struct smbsrv_request *req) lpq->retq.in.maxcount = SVAL(req->in.vwv, VWV(0)); lpq->retq.in.startidx = SVAL(req->in.vwv, VWV(1)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_printqueue_send; - req->async.private = lpq; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_printqueue_send; + req->async_states->private_data = lpq; /* call backend */ - req->async.status = ntvfs_lpq(req, lpq); + req->async_states->status = ntvfs_lpq(req, lpq); REQ_ASYNC_TAIL; } @@ -1546,11 +1546,11 @@ void reply_printwrite(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_write(req, io); + req->async_states->status = ntvfs_write(req, io); REQ_ASYNC_TAIL; } @@ -1570,11 +1570,11 @@ void reply_mkdir(struct smbsrv_request *req) io->generic.level = RAW_MKDIR_MKDIR; req_pull_ascii4(req, &io->mkdir.in.path, req->in.data, STR_TERMINATE); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_mkdir(req, io); + req->async_states->status = ntvfs_mkdir(req, io); REQ_ASYNC_TAIL; } @@ -1593,11 +1593,11 @@ void reply_rmdir(struct smbsrv_request *req) req_pull_ascii4(req, &io->in.path, req->in.data, STR_TERMINATE); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_rmdir(req, io); + req->async_states->status = ntvfs_rmdir(req, io); REQ_ASYNC_TAIL; } @@ -1627,11 +1627,11 @@ void reply_mv(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_rename(req, io); + req->async_states->status = ntvfs_rename(req, io); REQ_ASYNC_TAIL; } @@ -1663,11 +1663,11 @@ void reply_ntrename(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_rename(req, io); + req->async_states->status = ntvfs_rename(req, io); REQ_ASYNC_TAIL; } @@ -1677,7 +1677,7 @@ void reply_ntrename(struct smbsrv_request *req) ****************************************************************************/ static void reply_copy_send(struct smbsrv_request *req) { - struct smb_copy *cp = req->async.private; + struct smb_copy *cp = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1714,12 +1714,12 @@ void reply_copy(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_copy_send; - req->async.private = cp; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_copy_send; + req->async_states->private_data = cp; /* call backend */ - req->async.status = ntvfs_copy(req, cp); + req->async_states->status = ntvfs_copy(req, cp); REQ_ASYNC_TAIL; } @@ -1729,7 +1729,7 @@ void reply_copy(struct smbsrv_request *req) ****************************************************************************/ static void reply_lockingX_send(struct smbsrv_request *req) { - union smb_lock *lck = req->async.private; + union smb_lock *lck = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1815,12 +1815,12 @@ void reply_lockingX(struct smbsrv_request *req) p += lck_size; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_lockingX_send; - req->async.private = lck; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_lockingX_send; + req->async_states->private_data = lck; /* call backend */ - req->async.status = ntvfs_lock(req, lck); + req->async_states->status = ntvfs_lock(req, lck); REQ_ASYNC_TAIL; } @@ -1852,11 +1852,11 @@ void reply_setattrE(struct smbsrv_request *req) info->setattre.in.access_time = srv_pull_dos_date2(req->smb_conn, req->in.vwv + VWV(3)); info->setattre.in.write_time = srv_pull_dos_date2(req->smb_conn, req->in.vwv + VWV(5)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_simple_send; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_simple_send; /* call backend */ - req->async.status = ntvfs_setfileinfo(req, info); + req->async_states->status = ntvfs_setfileinfo(req, info); REQ_ASYNC_TAIL; } @@ -1888,7 +1888,7 @@ void reply_writebs(struct smbsrv_request *req) ****************************************************************************/ static void reply_getattrE_send(struct smbsrv_request *req) { - union smb_fileinfo *info = req->async.private; + union smb_fileinfo *info = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -1919,12 +1919,12 @@ void reply_getattrE(struct smbsrv_request *req) info->getattr.level = RAW_FILEINFO_GETATTRE; info->getattr.in.fnum = req_fnum(req, req->in.vwv, VWV(0)); - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_getattrE_send; - req->async.private = info; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_getattrE_send; + req->async_states->private_data = info; /* call backend */ - req->async.status = ntvfs_qfileinfo(req, info); + req->async_states->status = ntvfs_qfileinfo(req, info); REQ_ASYNC_TAIL; } @@ -2224,7 +2224,7 @@ void reply_findnclose(struct smbsrv_request *req) ****************************************************************************/ static void reply_ntcreate_and_X_send(struct smbsrv_request *req) { - union smb_open *io = req->async.private; + union smb_open *io = req->async_states->private_data; CHECK_ASYNC_STATUS; @@ -2291,12 +2291,12 @@ void reply_ntcreate_and_X(struct smbsrv_request *req) return; } - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_ntcreate_and_X_send; - req->async.private = io; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_ntcreate_and_X_send; + req->async_states->private_data = io; /* call the backend */ - req->async.status = ntvfs_open(req, io); + req->async_states->status = ntvfs_open(req, io); REQ_ASYNC_TAIL; } diff --git a/source4/smb_server/request.c b/source4/smb_server/request.c index 3095d0b70c..34273a63a8 100644 --- a/source4/smb_server/request.c +++ b/source4/smb_server/request.c @@ -54,7 +54,14 @@ struct smbsrv_request *init_smb_request(struct smbsrv_connection *smb_conn) /* setup the request context */ req->smb_conn = smb_conn; - + + req->async_states = talloc_p(req, struct ntvfs_async_state); + if (!req->async_states) { + return NULL; + } + + ZERO_STRUCTP(req->async_states); + return req; } diff --git a/source4/smb_server/search.c b/source4/smb_server/search.c index fdfad5e182..b7b3d10ab6 100644 --- a/source4/smb_server/search.c +++ b/source4/smb_server/search.c @@ -26,8 +26,8 @@ /* check req->async.status and if not OK then send an error reply */ #define CHECK_ASYNC_STATUS do { \ - if (!NT_STATUS_IS_OK(req->async.status)) { \ - req_reply_error(req, req->async.status); \ + if (!NT_STATUS_IS_OK(req->async_states->status)) { \ + req_reply_error(req, req->async_states->status); \ return; \ }} while (0) @@ -37,8 +37,8 @@ immediately */ #define REQ_ASYNC_TAIL do { \ - if (!(req->control_flags & REQ_CONTROL_ASYNC)) { \ - req->async.send_fn(req); \ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \ + req->async_states->send_fn(req); \ }} while (0) /* useful wrapper for talloc with NO_MEMORY reply */ @@ -268,12 +268,12 @@ void reply_fclose(struct smbsrv_request *req) sc->fclose.in.id.client_cookie = IVAL(p, 17); /* do a search close operation */ - req->control_flags |= REQ_CONTROL_MAY_ASYNC; - req->async.send_fn = reply_fclose_send; - req->async.private = sc; + req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC; + req->async_states->send_fn = reply_fclose_send; + req->async_states->private_data = sc; /* call backend */ - req->async.status = ntvfs_search_close(req, sc); + req->async_states->status = ntvfs_search_close(req, sc); REQ_ASYNC_TAIL; } diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index ff83bfc80c..86a876554f 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -621,10 +621,10 @@ static void construct_reply(struct smbsrv_request *req) return; } - - req->smbpid = SVAL(req->in.hdr,HDR_PID); req->flags = CVAL(req->in.hdr, HDR_FLG); req->flags2 = SVAL(req->in.hdr, HDR_FLG2); + req->smbpid = SVAL(req->in.hdr,HDR_PID); + req->mid = SVAL(req->in.hdr,HDR_MID); if (!req_signing_check_incoming(req)) { req_reply_error(req, NT_STATUS_ACCESS_DENIED); @@ -694,8 +694,7 @@ void chain_reply(struct smbsrv_request *req) /* the current request in the chain might have used an async reply, but that doesn't mean the next element needs to */ - ZERO_STRUCT(req->async); - req->control_flags &= ~REQ_CONTROL_ASYNC; + ZERO_STRUCTP(req->async_states); switch_message(chain_cmd, req); return; diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 4de2aac907..065c01d6f5 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -71,6 +71,9 @@ struct smbsrv_tcon { char *dev_type; }; +/* a set of flags to control handling of request structures */ +#define REQ_CONTROL_LARGE (1<<1) /* allow replies larger than max_xmit */ + /* the context for a single SMB request. This is passed to any request-context functions */ struct smbsrv_request { @@ -86,6 +89,9 @@ struct smbsrv_request { /* the session context is derived from the vuid */ struct smbsrv_session *session; + /* the mid of this packet - used to match replies */ + uint16_t mid; + /* a set of flags to control usage of the request. See REQ_CONTROL_* */ unsigned control_flags; @@ -108,26 +114,8 @@ struct smbsrv_request { /* the sequence number for signing */ uint64_t seq_num; - /* the async structure allows backend functions to delay - replying to requests. To use this, the front end must set - async.send_fn to a function to be called by the backend - when the reply is finally ready to be sent. The backend - must set async.status to the status it wants in the - reply. The backend must set the REQ_CONTROL_ASYNC - control_flag on the request to indicate that it wishes to - delay the reply - - If REQ_CONTROL_MAY_ASYNC is not set then the backend cannot - ask for a delayed reply for this request - - note that the async.private pointer is private to the front - end not the backend. The backend must not change it. - */ - struct { - void (*send_fn)(struct smbsrv_request *); - void *private; - NTSTATUS status; - } async; + /* ntvfs per request async states */ + struct ntvfs_async_state *async_states; struct request_buffer in; struct request_buffer out; |