Tidyup fixes for fcntl spin problem.
authorJeremy Allison <jra@samba.org>
Wed, 22 Aug 2001 01:01:37 +0000 (01:01 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 22 Aug 2001 01:01:37 +0000 (01:01 +0000)
Jeremy.
(This used to be commit 27d3dd0e7cb777ef6b21d6966c07045c2940fd37)

source3/locking/locking.c
source3/smbd/open.c

index fea821baa17b442c2fb8d6726994b55af3d58327..80537c8bc1beae2468faf59997b5d70847c1f5c3 100644 (file)
@@ -299,7 +299,7 @@ BOOL locking_init(int read_only)
                return True;
 
        tdb = tdb_open_log(lock_path("locking.tdb"), 
-                      0, TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG
+                      0, USE_TDB_MMAP_FLAG|(read_only?0x0:TDB_CLEAR_IF_FIRST)
                       read_only?O_RDONLY:O_RDWR|O_CREAT,
                       0644);
 
@@ -365,18 +365,35 @@ static TDB_DATA locking_key_fsp(files_struct *fsp)
        return locking_key(fsp->dev, fsp->inode);
 }
 
+#ifndef LOCK_SHARE_ENTRY_SPIN_COUNT
+#define LOCK_SHARE_ENTRY_SPIN_COUNT 100
+#endif
+
 /*******************************************************************
  Lock a hash bucket entry.
 ******************************************************************/
+
 BOOL lock_share_entry(connection_struct *conn,
                      SMB_DEV_T dev, SMB_INO_T inode)
 {
+#if 1 /* JRATEST */
+       int count = 0;
+       for (count = 0; count < LOCK_SHARE_ENTRY_SPIN_COUNT; count++)
+               if (tdb_chainlock(tdb, locking_key(dev, inode)) == 0)
+                       return True;
+               else
+                       DEBUG(0,("lock_share_entry: locking (%d) for dev = %x, inode = %.0f failed with error %s\n",
+                               count, (unsigned int)dev, (double)inode, strerror(errno) ));
+       return False;
+#else
        return tdb_chainlock(tdb, locking_key(dev, inode)) == 0;
+#endif
 }
 
 /*******************************************************************
  Unlock a hash bucket entry.
 ******************************************************************/
+
 void unlock_share_entry(connection_struct *conn,
                        SMB_DEV_T dev, SMB_INO_T inode)
 {
@@ -389,7 +406,18 @@ void unlock_share_entry(connection_struct *conn,
 
 BOOL lock_share_entry_fsp(files_struct *fsp)
 {
+#if 1 /* JRATEST */
+       int count = 0;
+       for (count = 0; count < LOCK_SHARE_ENTRY_SPIN_COUNT; count++)
+               if (tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0)
+                       return True;
+               else
+                       DEBUG(0,("lock_share_entry_fsp: locking (%d) for dev = %x, inode = %.0f failed with error %s\n",
+                               count, (unsigned int)fsp->dev, (double)fsp->inode, strerror(errno) ));
+       return False;
+#else
        return tdb_chainlock(tdb, locking_key(fsp->dev, fsp->inode)) == 0;
+#endif
 }
 
 /*******************************************************************
@@ -465,7 +493,7 @@ BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
  Ignore if no entry deleted.
 ********************************************************************/
 
-static ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
+ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
                        share_mode_entry *entry, share_mode_entry **ppse)
 {
        TDB_DATA dbuf;
@@ -705,15 +733,6 @@ BOOL downgrade_share_oplock(files_struct *fsp)
        return mod_share_mode(fsp->dev, fsp->inode, &entry, downgrade_share_oplock_fn, NULL);
 }
 
-/*******************************************************************
- Delete an exclusive share oplock owned by a defunct smbd..
-********************************************************************/
-
-BOOL clear_share_entry(SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *entry)
-{
-       return mod_share_mode(dev, inode, entry, remove_share_oplock_fn, NULL);
-}
-
 /*******************************************************************
  Get/Set the delete on close flag in a set of share modes.
  Return False on fail, True on success.
index 633cf718179f76890595e02b8db34181804c1b70..a8cf9aba8900cdac5e2d3a51d3cda35ba4b2d643 100644 (file)
@@ -3,6 +3,7 @@
    Version 1.9.
    file opening and share modes
    Copyright (C) Andrew Tridgell 1992-1998
+   Copyright (C) Jeremy Allison 2001
    
    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
@@ -542,8 +543,8 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
            * as exlusive.... The process *must* be dead.... 
            */
 
-          DEBUG(0,("open_mode_check: exlusive oplock left after break ! For file %s,
-dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
+          DEBUG(0,("open_mode_check: exlusive oplock left by process %d after break ! For file %s,
+dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
 
           if (process_exists(broken_entry.pid)) {
             pstring errmsg;
@@ -553,12 +554,21 @@ dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (double)inode));
             smb_panic(errmsg);
           }
 
-          if (!clear_share_entry(dev, inode, &broken_entry)) {
+          if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
             errno = EACCES;
             unix_ERR_class = ERRDOS;
             unix_ERR_code = ERRbadshare;
             return -1;
           }
+
+          /*
+           * We must reload the share modes after deleting the 
+           * other process's entry.
+           */
+
+          free((char *)old_shares);
+          num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
+          break;
         }
       } /* end for paranoia... */
     } /* end if broke_oplock */