summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ntvfs/cifs/vfs_cifs.c11
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c11
-rw-r--r--source4/ntvfs/nbench/vfs_nbench.c11
-rw-r--r--source4/ntvfs/ntvfs.h6
-rw-r--r--source4/ntvfs/ntvfs_interface.c22
-rw-r--r--source4/ntvfs/posix/pvfs_wait.c36
-rw-r--r--source4/ntvfs/posix/vfs_posix.c1
-rw-r--r--source4/ntvfs/simple/vfs_simple.c11
-rw-r--r--source4/ntvfs/unixuid/vfs_unixuid.c15
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";