summaryrefslogtreecommitdiffstats
path: root/source/smbd/open.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-08-22 00:29:40 +0000
committerJeremy Allison <jra@samba.org>2001-08-22 00:29:40 +0000
commitfe4aa720181a43f7a636ca029680fab0c836b968 (patch)
tree14ba095f2278198e00a7d79b2248c5efd6403cee /source/smbd/open.c
parentfeb9bf86723bce7dd1e81250b92191c370228a45 (diff)
downloadsamba-fe4aa720181a43f7a636ca029680fab0c836b968.tar.gz
samba-fe4aa720181a43f7a636ca029680fab0c836b968.tar.xz
samba-fe4aa720181a43f7a636ca029680fab0c836b968.zip
Fixed the (incorrect) paranioa fix I put in for the fcntl lock spin.
Don't delete a share mode that failed to remove the oplock (doh!), just set the oplock entry to zero.... Jeremy.
Diffstat (limited to 'source/smbd/open.c')
-rw-r--r--source/smbd/open.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 143aa934a68..633cf718179 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -527,17 +527,42 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
if(broke_oplock) {
free((char *)old_shares);
- if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
- DEBUG(0,("open_mode_check: cannot delete entry when breaking oplock (%x) on file %s, \
-dev = %x, inode = %.0f\n", broken_entry.op_type, fname, (unsigned int)dev, (double)inode));
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return -1;
- }
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
oplock_contention_count++;
- }
+
+ /* Paranoia check that this is no longer an exlusive entry. */
+ for(i = 0; i < num_share_modes; i++) {
+ share_mode_entry *share_entry = &old_shares[i];
+
+ if (share_modes_identical(&broken_entry, share_entry) &&
+ EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type) ) {
+
+ /*
+ * This should not happen. The target left this oplock
+ * 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));
+
+ if (process_exists(broken_entry.pid)) {
+ pstring errmsg;
+ slprintf(errmsg, sizeof(errmsg)-1,
+ "open_mode_check: Existant process %d left active oplock.\n",
+ broken_entry.pid );
+ smb_panic(errmsg);
+ }
+
+ if (!clear_share_entry(dev, inode, &broken_entry)) {
+ errno = EACCES;
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+ return -1;
+ }
+ }
+ } /* end for paranoia... */
+ } /* end if broke_oplock */
+
} while(broke_oplock);
if(old_shares != 0)
@@ -570,6 +595,7 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
else if (deny_mode == DENY_ALL) kernel_mode = LOCK_MAND;
if (kernel_mode) flock(fsp->fd, kernel_mode);
#endif
+ ;;
}