summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_wait.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix/pvfs_wait.c')
-rw-r--r--source4/ntvfs/posix/pvfs_wait.c36
1 files changed, 33 insertions, 3 deletions
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;