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);
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)
{
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
}
/*******************************************************************
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;
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.
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
* 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;
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 */