summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix/pvfs_lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix/pvfs_lock.c')
-rw-r--r--source4/ntvfs/posix/pvfs_lock.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c
index e32fcb2e3a..f52e68eeb1 100644
--- a/source4/ntvfs/posix/pvfs_lock.c
+++ b/source4/ntvfs/posix/pvfs_lock.c
@@ -75,6 +75,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs,
f->fnum,
locks[i].offset,
locks[i].count);
+ f->lock_count--;
}
req->async.status = status;
req->async.send_fn(req);
@@ -117,6 +118,10 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out)
locks[pending->pending_lock].count,
rw, NULL);
+ if (NT_STATUS_IS_OK(status)) {
+ f->lock_count++;
+ }
+
/* if we have failed and timed out, or succeeded, then we
don't need the pending lock any more */
if (NT_STATUS_IS_OK(status) || timed_out) {
@@ -182,6 +187,8 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out)
pvfs_lock_async_failed(pvfs, req, f, locks, i, status);
return;
}
+
+ f->lock_count++;
}
/* we've managed to get all the locks. Tell the client */
@@ -191,26 +198,28 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out)
/*
- called when we close a file that might have pending locks
+ called when we close a file that might have locks
*/
-void pvfs_lock_close_pending(struct pvfs_state *pvfs, struct pvfs_file *f)
+void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f)
{
struct pvfs_pending_lock *p, *next;
- NTSTATUS status;
+ if (f->lock_count || f->pending_list) {
+ DEBUG(5,("pvfs_lock: removing %.0f locks on close\n",
+ (double)f->lock_count));
+ brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum);
+ f->lock_count = 0;
+ }
+
+ /* reply to all the pending lock requests, telling them the
+ lock failed */
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);
}
-
}
@@ -262,6 +271,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
int i;
enum brl_type rw;
struct pvfs_pending_lock *pending = NULL;
+ NTSTATUS status;
f = pvfs_find_fd(pvfs, req, lck->generic.in.fnum);
if (!f) {
@@ -270,21 +280,29 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
switch (lck->generic.level) {
case RAW_LOCK_LOCK:
- return brl_lock(pvfs->brl_context,
- &f->locking_key,
- req->smbpid,
- f->fnum,
- lck->lock.in.offset,
- lck->lock.in.count,
- WRITE_LOCK, NULL);
-
- case RAW_LOCK_UNLOCK:
- return brl_unlock(pvfs->brl_context,
+ status = brl_lock(pvfs->brl_context,
&f->locking_key,
req->smbpid,
f->fnum,
lck->lock.in.offset,
- lck->lock.in.count);
+ lck->lock.in.count,
+ WRITE_LOCK, NULL);
+ if (NT_STATUS_IS_OK(status)) {
+ f->lock_count++;
+ }
+ return status;
+
+ case RAW_LOCK_UNLOCK:
+ status = brl_unlock(pvfs->brl_context,
+ &f->locking_key,
+ req->smbpid,
+ f->fnum,
+ lck->lock.in.offset,
+ lck->lock.in.count);
+ if (NT_STATUS_IS_OK(status)) {
+ f->lock_count--;
+ }
+ return status;
case RAW_LOCK_GENERIC:
return NT_STATUS_INVALID_LEVEL;
@@ -337,7 +355,6 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
locks = lck->lockx.in.locks;
for (i=0;i<lck->lockx.in.ulock_cnt;i++) {
- NTSTATUS status;
status = brl_unlock(pvfs->brl_context,
&f->locking_key,
locks[i].pid,
@@ -347,13 +364,12 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+ f->lock_count--;
}
locks += i;
for (i=0;i<lck->lockx.in.lock_cnt;i++) {
- NTSTATUS status;
-
if (pending) {
pending->pending_lock = i;
}
@@ -387,9 +403,11 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
f->fnum,
locks[i].offset,
locks[i].count);
+ f->lock_count--;
}
return status;
}
+ f->lock_count++;
}
return NT_STATUS_OK;