diff options
author | Andrew Tridgell <tridge@samba.org> | 2006-03-08 05:46:09 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:52:36 -0500 |
commit | 6ec250f55d7b7d9c899d3c3777666a96bf8ea06c (patch) | |
tree | c7a9241c0389c976f9f5180ac278581259cf9ffb /source/ntvfs/cifs | |
parent | 0ad70bfd83b4a03c0e67f11f63822b833be67aa1 (diff) | |
download | samba-6ec250f55d7b7d9c899d3c3777666a96bf8ea06c.tar.gz |
r14012: added support for the SMBntcancel operation in the cifs ntvfs
backend. This requires keeping a list of outstanding requests so the
MID can be matched. Use a talloc destructor to manage the list.
Diffstat (limited to 'source/ntvfs/cifs')
-rw-r--r-- | source/ntvfs/cifs/vfs_cifs.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/source/ntvfs/cifs/vfs_cifs.c b/source/ntvfs/cifs/vfs_cifs.c index 44d4d069e8f..5bac39f3a77 100644 --- a/source/ntvfs/cifs/vfs_cifs.c +++ b/source/ntvfs/cifs/vfs_cifs.c @@ -32,19 +32,24 @@ #include "smbd/service_stream.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" +#include "include/dlinklist.h" /* this is stored in ntvfs_private */ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; struct smbsrv_tcon *tcon; + struct async_info *pending; BOOL map_generic; }; /* a structure used to pass information to an async handler */ struct async_info { + struct async_info *next, *prev; + struct cvfs_private *cvfs; struct smbsrv_request *req; + struct smbcli_request *c_req; void *parms; }; @@ -93,11 +98,10 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, machine_account = lp_parm_bool(req->tcon->service, "cifs", "use_machine_account", False); - private = talloc(ntvfs, struct cvfs_private); + private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(private); ntvfs->private_data = private; @@ -184,6 +188,16 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs, } /* + destroy an async info structure +*/ +static int async_info_destructor(void *p) +{ + struct async_info *async = talloc_get_type(p, struct async_info); + DLIST_REMOVE(async->cvfs->pending, async); + return 0; +} + +/* a handler for simple async replies this handler can only be used for functions that don't return any parameters (those that just return a status code) @@ -206,7 +220,11 @@ static void async_simple(struct smbcli_request *c_req) if (!async) return NT_STATUS_NO_MEMORY; \ async->parms = io; \ async->req = req; \ + async->cvfs = private; \ + async->c_req = c_req; \ + DLIST_ADD(private->pending, async); \ c_req->async.private = async; \ + talloc_set_destructor(async, async_info_destructor); \ } \ c_req->async.fn = async_fn; \ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ @@ -673,7 +691,21 @@ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { - return NT_STATUS_NOT_IMPLEMENTED; + struct cvfs_private *private = ntvfs->private_data; + + /* find the matching request */ + struct async_info *a; + for (a=private->pending;a;a=a->next) { + if (SVAL(a->req->in.hdr, HDR_MID) == SVAL(req->in.hdr, HDR_MID)) { + break; + } + } + + if (a == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return smb_raw_ntcancel(a->c_req); } /* |