summaryrefslogtreecommitdiff
path: root/source4/ntvfs
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs')
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c46
-rw-r--r--source4/ntvfs/posix/pvfs_open.c4
-rw-r--r--source4/ntvfs/posix/pvfs_wait.c2
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;
}