summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c6
-rw-r--r--source4/ntvfs/posix/pvfs_open.c10
-rw-r--r--source4/ntvfs/posix/pvfs_wait.c19
-rw-r--r--source4/ntvfs/posix/vfs_posix.h13
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_ */