diff options
Diffstat (limited to 'source3/smbd/oplock.c')
-rw-r--r-- | source3/smbd/oplock.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 19e6956d9e..6739f5654f 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -388,6 +388,30 @@ pid %d, port %d, dev = %x, inode = %.0f, file_id = %lu\n", (int)remotepid, from_port, (unsigned int)dev, (double)inode, file_id)); break; + case RETRY_DEFERRED_OPEN_CMD: + + /* Request to retry and open that would return SHARING_VIOLATION. */ + if (msg_len != DEFERRED_OPEN_MSG_LEN) { + DEBUG(0,("process_local_message: incorrect length for RETRY_DEFERRED_OPEN_CMD (was %d, should be %d).\n", + (int)msg_len, (int)DEFERRED_OPEN_MSG_LEN)); + return False; + } + { + uint16 mid; + + memcpy((char *)&remotepid, msg_start+DEFERRED_OPEN_PID_OFFSET,sizeof(remotepid)); + memcpy((char *)&inode, msg_start+DEFERRED_OPEN_INODE_OFFSET,sizeof(inode)); + memcpy((char *)&dev, msg_start+DEFERRED_OPEN_DEV_OFFSET,sizeof(dev)); + memcpy((char *)&mid, msg_start+DEFERRED_OPEN_MID_OFFSET,sizeof(mid)); + + DEBUG(5,("process_local_message: RETRY_DEFERRED_OPEN from \ +pid %d, port %d, dev = %x, inode = %.0f, mid = %u\n", + (int)remotepid, from_port, (unsigned int)dev, (double)inode, (unsigned int)mid)); + + schedule_sharing_violation_open_smb_message(mid); + } + break; + /* * Keep this as a debug case - eventually we can remove it. */ @@ -1215,7 +1239,51 @@ void release_level_2_oplocks_on_change(files_struct *fsp) } /**************************************************************************** -setup oplocks for this process + Send a 'retry your open' message to a process with a deferred open entry. +****************************************************************************/ + +BOOL send_deferred_open_retry_message(deferred_open_entry *entry) +{ + char de_msg[DEFERRED_OPEN_MSG_LEN]; + struct sockaddr_in addr_out; + pid_t pid = sys_getpid(); + + memset(de_msg, '\0', DEFERRED_OPEN_MSG_LEN); + SSVAL(de_msg,DEFERRED_OPEN_CMD_OFFSET,RETRY_DEFERRED_OPEN_CMD); + memcpy(de_msg+DEFERRED_OPEN_PID_OFFSET,(char *)&pid,sizeof(pid)); + memcpy(de_msg+DEFERRED_OPEN_DEV_OFFSET,(char *)&entry->dev,sizeof(entry->dev)); + memcpy(de_msg+DEFERRED_OPEN_INODE_OFFSET,(char *)&entry->inode,sizeof(entry->inode)); + memcpy(de_msg+DEFERRED_OPEN_MID_OFFSET,(char *)&entry->mid,sizeof(entry->mid)); + + /* 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( entry->port ); + addr_out.sin_family = AF_INET; + + if( DEBUGLVL( 3 ) ) { + dbgtext( "send_deferred_open_retry_message: sending a message to "); + dbgtext( "pid %d on port %d ", (int)entry->pid, entry->port ); + dbgtext( "for dev = %x, inode = %.0f, mid = %u\n", + (unsigned int)entry->dev, (double)entry->inode, (unsigned int)entry->mid ); + } + + if(sys_sendto(oplock_sock,de_msg,DEFERRED_OPEN_MSG_LEN,0, + (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) { + if( DEBUGLVL( 0 ) ) { + dbgtext( "send_deferred_open_retry_message: failed sending a message to "); + dbgtext( "pid %d on port %d ", (int)entry->pid, entry->port ); + dbgtext( "for dev = %x, inode = %.0f, mid = %u\n", + (unsigned int)entry->dev, (double)entry->inode, (unsigned int)entry->mid ); + dbgtext( "Error was %s\n", strerror(errno) ); + } + return False; + } + return True; +} + +/**************************************************************************** + Setup oplocks for this process. ****************************************************************************/ BOOL init_oplocks(void) |