summaryrefslogtreecommitdiff
path: root/source3/smbd
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
commite4275a35a64fde95a3b59307572d44c8d53909ad (patch)
tree0460c54dfc40e3d982f0bc4c52e09a3bd2e398e0 /source3/smbd
parentf8d0031ad221f879ad1046963458ae781b868a28 (diff)
downloadsamba-e4275a35a64fde95a3b59307572d44c8d53909ad.tar.gz
samba-e4275a35a64fde95a3b59307572d44c8d53909ad.tar.bz2
samba-e4275a35a64fde95a3b59307572d44c8d53909ad.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. (This used to be commit fe4aa720181a43f7a636ca029680fab0c836b968)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c3
-rw-r--r--source3/smbd/open.c44
-rw-r--r--source3/smbd/oplock.c14
3 files changed, 50 insertions, 11 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 6b72a8563a..dd1a25293d 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -153,6 +153,9 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
lock_share_entry_fsp(fsp);
share_entry_count = del_share_mode(fsp, &share_entry);
+ DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
+ share_entry_count, fsp->fsp_name ));
+
/*
* We delete on close if it's the last open, and the
* delete on close flag was set in the entry we just deleted.
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 143aa934a6..633cf71817 100644
--- a/source3/smbd/open.c
+++ b/source3/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
+ ;;
}
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 4bc8fce698..f841432960 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -1141,6 +1141,9 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
num_share_modes = get_share_modes(fsp->conn, fsp->dev, fsp->inode, &share_list);
+ DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
+ num_share_modes ));
+
for(i = 0; i < num_share_modes; i++) {
share_mode_entry *share_entry = &share_list[i];
@@ -1153,6 +1156,9 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
* also no harm to ignore existing NO_OPLOCK states. JRA.
*/
+ DEBUG(10,("release_level_2_oplocks_on_change: share_entry[%i]->op_type == %d\n",
+ i, share_entry->op_type ));
+
if (share_entry->op_type == NO_OPLOCK)
continue;
@@ -1179,6 +1185,8 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
abort();
}
+ DEBUG(10,("release_level_2_oplocks_on_change: breaking our own oplock.\n"));
+
oplock_break_level2(new_fsp, True, token);
} else {
@@ -1188,17 +1196,19 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
* message.
*/
+ DEBUG(10,("release_level_2_oplocks_on_change: breaking remote oplock.\n"));
request_oplock_break(share_entry, fsp->dev, fsp->inode);
}
}
- free((char *)share_list);
+ if (share_list)
+ free((char *)share_list);
unlock_share_entry_fsp(fsp);
/* Paranoia check... */
if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(0,("release_level_2_oplocks_on_change: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name));
- abort();
+ smb_panic("release_level_2_oplocks_on_change");
}
}