summaryrefslogtreecommitdiffstats
path: root/source/locking/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/locking/locking.c')
-rw-r--r--source/locking/locking.c128
1 files changed, 89 insertions, 39 deletions
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 42036cc70cf..0a75420c67c 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 3.0
Locking functions
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Jeremy Allison 1992-2000
@@ -98,15 +99,16 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
****************************************************************************/
static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
- NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
+ NTSTATUS status;
if (!lp_locking(SNUM(conn)))
return NT_STATUS_OK;
/* NOTE! 0 byte long ranges ARE allowed and should be stored */
+
DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
@@ -114,7 +116,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
lock_pid, sys_getpid(), conn->cnum,
offset, count,
- lock_type, my_lock_ctx);
+ lock_type);
if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
@@ -125,11 +127,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
*/
if (!set_posix_lock(fsp, offset, count, lock_type)) {
- if (errno == EACCES || errno == EAGAIN)
- status = NT_STATUS_FILE_LOCK_CONFLICT;
- else
- status = map_nt_error_from_unix(errno);
-
+ status = NT_STATUS_LOCK_NOT_GRANTED;
/*
* We failed to map - we must now remove the brl
* lock entry.
@@ -153,7 +151,7 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
****************************************************************************/
NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
- SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
+ SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type)
{
int j, maxj = lp_lock_spin_count();
int sleeptime = lp_lock_sleep_time();
@@ -165,7 +163,7 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid
ret = NT_STATUS_OK; /* to keep dumb compilers happy */
for (j = 0; j < maxj; j++) {
- status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
+ status = do_lock(fsp, conn, lock_pid, count, offset, lock_type);
if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
return status;
@@ -173,9 +171,6 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid
/* if we do fail then return the first error code we got */
if (j == 0) {
ret = status;
- /* Don't spin if we blocked ourselves. */
- if (*my_lock_ctx)
- return ret;
}
if (sleeptime)
sys_usleep(sleeptime);
@@ -270,6 +265,67 @@ void locking_close_file(files_struct *fsp)
}
}
+#if 0
+/* Not currently used. JRA */
+
+/****************************************************************************
+ Delete a record if it is for a dead process, if check_self is true, then
+ delete any records belonging to this pid also (there shouldn't be any).
+ This function is only called on locking startup and shutdown.
+****************************************************************************/
+
+static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+{
+ struct locking_data *data;
+ share_mode_entry *shares;
+ int i, del_count=0;
+ pid_t mypid = sys_getpid();
+ BOOL check_self = *(BOOL *)state;
+ int ret = 0;
+
+ tdb_chainlock(tdb, kbuf);
+
+ data = (struct locking_data *)dbuf.dptr;
+ shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+
+ for (i=0;i<data->u.num_share_mode_entries;) {
+
+ if (check_self && (shares[i].pid == mypid)) {
+ DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n",
+ (unsigned int)shares[i].pid ));
+ } else if (!process_exists(shares[i].pid)) {
+ DEBUG(0,("locking : delete_fn. LOGIC ERROR ! Entry for pid %u and it no longer exists !\n",
+ (unsigned int)shares[i].pid ));
+ } else {
+ /* Process exists, leave this record alone. */
+ i++;
+ continue;
+ }
+
+ data->u.num_share_mode_entries--;
+ memmove(&shares[i], &shares[i+1],
+ dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
+ del_count++;
+
+ }
+
+ /* the record has shrunk a bit */
+ dbuf.dsize -= del_count * sizeof(*shares);
+
+ /* store it back in the database */
+ if (data->u.num_share_mode_entries == 0) {
+ if (tdb_delete(ttdb, kbuf) == -1)
+ ret = -1;
+ } else {
+ if (tdb_store(ttdb, kbuf, dbuf, TDB_REPLACE) == -1)
+ ret = -1;
+ }
+
+ tdb_chainunlock(tdb, kbuf);
+ return ret;
+}
+#endif
+
/****************************************************************************
Initialise the locking functions.
****************************************************************************/
@@ -283,10 +339,10 @@ BOOL locking_init(int read_only)
if (tdb)
return True;
- tdb = tdb_open_ex(lock_path("locking.tdb"),
+ tdb = tdb_open_log(lock_path("locking.tdb"),
0, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
read_only?O_RDONLY:O_RDWR|O_CREAT,
- 0644, smbd_tdb_log);
+ 0644);
if (!tdb) {
DEBUG(0,("ERROR: Failed to initialise locking database\n"));
@@ -387,8 +443,8 @@ char *share_mode_str(int num, share_mode_entry *e)
static pstring share_str;
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
-pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
- num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
+pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
+ num, e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
(unsigned int)e->dev, (double)e->inode );
return share_str;
@@ -422,10 +478,10 @@ int get_share_modes(connection_struct *conn,
struct locking_data *data;
int num_share_modes;
share_mode_entry *shares = NULL;
- TDB_DATA key = locking_key(dev, inode);
+
*pp_shares = NULL;
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return 0;
@@ -472,7 +528,7 @@ int get_share_modes(connection_struct *conn,
/* The record has shrunk a bit */
dbuf.dsize -= del_count * sizeof(share_mode_entry);
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) {
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1) {
SAFE_FREE(shares);
SAFE_FREE(dbuf.dptr);
return 0;
@@ -547,13 +603,12 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
int i, del_count=0;
share_mode_entry *shares;
ssize_t count = 0;
- TDB_DATA key = locking_key(dev, inode);
if (ppse)
*ppse = NULL;
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return -1;
@@ -594,10 +649,10 @@ ssize_t del_share_entry( SMB_DEV_T dev, SMB_INO_T inode,
/* store it back in the database */
if (data->u.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1)
+ if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
count = -1;
} else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
count = -1;
}
}
@@ -634,11 +689,10 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
struct locking_data *data;
char *p=NULL;
int size;
- TDB_DATA key = locking_key_fsp(fsp);
BOOL ret = True;
/* read in the existing share modes if any */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
if (!dbuf.dptr) {
size_t offset;
/* we'll need to create a new record */
@@ -663,7 +717,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
dbuf.dptr = p;
dbuf.dsize = size;
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
ret = False;
print_share_mode_table((struct locking_data *)p);
@@ -682,10 +736,8 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
size = dbuf.dsize + sizeof(share_mode_entry);
p = malloc(size);
- if (!p) {
- SAFE_FREE(dbuf.dptr);
+ if (!p)
return False;
- }
memcpy(p, dbuf.dptr, sizeof(*data));
fill_share_mode(p + sizeof(*data), fsp, port, op_type);
memcpy(p + sizeof(*data) + sizeof(share_mode_entry), dbuf.dptr + sizeof(*data),
@@ -693,7 +745,7 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
SAFE_FREE(dbuf.dptr);
dbuf.dptr = p;
dbuf.dsize = size;
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE) == -1)
ret = False;
print_share_mode_table((struct locking_data *)p);
SAFE_FREE(p);
@@ -714,10 +766,9 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
share_mode_entry *shares;
BOOL need_store=False;
BOOL ret = True;
- TDB_DATA key = locking_key(dev, inode);
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return False;
@@ -735,10 +786,10 @@ static BOOL mod_share_mode( SMB_DEV_T dev, SMB_INO_T inode, share_mode_entry *en
/* if the mod fn was called then store it back */
if (need_store) {
if (data->u.num_share_mode_entries == 0) {
- if (tdb_delete(tdb, key) == -1)
+ if (tdb_delete(tdb, locking_key(dev, inode)) == -1)
ret = False;
} else {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1)
+ if (tdb_store(tdb, locking_key(dev, inode), dbuf, TDB_REPLACE) == -1)
ret = False;
}
}
@@ -814,10 +865,9 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
struct locking_data *data;
int i;
share_mode_entry *shares;
- TDB_DATA key = locking_key(dev, inode);
/* read in the existing share modes */
- dbuf = tdb_fetch(tdb, key);
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
if (!dbuf.dptr)
return False;
@@ -833,7 +883,7 @@ BOOL modify_delete_flag( SMB_DEV_T dev, SMB_INO_T inode, BOOL delete_on_close)
/* store it back */
if (data->u.num_share_mode_entries) {
- if (tdb_store(tdb, key, dbuf, TDB_REPLACE)==-1) {
+ if (tdb_store(tdb, locking_key(dev,inode), dbuf, TDB_REPLACE)==-1) {
SAFE_FREE(dbuf.dptr);
return False;
}