r23792: convert Samba4 to GPLv3
[tprouty/samba.git] / source4 / ntvfs / posix / pvfs_lock.c
index 4dbb13cb429c0b378462cc95ca8783c8b2b22675..bf17ceb83b5e2a6602da52418e7ae0531c08d1ff 100644 (file)
@@ -7,7 +7,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "vfs_posix.h"
 #include "system/time.h"
-#include "dlinklist.h"
+#include "lib/util/dlinklist.h"
 #include "messaging/messaging.h"
 
 
@@ -41,8 +40,7 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs,
        }
 
        return brl_locktest(pvfs->brl_context,
-                           &f->handle->brl_locking_key,
-                           f->fnum,
+                           f->brl_handle,
                            smbpid,
                            offset, count, rw);
 }
@@ -70,12 +68,16 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs,
                                   int i,
                                   NTSTATUS status)
 {
+       /* in SMB2 mode we also try to unlock failing lock */ 
+       if (req->ctx->protocol != PROTOCOL_SMB2) {
+               i--;
+       }
+
        /* undo the locks we just did */
-       for (i=i-1;i>=0;i--) {
+       for (;i>=0;i--) {
                brl_unlock(pvfs->brl_context,
-                          &f->handle->brl_locking_key,
+                          f->brl_handle,
                           locks[i].pid,
-                          f->fnum,
                           locks[i].offset,
                           locks[i].count);
                f->lock_count--;
@@ -87,7 +89,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs,
 
 /*
   called when we receive a pending lock notification. It means that
-  either our lock timed out or somoene else has unlocked a overlapping
+  either our lock timed out or someone else has unlocked a overlapping
   range, so we should try the lock again. Note that on timeout we
   do retry the lock, giving it a last chance.
 */
@@ -120,13 +122,17 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas
        if (reason == PVFS_WAIT_CANCEL) {
                status = NT_STATUS_FILE_LOCK_CONFLICT;
        } else {
+               /* 
+                * here it's important to pass the pending pointer
+                * because with this we'll get the correct error code
+                * FILE_LOCK_CONFLICT in the error case
+                */
                status = brl_lock(pvfs->brl_context,
-                                 &f->handle->brl_locking_key,
-                                 req->smbpid,
-                                 f->fnum,
+                                 f->brl_handle,
+                                 locks[pending->pending_lock].pid,
                                  locks[pending->pending_lock].offset,
                                  locks[pending->pending_lock].count,
-                                 rw, NULL);
+                                 rw, pending);
        }
        if (NT_STATUS_IS_OK(status)) {
                f->lock_count++;
@@ -138,7 +144,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas
        if (NT_STATUS_IS_OK(status) || timed_out) {
                NTSTATUS status2;
                status2 = brl_remove_pending(pvfs->brl_context, 
-                                            &f->handle->brl_locking_key, pending);
+                                            f->brl_handle, pending);
                if (!NT_STATUS_IS_OK(status2)) {
                        DEBUG(0,("pvfs_lock: failed to remove pending lock - %s\n", nt_errstr(status2)));
                }
@@ -171,9 +177,8 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas
                }
 
                status = brl_lock(pvfs->brl_context,
-                                 &f->handle->brl_locking_key,
-                                 req->smbpid,
-                                 f->fnum,
+                                 f->brl_handle,
+                                 locks[i].pid,
                                  locks[i].offset,
                                  locks[i].count,
                                  rw, pending);
@@ -216,7 +221,7 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f)
        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->handle->brl_locking_key, f->fnum);
+               brl_close(f->pvfs->brl_context, f->brl_handle);
                f->lock_count = 0;
        }
 
@@ -243,7 +248,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request *
                /* check if the lock request matches exactly - you can only cancel with exact matches */
                if (p->lck->lockx.in.ulock_cnt == lck->lockx.in.ulock_cnt &&
                    p->lck->lockx.in.lock_cnt  == lck->lockx.in.lock_cnt &&
-                   p->lck->lockx.in.file.fnum == lck->lockx.in.file.fnum &&
+                   p->lck->lockx.in.file.ntvfs== lck->lockx.in.file.ntvfs &&
                    p->lck->lockx.in.mode      == (lck->lockx.in.mode & ~LOCKING_ANDX_CANCEL_LOCK)) {
                        int i;
 
@@ -258,7 +263,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request *
 
                        /* an exact match! we can cancel it, which is equivalent
                           to triggering the timeout early */
-                       pvfs_pending_lock_continue(p ,True);
+                       pvfs_pending_lock_continue(p, PVFS_WAIT_TIMEOUT);
                        return NT_STATUS_OK;
                }
        }
@@ -285,7 +290,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
                return ntvfs_map_lock(ntvfs, req, lck);
        }
 
-       f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.fnum);
+       f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs);
        if (!f) {
                return NT_STATUS_INVALID_HANDLE;
        }
@@ -338,9 +343,8 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
 
        for (i=0;i<lck->lockx.in.ulock_cnt;i++) {
                status = brl_unlock(pvfs->brl_context,
-                                   &f->handle->brl_locking_key,
+                                   f->brl_handle,
                                    locks[i].pid,
-                                   f->fnum,
                                    locks[i].offset,
                                    locks[i].count);
                if (!NT_STATUS_IS_OK(status)) {
@@ -357,9 +361,8 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
                }
 
                status = brl_lock(pvfs->brl_context,
-                                 &f->handle->brl_locking_key,
+                                 f->brl_handle,
                                  locks[i].pid,
-                                 f->fnum,
                                  locks[i].offset,
                                  locks[i].count,
                                  rw, pending);
@@ -378,12 +381,15 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
                                DLIST_ADD(f->pending_list, pending);
                                return NT_STATUS_OK;
                        }
+                       /* in SMB2 mode we also try to unlock failing lock */ 
+                       if (req->ctx->protocol != PROTOCOL_SMB2) {
+                               i--;
+                       }
                        /* undo the locks we just did */
-                       for (i=i-1;i>=0;i--) {
+                       for (;i>=0;i--) {
                                brl_unlock(pvfs->brl_context,
-                                          &f->handle->brl_locking_key,
+                                          f->brl_handle,
                                           locks[i].pid,
-                                          f->fnum,
                                           locks[i].offset,
                                           locks[i].count);
                                f->lock_count--;
@@ -395,4 +401,3 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs,
 
        return NT_STATUS_OK;
 }
-