Removed the "mangle locks" parameter and moved the functionality
authorJeremy Allison <jra@samba.org>
Wed, 22 Sep 1999 01:48:50 +0000 (01:48 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 22 Sep 1999 01:48:50 +0000 (01:48 +0000)
of lock mangling into lib/util.c for 64 bit failures on 32 bit
filesystesm.
Andrew - you can review the code now :-).
Jeremy.

source/include/proto.h
source/lib/util.c
source/param/loadparm.c
source/smbd/reply.c

index 73be16189c8ef406e9337ea6cf4e1e8324ed9472..3294802ad169c4bfca13b610c49ea61ea4b70b9a 100644 (file)
@@ -273,6 +273,7 @@ char *readdirname(DIR *p);
 BOOL is_in_path(char *name, name_compare_entry *namelist);
 void set_namearray(name_compare_entry **ppname_array, char *namelist);
 void free_namearray(name_compare_entry *name_array);
+uint32 map_lock_offset(uint32 high, uint32 low);
 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
 BOOL is_myname(char *s);
 void set_remote_arch(enum remote_arch_types type);
@@ -1165,7 +1166,6 @@ BOOL lp_dos_filetimes(int );
 BOOL lp_dos_filetime_resolution(int );
 BOOL lp_fake_dir_create_times(int );
 BOOL lp_blocking_locks(int );
-BOOL lp_mangle_locks(int );
 int lp_create_mask(int );
 int lp_force_create_mode(int );
 int _lp_security_mask(int );
@@ -2627,9 +2627,8 @@ int rename_internals(connection_struct *conn,
 int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
 int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
 int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err);
-uint32 map_lock_offset(uint32 high, uint32 low);
-SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err);
+SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err);
+SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err);
 int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
 int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
 int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
index 96dadd7e208af72ecb6fb065a94ddc7042c7e9a3..643b2c377d5003d9885c032ccf11377dfd881e93 100644 (file)
@@ -2613,14 +2613,56 @@ void free_namearray(name_compare_entry *name_array)
   free((char *)name_array);
 }
 
+/****************************************************************************
+ Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
+****************************************************************************/
+
+uint32 map_lock_offset(uint32 high, uint32 low)
+{
+  unsigned int i;
+  uint32 mask = 0;
+  uint32 highcopy = high;
+
+  /*
+   * Try and find out how many significant bits there are in high.
+   */
+
+  for(i = 0; highcopy; i++)
+    highcopy >>= 1;
+
+  /*
+   * We use 31 bits not 32 here as POSIX
+   * lock offsets may not be negative.
+   */
+
+  mask = (~0) << (31 - i);
+
+  if(low & mask)
+    return 0; /* Fail. */
+
+  high <<= (31 - i);
+
+  return (high|low);
+}
+
 /****************************************************************************
 routine to do file locking
 ****************************************************************************/
+
 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
+   * values in case we have to map to a 32 bit lock on
+   * a filesystem that doesn't support 64 bit locks.
+   */
+  SMB_OFF_T orig_offset = offset;
+  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);
@@ -2677,7 +2719,7 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
     }
     /* 32 bit NFS file system, retry with smaller offset */
     errno = 0;
-    lock.l_len = count & 0xffffffff;
+    lock.l_len = count & 0x7fffffff;
     ret = fcntl(fd,op,&lock);
   }
 
@@ -2705,6 +2747,44 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
   {
     DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
           (double)offset,(double)count,op,type,strerror(errno)));
+
+    /* perhaps it doesn't support this sort of locking?? */
+    if (errno == EINVAL)
+    {
+
+#if defined(LARGE_SMB_OFF_T)
+      {
+        /*
+         * Ok - if we get here then we have a 64 bit lock request
+         * that has returned EINVAL. Try and map to 31 bits for offset
+         * and length and try again. This may happen if a filesystem
+         * doesn't support 64 bit offsets (efs/ufs) although the underlying
+         * OS does.
+         */
+        uint32 off_low = (orig_offset & 0xFFFFFFFF);
+        uint32 off_high = ((orig_offset >> 32) & 0xFFFFFFFF);
+
+        lock.l_len = (orig_count & 0x7FFFFFFF);
+        lock.l_start = (SMB_OFF_T)map_lock_offset(off_high, off_low);
+        ret = fcntl(fd,op,&lock);
+        if (ret == -1)
+        {
+          if (errno == EINVAL)
+          {
+            DEBUG(3,("locking not supported? returning True\n"));
+            return(True);
+          }
+          return False;
+        }
+        DEBUG(3,("64 -> 32 bit modified lock call successful\n"));
+        return True;
+      }
+#else /* LARGE_SMB_OFF_T */
+      DEBUG(3,("locking not supported? returning True\n"));
+      return(True);
+#endif /* LARGE_SMB_OFF_T */
+    }
+
     return(False);
   }
 
index a36d7de4706792296c789b9addabd03c16ae8150..454109bde96d5ea4620f852339b6882074d9402b 100644 (file)
@@ -343,7 +343,6 @@ typedef struct
   BOOL bDosFiletimeResolution;
   BOOL bFakeDirCreateTimes;
   BOOL bBlockingLocks;
-  BOOL bMangleLocks;
   char dummy[3]; /* for alignment */
 } service;
 
@@ -443,7 +442,6 @@ static service sDefault =
   False, /* bDosFiletimeResolution */
   False, /* bFakeDirCreateTimes */
   True,  /* bBlockingLocks */
-  True,  /* bMangleLocks */
   ""     /* dummy */
 };
 
@@ -758,7 +756,6 @@ static struct parm_struct parm_table[] =
   {"fake oplocks",     P_BOOL,    P_LOCAL,  &sDefault.bFakeOplocks,     NULL,   NULL,  FLAG_SHARE},
   {"kernel oplocks",   P_BOOL,    P_GLOBAL, &Globals.bKernelOplocks,    NULL,   NULL,  FLAG_GLOBAL},
   {"locking",          P_BOOL,    P_LOCAL,  &sDefault.bLocking,         NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
-  {"mangle locks",     P_BOOL,    P_LOCAL,  &sDefault.bMangleLocks,     NULL,   NULL,  FLAG_SHARE|FLAG_GLOBAL},
   {"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},
@@ -1351,7 +1348,6 @@ FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
 FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
 FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
 FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
-FN_LOCAL_BOOL(lp_mangle_locks,bMangleLocks)
 
 FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask)
 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
index c0b6db23d4f5dc548fd2d9e627794146bcb8bd6f..40c937f3fd68e9f8fe12334376995d8c0bb43e95 100644 (file)
@@ -3973,7 +3973,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
  Get a lock count, dealing with large count requests.
 ****************************************************************************/
 
-SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err)
+SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err)
 {
   SMB_OFF_T count = 0;
 
@@ -3994,10 +3994,10 @@ SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, B
      * NT4.x seems to be broken in that it sends large file
      * lockingX calls even if the CAP_LARGE_FILES was *not*
      * negotiated. For boxes without large file locks truncate the
-     * lock count by dropping the top 32 bits if mangle_locks is set.
+     * lock count by dropping the top 32 bits.
      */
 
-    if(mangle_locks && (IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0)) {
+    if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
       DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
             (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
             (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
@@ -4034,43 +4034,11 @@ support large counts.\n", (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(da
   return count;
 }
 
-/****************************************************************************
- Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
-****************************************************************************/
-
-uint32 map_lock_offset(uint32 high, uint32 low)
-{
-  unsigned int i;
-  uint32 mask = 0;
-  uint32 highcopy = high;
-  /*
-   * Try and find out how many significant bits there are in high.
-   */
-
-  for(i = 0; highcopy; i++)
-    highcopy >>= 1;
-
-  /*
-   * We use 31 bits not 32 here as POSIX
-   * lock offsets may not be negative.
-   */
-  mask = (~0) << (31 - i);
-
-  if(low & mask)
-    return 0; /* Fail. */
-
-  high <<= (31 - i);
-
-  return (high|low);
-}
-
 /****************************************************************************
  Get a lock offset, dealing with large offset requests.
 ****************************************************************************/
 
-SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL mangle_locks, BOOL *err)
+SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
 {
   SMB_OFF_T offset = 0;
 
@@ -4091,11 +4059,10 @@ SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format,
      * NT4.x seems to be broken in that it sends large file
      * lockingX calls even if the CAP_LARGE_FILES was *not*
      * negotiated. For boxes without large file locks mangle the
-     * lock offset by mapping the top 32 bits onto the lower 32 if
-     * mangle_locks is set.
+     * lock offset by mapping the top 32 bits onto the lower 32.
      */
       
-    if(mangle_locks && (IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0)) {
+    if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
       uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
       uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
       uint32 new_low = 0;
@@ -4161,7 +4128,6 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
   uint32 ecode=0, dummy2;
   int eclass=0, dummy1;
   BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
-  BOOL mangle_locks = False;
   BOOL err1, err2;
 
   CHECK_FSP(fsp,conn);
@@ -4210,19 +4176,11 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
     }
   }
 
-#ifndef LARGE_SMB_OFF_T
-  /*
-   * We only look at this parameter if we're on a small file
-   * offset platform. JRA.
-   */
-  mangle_locks = lp_mangle_locks(SNUM(conn));
-#endif
-
   /* Data now points at the beginning of the list
      of smb_unlkrng structs */
   for(i = 0; i < (int)num_ulocks; i++) {
-    count = get_lock_count( data, i, large_file_format, mangle_locks, &err1);
-    offset = get_lock_offset( data, i, large_file_format, mangle_locks, &err2);
+    count = get_lock_count( data, i, large_file_format, &err1);
+    offset = get_lock_offset( data, i, large_file_format, &err2);
 
     /*
      * There is no error code marked "stupid client bug".... :-).
@@ -4247,8 +4205,8 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
      of smb_lkrng structs */
 
   for(i = 0; i < (int)num_locks; i++) {
-    count = get_lock_count( data, i, large_file_format, mangle_locks, &err1);
-    offset = get_lock_offset( data, i, large_file_format, mangle_locks, &err2);
+    count = get_lock_count( data, i, large_file_format, &err1);
+    offset = get_lock_offset( data, i, large_file_format, &err2);
 
     /*
      * There is no error code marked "stupid client bug".... :-).
@@ -4278,8 +4236,8 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
      all of the previous locks (X/Open spec). */
   if(i != num_locks && num_locks != 0) {
     for(; i >= 0; i--) {
-      count = get_lock_count( data, i, large_file_format, mangle_locks, &err1);
-      offset = get_lock_offset( data, i, large_file_format, mangle_locks, &err2);
+      count = get_lock_count( data, i, large_file_format, &err1);
+      offset = get_lock_offset( data, i, large_file_format, &err2);
 
       /*
        * There is no error code marked "stupid client bug".... :-).