diff options
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 1 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_wait.c | 31 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 1 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 4 |
4 files changed, 36 insertions, 1 deletions
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8ad6ad0389..2c0f55cf22 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -556,7 +556,6 @@ static NTSTATUS pvfs_open_setup_retry(struct smbsrv_request *req, } talloc_free(lck); - talloc_steal(pvfs, req); talloc_set_destructor(r, pvfs_retry_destructor); diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 0faab8ef55..df7f045e00 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -22,10 +22,13 @@ #include "include/includes.h" #include "events.h" +#include "dlinklist.h" #include "vfs_posix.h" /* the context for a single wait instance */ struct pvfs_wait { + struct pvfs_wait *next, *prev; + struct pvfs_state *pvfs; void (*handler)(void *, BOOL); void *private; struct timed_event *te; @@ -103,6 +106,7 @@ static int pvfs_wait_destructor(void *ptr) struct pvfs_wait *pwait = ptr; messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); event_remove_timed(pwait->ev, pwait->te); + DLIST_REMOVE(pwait->pvfs->wait_list, pwait); return 0; } @@ -134,6 +138,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; pwait->req = req; + pwait->pvfs = pvfs; /* setup a timer */ te.next_event = end_time; @@ -152,8 +157,34 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, asynchronously */ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + DLIST_ADD(pvfs->wait_list, pwait); + /* make sure we cleanup the timer and message handler */ talloc_set_destructor(pwait, pvfs_wait_destructor); + /* make sure that on a disconnect the request is not destroyed + before pvfs */ + talloc_steal(pvfs, req); + return pwait; } + + +/* + cancel an outstanding async request +*/ +NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_wait *pwait; + for (pwait=pvfs->wait_list;pwait;pwait=pwait->next) { + if (SVAL(req->in.hdr, HDR_MID) == SVAL(pwait->req->in.hdr, HDR_MID) && + req->smbpid == pwait->req->smbpid) { + /* trigger an early timeout */ + pvfs_wait_timeout(pwait->ev, pwait->te, timeval_current()); + return NT_STATUS_OK; + } + } + + return NT_STATUS_UNSUCCESSFUL; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 7ebea2ea9a..9ad1d3cb35 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -236,6 +236,7 @@ NTSTATUS ntvfs_posix_init(void) ops.trans = pvfs_trans; ops.logoff = pvfs_logoff; ops.async_setup = pvfs_async_setup; + ops.cancel = pvfs_cancel; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 265649f5a3..ce6e7ad24d 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -46,6 +46,10 @@ struct pvfs_state { /* an id tree mapping open file handle -> struct pvfs_file */ struct idr_context *idtree_fnum; + + /* a list of pending async requests. Needed to support + ntcancel */ + struct pvfs_wait *wait_list; }; |