summaryrefslogtreecommitdiffstats
path: root/source/locking
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2000-01-14 04:32:57 +0000
committerAndrew Tridgell <tridge@samba.org>2000-01-14 04:32:57 +0000
commit1b54cb4a33a65e62c2e3189b78ef073869a60c75 (patch)
treedeca330ac65a240a8bb19cbc2cd4ce6724115c52 /source/locking
parent4fbc7358d21f541b7a6e27f768a88007bf390da5 (diff)
downloadsamba-1b54cb4a33a65e62c2e3189b78ef073869a60c75.tar.gz
samba-1b54cb4a33a65e62c2e3189b78ef073869a60c75.tar.xz
samba-1b54cb4a33a65e62c2e3189b78ef073869a60c75.zip
we now pass all byte range locking tests
the last piece was to use a smb timeout slightly larger than the locking timeout in bloking locks to prevent a race
Diffstat (limited to 'source/locking')
-rw-r--r--source/locking/brlock.c59
-rw-r--r--source/locking/locking.c17
2 files changed, 72 insertions, 4 deletions
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index 5d928daa580..653a40728bd 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -43,6 +43,7 @@ struct lock_struct {
struct lock_context context;
br_off start;
br_off size;
+ int fnum;
enum lock_type lock_type;
};
@@ -102,7 +103,7 @@ void brl_init(void)
/****************************************************************************
lock a range of bytes
****************************************************************************/
-BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino,
+BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size,
enum lock_type lock_type)
@@ -127,6 +128,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino,
lock.context.tid = tid;
lock.start = start;
lock.size = size;
+ lock.fnum = fnum;
lock.lock_type = lock_type;
if (dbuf.dptr) {
@@ -161,7 +163,7 @@ BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino,
/****************************************************************************
unlock a range of bytes
****************************************************************************/
-BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino,
+BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size)
{
@@ -192,6 +194,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino,
count = dbuf.dsize / sizeof(*locks);
for (i=0; i<count; i++) {
if (brl_same_context(&locks[i].context, &context) &&
+ locks[i].fnum == fnum &&
locks[i].start == start &&
locks[i].size == size) {
/* found it - delete it */
@@ -273,3 +276,55 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino,
tdb_unlockchain(tdb, kbuf);
return False;
}
+
+
+/****************************************************************************
+remove any locks associated with a open file
+****************************************************************************/
+void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
+{
+ struct lock_key key;
+ TDB_DATA kbuf, dbuf;
+ int count, i;
+ struct lock_struct *locks;
+
+ key.device = dev;
+ key.inode = ino;
+ kbuf.dptr = (char *)&key;
+ kbuf.dsize = sizeof(key);
+
+ dbuf.dptr = NULL;
+
+ tdb_lockchain(tdb, kbuf);
+ dbuf = tdb_fetch(tdb, kbuf);
+
+ if (!dbuf.dptr) goto fail;
+
+ /* there are existing locks - remove any for this fnum */
+ locks = (struct lock_struct *)dbuf.dptr;
+ count = dbuf.dsize / sizeof(*locks);
+ for (i=0; i<count; i++) {
+ if (locks[i].context.tid == tid &&
+ locks[i].context.pid == pid &&
+ locks[i].fnum == fnum) {
+ /* found it - delete it */
+ if (count > 1 && i < count-1) {
+ memmove(&locks[i], &locks[i+1],
+ sizeof(*locks)*((count-1) - i));
+ }
+ count--;
+ i--;
+ }
+ }
+
+ if (count == 0) {
+ tdb_delete(tdb, kbuf);
+ } else if (count < (dbuf.dsize / sizeof(*locks))) {
+ tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+ }
+
+ /* we didn't find it */
+ fail:
+ if (dbuf.dptr) free(dbuf.dptr);
+ tdb_unlockchain(tdb, kbuf);
+}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index e95ec08c58b..350057d1a78 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -40,6 +40,19 @@ static TDB_CONTEXT *tdb;
int global_smbpid;
+
+/****************************************************************************
+remove any locks on this fd
+****************************************************************************/
+void locking_close_file(files_struct *fsp)
+{
+ if (!lp_locking(SNUM(fsp->conn))) return;
+
+ brl_close(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
+ getpid(), fsp->conn->cnum, fsp->fnum);
+}
+
+
/****************************************************************************
Utility function called to see if a file region is locked.
****************************************************************************/
@@ -83,7 +96,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
lock_type, (double)offset, (double)count, fsp->fsp_name ));
if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
- ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
+ ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
global_smbpid, getpid(), conn->cnum,
offset, count,
lock_type);
@@ -114,7 +127,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
(double)offset, (double)count, fsp->fsp_name ));
if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
- ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
+ ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
global_smbpid, getpid(), conn->cnum,
offset, count);
}