mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
proto.h: Updated.
server.c: Updated after netbench observation. Oplocks must be broken *before* share modes are checked, not after. Netbench seems to be working now. smb.h: Added offsets for oplock break time fields. trans2.c: Upped debug messages. util.c: Upped debug messages. Jeremy (jallison@whistle.com)
This commit is contained in:
parent
1ed901ddff
commit
bc4b70c566
@ -722,7 +722,7 @@ int find_service(char *service);
|
||||
int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
|
||||
int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
|
||||
int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
|
||||
BOOL oplock_break(uint32 dev, uint32 inode);
|
||||
BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval);
|
||||
BOOL request_oplock_break(min_share_mode_entry *share_entry,
|
||||
uint32 dev, uint32 inode);
|
||||
BOOL snum_used(int snum);
|
||||
|
@ -1049,17 +1049,19 @@ extern int unix_ERR_code;
|
||||
*
|
||||
* Form of this is :
|
||||
*
|
||||
* 0 2 6 10
|
||||
* +----+--------+--------+--------+
|
||||
* | cmd| pid | dev | inode |
|
||||
* +----+--------+--------+--------+
|
||||
* 0 2 6 10 14 18 22
|
||||
* +----+--------+--------+--------+-------+--------+
|
||||
* | cmd| pid | dev | inode | sec | usec |
|
||||
* +----+--------+--------+--------+-------+--------+
|
||||
*/
|
||||
|
||||
#define OPLOCK_BREAK_CMD 0x1
|
||||
#define OPLOCK_BREAK_PID_OFFSET 2
|
||||
#define OPLOCK_BREAK_DEV_OFFSET 6
|
||||
#define OPLOCK_BREAK_INODE_OFFSET 10
|
||||
#define OPLOCK_BREAK_MSG_LEN 14
|
||||
#define OPLOCK_BREAK_SEC_OFFSET 14
|
||||
#define OPLOCK_BREAK_USEC_OFFSET 18
|
||||
#define OPLOCK_BREAK_MSG_LEN 22
|
||||
|
||||
|
||||
#define CMD_REPLY 0x8000
|
||||
|
@ -2860,7 +2860,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
|
||||
|
||||
if (strequal(p1,"*")) return(True);
|
||||
|
||||
DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
|
||||
DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
|
||||
|
||||
if (trans2) {
|
||||
fstrcpy(ebase,p1);
|
||||
@ -2888,7 +2888,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
|
||||
matched = do_match(sbase,ebase,case_sig) &&
|
||||
(trans2 || do_match(sext,eext,case_sig));
|
||||
|
||||
DEBUG(5,("mask_match returning %d\n", matched));
|
||||
DEBUG(8,("mask_match returning %d\n", matched));
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
@ -1404,7 +1404,8 @@ static int access_table(int new_deny,int old_deny,int old_mode,
|
||||
if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
|
||||
|
||||
if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
|
||||
if (old_deny == new_deny && share_pid == getpid())
|
||||
int pid = getpid();
|
||||
if (old_deny == new_deny && share_pid == pid)
|
||||
return(AALL);
|
||||
|
||||
if (old_mode == 0) return(AREAD);
|
||||
@ -1487,16 +1488,12 @@ BOOL check_file_sharing(int cnum,char *fname)
|
||||
{
|
||||
min_share_mode_entry *share_entry = &old_shares[i];
|
||||
|
||||
/* someone else has a share lock on it, check to see
|
||||
if we can too */
|
||||
if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
|
||||
goto free_and_exit;
|
||||
|
||||
#ifdef USE_OPLOCKS
|
||||
/*
|
||||
* The share modes would give us access. Check if someone
|
||||
* has an oplock on this file. If so we must break it before
|
||||
* continuing.
|
||||
* Break oplocks before checking share modes. See comment in
|
||||
* open_file_shared for details.
|
||||
* Check if someone has an oplock on this file. If so we must
|
||||
* break it before continuing.
|
||||
*/
|
||||
if(share_entry->op_type & BATCH_OPLOCK)
|
||||
{
|
||||
@ -1518,6 +1515,12 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
|
||||
break;
|
||||
}
|
||||
#endif /* USE_OPLOCKS */
|
||||
|
||||
/* someone else has a share lock on it, check to see
|
||||
if we can too */
|
||||
if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
|
||||
goto free_and_exit;
|
||||
|
||||
} /* end for */
|
||||
|
||||
if(broke_oplock)
|
||||
@ -1727,22 +1730,13 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
|
||||
{
|
||||
min_share_mode_entry *share_entry = &old_shares[i];
|
||||
|
||||
/* someone else has a share lock on it, check to see
|
||||
if we can too */
|
||||
if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
|
||||
{
|
||||
free((char *)old_shares);
|
||||
unlock_share_entry(cnum, dev, inode, token);
|
||||
errno = EACCES;
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadshare;
|
||||
return;
|
||||
}
|
||||
#ifdef USE_OPLOCKS
|
||||
/*
|
||||
* The share modes would give us access. Check if someone
|
||||
* has an oplock on this file. If so we must break it before
|
||||
* continuing.
|
||||
* By observation of NetBench, oplocks are broken *before* share
|
||||
* modes are checked. This allows a file to be closed by the client
|
||||
* if the share mode would deny access and the client has an oplock.
|
||||
* Check if someone has an oplock on this file. If so we must break
|
||||
* it before continuing.
|
||||
*/
|
||||
if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
|
||||
{
|
||||
@ -1767,6 +1761,19 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
|
||||
break;
|
||||
}
|
||||
#endif /* USE_OPLOCKS */
|
||||
|
||||
/* someone else has a share lock on it, check to see
|
||||
if we can too */
|
||||
if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
|
||||
{
|
||||
free((char *)old_shares);
|
||||
unlock_share_entry(cnum, dev, inode, token);
|
||||
errno = EACCES;
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadshare;
|
||||
return;
|
||||
}
|
||||
|
||||
} /* end for */
|
||||
|
||||
if(broke_oplock)
|
||||
@ -2428,7 +2435,7 @@ static void process_smb(char *inbuf, char *outbuf)
|
||||
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
|
||||
DEBUG(1,("%s Connection denied from %s\n",
|
||||
timestring(),client_addr()));
|
||||
send_smb(Client,buf);
|
||||
send_smb(Client,(char *)buf);
|
||||
exit_server("connection denied");
|
||||
}
|
||||
}
|
||||
@ -2535,8 +2542,12 @@ should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
|
||||
uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
|
||||
uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
|
||||
uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
|
||||
struct timeval tval;
|
||||
struct sockaddr_in toaddr;
|
||||
|
||||
tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
|
||||
tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
|
||||
|
||||
DEBUG(5,("process_local_message: oplock break request from \
|
||||
pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
|
||||
|
||||
@ -2549,7 +2560,7 @@ pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
|
||||
|
||||
if(global_oplocks_open != 0)
|
||||
{
|
||||
if(oplock_break(dev, inode) == False)
|
||||
if(oplock_break(dev, inode, &tval) == False)
|
||||
{
|
||||
DEBUG(0,("process_local_message: oplock break failed - \
|
||||
not returning udp message.\n"));
|
||||
@ -2595,7 +2606,7 @@ pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
|
||||
/****************************************************************************
|
||||
Process an oplock break directly.
|
||||
****************************************************************************/
|
||||
BOOL oplock_break(uint32 dev, uint32 inode)
|
||||
BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
|
||||
{
|
||||
extern int Client;
|
||||
static char *inbuf = NULL;
|
||||
@ -2633,7 +2644,9 @@ global_oplocks_open = %d\n", dev, inode, global_oplocks_open));
|
||||
if(OPEN_FNUM(fnum))
|
||||
{
|
||||
fsp = &Files[fnum];
|
||||
if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode))
|
||||
if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
|
||||
(fsp->open_time.tv_sec == tval->tv_sec) &&
|
||||
(fsp->open_time.tv_usec == tval->tv_usec))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2797,8 +2810,11 @@ BOOL request_oplock_break(min_share_mode_entry *share_entry,
|
||||
should be %d\n", pid, share_entry->op_port, oplock_port));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
|
||||
|
||||
/* Call oplock break direct. */
|
||||
return oplock_break(dev, inode);
|
||||
return oplock_break(dev, inode, &share_entry->time);
|
||||
}
|
||||
|
||||
/* We need to send a OPLOCK_BREAK_CMD message to the
|
||||
@ -2808,6 +2824,8 @@ should be %d\n", pid, share_entry->op_port, oplock_port));
|
||||
SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
|
||||
SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
|
||||
SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
|
||||
SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
|
||||
SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
|
||||
|
||||
/* set the address and port */
|
||||
bzero((char *)&addr_out,sizeof(addr_out));
|
||||
|
@ -319,7 +319,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l
|
||||
|
||||
reskey = TellDir(Connections[cnum].dirptr);
|
||||
|
||||
DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
|
||||
DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
|
||||
Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
|
||||
|
||||
if (!dname)
|
||||
|
Loading…
Reference in New Issue
Block a user