summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-01-26 20:01:21 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:55:11 -0500
commit02c25a2683204d8b20a1e69ea354b9e08b0fd94d (patch)
treec027beebee56dbbfe82b272f191de61ea9f34a02
parentf0df38a4e8d7ce8e11e5d34f645c5b4da9d47291 (diff)
downloadsamba-02c25a2683204d8b20a1e69ea354b9e08b0fd94d.tar.gz
samba-02c25a2683204d8b20a1e69ea354b9e08b0fd94d.tar.bz2
samba-02c25a2683204d8b20a1e69ea354b9e08b0fd94d.zip
r5014: Split out the request to send an async level II oplock break into a
new function to make it clear when it's called. Remove async parameter that had been overloaded into request_oplock_break. Inspired by work from Nadav Danieli <nadavd@exanet.com>. Jeremy. (This used to be commit 05697fb50236dfc28e81f8b3900eac17cace57c1)
-rw-r--r--source3/smbd/open.c2
-rw-r--r--source3/smbd/oplock.c75
2 files changed, 59 insertions, 18 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index bf3fbf7fec..70632a20eb 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -665,7 +665,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
/* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode);
- opb_ret = request_oplock_break(share_entry, False);
+ opb_ret = request_oplock_break(share_entry);
/* Now relock. */
lock_share_entry(conn, dev, inode);
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 8d1b6911e7..a55d5443d5 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -944,12 +944,12 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
}
/****************************************************************************
-Send an oplock break message to another smbd process. If the oplock is held
-by the local smbd then call the oplock break function directly.
-Note this function is always called with the share mode lock *NOT* held.
+ Send an oplock break message to another smbd process. If the oplock is held
+ by the local smbd then call the oplock break function directly.
+ This function is called with no share locks held.
****************************************************************************/
-BOOL request_oplock_break(share_mode_entry *share_entry, BOOL async)
+BOOL request_oplock_break(share_mode_entry *share_entry)
{
char op_break_msg[OPLOCK_BREAK_MSG_LEN];
struct sockaddr_in addr_out;
@@ -990,7 +990,7 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
/* We need to send a OPLOCK_BREAK_CMD message to the port in the share mode entry. */
if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- break_cmd_type = async ? ASYNC_LEVEL_II_OPLOCK_BREAK_CMD : LEVEL_II_OPLOCK_BREAK_CMD;
+ break_cmd_type = LEVEL_II_OPLOCK_BREAK_CMD;
} else {
break_cmd_type = OPLOCK_BREAK_CMD;
}
@@ -1008,7 +1008,7 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
addr_out.sin_family = AF_INET;
if( DEBUGLVL( 3 ) ) {
- dbgtext( "request_oplock_break: sending a %s oplock break message to ", async ? "asynchronous" : "synchronous" );
+ dbgtext( "request_oplock_break: sending a synchronous oplock break message to " );
dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
(unsigned int)dev, (double)inode, file_id );
@@ -1028,16 +1028,6 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
}
/*
- * If we just sent a message to a level II oplock share entry in async mode then
- * we are done and may return.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type) && async) {
- DEBUG(3,("request_oplock_break: sent async break message to level II entry.\n"));
- return True;
- }
-
- /*
* Now we must await the oplock broken message coming back
* from the target smbd process. Timeout if it fails to
* return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
@@ -1150,6 +1140,57 @@ BOOL attempt_close_oplocked_file(files_struct *fsp)
}
/****************************************************************************
+ Send an asynchronous oplock break message to another smbd process.
+****************************************************************************/
+
+static BOOL request_remote_level2_async_oplock_break(share_mode_entry *share_entry)
+{
+ char op_break_msg[OPLOCK_BREAK_MSG_LEN];
+ struct sockaddr_in addr_out;
+ pid_t pid = sys_getpid();
+ SMB_DEV_T dev = share_entry->dev;
+ SMB_INO_T inode = share_entry->inode;
+ unsigned long file_id = share_entry->share_file_id;
+
+ /* We need to send a ASYNC_LEVEL_II_OPLOCK_BREAK_CMD message to the port in the share mode entry. */
+
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,ASYNC_LEVEL_II_OPLOCK_BREAK_CMD);
+ memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
+ memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
+ memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
+ memcpy(op_break_msg+OPLOCK_BREAK_FILEID_OFFSET,(char *)&file_id,sizeof(file_id));
+
+ /* Set the address and port. */
+ memset((char *)&addr_out,'\0',sizeof(addr_out));
+ addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr_out.sin_port = htons( share_entry->op_port );
+ addr_out.sin_family = AF_INET;
+
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "request_remote_level2_async_oplock_break: sending an asynchronous oplock break message to ");
+ dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ }
+
+ if(sys_sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
+ (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "request_remote_level2_async_oplock_break: failed when sending a oplock " );
+ dbgtext( "break message to pid %d ", (int)share_entry->pid );
+ dbgtext( "on port %d ", share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ dbgtext( "Error was %s\n", strerror(errno) );
+ }
+ return False;
+ }
+
+ DEBUG(3,("request_remote_level2_async_oplock_break: sent async break message to level II entry.\n"));
+ return True;
+}
+
+/****************************************************************************
This function is called on any file modification or lock request. If a file
is level 2 oplocked then it must tell all other level 2 holders to break to none.
****************************************************************************/
@@ -1234,7 +1275,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
*/
DEBUG(10,("release_level_2_oplocks_on_change: breaking remote oplock (async).\n"));
- request_oplock_break(share_entry, True);
+ request_remote_level2_async_oplock_break(share_entry);
}
}