diff options
-rw-r--r-- | source4/ntvfs/cifs/vfs_cifs.c | 11 | ||||
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 11 | ||||
-rw-r--r-- | source4/ntvfs/nbench/vfs_nbench.c | 11 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs.h | 6 | ||||
-rw-r--r-- | source4/ntvfs/ntvfs_interface.c | 22 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_wait.c | 36 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 1 | ||||
-rw-r--r-- | source4/ntvfs/simple/vfs_simple.c | 11 | ||||
-rw-r--r-- | source4/ntvfs/unixuid/vfs_unixuid.c | 15 |
9 files changed, 120 insertions, 4 deletions
diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 7c4a1d79d6..5b10e72411 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -564,6 +564,16 @@ static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, } /* + setup for an async call - nothing to do yet +*/ +static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* lock a byte range */ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, @@ -748,6 +758,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.search_close = cvfs_search_close; ops.trans = cvfs_trans; ops.logoff = cvfs_logoff; + ops.async_setup = cvfs_async_setup; if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { ops.trans2 = cvfs_trans2; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 69fed6f86f..b37b3e917d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -572,6 +572,16 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, } /* + setup for an async call +*/ +static NTSTATUS ipc_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* lock a byte range */ static NTSTATUS ipc_lock(struct ntvfs_module_context *ntvfs, @@ -795,6 +805,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.search_close = ipc_search_close; ops.trans = ipc_trans; ops.logoff = ipc_logoff; + ops.async_setup = ipc_async_setup; /* register ourselves with the NTVFS subsystem. */ ret = register_backend("ntvfs", &ops); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 06c237afb5..6203c21506 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -490,6 +490,16 @@ static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, } /* + async setup +*/ +static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* lock a byte range */ static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, @@ -695,6 +705,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.search_close = nbench_search_close; ops.trans = nbench_trans; ops.logoff = nbench_logoff; + ops.async_setup = nbench_async_setup; /* we don't register a trans2 handler as we want to be able to log individual trans2 requests */ diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index bee10e3c38..c9fe276f54 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -112,7 +112,11 @@ struct ntvfs_ops { /* logoff - called when a vuid is closed */ NTSTATUS (*logoff)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req); + struct smbsrv_request *req); + + /* async_setup - called when a backend is processing a async request */ + NTSTATUS (*async_setup)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, void *private); }; struct ntvfs_module_context { diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 06cda11000..7ba1c0d6be 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -293,6 +293,17 @@ NTSTATUS ntvfs_logoff(struct smbsrv_request *req) return ntvfs->ops->logoff(ntvfs, req); } +/* async setup - called by a backend that wants to setup any state for + a async request */ +NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->async_setup) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->async_setup(ntvfs, req, private); +} + /* initial setup */ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) @@ -564,3 +575,14 @@ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, } return ntvfs->next->ops->logoff(ntvfs->next, req); } + +/* async_setup - called when setting up for a async request */ +NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + if (!ntvfs->next || !ntvfs->next->ops->async_setup) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->async_setup(ntvfs->next, req, private); +} diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 5815b8edde..2a4a1d286b 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -31,8 +31,22 @@ struct pvfs_wait { int msg_type; void *msg_ctx; struct event_context *ev; + struct smbsrv_request *req; + BOOL timed_out; }; +/* + called from the ntvfs layer when we have requested setup of an async + call. this ensures that async calls runs with the right state of + previous ntvfs handlers in the chain (such as security context) +*/ +NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, void *private) +{ + struct pvfs_wait *pwait = private; + pwait->handler(pwait->private, pwait->timed_out); + return NT_STATUS_OK; +} /* receive a completion message for a wait @@ -41,6 +55,7 @@ static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, servid_t src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; + struct smbsrv_request *req; /* we need to check that this one is for us. This sender sends the private pointer as the body of the message. This might @@ -50,8 +65,16 @@ static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, *(void **)data->data != pwait->private) { return; } - - pwait->handler(pwait->private, False); + pwait->timed_out = False; + req = pwait->req; + + /* the extra reference here is to ensure that the req + structure is not destroyed when the async request reply is + sent, which would cause problems with the other ntvfs + modules above us */ + talloc_increase_ref_count(req); + ntvfs_async_setup(pwait->req, pwait); + talloc_free(req); } @@ -61,7 +84,13 @@ static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, time_t t) { struct pvfs_wait *pwait = te->private; - pwait->handler(pwait->private, True); + struct smbsrv_request *req = pwait->req; + + pwait->timed_out = True; + + talloc_increase_ref_count(req); + ntvfs_async_setup(pwait->req, pwait); + talloc_free(req); } @@ -103,6 +132,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx; pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; + pwait->req = req; /* setup a timer */ te.next_event = end_time; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 6e6c8b4275..e989f8de67 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -237,6 +237,7 @@ NTSTATUS ntvfs_posix_init(void) ops.search_close = pvfs_search_close; ops.trans = pvfs_trans; ops.logoff = pvfs_logoff; + ops.async_setup = pvfs_async_setup; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 7f5d447a09..7ebc040608 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -623,6 +623,16 @@ static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, } /* + setup for an async call +*/ +static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* lock a byte range */ static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, @@ -999,6 +1009,7 @@ NTSTATUS ntvfs_simple_init(void) ops.search_close = svfs_search_close; ops.trans = svfs_trans; ops.logoff = svfs_logoff; + ops.async_setup = svfs_async_setup; /* register ourselves with the NTVFS subsystem. We register under names 'simple' diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 542b011c67..d0060bf11d 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -625,6 +625,20 @@ static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, } /* + async setup +*/ +static NTSTATUS unixuid_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, async_setup, (ntvfs, req, private)); + + return status; +} + +/* lock a byte range */ static NTSTATUS unixuid_lock(struct ntvfs_module_context *ntvfs, @@ -767,6 +781,7 @@ NTSTATUS ntvfs_unixuid_init(void) ops.search_close = unixuid_search_close; ops.trans = unixuid_trans; ops.logoff = unixuid_logoff; + ops.async_setup = unixuid_async_setup; ops.name = "unixuid"; |