diff options
Diffstat (limited to 'source4/ntvfs')
-rw-r--r-- | source4/ntvfs/posix/pvfs_lock.c | 46 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_open.c | 4 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_wait.c | 2 |
3 files changed, 38 insertions, 14 deletions
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 100fc50e55..ead1371ebc 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -152,7 +152,7 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) /* we've now got the pending lock. try and get the rest, which might lead to more pending locks */ - for (i=pending->pending_lock;i<lck->lockx.in.lock_cnt;i++) { + for (i=pending->pending_lock+1;i<lck->lockx.in.lock_cnt;i++) { if (pending) { pending->pending_lock = i; } @@ -184,13 +184,6 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) } } - brl_unlock(pvfs->brl_context, - &f->locking_key, - req->smbpid, - f->fnum, - lck->lock.in.offset, - lck->lock.in.count); - /* we've managed to get all the locks. Tell the client */ req->async.status = NT_STATUS_OK; req->async.send_fn(req); @@ -198,6 +191,30 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) /* + called when we close a file that might have pending locks +*/ +void pvfs_lock_close_pending(struct pvfs_state *pvfs, struct pvfs_file *f) +{ + struct pvfs_pending_lock *p, *next; + NTSTATUS status; + + for (p=f->pending_list;p;p=next) { + next = p->next; + DLIST_REMOVE(f->pending_list, p); + status = brl_remove_pending(pvfs->brl_context, &f->locking_key, p); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("pvfs_lock_close_pending: failed to remove pending lock - %s\n", + nt_errstr(status))); + } + talloc_free(p->wait_handle); + p->req->async.status = NT_STATUS_RANGE_NOT_LOCKED; + p->req->async.send_fn(p->req); + } + +} + + +/* cancel a set of locks */ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct smbsrv_request *req, union smb_lock *lck, @@ -303,11 +320,14 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return pvfs_lock_cancel(pvfs, req, lck, f); } - if (lck->lockx.in.mode & - (LOCKING_ANDX_OPLOCK_RELEASE | - LOCKING_ANDX_CHANGE_LOCKTYPE | - LOCKING_ANDX_CANCEL_LOCK)) { - /* todo: need to add support for these */ + if (lck->lockx.in.mode & LOCKING_ANDX_CHANGE_LOCKTYPE) { + /* this seems to not be supported by any windows server, + or used by any clients */ + return NT_STATUS_UNSUCCESSFUL; + } + + if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) { + DEBUG(0,("received unexpected oplock break\n")); return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 05c2bdda28..429f519bca 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -52,6 +52,8 @@ static int pvfs_fd_destructor(void *p) { struct pvfs_file *f = p; + pvfs_lock_close_pending(f->pvfs, f); + brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum); if (f->fd != -1) { @@ -221,6 +223,8 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } + pvfs_lock_close_pending(pvfs, f); + status = brl_close(pvfs->brl_context, &f->locking_key, f->fnum); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 1d6da6aaf8..5815b8edde 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -71,7 +71,7 @@ static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, static int pvfs_wait_destructor(void *ptr) { struct pvfs_wait *pwait = ptr; - messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait->private); + messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); event_remove_timed(pwait->ev, pwait->te); return 0; } |