diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-11-05 02:22:07 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:05:30 -0500 |
commit | 1d97e7b9d8a8e716cd50bb42065687a65d542b2d (patch) | |
tree | 4cb4743b53cbb51dd2f01bf032cd53cba2006b61 /source4/ntvfs/posix | |
parent | 80eef3ea6647a9f8600466b2b468d38bd2eb0664 (diff) | |
download | samba-1d97e7b9d8a8e716cd50bb42065687a65d542b2d.tar.gz samba-1d97e7b9d8a8e716cd50bb42065687a65d542b2d.tar.bz2 samba-1d97e7b9d8a8e716cd50bb42065687a65d542b2d.zip |
r3540: added testing of SMBntcancel in the open/open/close mux
testing. Interestingly, w2k3 does not allow the cancel of an
outstanding async open request, whereas it does allow the cancel of an
outstanding async lock request. To support this I have changed the
pvfs_wait interface to provide a enum on why the event is happening,
so the callback can decide what to do.
(This used to be commit f23d6a28008a13588cde24b5012ec21e488ac47a)
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r-- | source4/ntvfs/posix/pvfs_lock.c | 6 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 10 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_wait.c | 19 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 13 |
4 files changed, 36 insertions, 12 deletions
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 82ac9ebad5..f778b59d95 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -91,7 +91,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, range, so we should try the lock again. Note that on timeout we do retry the lock, giving it a last chance. */ -static void pvfs_pending_lock_continue(void *private, BOOL timed_out) +static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reason) { struct pvfs_pending_lock *pending = private; struct pvfs_state *pvfs = pending->pvfs; @@ -102,6 +102,10 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) enum brl_type rw; NTSTATUS status; int i; + BOOL timed_out; + + /* we consider a cancel to be a timeout */ + timed_out = (reason != PVFS_WAIT_EVENT); locks = lck->lockx.in.locks + lck->lockx.in.ulock_cnt; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 73b1949acb..c8f96849ec 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -430,7 +430,7 @@ static int pvfs_retry_destructor(void *ptr) /* retry an open */ -static void pvfs_open_retry(void *private, BOOL timed_out) +static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) { struct pvfs_open_retry *r = private; struct ntvfs_module_context *ntvfs = r->ntvfs; @@ -438,9 +438,15 @@ static void pvfs_open_retry(void *private, BOOL timed_out) union smb_open *io = r->io; NTSTATUS status; + /* w2k3 ignores SMBntcancel for outstanding open requests. It's probably + just a bug in their server, but we better do the same */ + if (reason == PVFS_WAIT_CANCEL) { + return; + } + talloc_free(r->wait_handle); - if (timed_out) { + if (reason == PVFS_WAIT_TIMEOUT) { /* if it timed out, then give the failure immediately */ talloc_free(r); diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index df7f045e00..dd7afaf653 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -29,14 +29,14 @@ struct pvfs_wait { struct pvfs_wait *next, *prev; struct pvfs_state *pvfs; - void (*handler)(void *, BOOL); + void (*handler)(void *, enum pvfs_wait_notice); void *private; struct timed_event *te; int msg_type; struct messaging_context *msg_ctx; struct event_context *ev; struct smbsrv_request *req; - BOOL timed_out; + enum pvfs_wait_notice reason; }; /* @@ -48,7 +48,7 @@ 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); + pwait->handler(pwait->private, pwait->reason); return NT_STATUS_OK; } @@ -68,7 +68,7 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin *(void **)data->data != pwait->private) { return; } - pwait->timed_out = False; + pwait->reason = PVFS_WAIT_EVENT; req = pwait->req; /* the extra reference here is to ensure that the req @@ -90,7 +90,7 @@ static void pvfs_wait_timeout(struct event_context *ev, struct pvfs_wait *pwait = te->private; struct smbsrv_request *req = pwait->req; - pwait->timed_out = True; + pwait->reason = PVFS_WAIT_TIMEOUT; talloc_increase_ref_count(req); ntvfs_async_setup(pwait->req, pwait); @@ -117,11 +117,11 @@ static int pvfs_wait_destructor(void *ptr) the return value is a handle. To stop waiting talloc_free this handle. */ -void *pvfs_wait_message(struct pvfs_state *pvfs, + void *pvfs_wait_message(struct pvfs_state *pvfs, struct smbsrv_request *req, int msg_type, struct timeval end_time, - void (*fn)(void *, BOOL), + void (*fn)(void *, enum pvfs_wait_notice), void *private) { struct timed_event te; @@ -180,8 +180,9 @@ NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request * 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()); + /* trigger a cancel on the request */ + pwait->reason = PVFS_WAIT_CANCEL; + ntvfs_async_setup(pwait->req, pwait); return NT_STATUS_OK; } } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index e0d8e7fe37..4ee06723ac 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -165,4 +165,17 @@ struct pvfs_mangle_context { /* forward declare some anonymous structures */ struct pvfs_dir; +/* types of notification for pvfs wait events */ +enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; + + +/* putting this prototype here avoids us having to expose this whole header in the + rest of Samba */ +void *pvfs_wait_message(struct pvfs_state *pvfs, + struct smbsrv_request *req, + int msg_type, + struct timeval end_time, + void (*fn)(void *, enum pvfs_wait_notice), + void *private); + #endif /* _VFS_POSIX_H_ */ |