Removed "ole locking compat" parameter (no longer used).
authorJeremy Allison <jra@samba.org>
Wed, 12 Apr 2000 23:01:11 +0000 (23:01 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 12 Apr 2000 23:01:11 +0000 (23:01 +0000)
We now get/set/check POSIX locks, but I still need to code up the
close fd braindamage...
Jeremy.

source/lib/util.c
source/locking/locking.c
source/param/loadparm.c

index 8c5ea1d208cb5a72e42d570532b7f30b04c0aedb..c78c839325bb3d6cb459614b9e7a7fe9fd4c3a2f 100644 (file)
@@ -2400,6 +2400,7 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 #if HAVE_FCNTL_LOCK
   SMB_STRUCT_FLOCK lock;
   int ret;
+
 #if defined(LARGE_SMB_OFF_T)
   /*
    * In the 64 bit locking case we store the original
@@ -2410,40 +2411,6 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
   SMB_OFF_T orig_count = count;
 #endif /* LARGE_SMB_OFF_T */
 
-  if(lp_ole_locking_compat()) {
-    SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
-    SMB_OFF_T mask = (mask2<<2);
-
-    /* make sure the count is reasonable, we might kill the lockd otherwise */
-    count &= ~mask;
-
-    /* the offset is often strange - remove 2 of its bits if either of
-       the top two bits are set. Shift the top ones by two bits. This
-       still allows OLE2 apps to operate, but should stop lockd from
-       dieing */
-    if ((offset & mask) != 0)
-      offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
-  } else {
-    SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
-    SMB_OFF_T mask = (mask2<<1);
-    SMB_OFF_T neg_mask = ~mask;
-
-    /* interpret negative counts as large numbers */
-    if (count < 0)
-      count &= ~mask;
-
-    /* no negative offsets */
-    if(offset < 0)
-      offset &= ~mask;
-
-    /* count + offset must be in range */
-    while ((offset < 0 || (offset + count < 0)) && mask)
-    {
-      offset &= ~mask;
-      mask = ((mask >> 1) & neg_mask);
-    }
-  }
-
   DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
 
   lock.l_type = type;
index d72d3908ce8f86e5293285fd684ae7b301e18cc7..decc36fc030164f00f62ca1368ceb600d1cf77dc 100644 (file)
@@ -84,6 +84,37 @@ static const char *lock_type_name(enum brl_type lock_type)
        return (lock_type == READ_LOCK) ? "READ" : "WRITE";
 }
 
+/****************************************************************************
+ Utility function to map a lock type correctly depending on the open
+ mode of a file.
+****************************************************************************/
+
+static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type)
+{
+       if((lock_type == WRITE_LOCK) && !fsp->can_write) {
+               /*
+                * Many UNIX's cannot get a write lock on a file opened read-only.
+                * Win32 locking semantics allow this.
+                * Do the best we can and attempt a read-only lock.
+                */
+               DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n"));
+               return F_RDLCK;
+       } else if((lock_type == READ_LOCK) && !fsp->can_read) {
+               /*
+                * Ditto for read locks on write only files.
+                */
+               DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n"));
+               return F_WRLCK;
+       }
+
+  /*
+   * This return should be the most normal, as we attempt
+   * to always open files read/write.
+   */
+
+  return (lock_type == READ_LOCK) ? F_RDLCK : F_WRLCK;
+}
+
 /****************************************************************************
  Check to see if the given unsigned lock range is within the possible POSIX
  range. Modifies the given args to be in range if possible, just returns
@@ -98,6 +129,10 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
 
 #if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
 
+    SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
+    SMB_OFF_T mask = (mask2<<1);
+    SMB_OFF_T neg_mask = ~mask;
+
        /*
         * In this case SMB_OFF_T is 64 bits,
         * and the underlying system can handle 64 bit signed locks.
@@ -107,13 +142,21 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
        offset = (SMB_OFF_T)u_offset;
        count = (SMB_OFF_T)u_count;
 
+       /*
+        * Deal with a very common case of count of all ones.
+        * (lock entire file).
+        */
+
+       if(count == (SMB_OFF_T)-1)
+               count &= ~mask;
+
        /*
         * POSIX lock ranges cannot be negative.
         * Fail if any combination becomes negative.
         */
 
        if(offset < 0 || count < 0 || (offset + count < 0)) {
-               DEBUG(10,("posix_lock_in_range: negative range offset = %.0f, count = %.0f. Ignoring lock.\n",
+               DEBUG(10,("posix_lock_in_range: negative range: offset = %.0f, count = %.0f. Ignoring lock.\n",
                                (double)offset, (double)count ));
                return False;
 
@@ -140,6 +183,14 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
         * broken large locking.
         */
 
+       /*
+        * Deal with a very common case of count of all ones.
+        * (lock entire file).
+        */
+
+       if(u_count == (SMB_BIG_UINT)-1)
+               count = 0x7FFFFFFF;
+
        if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) {
                DEBUG(10,("posix_lock_in_range: top 32 bits not zero. offset = %.0f, count = %.0f. Ignoring lock.\n",
                                (double)u_offset, (double)u_count ));
@@ -182,6 +233,14 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
         * SMB_BIG_UINT is 64 bits, we can do a 32 bit shift.
         */
 
+       /*
+        * Deal with a very common case of count of all ones.
+        * (lock entire file).
+        */
+
+       if(u_count == (SMB_BIG_UINT)-1)
+               count = 0x7FFFFFFF;
+
        if(((u_offset >> 32) & 0xFFFFFFFF) || ((u_count >> 32) & 0xFFFFFFFF)) {
                DEBUG(10,("posix_lock_in_range: top 32 bits not zero. u_offset = %.0f, u_count = %.0f. Ignoring lock.\n",
                                (double)u_offset, (double)u_count ));
@@ -209,6 +268,14 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
         * just cast.
         */
 
+       /*
+        * Deal with a very common case of count of all ones.
+        * (lock entire file).
+        */
+
+       if(u_count == (SMB_BIG_UINT)-1)
+               count = 0x7FFFFFFF;
+
        /* Cast from 32 bits unsigned to 32 bits signed. */
        offset = (SMB_OFF_T)u_offset;
        count = (SMB_OFF_T)u_count;
@@ -242,22 +309,32 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
 
 /****************************************************************************
  POSIX function to see if a file region is locked. Returns True if the
lock could be granted, False if not.
region is locked, False otherwise.
 ****************************************************************************/
 
-static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
+static BOOL is_posix_locked(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
 {
        SMB_OFF_T offset;
        SMB_OFF_T count;
 
-       DEBUG(10,("posix_locktest: File %s, offset = %.0f, count = %.0f, type = %s\n",
+       DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n",
                        fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) ));
 
+       /*
+        * If the requested lock won't fit in the POSIX range, we will
+        * never set it, so presume it is not locked.
+        */
+
        if(!posix_lock_in_range(&offset, &count, u_offset, u_count))
-               return True;
+               return False;
 
-       /* Placeholder - for now always return that the lock could be granted. */
-       return True;
+       /*
+        * Note that most UNIX's can *test* for a write lock on
+        * a read-only fd, just not *set* a write lock on a read-only
+        * fd. So we don't need to use map_lock_type here.
+        */ 
+
+       return fcntl_lock(fsp->fd,SMB_F_GETLK,offset,count,lock_type);
 }
 
 /****************************************************************************
@@ -265,40 +342,58 @@ static BOOL posix_locktest(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UIN
  lock could be granted, False if not.
 ****************************************************************************/
 
-static BOOL get_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
+static BOOL set_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count, enum brl_type lock_type)
 {
        SMB_OFF_T offset;
        SMB_OFF_T count;
+       BOOL ret = True;
 
-       DEBUG(5,("get_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n",
+       DEBUG(5,("set_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n",
                        fsp->fsp_name, (double)offset, (double)count, lock_type_name(lock_type) ));
 
+       /*
+        * If the requested lock won't fit in the POSIX range, we will
+        * pretend it was successful.
+        */
+
        if(!posix_lock_in_range(&offset, &count, u_offset, u_count))
                return True;
 
-       /* Placeholder - for now always return that the lock could be granted. */
-       fsp->num_posix_locks++;
-       return True;
+    ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,map_posix_lock_type(fsp,lock_type)); 
+
+       if(ret)
+               fsp->num_posix_locks++;
+
+       return ret;
 }
 
 /****************************************************************************
  POSIX function to release a lock. Returns True if the
- lock could be granted, False if not.
+ lock could be released, False if not.
 ****************************************************************************/
 
 static BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count)
 {
        SMB_OFF_T offset;
        SMB_OFF_T count;
+       BOOL ret;
 
        DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n",
                        fsp->fsp_name, (double)offset, (double)count ));
 
+       /*
+        * If the requested lock won't fit in the POSIX range, we will
+        * pretend it was successful.
+        */
+
        if(!posix_lock_in_range(&offset, &count, u_offset, u_count))
                return True;
 
-       /* Placeholder - for now always return that the lock could be granted. */
-       fsp->num_posix_locks--;
+       ret = fcntl_lock(fsp->fd,SMB_F_SETLK,offset,count,F_UNLCK);
+
+       if(ret)
+               fsp->num_posix_locks--;
+
        return True;
 }
 
@@ -332,7 +427,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
         */
 
        if(!ret && !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && lp_posix_locking(snum))
-               ret = !posix_locktest(fsp, offset, count, lock_type);
+               ret = is_posix_locked(fsp, offset, count, lock_type);
 
        return ret;
 }
@@ -371,7 +466,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
                         * Try and get a POSIX lock on this range.
                         */
 
-                       ok = get_posix_lock(fsp, offset, count, lock_type);
+                       ok = set_posix_lock(fsp, offset, count, lock_type);
 
                        if(!ok) {
                                /*
@@ -393,10 +488,10 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
        return True; /* Got lock */
 }
 
-
 /****************************************************************************
  Utility function called by unlocking requests.
 ****************************************************************************/
+
 BOOL do_unlock(files_struct *fsp,connection_struct *conn,
                SMB_BIG_UINT count,SMB_BIG_UINT offset, 
               int *eclass,uint32 *ecode)
index a55018446dbc89de03a70af1726664d95a353eb1..6890a08fce3b65418a59f594f124dd7d5c84cf78 100644 (file)
@@ -239,7 +239,6 @@ typedef struct
   BOOL bBindInterfacesOnly;
   BOOL bUnixPasswdSync;
   BOOL bPasswdChatDebug;
-  BOOL bOleLockingCompat;
   BOOL bTimestampLogs;
   BOOL bNTSmbSupport;
   BOOL bNTPipeSupport;
@@ -811,7 +810,6 @@ static struct parm_struct parm_table[] =
 #ifdef WITH_UTMP
   {"utmp",             P_BOOL,    P_LOCAL,  &sDefault.bUtmp,            NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
 #endif
-  {"ole locking compatibility",   P_BOOL,    P_GLOBAL,  &Globals.bOleLockingCompat,   NULL,   NULL,  FLAG_GLOBAL},
   {"oplocks",          P_BOOL,    P_LOCAL,  &sDefault.bOpLocks,         NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
   {"level2 oplocks",   P_BOOL,    P_LOCAL,  &sDefault.bLevel2OpLocks,   NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
   {"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL},
@@ -1011,7 +1009,6 @@ static void init_globals(void)
   Globals.bBindInterfacesOnly = False;
   Globals.bUnixPasswdSync = False;
   Globals.bPasswdChatDebug = False;
-  Globals.bOleLockingCompat = True;
   Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
   Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
   Globals.bNTAclSupport = True; /* Use NT ACLs by default. */
@@ -1318,7 +1315,6 @@ static FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
 FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
 FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
 FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
-FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
 FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
 FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport)
 FN_GLOBAL_BOOL(lp_nt_acl_support,&Globals.bNTAclSupport)