1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

Fixed the first locking error (test #8 found by locktest code from

Clarion locktest.
Jeremy.
This commit is contained in:
Jeremy Allison 0001-01-01 00:00:00 +00:00
parent 332f646fdc
commit 5c42845b5b
4 changed files with 56 additions and 17 deletions

View File

@ -340,6 +340,26 @@ smbpid = %u, pid = %u, tid = %u\n",
return False;
}
/****************************************************************************
Check to see if this lock conflicts, but ignore our own locks on the
same fnum only.
****************************************************************************/
static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2)
{
if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
return False;
if (brl_same_context(&lck1->context, &lck2->context) &&
lck1->fnum == lck2->fnum)
return False;
if (lck1->start >= (lck2->start + lck2->size) ||
lck2->start >= (lck1->start + lck1->size)) return False;
return True;
}
/****************************************************************************
Test if we could add a lock if we wanted to.
****************************************************************************/
@ -347,7 +367,7 @@ smbpid = %u, pid = %u, tid = %u\n",
BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size,
enum brl_type lock_type)
enum brl_type lock_type, int check_self)
{
TDB_DATA kbuf, dbuf;
int count, i;
@ -373,8 +393,15 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
locks = (struct lock_struct *)dbuf.dptr;
count = dbuf.dsize / sizeof(*locks);
for (i=0; i<count; i++) {
if (brl_conflict(&locks[i], &lock)) {
goto fail;
if (check_self) {
if (brl_conflict(&locks[i], &lock))
goto fail;
} else {
/*
* Our own locks don't conflict.
*/
if (brl_conflict_other(&locks[i], &lock))
goto fail;
}
}
}

View File

@ -53,11 +53,14 @@ static const char *lock_type_name(enum brl_type lock_type)
/****************************************************************************
Utility function called to see if a file region is locked.
If check_self is True, then checks on our own fd with the same locking context
are still made. If check_self is False, then checks are not made on our own fd
with the same locking context are not made.
****************************************************************************/
BOOL is_locked(files_struct *fsp,connection_struct *conn,
SMB_BIG_UINT count,SMB_BIG_UINT offset,
enum brl_type lock_type)
enum brl_type lock_type, BOOL check_self)
{
int snum = SNUM(conn);
BOOL ret;
@ -70,16 +73,25 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
global_smbpid, sys_getpid(), conn->cnum,
offset, count, lock_type);
offset, count, lock_type, check_self);
DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
(double)offset, (double)count, ret ? "locked" : "unlocked",
fsp->fsp_name ));
/*
* There is no lock held by an SMB daemon, check to
* see if there is a POSIX lock from a UNIX or NFS process.
*/
if(!ret && lp_posix_locking(snum))
if(!ret && lp_posix_locking(snum)) {
ret = is_posix_locked(fsp, offset, count, lock_type);
DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
(double)offset, (double)count, ret ? "locked" : "unlocked",
fsp->fsp_name ));
}
return ret;
}

View File

@ -238,7 +238,7 @@ static int truncate_unless_locked(struct connection_struct *conn, files_struct *
{
SMB_BIG_UINT mask = (SMB_BIG_UINT)-1;
if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK)){
if (is_locked(fsp,fsp->conn,mask,0,WRITE_LOCK,True)){
errno = EACCES;
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRlock;

View File

@ -2193,7 +2193,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
maxcount = MIN(65535,maxcount);
maxcount = MAX(mincount,maxcount);
if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK))
if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False))
{
SMB_OFF_T size = fsp->size;
SMB_OFF_T sizeneeded = startpos + maxcount;
@ -2350,7 +2350,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
END_PROFILE(SMBread);
return(ERROR(ERRDOS,ERRlock));
}
@ -2427,7 +2427,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
}
if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
END_PROFILE(SMBreadX);
return(ERROR(ERRDOS,ERRlock));
}
@ -2488,7 +2488,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
CVAL(inbuf,smb_com) = SMBwritec;
CVAL(outbuf,smb_com) = SMBwritec;
if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwritebraw);
return(ERROR(ERRDOS,ERRlock));
}
@ -2584,7 +2584,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
startpos = IVAL(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwriteunlock);
return(ERROR(ERRDOS,ERRlock));
}
@ -2648,7 +2648,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
startpos = IVAL(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwrite);
return(ERROR(ERRDOS,ERRlock));
}
@ -2746,7 +2746,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
#endif /* LARGE_SMB_OFF_T */
}
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwriteX);
return(ERROR(ERRDOS,ERRlock));
}
@ -3031,7 +3031,7 @@ int reply_writeclose(connection_struct *conn,
mtime = make_unix_date3(inbuf+smb_vwv4);
data = smb_buf(inbuf) + 1;
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
END_PROFILE(SMBwriteclose);
return(ERROR(ERRDOS,ERRlock));
}
@ -4556,7 +4556,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
tcount = maxcount;
total_read = 0;
if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
END_PROFILE(SMBreadBmpx);
return(ERROR(ERRDOS,ERRlock));
}
@ -4623,7 +4623,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
not an SMBwritebmpx - set this up now so we don't forget */
CVAL(outbuf,smb_com) = SMBwritec;
if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
END_PROFILE(SMBwriteBmpx);
return(ERROR(ERRDOS,ERRlock));
}