summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1999-12-21 09:25:59 +0000
committerAndrew Tridgell <tridge@samba.org>1999-12-21 09:25:59 +0000
commit4e1291a83f61a72989045879763d9ef05fd38f71 (patch)
tree0711bf9c940e930c327f9a5a00d65dd6ec1a8ae9
parent69d24d869bf97978b31a51fe8e8d08cac4874d67 (diff)
downloadsamba-4e1291a83f61a72989045879763d9ef05fd38f71.tar.gz
samba-4e1291a83f61a72989045879763d9ef05fd38f71.tar.bz2
samba-4e1291a83f61a72989045879763d9ef05fd38f71.zip
converted all our existing shared memory code to use a tdb database
instead of either sysv or mmap shared memory or lock files. this means we can now completely remove locking_shm.c locking_slow.c shmem.c shmem_sysv.c and lots of other things also got simpler locking.c got a bit larger, but is much better compartmentalised now (This used to be commit e48c2d9937eea0667b8cd3332e49c06314ef31e7)
-rw-r--r--source3/Makefile.in3
-rw-r--r--source3/include/proto.h21
-rw-r--r--source3/include/smb.h16
-rw-r--r--source3/lib/util.c21
-rw-r--r--source3/locking/locking.c423
-rw-r--r--source3/locking/locking_shm.c711
-rw-r--r--source3/locking/locking_slow.c1144
-rw-r--r--source3/locking/shmem.c963
-rw-r--r--source3/locking/shmem_sysv.c724
-rw-r--r--source3/rpc_client/cli_netlogon.c2
-rw-r--r--source3/smbd/close.c7
-rw-r--r--source3/smbd/connection.c27
-rw-r--r--source3/smbd/fileio.c6
-rw-r--r--source3/smbd/open.c33
-rw-r--r--source3/smbd/oplock.c15
-rw-r--r--source3/smbd/trans2.c11
-rw-r--r--source3/tdb/tdb.c65
-rw-r--r--source3/utils/status.c33
-rw-r--r--source3/web/statuspage.c8
19 files changed, 428 insertions, 3805 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index ca85566703..5236274255 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -135,8 +135,7 @@ RPC_CLIENT_OBJ = \
rpc_client/cli_samr.o
-LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \
- locking/shmem.o locking/shmem_sysv.o
+LOCKING_OBJ = locking/locking.o
PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
passdb/pass_check.o passdb/ldap.o passdb/nispass.o passdb/smbpasschange.o
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 125ef3a27c..401a619110 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -299,6 +299,7 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name);
char *smbd_mktemp(char *template);
void *memdup(void *p, size_t size);
char *myhostname(void);
+char *lock_path(char *name);
/*The following definitions come from lib/util_file.c */
@@ -618,17 +619,18 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
BOOL locking_init(int read_only);
BOOL locking_end(void);
BOOL lock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int *ptok);
+ SMB_DEV_T dev, SMB_INO_T inode);
BOOL unlock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int token);
+ SMB_DEV_T dev, SMB_INO_T inode);
int get_share_modes(connection_struct *conn,
- int token, SMB_DEV_T dev, SMB_INO_T inode,
+ SMB_DEV_T dev, SMB_INO_T inode,
share_mode_entry **shares);
-void del_share_mode(int token, files_struct *fsp);
-BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type);
-BOOL remove_share_oplock(int token, files_struct *fsp);
-BOOL downgrade_share_oplock(int token, files_struct *fsp);
-BOOL modify_share_mode(int token, files_struct *fsp, int new_mode, uint16 new_oplock);
+void del_share_mode(files_struct *fsp);
+BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type);
+BOOL remove_share_oplock(files_struct *fsp);
+BOOL downgrade_share_oplock(files_struct *fsp);
+BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock);
+int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf);
int share_mode_forall(void (*fn)(share_mode_entry *, char *));
void share_status(FILE *f);
@@ -2375,7 +2377,6 @@ void conn_free(connection_struct *conn);
/*The following definitions come from smbd/connection.c */
-TDB_CONTEXT *open_db(char *name);
BOOL yield_connection(connection_struct *conn,char *name,int max_connections);
int delete_dead(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf);
BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear);
@@ -2809,6 +2810,8 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int flags, mode_t mode);
int tdb_close(TDB_CONTEXT *tdb);
int tdb_writelock(TDB_CONTEXT *tdb);
int tdb_writeunlock(TDB_CONTEXT *tdb);
+int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key);
/*The following definitions come from utils/nbio.c */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 6c3d7488c3..de269f1d7d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -858,6 +858,22 @@ struct connections_data {
time_t start;
};
+
+/* key and data records in the tdb locking database */
+struct locking_key {
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+};
+
+struct locking_data {
+ int num_share_mode_entries;
+ /* the following two entries are implicit
+ share_mode_entry modes[num_share_mode_entries];
+ char file_name[];
+ */
+};
+
+
/* the following are used by loadparm for option lists */
typedef enum
{
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 8f904d486d..d3a63691df 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3213,3 +3213,24 @@ char *myhostname(void)
}
return ret;
}
+
+
+/*****************************************************************
+a useful function for returning a path in the Samba lock directory
+ *****************************************************************/
+char *lock_path(char *name)
+{
+ static pstring fname;
+
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL)) {
+ mkdir(fname,0755);
+ }
+
+ pstrcat(fname,"/");
+ pstrcat(fname,name);
+
+ return fname;
+}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 012d954e50..fc4ce725c5 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -1,8 +1,8 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 3.0
Locking functions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,42 +29,43 @@
September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
support.
+ rewrtten completely to use new tdb code. Tridge, Dec '99
*/
#include "includes.h"
extern int DEBUGLEVEL;
-static struct share_ops *share_ops;
+/* the locking database handle */
+static TDB_CONTEXT *tdb;
/****************************************************************************
Utility function to map a lock type correctly depending on the real open
mode of a file.
****************************************************************************/
-
-static int map_lock_type( files_struct *fsp, int lock_type)
+static int map_lock_type(files_struct *fsp, int lock_type)
{
- if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) {
- /*
- * Many UNIX's cannot get a write lock on a file opened read-only.
- * Win32 locking semantics allow this.
- * Do the best we can and attempt a read-only lock.
- */
- DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n"));
- return F_RDLCK;
- } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) {
- /*
- * Ditto for read locks on write only files.
- */
- DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n"));
- return F_WRLCK;
- }
-
- /*
- * This return should be the most normal, as we attempt
- * to always open files read/write.
- */
-
- return lock_type;
+ if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) {
+ /*
+ * Many UNIX's cannot get a write lock on a file opened read-only.
+ * Win32 locking semantics allow this.
+ * Do the best we can and attempt a read-only lock.
+ */
+ DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n"));
+ return F_RDLCK;
+ } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) {
+ /*
+ * Ditto for read locks on write only files.
+ */
+ DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n"));
+ return F_WRLCK;
+ }
+
+ /*
+ * This return should be the most normal, as we attempt
+ * to always open files read/write.
+ */
+
+ return lock_type;
}
/****************************************************************************
@@ -74,7 +75,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
SMB_OFF_T count,SMB_OFF_T offset, int lock_type)
{
int snum = SNUM(conn);
-
+
if (count == 0)
return(False);
@@ -98,30 +99,30 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
int *eclass,uint32 *ecode)
{
- BOOL ok = False;
-
- if (!lp_locking(SNUM(conn)))
- return(True);
-
- if (count == 0) {
- *eclass = ERRDOS;
- *ecode = ERRnoaccess;
- return False;
- }
-
- DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n",
- lock_type, (double)offset, (double)count, fsp->fsp_name ));
-
- if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
- ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
- map_lock_type(fsp,lock_type));
-
- if (!ok) {
- *eclass = ERRDOS;
- *ecode = ERRlock;
- return False;
- }
- return True; /* Got lock */
+ BOOL ok = False;
+
+ if (!lp_locking(SNUM(conn)))
+ return(True);
+
+ if (count == 0) {
+ *eclass = ERRDOS;
+ *ecode = ERRnoaccess;
+ return False;
+ }
+
+ DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n",
+ lock_type, (double)offset, (double)count, fsp->fsp_name ));
+
+ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
+ ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
+ map_lock_type(fsp,lock_type));
+
+ if (!ok) {
+ *eclass = ERRDOS;
+ *ecode = ERRlock;
+ return False;
+ }
+ return True; /* Got lock */
}
@@ -131,46 +132,38 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
BOOL do_unlock(files_struct *fsp,connection_struct *conn,
SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode)
{
- BOOL ok = False;
-
- if (!lp_locking(SNUM(conn)))
- return(True);
-
- DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
- (double)offset, (double)count, fsp->fsp_name ));
-
- if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
- ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
+ BOOL ok = False;
+
+ if (!lp_locking(SNUM(conn)))
+ return(True);
+
+ DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
+ (double)offset, (double)count, fsp->fsp_name ));
+
+ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
+ ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
- if (!ok) {
- *eclass = ERRDOS;
- *ecode = ERRlock;
- return False;
- }
- return True; /* Did unlock */
+ if (!ok) {
+ *eclass = ERRDOS;
+ *ecode = ERRlock;
+ return False;
+ }
+ return True; /* Did unlock */
}
/****************************************************************************
Initialise the locking functions.
****************************************************************************/
-
BOOL locking_init(int read_only)
{
- if (share_ops)
- return True;
+ if (tdb) return True;
-#ifdef FAST_SHARE_MODES
- share_ops = locking_shm_init(read_only);
- if (!share_ops && read_only && (getuid() == 0)) {
- /* this may be the first time the share modes code has
- been run. Initialise it now by running it read-write */
- share_ops = locking_shm_init(0);
- }
-#else
- share_ops = locking_slow_init(read_only);
-#endif
+ tdb = tdb_open(lock_path("locking.tdb"),
+ 0,
+ read_only?O_RDONLY:O_RDWR|O_CREAT,
+ 0644);
- if (!share_ops) {
+ if (!tdb) {
DEBUG(0,("ERROR: Failed to initialise share modes\n"));
return False;
}
@@ -181,110 +174,271 @@ BOOL locking_init(int read_only)
/*******************************************************************
Deinitialize the share_mode management.
******************************************************************/
-
BOOL locking_end(void)
{
- if (share_ops)
- return share_ops->stop_mgmt();
+ if (tdb && tdb_close(tdb) != 0) return False;
return True;
}
+/*******************************************************************
+ form a static locking key for a dev/inode pair
+******************************************************************/
+static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
+{
+ static struct locking_key key;
+ TDB_DATA kbuf;
+ key.dev = dev;
+ key.inode = inode;
+ kbuf.dptr = (char *)&key;
+ kbuf.dsize = sizeof(key);
+ return kbuf;
+}
+static TDB_DATA locking_key_fsp(files_struct *fsp)
+{
+ return locking_key(fsp->fd_ptr->dev, fsp->fd_ptr->inode);
+}
/*******************************************************************
Lock a hash bucket entry.
******************************************************************/
BOOL lock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
+ SMB_DEV_T dev, SMB_INO_T inode)
{
- return share_ops->lock_entry(conn, dev, inode, ptok);
+ return tdb_lockchain(tdb, locking_key(dev, inode)) == 0;
}
/*******************************************************************
Unlock a hash bucket entry.
******************************************************************/
BOOL unlock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int token)
+ SMB_DEV_T dev, SMB_INO_T inode)
{
- return share_ops->unlock_entry(conn, dev, inode, token);
+ return tdb_unlockchain(tdb, locking_key(dev, inode)) == 0;
}
/*******************************************************************
Get all share mode entries for a dev/inode pair.
********************************************************************/
int get_share_modes(connection_struct *conn,
- int token, SMB_DEV_T dev, SMB_INO_T inode,
+ SMB_DEV_T dev, SMB_INO_T inode,
share_mode_entry **shares)
{
- return share_ops->get_entries(conn, token, dev, inode, shares);
+ TDB_DATA dbuf;
+ struct locking_data *data;
+ int ret;
+
+ dbuf = tdb_fetch(tdb, locking_key(dev, inode));
+ if (!dbuf.dptr) return 0;
+
+ data = (struct locking_data *)dbuf.dptr;
+ ret = data->num_share_mode_entries;
+ *shares = (share_mode_entry *)memdup(dbuf.dptr + sizeof(*data), ret * sizeof(**shares));
+ free(dbuf.dptr);
+
+ if (! *shares) return 0;
+
+ return ret;
+}
+
+/*******************************************************************
+ Del the share mode of a file for this process
+********************************************************************/
+void del_share_mode(files_struct *fsp)
+{
+ TDB_DATA dbuf;
+ struct locking_data *data;
+ int i, del_count=0;
+ share_mode_entry *shares;
+ pid_t pid = getpid();
+
+ /* read in the existing share modes */
+ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
+ if (!dbuf.dptr) return;
+
+ data = (struct locking_data *)dbuf.dptr;
+ shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+
+ /* find any with our pid and delete it by overwriting with the rest of the data
+ from the record */
+ for (i=0;i<data->num_share_mode_entries;) {
+ if (shares[i].pid == pid &&
+ memcmp(&shares[i].time,
+ &fsp->open_time,sizeof(struct timeval)) == 0) {
+ data->num_share_mode_entries--;
+ memmove(&shares[i], &shares[i+1],
+ dbuf.dsize - (sizeof(*data) + (i+1)*sizeof(*shares)));
+ del_count++;
+ } else {
+ i++;
+ }
+ }
+
+ /* the record has shrunk a bit */
+ dbuf.dsize -= del_count * sizeof(*shares);
+
+ /* store it back in the database */
+ tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+
+ free(dbuf.dptr);
}
/*******************************************************************
- Del the share mode of a file.
+fill a share mode entry
********************************************************************/
-void del_share_mode(int token, files_struct *fsp)
+static void fill_share_mode(char *p, files_struct *fsp, uint16 port, uint16 op_type)
{
- share_ops->del_entry(token, fsp);
+ share_mode_entry *e = (share_mode_entry *)p;
+ e->pid = getpid();
+ e->share_mode = fsp->share_mode;
+ e->op_port = port;
+ e->op_type = op_type;
+ memcpy((char *)&e->time, (char *)&fsp->open_time, sizeof(struct timeval));
}
/*******************************************************************
Set the share mode of a file. Return False on fail, True on success.
********************************************************************/
-BOOL set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
+BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type)
{
- return share_ops->set_entry(token, fsp, port, op_type);
+ TDB_DATA dbuf;
+ struct locking_data *data;
+ share_mode_entry *shares;
+ char *p=NULL;
+ int size;
+
+ /* read in the existing share modes if any */
+ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
+ if (!dbuf.dptr) {
+ /* we'll need to create a new record */
+ pstring fname;
+
+ pstrcpy(fname, fsp->conn->connectpath);
+ pstrcat(fname, "/");
+ pstrcat(fname, fsp->fsp_name);
+
+ size = sizeof(*data) + sizeof(*shares) + strlen(fname) + 1;
+ p = (char *)malloc(size);
+ data = (struct locking_data *)p;
+ shares = (share_mode_entry *)(p + sizeof(*data));
+ data->num_share_mode_entries = 1;
+ pstrcpy(p + sizeof(*data) + sizeof(*shares), fname);
+ fill_share_mode(p + sizeof(*data), fsp, port, op_type);
+ dbuf.dptr = p;
+ dbuf.dsize = size;
+ tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ free(p);
+ return True;
+ }
+
+ /* we're adding to an existing entry - this is a bit fiddly */
+ data = (struct locking_data *)dbuf.dptr;
+ shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+
+ data->num_share_mode_entries++;
+ size = dbuf.dsize + sizeof(*shares);
+ p = malloc(size);
+ memcpy(p, dbuf.dptr, sizeof(*data));
+ fill_share_mode(p + sizeof(*data), fsp, port, op_type);
+ memcpy(p + sizeof(*data) + sizeof(*shares), dbuf.dptr + sizeof(*data),
+ dbuf.dsize - sizeof(*data));
+ free(dbuf.dptr);
+ dbuf.dptr = p;
+ dbuf.dsize = size;
+ tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ free(p);
+ return True;
}
+
+/*******************************************************************
+a generic in-place modification call for share mode entries
+********************************************************************/
+static BOOL mod_share_mode(files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
+{
+ TDB_DATA dbuf;
+ struct locking_data *data;
+ int i;
+ share_mode_entry *shares;
+ pid_t pid = getpid();
+ int need_store=0;
+
+ /* read in the existing share modes */
+ dbuf = tdb_fetch(tdb, locking_key_fsp(fsp));
+ if (!dbuf.dptr) return False;
+
+ data = (struct locking_data *)dbuf.dptr;
+ shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+
+ /* find any with our pid and call the supplied function */
+ for (i=0;i<data->num_share_mode_entries;i++) {
+ if (pid == shares[i].pid &&
+ shares[i].share_mode == fsp->share_mode &&
+ memcmp(&shares[i].time,
+ &fsp->open_time,sizeof(struct timeval)) == 0) {
+ mod_fn(&shares[i], fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
+ need_store=1;
+ }
+ }
+
+ /* if the mod fn was called then store it back */
+ if (need_store) {
+ tdb_store(tdb, locking_key_fsp(fsp), dbuf, TDB_REPLACE);
+ }
+
+ free(dbuf.dptr);
+ return need_store;
+}
+
+
/*******************************************************************
Static function that actually does the work for the generic function
below.
********************************************************************/
-
static void remove_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
void *param)
{
- DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode ));
- /* Delete the oplock info. */
- entry->op_port = 0;
- entry->op_type = NO_OPLOCK;
+ DEBUG(10,("remove_share_oplock_fn: removing oplock info for entry dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode ));
+ /* Delete the oplock info. */
+ entry->op_port = 0;
+ entry->op_type = NO_OPLOCK;
}
/*******************************************************************
Remove an oplock port and mode entry from a share mode.
********************************************************************/
-
-BOOL remove_share_oplock(int token, files_struct *fsp)
+BOOL remove_share_oplock(files_struct *fsp)
{
- return share_ops->mod_entry(token, fsp, remove_share_oplock_fn, NULL);
+ return mod_share_mode(fsp, remove_share_oplock_fn, NULL);
}
/*******************************************************************
Static function that actually does the work for the generic function
below.
********************************************************************/
-
static void downgrade_share_oplock_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO_T inode,
void *param)
{
- DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode ));
- entry->op_type = LEVEL_II_OPLOCK;
+ DEBUG(10,("downgrade_share_oplock_fn: downgrading oplock info for entry dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode ));
+ entry->op_type = LEVEL_II_OPLOCK;
}
/*******************************************************************
Downgrade a oplock type from exclusive to level II.
********************************************************************/
-
-BOOL downgrade_share_oplock(int token, files_struct *fsp)
+BOOL downgrade_share_oplock(files_struct *fsp)
{
- return share_ops->mod_entry(token, fsp, downgrade_share_oplock_fn, NULL);
+ return mod_share_mode(fsp, downgrade_share_oplock_fn, NULL);
}
+
/*******************************************************************
Static function that actually does the work for the generic function
below.
********************************************************************/
-
struct mod_val {
int new_share_mode;
uint16 new_oplock;
@@ -308,33 +462,46 @@ static void modify_share_mode_fn(share_mode_entry *entry, SMB_DEV_T dev, SMB_INO
Modify a share mode on a file. Used by the delete open file code.
Return False on fail, True on success.
********************************************************************/
-
-BOOL modify_share_mode(int token, files_struct *fsp, int new_mode, uint16 new_oplock)
+BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock)
{
struct mod_val mv;
mv.new_share_mode = new_mode;
- mv.new_oplock = new_oplock;
+ mv.new_oplock = new_oplock;
- return share_ops->mod_entry(token, fsp, modify_share_mode_fn, (void *)&mv);
+ return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv);
}
-/*******************************************************************
- Call the specified function on each entry under management by the
- share mode system.
-********************************************************************/
+static void (*traverse_callback)(share_mode_entry *, char *);
-int share_mode_forall(void (*fn)(share_mode_entry *, char *))
+/****************************************************************************
+traverse the whole database with this function, calling traverse_callback
+on each share mode
+****************************************************************************/
+int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
{
- if (!share_ops) return 0;
- return share_ops->forall(fn);
+ struct locking_data *data;
+ share_mode_entry *shares;
+ char *name;
+ int i;
+
+ data = (struct locking_data *)dbuf.dptr;
+ shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
+ name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares);
+
+ for (i=0;i<data->num_share_mode_entries;i++) {
+ traverse_callback(&shares[i], name);
+ }
+ return 0;
}
/*******************************************************************
- Dump the state of the system.
+ Call the specified function on each entry under management by the
+ share mode system.
********************************************************************/
-
-void share_status(FILE *f)
+int share_mode_forall(void (*fn)(share_mode_entry *, char *))
{
- share_ops->status(f);
+ if (!tdb) return 0;
+ traverse_callback = fn;
+ return tdb_traverse(tdb, traverse_fn);
}
diff --git a/source3/locking/locking_shm.c b/source3/locking/locking_shm.c
deleted file mode 100644
index 174ad73e97..0000000000
--- a/source3/locking/locking_shm.c
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- shared memory locking implementation
- Copyright (C) Andrew Tridgell 1992-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Revision History:
-
- 12 aug 96: Erik.Devriendt@te6.siemens.be
- added support for shared memory implementation of share mode locking
-
- May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
- locking to deal with multiple share modes per open file.
-
- September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
- support.
-
- October 1997 - split into separate file (tridge)
-*/
-
-#include "includes.h"
-
-#ifdef FAST_SHARE_MODES
-
-extern int DEBUGLEVEL;
-
-static struct shmem_ops *shmops;
-
-/* share mode record pointed to in shared memory hash bucket */
-typedef struct
-{
- int next_offset; /* offset of next record in chain from hash bucket */
- int locking_version;
- SMB_DEV_T st_dev;
- SMB_INO_T st_ino;
- int num_share_mode_entries;
- int share_mode_entries; /* Chain of share mode entries for this file */
- char file_name[1];
-} share_mode_record;
-
-/* share mode entry pointed to by share_mode_record struct */
-typedef struct
-{
- int next_share_mode_entry;
- share_mode_entry e;
-} shm_share_mode_entry;
-
-static int read_only;
-
-
-/* Conversion to hash entry index from device and inode numbers. */
-#define HASH_ENTRY(dev,ino) ((unsigned int)(((dev) ^ (ino)) % shmops->hash_size()))
-
-
-/*******************************************************************
- deinitialize the shared memory for share_mode management
- ******************************************************************/
-static BOOL shm_stop_share_mode_mgmt(void)
-{
- return shmops->shm_close();
-}
-
-/*******************************************************************
- lock a hash bucket entry in shared memory for share_mode management
- ******************************************************************/
-static BOOL shm_lock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
-{
- *ptok = 0; /* For purify... */
- return shmops->lock_hash_entry(HASH_ENTRY(dev, inode));
-}
-
-/*******************************************************************
- unlock a hash bucket entry in shared memory for share_mode management
- ******************************************************************/
-static BOOL shm_unlock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int token)
-{
- return shmops->unlock_hash_entry(HASH_ENTRY(dev, inode));
-}
-
-/*******************************************************************
-get all share mode entries in shared memory for a dev/inode pair.
-********************************************************************/
-static int shm_get_share_modes(connection_struct *conn,
- int token, SMB_DEV_T dev, SMB_INO_T inode,
- share_mode_entry **old_shares)
-{
- int *mode_array;
- unsigned int hash_entry = HASH_ENTRY(dev, inode);
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- shm_share_mode_entry *entry_scanner_p;
- shm_share_mode_entry *entry_prev_p;
- int num_entries;
- int num_entries_copied;
- BOOL found = False;
- share_mode_entry *share_array = (share_mode_entry *)0;
-
- *old_shares = 0;
-
- mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
-
- if(mode_array[hash_entry] == 0)
- {
- DEBUG(5,("get_share_modes hash bucket %d empty\n", hash_entry));
- return 0;
- }
-
- file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)shmops->offset2addr(
- file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(5,("get_share_modes no entry for file dev = %x ino = %.0f\n",
- (unsigned int)dev, (double)inode));
- return (0);
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: get_share_modes Deleting old share mode v1 %d dev=%x ino=%.0f\n",
- file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
-
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- shmops->shm_free(shmops->addr2offset(file_scanner_p));
- return (0);
- }
-
- /* Allocate the old_shares array */
- num_entries = file_scanner_p->num_share_mode_entries;
- if(num_entries)
- {
- *old_shares = share_array = (share_mode_entry *)
- malloc(num_entries * sizeof(share_mode_entry));
- if(*old_shares == 0)
- {
- DEBUG(0,("get_share_modes: malloc fail for size 0x%x!\n", (unsigned int)(num_entries * sizeof(share_mode_entry))));
- return 0;
- }
- }
-
- num_entries_copied = 0;
-
- entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- while(entry_scanner_p)
- {
- pid_t pid = entry_scanner_p->e.pid;
-
- if (pid && !process_exists(pid))
- {
- /* Delete this share mode entry */
- shm_share_mode_entry *delete_entry_p = entry_scanner_p;
-
- if(entry_prev_p == entry_scanner_p)
- {
- /* We are at start of list */
- file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
- entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- }
- else
- {
- entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
- entry_scanner_p = (shm_share_mode_entry*)
- shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- /* Decrement the number of share mode entries on this share mode record */
- file_scanner_p->num_share_mode_entries -= 1;
-
- /* PARANOIA TEST */
- if(file_scanner_p->num_share_mode_entries < 0)
- {
- DEBUG(0,("PANIC ERROR: get_share_mode: entries=%d dev=%x ino=%.0f\n",
- file_scanner_p->num_share_mode_entries, (unsigned int)dev, (double)inode));
- return 0;
- }
-
- DEBUG(0,("get_share_modes: process %d no longer exists\n", (int)pid));
-
- shmops->shm_free(shmops->addr2offset(delete_entry_p));
- }
- else
- {
- /* This is a valid share mode entry and the process that
- created it still exists. Copy it into the output array.
- */
- share_array[num_entries_copied].pid = entry_scanner_p->e.pid;
- share_array[num_entries_copied].share_mode = entry_scanner_p->e.share_mode;
- share_array[num_entries_copied].op_port = entry_scanner_p->e.op_port;
- share_array[num_entries_copied].op_type = entry_scanner_p->e.op_type;
- memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->e.time,
- sizeof(struct timeval));
- num_entries_copied++;
- DEBUG(5,("get_share_modes Read share mode 0x%X pid=%d\n",
- entry_scanner_p->e.share_mode, (int)entry_scanner_p->e.pid));
- entry_prev_p = entry_scanner_p;
- entry_scanner_p = (shm_share_mode_entry *)
- shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- /* If no valid share mode entries were found then this record shouldn't exist ! */
- if(num_entries_copied == 0)
- {
- DEBUG(0,("get_share_modes: file with dev %x inode %.0f empty\n",
- (unsigned int)dev, (double)inode));
-
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
-
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- shmops->shm_free(shmops->addr2offset(file_scanner_p));
- }
-
- DEBUG(5,("get_share_modes: file with dev %x inode %.0f -> %d entries\n",
- (unsigned int)dev, (double)inode, num_entries_copied));
-
- return(num_entries_copied);
-}
-
-/*******************************************************************
-del the share mode of a file.
-********************************************************************/
-static void shm_del_share_mode(int token, files_struct *fsp)
-{
- SMB_DEV_T dev;
- SMB_INO_T inode;
- int *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- shm_share_mode_entry *entry_scanner_p;
- shm_share_mode_entry *entry_prev_p;
- BOOL found = False;
- pid_t pid = getpid();
-
- dev = fsp->fd_ptr->dev;
- inode = fsp->fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
-
- mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
-
- if(mode_array[hash_entry] == 0)
- {
- DEBUG(0,("PANIC ERROR:del_share_mode hash bucket %d empty\n",
- hash_entry));
- return;
- }
-
- file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- shmops->offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR: del_share_mode no entry for dev %x inode %.0f\n",
- (unsigned int)dev, (double)inode));
- return;
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: del_share_modes Deleting old share mode v1 %d dev=%x ino=%.0f\n",
- file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
-
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- shmops->shm_free(shmops->addr2offset(file_scanner_p));
- return;
- }
-
- found = False;
- entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- while(entry_scanner_p)
- {
- if( (pid == entry_scanner_p->e.pid) &&
- (memcmp(&entry_scanner_p->e.time,
- &fsp->open_time,sizeof(struct timeval)) == 0) )
- {
- found = True;
- break;
- }
- else
- {
- entry_prev_p = entry_scanner_p;
- entry_scanner_p = (shm_share_mode_entry *)
- shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- if (found)
- {
- /* Decrement the number of entries in the record. */
- file_scanner_p->num_share_mode_entries -= 1;
-
- DEBUG(2,("del_share_modes Deleting share mode entry dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode));
-
- if(entry_prev_p == entry_scanner_p)
- /* We are at start of list */
- file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
- else
- entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
- shmops->shm_free(shmops->addr2offset(entry_scanner_p));
-
- /* PARANOIA TEST */
- if(file_scanner_p->num_share_mode_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:del_share_mode num_share_mode_entries=%d\n",
- file_scanner_p->num_share_mode_entries));
- return;
- }
-
- /* If we deleted the last share mode entry then remove the share mode record. */
- if(file_scanner_p->num_share_mode_entries == 0)
- {
- DEBUG(2,("del_share_modes num entries = 0, deleting share_mode dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode));
-
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- shmops->shm_free(shmops->addr2offset(file_scanner_p));
- }
- }
- else
- {
- DEBUG(0,("ERROR: del_share_modes No share mode dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode));
- }
-}
-
-/*******************************************************************
-set the share mode of a file. Return False on fail, True on success.
-********************************************************************/
-static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
-{
- SMB_DEV_T dev;
- SMB_INO_T inode;
- int *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- shm_share_mode_entry *new_entry_p;
- int new_entry_offset;
- BOOL found = False;
-
- dev = fsp->fd_ptr->dev;
- inode = fsp->fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
-
- mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
-
- file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_scanner_p = (share_mode_record *)
- shmops->offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- /* We must create a share_mode_record */
- share_mode_record *new_mode_p = NULL;
- int new_offset = shmops->shm_alloc(sizeof(share_mode_record) +
- strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2);
- if(new_offset == 0) {
- DEBUG(0,("ERROR:set_share_mode shmops->shm_alloc fail!\n"));
- return False;
- }
- new_mode_p = shmops->offset2addr(new_offset);
- new_mode_p->locking_version = LOCKING_VERSION;
- new_mode_p->st_dev = dev;
- new_mode_p->st_ino = inode;
- new_mode_p->num_share_mode_entries = 0;
- new_mode_p->share_mode_entries = 0;
- pstrcpy(new_mode_p->file_name, fsp->conn->connectpath);
- pstrcat(new_mode_p->file_name, "/");
- pstrcat(new_mode_p->file_name, fsp->fsp_name);
-
- /* Chain onto the start of the hash chain (in the hope we will be used first). */
- new_mode_p->next_offset = mode_array[hash_entry];
- mode_array[hash_entry] = new_offset;
-
- file_scanner_p = new_mode_p;
-
- DEBUG(3,("set_share_mode: Created share record for %s (dev %x inode %.0f)\n",
- fsp->fsp_name, (unsigned int)dev, (double)inode));
- }
-
- /* Now create the share mode entry */
- new_entry_offset = shmops->shm_alloc(sizeof(shm_share_mode_entry));
- if(new_entry_offset == 0) {
- int delete_offset = mode_array[hash_entry];
- DEBUG(0,("ERROR:set_share_mode: shmops->shm_alloc fail 1!\n"));
- /* Unlink the damaged record */
- mode_array[hash_entry] = file_scanner_p->next_offset;
- /* And delete it */
- shmops->shm_free( delete_offset );
- return False;
- }
-
- new_entry_p = shmops->offset2addr(new_entry_offset);
-
- new_entry_p->e.pid = getpid();
- new_entry_p->e.share_mode = fsp->share_mode;
- new_entry_p->e.op_port = port;
- new_entry_p->e.op_type = op_type;
- memcpy( (char *)&new_entry_p->e.time, (char *)&fsp->open_time, sizeof(struct timeval));
-
- /* Chain onto the share_mode_record */
- new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
- file_scanner_p->share_mode_entries = new_entry_offset;
-
- /* PARANOIA TEST */
- if(file_scanner_p->num_share_mode_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:set_share_mode num_share_mode_entries=%d\n",
- file_scanner_p->num_share_mode_entries));
- return False;
- }
-
- /* Increment the share_mode_entries counter */
- file_scanner_p->num_share_mode_entries += 1;
-
- DEBUG(3,("set_share_mode: Created share entry for %s with mode 0x%X pid=%d\n",
- fsp->fsp_name, fsp->share_mode, (int)new_entry_p->e.pid));
-
- return(True);
-}
-
-/*******************************************************************
- Call a generic modify function for a share mode entry.
-********************************************************************/
-
-static BOOL shm_mod_share_entry(int token, files_struct *fsp,
- void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
- void *param)
-{
- SMB_DEV_T dev;
- SMB_INO_T inode;
- int *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- shm_share_mode_entry *entry_scanner_p;
- BOOL found = False;
- pid_t pid = getpid();
-
- dev = fsp->fd_ptr->dev;
- inode = fsp->fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
-
- mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
-
- if(mode_array[hash_entry] == 0)
- {
- DEBUG(0,("PANIC ERROR:modify_share_entry: hash bucket %d empty\n",
- hash_entry));
- return False;
- }
-
- file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- shmops->offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR:modify_share_entry: no entry found for dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode));
- return False;
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: modify_share_entry: Deleting old share mode v1=%d dev=%x ino=%.0f\n",
- file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
-
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- shmops->shm_free(shmops->addr2offset(file_scanner_p));
- return False;
- }
-
- found = False;
- entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
- file_scanner_p->share_mode_entries);
- while(entry_scanner_p)
- {
- if( (pid == entry_scanner_p->e.pid) &&
- (entry_scanner_p->e.share_mode == fsp->share_mode) &&
- (memcmp(&entry_scanner_p->e.time,
- &fsp->open_time,sizeof(struct timeval)) == 0) )
- {
- /*
- * Call the generic function with the given parameter.
- */
-
- DEBUG(5,("modify_share_entry: Calling generic function to modify entry for dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode));
-
- (*mod_fn)( &entry_scanner_p->e, dev, inode, param);
- found = True;
- break;
- }
- else
- {
- entry_scanner_p = (shm_share_mode_entry *)
- shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR: modify_share_entry: No entry found for dev=%x ino=%.0f\n",
- (unsigned int)dev, (double)inode));
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
-call the specified function on each entry under management by the
-share mode system
-********************************************************************/
-static int shm_share_forall(void (*fn)(share_mode_entry *, char *))
-{
- int i, count=0;
- int *mode_array;
- share_mode_record *file_scanner_p;
-
- mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
-
- for( i = 0; i < shmops->hash_size(); i++) {
- shmops->lock_hash_entry(i);
- if(mode_array[i] == 0) {
- shmops->unlock_hash_entry(i);
- continue;
- }
-
- file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[i]);
- while((file_scanner_p != 0) &&
- (file_scanner_p->num_share_mode_entries != 0)) {
- shm_share_mode_entry *entry_scanner_p =
- (shm_share_mode_entry *)
- shmops->offset2addr(file_scanner_p->share_mode_entries);
-
- while(entry_scanner_p != 0) {
-
- if (process_exists(entry_scanner_p->e.pid)) {
- fn(&entry_scanner_p->e,
- file_scanner_p->file_name);
- count++;
- }
-
- entry_scanner_p =
- (shm_share_mode_entry *)
- shmops->offset2addr(
- entry_scanner_p->next_share_mode_entry);
- } /* end while entry_scanner_p */
- file_scanner_p = (share_mode_record *)
- shmops->offset2addr(file_scanner_p->next_offset);
- } /* end while file_scanner_p */
- shmops->unlock_hash_entry(i);
- } /* end for */
-
- return count;
-}
-
-
-/*******************************************************************
-dump the state of the system
-********************************************************************/
-static void shm_share_status(FILE *f)
-{
- int bytes_free, bytes_used, bytes_overhead, bytes_total;
-
- shmops->get_usage(&bytes_free, &bytes_used, &bytes_overhead);
- bytes_total = bytes_free + bytes_used + bytes_overhead;
-
- fprintf(f, "Share mode memory usage (bytes):\n");
- fprintf(f, " %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
- bytes_free, (bytes_free * 100)/bytes_total,
- bytes_used, (bytes_used * 100)/bytes_total,
- bytes_overhead, (bytes_overhead * 100)/bytes_total,
- bytes_total);
-}
-
-
-static struct share_ops share_ops = {
- shm_stop_share_mode_mgmt,
- shm_lock_share_entry,
- shm_unlock_share_entry,
- shm_get_share_modes,
- shm_del_share_mode,
- shm_set_share_mode,
- shm_mod_share_entry,
- shm_share_forall,
- shm_share_status,
-};
-
-/*******************************************************************
- initialize the shared memory for share_mode management
- ******************************************************************/
-struct share_ops *locking_shm_init(int ronly)
-{
- read_only = ronly;
-
-#ifdef USE_SYSV_IPC
- shmops = sysv_shm_open(read_only);
- if (shmops) return &share_ops;
-#endif
-
-#ifdef USE_SHARED_MMAP
- shmops = smb_shm_open(read_only);
- if (shmops) return &share_ops;
-#endif
-
- return NULL;
-}
-
-#else
- int locking_shm_dummy_procedure(void)
-{return 0;}
-#endif /* FAST_SHARE_MODES */
diff --git a/source3/locking/locking_slow.c b/source3/locking/locking_slow.c
deleted file mode 100644
index 58673d2707..0000000000
--- a/source3/locking/locking_slow.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- slow (lockfile) locking implementation
- Copyright (C) Andrew Tridgell 1992-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Revision History:
-
- 12 aug 96: Erik.Devriendt@te6.siemens.be
- added support for shared memory implementation of share mode locking
-
- May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
- locking to deal with multiple share modes per open file.
-
- September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
- support.
-
- October 1997 - split into separate file (tridge)
-*/
-
-#include "includes.h"
-
-#ifndef FAST_SHARE_MODES
-
-extern int DEBUGLEVEL;
-
-/*
- * Locking file header lengths & offsets.
- */
-#define SMF_VERSION_OFFSET 0
-#define SMF_NUM_ENTRIES_OFFSET 4
-#define SMF_FILENAME_LEN_OFFSET 8
-#define SMF_HEADER_LENGTH 10
-
-#define SMF_ENTRY_LENGTH 20
-
-/*
- * Share mode record offsets.
- */
-
-#define SME_SEC_OFFSET 0
-#define SME_USEC_OFFSET 4
-#define SME_SHAREMODE_OFFSET 8
-#define SME_PID_OFFSET 12
-#define SME_PORT_OFFSET 16
-#define SME_OPLOCK_TYPE_OFFSET 18
-
-/* we need world read for smbstatus to function correctly */
-#ifdef SECURE_SHARE_MODES
-#define SHARE_FILE_MODE 0600
-#else
-#define SHARE_FILE_MODE 0644
-#endif
-
-static int read_only;
-
-/*******************************************************************
- deinitialize share_mode management
- ******************************************************************/
-static BOOL slow_stop_share_mode_mgmt(void)
-{
- return True;
-}
-
-
-/*******************************************************************
- name a share file
- ******************************************************************/
-static BOOL share_name(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, char *name)
-{
- int len;
- pstrcpy(name,lp_lockdir());
- trim_string(name,"","/");
- if (!*name) return(False);
- len = strlen(name);
- name += len;
-
-#ifdef LARGE_SMB_INO_T
- slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%.0f",(unsigned int)dev,(double)inode);
-#else /* LARGE_SMB_INO_T */
- slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%lu",(unsigned int)dev,(unsigned long)inode);
-#endif /* LARGE_SMB_INO_T */
- return(True);
-}
-
-/*******************************************************************
-Force a share file to be deleted.
-********************************************************************/
-static int delete_share_file(connection_struct *conn, char *fname )
-{
- if (read_only) return -1;
-
- /* the share file could be owned by anyone, so do this as root */
- become_root(False);
-
- if(unlink(fname) != 0)
- {
- DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
- fname, strerror(errno)));
- }
- else
- {
- DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
- }
-
- /* return to our previous privilege level */
- unbecome_root(False);
-
- return 0;
-}
-
-/*******************************************************************
- lock a share mode file.
- ******************************************************************/
-static BOOL slow_lock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
-{
- pstring fname;
- int fd;
- int ret = True;
-
- *ptok = (int)-1;
-
- if(!share_name(conn, dev, inode, fname))
- return False;
-
- if (read_only) return True;
-
- /* we need to do this as root */
- become_root(False);
-
- {
- BOOL gotlock = False;
- /*
- * There was a race condition in the original slow share mode code.
- * A smbd could open a share mode file, and before getting
- * the lock, another smbd could delete the last entry for
- * the share mode file and delete the file entry from the
- * directory. Thus this smbd would be left with a locked
- * share mode fd attached to a file that no longer had a
- * directory entry. Thus another smbd would think that
- * there were no outstanding opens on the file. To fix
- * this we now check we can do a stat() call on the filename
- * before allowing the lock to proceed, and back out completely
- * and try the open again if we cannot.
- * Jeremy Allison (jallison@whistle.com).
- */
-
- do
- {
- SMB_STRUCT_STAT dummy_stat;
-
- fd = sys_open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT), SHARE_FILE_MODE);
-
- if(fd < 0)
- {
- DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
- fname, strerror(errno)));
- ret = False;
- break;
- }
-
- /* At this point we have an open fd to the share mode file.
- Lock the first byte exclusively to signify a lock. */
- if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
- {
- DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
- fname, strerror(errno)));
- close(fd);
- ret = False;
- break;
- }
-
- /*
- * If we cannot stat the filename, the file was deleted between
- * the open and the lock call. Back out and try again.
- */
-
- if(sys_stat(fname, &dummy_stat)!=0)
- {
- DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
- fname, strerror(errno)));
- close(fd);
- }
- else
- gotlock = True;
- } while(!gotlock);
-
- /*
- * We have to come here if any of the above calls fail
- * as we don't want to return and leave ourselves running
- * as root !
- */
- }
-
- *ptok = (int)fd;
-
- /* return to our previous privilege level */
- unbecome_root(False);
-
- return ret;
-}
-
-/*******************************************************************
- unlock a share mode file.
- ******************************************************************/
-static BOOL slow_unlock_share_entry(connection_struct *conn,
- SMB_DEV_T dev, SMB_INO_T inode, int token)
-{
- int fd = token;
- int ret = True;
- SMB_STRUCT_STAT sb;
- pstring fname;
-
- if (read_only) return True;
-
- /* Fix for zero length share files from
- Gerald Werner <wernerg@mfldclin.edu> */
-
- share_name(conn, dev, inode, fname);
-
- /* get the share mode file size */
- if(sys_fstat((int)token, &sb) != 0)
- {
- DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
- fname, strerror(errno)));
- sb.st_size = 1;
- ret = False;
- }
-
- /* If the file was zero length, we must delete before
- doing the unlock to avoid a race condition (see
- the code in lock_share_mode_entry for details.
- */
-
- /* remove the share file if zero length */
- if(sb.st_size == 0)
- delete_share_file(conn, fname);
-
- /* token is the fd of the open share mode file. */
- /* Unlock the first byte. */
- if(fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
- {
- DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
- strerror(errno)));
- ret = False;
- }
-
- close(fd);
- return ret;
-}
-
-/*******************************************************************
-Read a share file into a buffer.
-********************************************************************/
-static int read_share_file(connection_struct *conn, int fd, char *fname, char **out, BOOL *p_new_file)
-{
- SMB_STRUCT_STAT sb;
- char *buf;
- SMB_OFF_T size;
-
- *out = 0;
- *p_new_file = False;
-
- if(sys_fstat(fd, &sb) != 0)
- {
- DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
- fname, strerror(errno)));
- return -1;
- }
-
- if(sb.st_size == 0)
- {
- *p_new_file = True;
- return 0;
- }
-
- /* Allocate space for the file */
- if((buf = (char *)malloc((size_t)sb.st_size)) == NULL)
- {
- DEBUG(0,("read_share_file: malloc for file size %d fail !\n",
- (int)sb.st_size));
- return -1;
- }
-
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
-for share file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return -1;
- }
-
- if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
- {
- DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
- fname, strerror(errno)));
- if(buf)
- free(buf);
- return -1;
- }
-
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
- DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname,
- IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
- if(buf)
- free(buf);
- delete_share_file(conn, fname);
- return -1;
- }
-
- /* Sanity check for file contents */
- size = sb.st_size;
- size -= SMF_HEADER_LENGTH; /* Remove the header */
-
- /* Remove the filename component. */
- size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
-
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
- {
- DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
-deleting it.\n", fname));
- if(buf)
- free(buf);
- delete_share_file(conn, fname);
- return -1;
- }
-
- *out = buf;
- return 0;
-}
-
-/*******************************************************************
-get all share mode entries in a share file for a dev/inode pair.
-********************************************************************/
-static int slow_get_share_modes(connection_struct *conn, int token,
- SMB_DEV_T dev, SMB_INO_T inode,
- share_mode_entry **old_shares)
-{
- int fd = token;
- pstring fname;
- int i;
- int num_entries;
- int num_entries_copied;
- int newsize;
- share_mode_entry *share_array;
- char *buf = 0;
- char *base = 0;
- BOOL new_file;
-
- *old_shares = 0;
-
- /* Read the share file header - this is of the form:
- 0 - locking version.
- 4 - number of share mode entries.
- 8 - 2 byte name length
- [n bytes] file name (zero terminated).
-
- Followed by <n> share mode entries of the form :
-
- 0 - tv_sec
- 4 - tv_usec
- 8 - share_mode
- 12 - pid
- 16 - oplock port (if oplocks in use) - 2 bytes.
- */
-
- share_name(conn, dev, inode, fname);
-
- if(read_share_file( conn, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
- fname));
- return 0;
- }
-
- if(new_file == True)
- return 0;
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
- fname, num_entries));
-
- /* PARANOIA TEST */
- if(num_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
-for share file %s\n", num_entries, fname));
- return 0;
- }
-
- if(num_entries)
- {
- *old_shares = share_array = (share_mode_entry *)
- malloc(num_entries * sizeof(share_mode_entry));
- if(*old_shares == 0)
- {
- DEBUG(0,("get_share_modes: malloc fail !\n"));
- return 0;
- }
- }
- else
- {
- /* No entries - just delete the file. */
- DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(conn, fname);
- return 0;
- }
-
- num_entries_copied = 0;
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
-
- for( i = 0; i < num_entries; i++)
- {
- pid_t pid;
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- pid = (pid_t)IVAL(p,SME_PID_OFFSET);
-
- if(!process_exists(pid))
- {
- DEBUG(0,("get_share_modes: process %d no longer exists and \
-it left a share mode entry with mode 0x%X in share file %s\n",
- (int)pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
- continue;
- }
- share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
- share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
- share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
- share_array[num_entries_copied].pid = pid;
- share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
- share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
-
- num_entries_copied++;
- }
-
- if(num_entries_copied == 0)
- {
- /* Delete the whole file. */
- DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
- fname));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- delete_share_file(conn, fname);
- return 0;
- }
-
- /* If we deleted some entries we need to re-write the whole number of
- share mode entries back into the file. */
-
- if(num_entries_copied != num_entries)
- {
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- return 0;
- }
-
- SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
- for( i = 0; i < num_entries_copied; i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- SIVAL(p,SME_PID_OFFSET,(uint32)share_array[i].pid);
- SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
- SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
- SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
- }
-
- newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
- if(write(fd, buf, newsize) != newsize)
- {
- DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- return 0;
- }
- /* Now truncate the file at this point. */
-#ifdef FTRUNCATE_NEEDS_ROOT
- become_root(False);
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- if(sys_ftruncate(fd, (SMB_OFF_T)newsize)!= 0)
- {
-#ifdef FTRUNCATE_NEEDS_ROOT
- int saved_errno = errno;
- unbecome_root(False);
- errno = saved_errno;
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- return 0;
- }
- }
-
-#ifdef FTRUNCATE_NEEDS_ROOT
- unbecome_root(False);
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- if(buf)
- free(buf);
-
- DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
- num_entries_copied));
-
- return num_entries_copied;
-}
-
-/*******************************************************************
-del a share mode from a share mode file.
-********************************************************************/
-static void slow_del_share_mode(int token, files_struct *fsp)
-{
- pstring fname;
- int fd = (int)token;
- char *buf = 0;
- char *base = 0;
- int num_entries;
- int newsize;
- int i;
- pid_t pid;
- BOOL deleted = False;
- BOOL new_file;
-
- share_name(fsp->conn, fsp->fd_ptr->dev,
- fsp->fd_ptr->inode, fname);
-
- if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
- fname));
- return;
- }
-
- if(new_file == True)
- {
- DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
- fname));
- delete_share_file(fsp->conn, fname);
- return;
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
- fname, num_entries));
-
- /* PARANOIA TEST */
- if(num_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
-for share file %s\n", num_entries, fname));
- return;
- }
-
- if(num_entries == 0)
- {
- /* No entries - just delete the file. */
- DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fsp->conn, fname);
- return;
- }
-
- pid = getpid();
-
- /* Go through the entries looking for the particular one
- we have set - delete it.
- */
-
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
-
- for(i = 0; i < num_entries; i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) ||
- (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
- (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) ||
- (((pid_t)IVAL(p,SME_PID_OFFSET)) != pid))
- continue;
-
- DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
- i, num_entries, fname));
-
- /* Remove this entry. */
- if(i != num_entries - 1)
- memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
-
- deleted = True;
- break;
- }
-
- if(!deleted)
- {
- DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
- if(buf)
- free(buf);
- return;
- }
-
- num_entries--;
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
-
- if(num_entries == 0)
- {
- /* Deleted the last entry - remove the file. */
- DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fsp->conn,fname);
- return;
- }
-
- /* Re-write the file - and truncate it at the correct point. */
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
-
- newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
- if(write(fd, buf, newsize) != newsize)
- {
- DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
-
- /* Now truncate the file at this point. */
-#ifdef FTRUNCATE_NEEDS_ROOT
- become_root(False);
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- if(sys_ftruncate(fd, (SMB_OFF_T)newsize) != 0)
- {
-#ifdef FTRUNCATE_NEEDS_ROOT
- int saved_errno = errno;
- unbecome_root(False);
- errno = saved_errno;
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
-
- DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
-
-#ifdef FTRUNCATE_NEEDS_ROOT
- unbecome_root(False);
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
-}
-
-/*******************************************************************
-set the share mode of a file
-********************************************************************/
-static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16 op_type)
-{
- pstring fname;
- int fd = (int)token;
- pid_t pid = getpid();
- SMB_STRUCT_STAT sb;
- char *buf;
- int num_entries;
- int header_size;
- char *p;
-
- share_name(fsp->conn, fsp->fd_ptr->dev,
- fsp->fd_ptr->inode, fname);
-
- if(sys_fstat(fd, &sb) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
- fname));
- return False;
- }
-
- /* Sanity check for file contents (if it's not a new share file). */
- if(sb.st_size != 0)
- {
- SMB_OFF_T size = sb.st_size;
-
- /* Allocate space for the file plus one extra entry */
- if((buf = (char *)malloc((size_t)(sb.st_size + SMF_ENTRY_LENGTH))) == NULL)
- {
- DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
- (int)(sb.st_size + SMF_ENTRY_LENGTH)));
- return False;
- }
-
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
-to 0 for share file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
- {
- DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
- fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
- LOCKING_VERSION));
- if(buf)
- free(buf);
- delete_share_file(fsp->conn, fname);
- return False;
- }
-
- size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
-
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
-deleting it.\n", fname));
- if(buf)
- free(buf);
- delete_share_file(fsp->conn, fname);
- return False;
- }
-
- }
- else
- {
- /* New file - just use a single_entry. */
- if((buf = (char *)malloc(SMF_HEADER_LENGTH +
- strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2 + SMF_ENTRY_LENGTH)) == NULL)
- {
- DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
- return False;
- }
- SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
- SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->fsp_name) + strlen(fsp->conn->connectpath) + 2);
- pstrcpy(buf + SMF_HEADER_LENGTH, fsp->conn->connectpath);
- pstrcat(buf + SMF_HEADER_LENGTH, "/");
- pstrcat(buf + SMF_HEADER_LENGTH, fsp->fsp_name);
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
- header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
- p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
- SIVAL(p,SME_SEC_OFFSET,fsp->open_time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,fsp->open_time.tv_usec);
- SIVAL(p,SME_SHAREMODE_OFFSET,fsp->share_mode);
- SIVAL(p,SME_PID_OFFSET,(uint32)pid);
- SSVAL(p,SME_PORT_OFFSET,port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
-
- num_entries++;
-
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
-
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
-0 for share file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
- (header_size + (num_entries*SMF_ENTRY_LENGTH)))
- {
- DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
-deleting it (%s).\n",fname, strerror(errno)));
- delete_share_file(fsp->conn, fname);
- if(buf)
- free(buf);
- return False;
- }
-
- /* Now truncate the file at this point - just for safety. */
-
-#ifdef FTRUNCATE_NEEDS_ROOT
- become_root(False);
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- if(sys_ftruncate(fd, (SMB_OFF_T)(header_size + (SMF_ENTRY_LENGTH*num_entries)))!= 0)
- {
-
-#ifdef FTRUNCATE_NEEDS_ROOT
- int saved_errno = errno;
- unbecome_root(False);
- errno = saved_errno;
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
- strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
-#ifdef FTRUNCATE_NEEDS_ROOT
- unbecome_root(False);
-#endif /* FTRUNCATE_NEEDS_ROOT */
-
- if(buf)
- free(buf);
-
- DEBUG(3,("set_share_mode: Created share file %s with \
-mode 0x%X pid=%d\n",fname,fsp->share_mode,(int)pid));
-
- return True;
-}
-
-/*******************************************************************
- Call a generic modify function for a share mode entry.
-********************************************************************/
-
-static BOOL slow_mod_share_entry(int token, files_struct *fsp,
- void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
- void *param)
-{
- pstring fname;
- int fd = (int)token;
- char *buf = 0;
- char *base = 0;
- int num_entries;
- int fsize;
- int i;
- pid_t pid;
- BOOL found = False;
- BOOL new_file;
- share_mode_entry entry;
-
- share_name(fsp->conn, fsp->fd_ptr->dev,
- fsp->fd_ptr->inode, fname);
-
- if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: slow_mod_share_entry: Failed to read share file %s\n",
- fname));
- return False;
- }
-
- if(new_file == True)
- {
- DEBUG(0,("ERROR: slow_mod_share_entry: share file %s is new (size zero), \
-deleting it.\n", fname));
- delete_share_file(fsp->conn, fname);
- return False;
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("slow_mod_share_entry: share file %s has %d share mode entries.\n",
- fname, num_entries));
-
- /* PARANOIA TEST */
- if(num_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:slow_mod_share_entry: num_share_mode_entries < 0 (%d) \
-for share file %s\n", num_entries, fname));
- return False;
- }
-
- if(num_entries == 0)
- {
- /* No entries - just delete the file. */
- DEBUG(0,("slow_mod_share_entry: share file %s has no share mode entries - deleting.\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fsp->conn, fname);
- return False;
- }
-
- pid = getpid();
-
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
-
- for(i = 0; i < num_entries; i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) ||
- (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
- (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) ||
- (((pid_t)IVAL(p,SME_PID_OFFSET)) != pid))
- continue;
-
- DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
-from the share file %s\n", i, num_entries, fname));
-
- /*
- * Copy into the share_mode_entry structure and then call
- * the generic function with the given parameter.
- */
-
- entry.pid = (pid_t)IVAL(p,SME_PID_OFFSET);
- entry.op_port = SVAL(p,SME_PORT_OFFSET);
- entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
- entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
- entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
- entry.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
-
- (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
-
- /*
- * Now copy any changes the function made back into the buffer.
- */
-
- SIVAL(p,SME_PID_OFFSET, (uint32)entry.pid);
- SSVAL(p,SME_PORT_OFFSET,entry.op_port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
- SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
- SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,entry.time.tv_usec);
-
- found = True;
- break;
- }
-
- if(!found)
- {
- DEBUG(0,("slow_mod_share_entry: entry not found in share file %s\n", fname));
- if(buf)
- free(buf);
- return False;
- }
-
- /* Re-write the file - and truncate it at the correct point. */
- if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: slow_mod_share_entry: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
- if(write(fd, buf, fsize) != fsize)
- {
- DEBUG(0,("ERROR: slow_mod_share_entry: failed to re-write share \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- return True;
-}
-
-
-
-/*******************************************************************
-call the specified function on each entry under management by the
-share mode system
-********************************************************************/
-static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
-{
- int i, count=0;
- DIR *dir;
- char *s;
- share_mode_entry e;
-
- dir = opendir(lp_lockdir());
- if (!dir) {
- return(0);
- }
-
- while ((s=readdirname(dir))) {
- char *buf;
- char *base;
- int fd;
- pstring lname;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- BOOL new_file;
- pstring fname;
-
-#ifdef LARGE_SMB_INO_T
- double inode_ascii;
- if (sscanf(s,"share.%u.%lf",&dev,&inode_ascii)!=2) continue;
- inode = (SMB_INO_T)inode_ascii;
-#else /* LARGE_SMB_INO_T */
- unsigned long inode_long;
- if (sscanf(s,"share.%u.%lu",&dev,&inode_long)!=2) continue;
- inode = (SMB_INO_T)inode_long;
-#endif /* LARGE_SMB_INO_T */
-
- pstrcpy(lname,lp_lockdir());
- trim_string(lname,NULL,"/");
- pstrcat(lname,"/");
- pstrcat(lname,s);
-
- fd = sys_open(lname,read_only?O_RDONLY:O_RDWR,0);
- if (fd < 0) {
- continue;
- }
-
- /* Lock the share mode file while we read it. */
- if(!read_only &&
- fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False) {
- close(fd);
- continue;
- }
-
- if(read_share_file( 0, fd, lname, &buf, &new_file)) {
- close(fd);
- continue;
- }
- pstrcpy( fname, &buf[10]);
- close(fd);
-
- base = buf + SMF_HEADER_LENGTH +
- SVAL(buf,SMF_FILENAME_LEN_OFFSET);
- for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
- char *p = base + (i*SMF_ENTRY_LENGTH);
- e.pid = (pid_t)IVAL(p,SME_PID_OFFSET);
- e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
- e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
- e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
- e.op_port = SVAL(p,SME_PORT_OFFSET);
- e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
-
- if (process_exists(e.pid)) {
- fn(&e, fname);
- count++;
- }
- } /* end for i */
-
- if(buf)
- free(buf);
- base = 0;
- } /* end while */
- closedir(dir);
-
- return count;
-}
-
-
-/*******************************************************************
-dump the state of the system
-********************************************************************/
-static void slow_share_status(FILE *f)
-{
-
-}
-
-
-static struct share_ops share_ops = {
- slow_stop_share_mode_mgmt,
- slow_lock_share_entry,
- slow_unlock_share_entry,
- slow_get_share_modes,
- slow_del_share_mode,
- slow_set_share_mode,
- slow_mod_share_entry,
- slow_share_forall,
- slow_share_status,
-};
-
-/*******************************************************************
- initialize the slow share_mode management
- ******************************************************************/
-struct share_ops *locking_slow_init(int ronly)
-{
-
- read_only = ronly;
-
- if (!directory_exist(lp_lockdir(),NULL)) {
- if (!read_only)
- mkdir(lp_lockdir(),0755);
- if (!directory_exist(lp_lockdir(),NULL))
- return NULL;
- }
-
- return &share_ops;
-}
-#else
- int locking_slow_dummy_procedure(void);
- int locking_slow_dummy_procedure(void) {return 0;}
-#endif /* !FAST_SHARE_MODES */
diff --git a/source3/locking/shmem.c b/source3/locking/shmem.c
deleted file mode 100644
index bf2802c9ec..0000000000
--- a/source3/locking/shmem.c
+++ /dev/null
@@ -1,963 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Shared memory functions
- Copyright (C) Erik Devriendt 1996-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "includes.h"
-
-
-#ifdef USE_SHARED_MMAP
-
-
-extern int DEBUGLEVEL;
-
-
-#define SMB_SHM_MAGIC 0x53484100
-/* = "SHM" in hex */
-
-#define SMB_SHM_VERSION 2
-
-/* we need world read for smbstatus to function correctly */
-#ifdef SECURE_SHARE_MODES
-#define SHM_FILE_MODE 0600
-#else
-#define SHM_FILE_MODE 0644
-#endif
-
-#define SHMEM_HASH_SIZE 13
-
-
-/* WARNING : offsets are used because mmap() does not guarantee that all processes have the
- shared memory mapped to the same address */
-
-struct SmbShmHeader
-{
- int smb_shm_magic;
- int smb_shm_version;
- int total_size; /* in bytes */
- BOOL consistent;
- int first_free_off;
- int userdef_off; /* a userdefined offset. can be used to store root of tree or list */
- struct { /* a cell is a range of bytes of sizeof(struct SmbShmBlockDesc) size */
- int cells_free;
- int cells_used;
- int cells_system; /* number of cells used as allocated block descriptors */
- } statistics;
-};
-
-#define SMB_SHM_NOT_FREE_OFF (-1)
-struct SmbShmBlockDesc
-{
- int next; /* offset of next block in the free list or SMB_SHM_NOT_FREE_OFF when block in use */
- int size; /* user size in BlockDescSize units */
-};
-
-#define EOList_Addr (struct SmbShmBlockDesc *)( 0 )
-#define EOList_Off 0
-
-#define CellSize sizeof(struct SmbShmBlockDesc)
-
-/* HeaderSize aligned on 8 byte boundary */
-#define AlignedHeaderSize ((sizeof(struct SmbShmHeader)+7) & ~7)
-
-static int smb_shm_fd = -1;
-static pstring smb_shm_processreg_name = "";
-
-static struct SmbShmHeader *smb_shm_header_p = (struct SmbShmHeader *)0;
-static int smb_shm_times_locked = 0;
-
-static BOOL smb_shm_initialize_called = False;
-
-static int read_only;
-
-static BOOL smb_shm_global_lock(void)
-{
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_global_lock : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- smb_shm_times_locked++;
-
- if(smb_shm_times_locked > 1)
- {
- DEBUG(5,("smb_shm_global_lock : locked %d times\n",smb_shm_times_locked));
- return True;
- }
-
- if (read_only)
- return True;
-
- /* Do an exclusive wait lock on the first byte of the file */
- if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %s\n",strerror(errno)));
- smb_shm_times_locked--;
- return False;
- }
-
- return True;
-
-}
-
-static BOOL smb_shm_global_unlock(void)
-{
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_global_unlock : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- if(smb_shm_times_locked == 0)
- {
- DEBUG(0,("ERROR smb_shm_global_unlock : shmem not locked\n"));
- return False;
- }
-
- smb_shm_times_locked--;
-
- if(smb_shm_times_locked > 0)
- {
- DEBUG(5,("smb_shm_global_unlock : still locked %d times\n",smb_shm_times_locked));
- return True;
- }
-
- if (read_only)
- return True;
-
- /* Do a wait unlock on the first byte of the file */
- if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %s\n",strerror(errno)));
- smb_shm_times_locked++;
- return False;
- }
-
- return True;
-
-}
-
-
-static void *smb_shm_offset2addr(int offset)
-{
- if (offset == 0 )
- return (void *)(0);
-
- if (!smb_shm_header_p)
- return (void *)(0);
-
- return (void *)((char *)smb_shm_header_p + offset );
-}
-
-static int smb_shm_addr2offset(void *addr)
-{
- if (!addr)
- return 0;
-
- if (!smb_shm_header_p)
- return 0;
-
- return (int)((char *)addr - (char *)smb_shm_header_p);
-}
-
-
-
-static int smb_shm_alloc(int size)
-{
- unsigned num_cells ;
- struct SmbShmBlockDesc *scanner_p;
- struct SmbShmBlockDesc *prev_p;
- struct SmbShmBlockDesc *new_p;
- int result_offset;
-
-
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_alloc : shmem not mapped\n"));
- return 0;
- }
-
- smb_shm_global_lock();
-
- if( !smb_shm_header_p->consistent)
- {
- DEBUG(0,("ERROR smb_shm_alloc : shmem not consistent\n"));
- smb_shm_global_unlock();
- return 0;
- }
-
-
- /* calculate the number of cells */
- num_cells = (size + CellSize -1) / CellSize;
-
- /* set start of scan */
- prev_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
- scanner_p = prev_p ;
-
- /* scan the free list to find a matching free space */
- while ( ( scanner_p != EOList_Addr ) && ( scanner_p->size < num_cells ) )
- {
- prev_p = scanner_p;
- scanner_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(scanner_p->next);
- }
-
- /* at this point scanner point to a block header or to the end of the list */
- if ( scanner_p == EOList_Addr )
- {
- DEBUG(0,("ERROR smb_shm_alloc : alloc of %d bytes failed, no free space found\n",size));
- smb_shm_global_unlock();
- return (0);
- }
-
- /* going to modify shared mem */
- smb_shm_header_p->consistent = False;
-
- /* if we found a good one : scanner == the good one */
- if ( scanner_p->size <= num_cells + 2 )
- {
- /* there is no use in making a new one, it will be too small anyway
- * we will link out scanner
- */
- if ( prev_p == scanner_p )
- {
- smb_shm_header_p->first_free_off = scanner_p->next ;
- }
- else
- {
- prev_p->next = scanner_p->next ;
- }
- smb_shm_header_p->statistics.cells_free -= scanner_p->size;
- smb_shm_header_p->statistics.cells_used += scanner_p->size;
- }
- else
- {
- /* Make a new one */
- new_p = scanner_p + 1 + num_cells;
- new_p->size = scanner_p->size - num_cells - 1;
- new_p->next = scanner_p->next;
- scanner_p->size = num_cells;
- scanner_p->next = smb_shm_addr2offset(new_p);
-
- if ( prev_p != scanner_p )
- {
- prev_p->next = smb_shm_addr2offset(new_p) ;
- }
- else
- {
- smb_shm_header_p->first_free_off = smb_shm_addr2offset(new_p) ;
- }
- smb_shm_header_p->statistics.cells_free -= num_cells+1;
- smb_shm_header_p->statistics.cells_used += num_cells;
- smb_shm_header_p->statistics.cells_system += 1;
- }
-
- result_offset = smb_shm_addr2offset( &(scanner_p[1]) );
- scanner_p->next = SMB_SHM_NOT_FREE_OFF ;
-
- /* end modification of shared mem */
- smb_shm_header_p->consistent = True;
-
- DEBUG(6,("smb_shm_alloc : request for %d bytes, allocated %d bytes at offset %d\n",size,scanner_p->size*CellSize,result_offset ));
-
- smb_shm_global_unlock();
- return ( result_offset );
-}
-
-
-
-
-/*
- * Function to create the hash table for the share mode entries. Called
- * when smb shared memory is global locked.
- */
-static BOOL smb_shm_create_hash_table( unsigned int size )
-{
- size *= sizeof(int);
-
- smb_shm_global_lock();
- smb_shm_header_p->userdef_off = smb_shm_alloc( size );
-
- if(smb_shm_header_p->userdef_off == 0)
- {
- DEBUG(0,("smb_shm_create_hash_table: Failed to create hash table of size %d\n",size));
- smb_shm_global_unlock();
- return False;
- }
-
- /* Clear hash buckets. */
- memset( smb_shm_offset2addr(smb_shm_header_p->userdef_off), '\0', size);
- smb_shm_global_unlock();
- return True;
-}
-
-static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *other_processes)
-{
- int smb_shm_processes_fd = -1;
- int nb_read;
- pid_t other_pid;
- SMB_OFF_T seek_back = -((SMB_OFF_T)sizeof(other_pid));
- SMB_OFF_T free_slot = -1;
- SMB_OFF_T erased_slot;
-
- smb_shm_processes_fd = sys_open(processreg_file,
- read_only?O_RDONLY:(O_RDWR|O_CREAT),
- SHM_FILE_MODE);
-
- if ( smb_shm_processes_fd < 0 )
- {
- DEBUG(0, ("ERROR smb_shm_register_process : processreg_file \
-open failed with code %s\n",strerror(errno)));
- return False;
- }
-
- *other_processes = False;
-
- while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
- {
- if(other_pid)
- {
- if(process_exists(other_pid))
- *other_processes = True;
- else
- {
- /* erase old pid */
- DEBUG(5,("smb_shm_register_process : erasing stale record \
-for pid %d (seek_back = %.0f)\n", (int)other_pid, (double)seek_back));
- other_pid = (pid_t)0;
- if((erased_slot = sys_lseek(smb_shm_processes_fd,
- seek_back, SEEK_CUR)) == -1)
- {
- DEBUG(0, ("ERROR smb_shm_register_process : sys_lseek failed \
-with error %s\n", strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) == -1)
- {
- DEBUG(0, ("ERROR smb_shm_register_process : write failed \
-with error %s\n", strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(free_slot < 0)
- free_slot = erased_slot;
- }
- }
- else
- {
- if(free_slot < 0)
- {
- if((free_slot = sys_lseek(smb_shm_processes_fd,
- seek_back, SEEK_CUR))==-1)
- {
- DEBUG(0, ("ERROR smb_shm_register_process : sys_lseek \
-failed with error %s\n", strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
- } /* end if free_slot */
- } /* end else */
- } /* end if other_pid */
-
- if (nb_read < 0)
- {
- DEBUG(0,("ERROR smb_shm_register_process : processreg_file read \
-failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(free_slot < 0)
- {
- if((free_slot = sys_lseek(smb_shm_processes_fd, 0, SEEK_END)) == -1)
- {
- DEBUG(0,("ERROR smb_shm_register_process : sys_lseek failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
- }
-
- DEBUG(5,("smb_shm_register_process : writing record for pid %d at offset %.0f\n",
- (int)pid, (double)free_slot));
-
- if(sys_lseek(smb_shm_processes_fd, free_slot, SEEK_SET) == -1)
- {
- DEBUG(0,("ERROR smb_shm_register_process : sys_lseek failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(write(smb_shm_processes_fd, &pid, sizeof(pid)) == -1)
- {
- DEBUG(0,("ERROR smb_shm_register_process : processreg_file write failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- close(smb_shm_processes_fd);
-
- return True;
-}
-
-static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
-{
- int smb_shm_processes_fd = -1;
- int nb_read;
- pid_t other_pid;
- SMB_OFF_T seek_back = -((SMB_OFF_T)sizeof(other_pid));
- BOOL found = False;
-
-
- smb_shm_processes_fd = sys_open(processreg_file, O_RDWR, 0);
- if ( smb_shm_processes_fd < 0 )
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file open failed with code %s\n",strerror(errno)));
- return False;
- }
-
- while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
- {
- DEBUG(5,("smb_shm_unregister_process : read record for pid %d\n",(int)other_pid));
- if(other_pid == pid)
- {
- /* erase pid */
- DEBUG(5,("smb_shm_unregister_process : erasing record for pid %d (seek_val = %.0f)\n",
- (int)other_pid, (double)seek_back));
- other_pid = (pid_t)0;
- if(sys_lseek(smb_shm_processes_fd, seek_back, SEEK_CUR) == -1)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file sys_lseek failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
- if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- found = True;
- break;
- }
- }
- if (nb_read < 0)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file read failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : couldn't find pid %d in file %s\n",
- (int)pid,processreg_file));
- close(smb_shm_processes_fd);
- return False;
- }
-
-
- close(smb_shm_processes_fd);
-
- return True;
-}
-
-
-static BOOL smb_shm_validate_header(int size)
-{
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_validate_header : shmem not mapped\n"));
- return False;
- }
-
- if(smb_shm_header_p->smb_shm_magic != SMB_SHM_MAGIC)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : bad magic\n"));
- return False;
- }
- if(smb_shm_header_p->smb_shm_version != SMB_SHM_VERSION)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : bad version %X\n",smb_shm_header_p->smb_shm_version));
- return False;
- }
-
- if(smb_shm_header_p->total_size != size)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : shmem size mismatch (old = %d, new = %d)\n",smb_shm_header_p->total_size,size));
- return False;
- }
-
- if(!smb_shm_header_p->consistent)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : shmem not consistent\n"));
- return False;
- }
- return True;
-}
-
-static BOOL smb_shm_initialize(int size)
-{
- struct SmbShmBlockDesc * first_free_block_p;
-
- DEBUG(5,("smb_shm_initialize : initializing shmem file of size %d\n",size));
-
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_initialize : shmem not mapped\n"));
- return False;
- }
-
- smb_shm_header_p->smb_shm_magic = SMB_SHM_MAGIC;
- smb_shm_header_p->smb_shm_version = SMB_SHM_VERSION;
- smb_shm_header_p->total_size = size;
- smb_shm_header_p->first_free_off = AlignedHeaderSize;
- smb_shm_header_p->userdef_off = 0;
-
- first_free_block_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
- first_free_block_p->next = EOList_Off;
- first_free_block_p->size = ( size - AlignedHeaderSize - CellSize ) / CellSize ;
-
- smb_shm_header_p->statistics.cells_free = first_free_block_p->size;
- smb_shm_header_p->statistics.cells_used = 0;
- smb_shm_header_p->statistics.cells_system = 1;
-
- smb_shm_header_p->consistent = True;
-
- smb_shm_initialize_called = True;
-
- return True;
-}
-
-static void smb_shm_solve_neighbors(struct SmbShmBlockDesc *head_p )
-{
- struct SmbShmBlockDesc *next_p;
-
- /* Check if head_p and head_p->next are neighbors and if so join them */
- if ( head_p == EOList_Addr ) return ;
- if ( head_p->next == EOList_Off ) return ;
-
- next_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(head_p->next);
- if ( ( head_p + head_p->size + 1 ) == next_p)
- {
- head_p->size += next_p->size +1 ; /* adapt size */
- head_p->next = next_p->next ; /* link out */
-
- smb_shm_header_p->statistics.cells_free += 1;
- smb_shm_header_p->statistics.cells_system -= 1;
- }
-}
-
-
-
-static BOOL smb_shm_close( void )
-{
-
- if(smb_shm_initialize_called == False)
- return True;
-
- DEBUG(5,("smb_shm_close\n"));
- if(smb_shm_times_locked > 0)
- DEBUG(0,("WARNING smb_shm_close : shmem was still locked %d times\n",smb_shm_times_locked));;
- if ((smb_shm_header_p != NULL) &&
- (munmap((caddr_t)smb_shm_header_p, smb_shm_header_p->total_size) < 0))
- {
- DEBUG(0,("ERROR smb_shm_close : munmap failed with code %s\n",strerror(errno)));
- }
-
- smb_shm_global_lock();
- DEBUG(5,("calling smb_shm_unregister_process(%s, %d)\n",
- smb_shm_processreg_name, (int)getpid()));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
-
- close(smb_shm_fd);
-
- smb_shm_fd = -1;
- smb_shm_processreg_name[0] = '\0';
-
- smb_shm_header_p = (struct SmbShmHeader *)0;
- smb_shm_times_locked = 0;
-
- return True;
-}
-
-
-static BOOL smb_shm_free(int offset)
-{
- struct SmbShmBlockDesc *header_p ; /* pointer to header of block to free */
- struct SmbShmBlockDesc *scanner_p ; /* used to scan the list */
- struct SmbShmBlockDesc *prev_p ; /* holds previous in the list */
-
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_free : shmem not mapped\n"));
- return False;
- }
-
- smb_shm_global_lock();
-
- if( !smb_shm_header_p->consistent)
- {
- DEBUG(0,("ERROR smb_shm_free : shmem not consistent\n"));
- smb_shm_global_unlock();
- return False;
- }
-
- header_p = ( (struct SmbShmBlockDesc *)smb_shm_offset2addr(offset) - 1); /* make pointer to header of block */
-
- if (header_p->next != SMB_SHM_NOT_FREE_OFF)
- {
- DEBUG(0,("ERROR smb_shm_free : bad offset (%d)\n",offset));
- smb_shm_global_unlock();
- return False;
- }
-
- /* find a place in the free_list to put the header in */
-
- /* set scanner and previous pointer to start of list */
- prev_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
- scanner_p = prev_p ;
-
- while ( ( scanner_p != EOList_Addr) && (scanner_p < header_p) ) /* while we didn't scan past its position */
- {
- prev_p = scanner_p ;
- scanner_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(scanner_p->next);
- }
-
- smb_shm_header_p->consistent = False;
-
- DEBUG(6,("smb_shm_free : freeing %d bytes at offset %d\n",header_p->size*CellSize,offset));
-
- /* zero the area being freed - this allows us to find bugs faster */
- memset(smb_shm_offset2addr(offset), 0, header_p->size*CellSize);
-
- if ( scanner_p == prev_p )
- {
- smb_shm_header_p->statistics.cells_free += header_p->size;
- smb_shm_header_p->statistics.cells_used -= header_p->size;
-
- /* we must free it at the beginning of the list */
- smb_shm_header_p->first_free_off = smb_shm_addr2offset(header_p); /* set the free_list_pointer to this block_header */
-
- /* scanner is the one that was first in the list */
- header_p->next = smb_shm_addr2offset(scanner_p);
- smb_shm_solve_neighbors( header_p ); /* if neighbors then link them */
-
- smb_shm_header_p->consistent = True;
- smb_shm_global_unlock();
- return True;
- }
- else
- {
- smb_shm_header_p->statistics.cells_free += header_p->size;
- smb_shm_header_p->statistics.cells_used -= header_p->size;
-
- prev_p->next = smb_shm_addr2offset(header_p);
- header_p->next = smb_shm_addr2offset(scanner_p);
- smb_shm_solve_neighbors(header_p) ;
- smb_shm_solve_neighbors(prev_p) ;
-
- smb_shm_header_p->consistent = True;
- smb_shm_global_unlock();
- return True;
- }
-}
-
-static int smb_shm_get_userdef_off(void)
-{
- if (!smb_shm_header_p)
- return 0;
- else
- return smb_shm_header_p->userdef_off;
-}
-
-/*******************************************************************
- Lock a particular hash bucket entry.
- ******************************************************************/
-static BOOL smb_shm_lock_hash_entry( unsigned int entry)
-{
- int start = (smb_shm_header_p->userdef_off + (entry * sizeof(int)));
-
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_lock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- if (read_only)
- return True;
-
- /* Do an exclusive wait lock on the 4 byte region mapping into this entry */
- if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, start, sizeof(int), F_WRLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
- return False;
- }
-
- DEBUG(9,("smb_shm_lock_hash_entry: locked hash bucket %d\n", entry));
- return True;
-}
-
-/*******************************************************************
- Unlock a particular hash bucket entry.
- ******************************************************************/
-static BOOL smb_shm_unlock_hash_entry( unsigned int entry )
-{
- int start = (smb_shm_header_p->userdef_off + (entry * sizeof(int)));
-
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_unlock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- if (read_only)
- return True;
-
- /* Do a wait lock on the 4 byte region mapping into this entry */
- if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, start, sizeof(int), F_UNLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
- return False;
- }
-
- DEBUG(9,("smb_shm_unlock_hash_entry: unlocked hash bucket %d\n", entry));
- return True;
-}
-
-/*******************************************************************
- Gather statistics on shared memory usage.
- ******************************************************************/
-static BOOL smb_shm_get_usage(int *bytes_free,
- int *bytes_used,
- int *bytes_overhead)
-{
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_free : shmem not mapped\n"));
- return False;
- }
- *bytes_free = smb_shm_header_p->statistics.cells_free * CellSize;
- *bytes_used = smb_shm_header_p->statistics.cells_used * CellSize;
- *bytes_overhead = smb_shm_header_p->statistics.cells_system * CellSize + AlignedHeaderSize;
-
- return True;
-}
-
-/*******************************************************************
-hash a number into a hash_entry
- ******************************************************************/
-static unsigned smb_shm_hash_size(void)
-{
- return SHMEM_HASH_SIZE;
-}
-
-static struct shmem_ops shmops = {
- smb_shm_close,
- smb_shm_alloc,
- smb_shm_free,
- smb_shm_get_userdef_off,
- smb_shm_offset2addr,
- smb_shm_addr2offset,
- smb_shm_lock_hash_entry,
- smb_shm_unlock_hash_entry,
- smb_shm_get_usage,
- smb_shm_hash_size,
-};
-
-/*******************************************************************
- open the shared memory
- ******************************************************************/
-struct shmem_ops *smb_shm_open(int ronly)
-{
- pstring file_name;
- SMB_OFF_T filesize;
- BOOL created_new = False;
- BOOL other_processes = True;
- SMB_OFF_T size = (SMB_OFF_T)lp_shmem_size();
-
- read_only = ronly;
-
- pstrcpy(file_name,lp_lockdir());
- if (!directory_exist(file_name,NULL)) {
- if (read_only)
- return NULL;
- mkdir(file_name,0755);
- }
- trim_string(file_name,"","/");
- if (!*file_name)
- return(False);
- pstrcat(file_name, "/SHARE_MEM_FILE");
-
- DEBUG(5,("smb_shm_open : using shmem file %s to be of size %.0f\n",
- file_name,(double)size));
-
- smb_shm_fd = sys_open(file_name, read_only?O_RDONLY:(O_RDWR|O_CREAT),
- SHM_FILE_MODE);
-
- if ( smb_shm_fd < 0 )
- {
- DEBUG(0,("ERROR smb_shm_open : open failed with code %s\n",strerror(errno)));
- return NULL;
- }
-
- if (!smb_shm_global_lock())
- {
- DEBUG(0,("ERROR smb_shm_open : can't do smb_shm_global_lock\n"));
- return NULL;
- }
-
- if( (filesize = sys_lseek(smb_shm_fd, 0, SEEK_END)) == -1)
- {
- DEBUG(0,("ERROR smb_shm_open : sys_lseek failed with code %s\n",
- strerror(errno)));
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
- /*
- * Return the file offset to 0 to save on later seeks.
- */
- if(sys_lseek(smb_shm_fd,0,SEEK_SET) == -1)
- {
- DEBUG(0,("ERROR smb_shm_open : sys_lseek failed with code %s\n",
- strerror(errno)));
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
- if (filesize == 0)
- {
- /*
- * We just created a new one.
- */
- created_new = True;
- }
-
- /*
- * To find out if some other process is already mapping the file,
- * we use a registration file containing the processids of the file
- * mapping processes.
- */
-
- /* construct processreg file name */
- pstrcpy(smb_shm_processreg_name, file_name);
- pstrcat(smb_shm_processreg_name, ".processes");
-
- if (!read_only && !smb_shm_register_process(smb_shm_processreg_name,
- getpid(), &other_processes))
- {
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
- if (!read_only && (created_new || !other_processes))
- {
- /* we just created a new one, or are the first opener, lets set it size */
- if( sys_ftruncate(smb_shm_fd, size) <0)
- {
- DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %s\n",
- strerror(errno)));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
- /* paranoia */
- if(sys_lseek(smb_shm_fd,0,SEEK_SET) == -1)
- {
- DEBUG(0,("ERROR smb_shm_open : sys_lseek failed with code %s\n",
- strerror(errno)));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
- filesize = size;
- }
-
- if (size != filesize )
- {
- /* the existing file has a different size and we are not the first opener.
- Since another process is still using it, we will use the file size */
- DEBUG(0,("WARNING smb_shm_open : filesize (%.0f) != expected \
-size (%.0f), using filesize\n", (double)filesize, (double)size));
-
- size = filesize;
- }
-
- smb_shm_header_p = (struct SmbShmHeader *)sys_mmap(NULL, size,
- read_only?PROT_READ: (PROT_READ | PROT_WRITE),
- MAP_FILE | MAP_SHARED, smb_shm_fd, (SMB_OFF_T)0);
-
- /*
- * WARNING, smb_shm_header_p can be different for different
- * processes mapping the same file !
- */
- if (smb_shm_header_p == (struct SmbShmHeader *)(-1))
- {
- DEBUG(0,("ERROR smb_shm_open : mmap failed with code %s\n",strerror(errno)));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
-
- if (!read_only && (created_new || !other_processes))
- {
- smb_shm_initialize(size);
- /* Create the hash buckets for the share file entries. */
- smb_shm_create_hash_table(SHMEM_HASH_SIZE);
- }
- else if (!smb_shm_validate_header(size) )
- {
- /* existing file is corrupt, samba admin should remove it by hand */
- DEBUG(0,("ERROR smb_shm_open : corrupt shared mem file, remove it manually\n"));
- munmap((caddr_t)smb_shm_header_p, size);
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return NULL;
- }
-
- smb_shm_global_unlock();
- return &shmops;
-}
-
-
-#else /* HAVE_SHARED_MMAP */
- int shmem_dummy_procedure(void)
-{return 0;}
-#endif /* HAVE_SHARED_MMAP */
diff --git a/source3/locking/shmem_sysv.c b/source3/locking/shmem_sysv.c
deleted file mode 100644
index 04a2e74460..0000000000
--- a/source3/locking/shmem_sysv.c
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Shared memory functions - SYSV IPC implementation
- Copyright (C) Andrew Tridgell 1997-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#include "includes.h"
-
-
-#ifdef USE_SYSV_IPC
-
-extern int DEBUGLEVEL;
-
-#define SHMEM_KEY ((key_t)0x280267)
-#define SEMAPHORE_KEY (SHMEM_KEY+2)
-
-#define SHM_MAGIC 0x53484100
-#define SHM_VERSION 2
-
-#ifdef SHM_R
-#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
-#else
-#define IPC_PERMS 0644
-#endif
-
-
-#ifdef SECURE_SEMAPHORES
-/* secure semaphores are slow because we have to do a become_root()
- on every call! */
-#define SEMAPHORE_PERMS IPC_PERMS
-#else
-#define SEMAPHORE_PERMS 0666
-#endif
-
-#define SHMEM_HASH_SIZE 13
-
-#define MIN_SHM_SIZE 0x1000
-
-static int shm_id;
-static int sem_id;
-static int shm_size;
-static int hash_size;
-static int global_lock_count;
-
-struct ShmHeader {
- int shm_magic;
- int shm_version;
- int total_size; /* in bytes */
- BOOL consistent;
- int first_free_off;
- int userdef_off; /* a userdefined offset. can be used to store
- root of tree or list */
- struct { /* a cell is a range of bytes of sizeof(struct
- ShmBlockDesc) size */
- int cells_free;
- int cells_used;
- int cells_system; /* number of cells used as allocated
- block descriptors */
- } statistics;
-};
-
-#define SHM_NOT_FREE_OFF (-1)
-struct ShmBlockDesc
-{
- int next; /* offset of next block in the free list or
- SHM_NOT_FREE_OFF when block in use */
- int size; /* user size in BlockDescSize units */
-};
-
-#define EOList_Addr NULL
-#define EOList_Off (0)
-
-#define CellSize sizeof(struct ShmBlockDesc)
-
-/* HeaderSize aligned on a 8 byte boundary */
-#define AlignedHeaderSize ((sizeof(struct ShmHeader)+7) & ~7)
-
-static struct ShmHeader *shm_header_p = NULL;
-
-static int read_only;
-
-static BOOL sem_change(int i, int op)
-{
-#ifdef SECURE_SEMAPHORES
- extern struct current_user current_user;
- int became_root=0;
-#endif
- struct sembuf sb;
- int ret;
-
- if (read_only) return True;
-
-#ifdef SECURE_SEMAPHORES
- if (current_user.uid != 0) {
- become_root(0);
- became_root = 1;
- }
-#endif
-
- sb.sem_num = i;
- sb.sem_op = op;
- sb.sem_flg = 0;
-
- ret = semop(sem_id, &sb, 1);
-
- if (ret != 0) {
- DEBUG(0,("ERROR: sem_change(%d,%d) failed (%s)\n",
- i, op, strerror(errno)));
- }
-
-#ifdef SECURE_SEMAPHORES
- if (became_root) {
- unbecome_root(0);
- }
-#endif
-
- return ret == 0;
-}
-
-static BOOL global_lock(void)
-{
- global_lock_count++;
- if (global_lock_count == 1)
- return sem_change(0, -1);
- return True;
-}
-
-static BOOL global_unlock(void)
-{
- global_lock_count--;
- if (global_lock_count == 0)
- return sem_change(0, 1);
- return True;
-}
-
-static void *shm_offset2addr(int offset)
-{
- if (offset == 0 )
- return (void *)(0);
-
- if (!shm_header_p)
- return (void *)(0);
-
- return (void *)((char *)shm_header_p + offset);
-}
-
-static int shm_addr2offset(void *addr)
-{
- if (!addr)
- return 0;
-
- if (!shm_header_p)
- return 0;
-
- return (int)((char *)addr - (char *)shm_header_p);
-}
-
-
-static int shm_alloc(int size)
-{
- unsigned num_cells ;
- struct ShmBlockDesc *scanner_p;
- struct ShmBlockDesc *prev_p;
- struct ShmBlockDesc *new_p;
- int result_offset;
-
-
- if (!shm_header_p) {
- /* not mapped yet */
- DEBUG(0,("ERROR shm_alloc : shmem not mapped\n"));
- return 0;
- }
-
- global_lock();
-
- if (!shm_header_p->consistent) {
- DEBUG(0,("ERROR shm_alloc : shmem not consistent\n"));
- global_unlock();
- return 0;
- }
-
- /* calculate the number of cells */
- num_cells = (size + (CellSize-1)) / CellSize;
-
- /* set start of scan */
- prev_p = (struct ShmBlockDesc *)shm_offset2addr(shm_header_p->first_free_off);
- scanner_p = prev_p ;
-
- /* scan the free list to find a matching free space */
- while ((scanner_p != EOList_Addr) && (scanner_p->size < num_cells)) {
- prev_p = scanner_p;
- scanner_p = (struct ShmBlockDesc *)shm_offset2addr(scanner_p->next);
- }
-
- /* at this point scanner point to a block header or to the end of
- the list */
- if (scanner_p == EOList_Addr) {
- DEBUG(0,("ERROR shm_alloc : alloc of %d bytes failed\n",size));
- global_unlock();
- return (0);
- }
-
- /* going to modify shared mem */
- shm_header_p->consistent = False;
-
- /* if we found a good one : scanner == the good one */
- if (scanner_p->size > num_cells + 2) {
- /* Make a new one */
- new_p = scanner_p + 1 + num_cells;
- new_p->size = scanner_p->size - (num_cells + 1);
- new_p->next = scanner_p->next;
- scanner_p->size = num_cells;
- scanner_p->next = shm_addr2offset(new_p);
-
- shm_header_p->statistics.cells_free -= 1;
- shm_header_p->statistics.cells_system += 1;
- }
-
- /* take it from the free list */
- if (prev_p == scanner_p) {
- shm_header_p->first_free_off = scanner_p->next;
- } else {
- prev_p->next = scanner_p->next;
- }
- shm_header_p->statistics.cells_free -= scanner_p->size;
- shm_header_p->statistics.cells_used += scanner_p->size;
-
- result_offset = shm_addr2offset(&(scanner_p[1]));
- scanner_p->next = SHM_NOT_FREE_OFF;
-
- /* end modification of shared mem */
- shm_header_p->consistent = True;
-
- global_unlock();
-
- DEBUG(6,("shm_alloc : allocated %d bytes at offset %d\n",
- size,result_offset));
-
- return result_offset;
-}
-
-static void shm_solve_neighbors(struct ShmBlockDesc *head_p )
-{
- struct ShmBlockDesc *next_p;
-
- /* Check if head_p and head_p->next are neighbors and if so
- join them */
- if ( head_p == EOList_Addr ) return ;
- if ( head_p->next == EOList_Off ) return ;
-
- next_p = (struct ShmBlockDesc *)shm_offset2addr(head_p->next);
- if ((head_p + head_p->size + 1) == next_p) {
- head_p->size += next_p->size + 1; /* adapt size */
- head_p->next = next_p->next; /* link out */
-
- shm_header_p->statistics.cells_free += 1;
- shm_header_p->statistics.cells_system -= 1;
- }
-}
-
-
-static BOOL shm_free(int offset)
-{
- struct ShmBlockDesc *header_p; /* pointer to header of
- block to free */
- struct ShmBlockDesc *scanner_p; /* used to scan the list */
- struct ShmBlockDesc *prev_p; /* holds previous in the
- list */
-
- if (!shm_header_p) {
- /* not mapped yet */
- DEBUG(0,("ERROR shm_free : shmem not mapped\n"));
- return False;
- }
-
- global_lock();
-
- if (!shm_header_p->consistent) {
- DEBUG(0,("ERROR shm_free : shmem not consistent\n"));
- global_unlock();
- return False;
- }
-
- /* make pointer to header of block */
- header_p = ((struct ShmBlockDesc *)shm_offset2addr(offset) - 1);
-
- if (header_p->next != SHM_NOT_FREE_OFF) {
- DEBUG(0,("ERROR shm_free : bad offset (%d)\n",offset));
- global_unlock();
- return False;
- }
-
- /* find a place in the free_list to put the header in */
-
- /* set scanner and previous pointer to start of list */
- prev_p = (struct ShmBlockDesc *)
- shm_offset2addr(shm_header_p->first_free_off);
- scanner_p = prev_p ;
-
- while ((scanner_p != EOList_Addr) &&
- (scanner_p < header_p)) {
- /* while we didn't scan past its position */
- prev_p = scanner_p ;
- scanner_p = (struct ShmBlockDesc *)
- shm_offset2addr(scanner_p->next);
- }
-
- shm_header_p->consistent = False;
-
- DEBUG(6,("shm_free : freeing %d bytes at offset %d\n",
- (int)(header_p->size*CellSize),(int)offset));
-
- /* zero the area being freed - this allows us to find bugs faster */
- memset(shm_offset2addr(offset), 0, header_p->size*CellSize);
-
- if (scanner_p == prev_p) {
- shm_header_p->statistics.cells_free += header_p->size;
- shm_header_p->statistics.cells_used -= header_p->size;
-
- /* we must free it at the beginning of the list */
- shm_header_p->first_free_off = shm_addr2offset(header_p);
- /* set the free_list_pointer to this block_header */
-
- /* scanner is the one that was first in the list */
- header_p->next = shm_addr2offset(scanner_p);
- shm_solve_neighbors(header_p);
-
- shm_header_p->consistent = True;
- } else {
- shm_header_p->statistics.cells_free += header_p->size;
- shm_header_p->statistics.cells_used -= header_p->size;
-
- prev_p->next = shm_addr2offset(header_p);
- header_p->next = shm_addr2offset(scanner_p);
- shm_solve_neighbors(header_p) ;
- shm_solve_neighbors(prev_p) ;
-
- shm_header_p->consistent = True;
- }
-
- global_unlock();
- return True;
-}
-
-
-/*
- * Function to create the hash table for the share mode entries. Called
- * when smb shared memory is global locked.
- */
-static BOOL shm_create_hash_table(unsigned int hash_entries)
-{
- int size = hash_entries * sizeof(int);
-
- global_lock();
- shm_header_p->userdef_off = shm_alloc(size);
-
- if(shm_header_p->userdef_off == 0) {
- DEBUG(0,("shm_create_hash_table: Failed to create hash table of size %d\n",
- size));
- global_unlock();
- return False;
- }
-
- /* Clear hash buckets. */
- memset(shm_offset2addr(shm_header_p->userdef_off), '\0', size);
- global_unlock();
- return True;
-}
-
-
-static BOOL shm_validate_header(int size)
-{
- if(!shm_header_p) {
- /* not mapped yet */
- DEBUG(0,("ERROR shm_validate_header : shmem not mapped\n"));
- return False;
- }
-
- if(shm_header_p->shm_magic != SHM_MAGIC) {
- DEBUG(0,("ERROR shm_validate_header : bad magic\n"));
- return False;
- }
-
- if(shm_header_p->shm_version != SHM_VERSION) {
- DEBUG(0,("ERROR shm_validate_header : bad version %X\n",
- shm_header_p->shm_version));
- return False;
- }
-
- if(shm_header_p->total_size != size) {
- DEBUG(0,("ERROR shmem size mismatch (old = %d, new = %d)\n",
- shm_header_p->total_size,size));
- return False;
- }
-
- if(!shm_header_p->consistent) {
- DEBUG(0,("ERROR shmem not consistent\n"));
- return False;
- }
- return True;
-}
-
-
-static BOOL shm_initialize(int size)
-{
- struct ShmBlockDesc * first_free_block_p;
-
- DEBUG(5,("shm_initialize : initializing shmem size %d\n",size));
-
- if( !shm_header_p ) {
- /* not mapped yet */
- DEBUG(0,("ERROR shm_initialize : shmem not mapped\n"));
- return False;
- }
-
- shm_header_p->shm_magic = SHM_MAGIC;
- shm_header_p->shm_version = SHM_VERSION;
- shm_header_p->total_size = size;
- shm_header_p->first_free_off = AlignedHeaderSize;
- shm_header_p->userdef_off = 0;
-
- first_free_block_p = (struct ShmBlockDesc *)
- shm_offset2addr(shm_header_p->first_free_off);
- first_free_block_p->next = EOList_Off;
- first_free_block_p->size =
- (size - (AlignedHeaderSize+CellSize))/CellSize;
- shm_header_p->statistics.cells_free = first_free_block_p->size;
- shm_header_p->statistics.cells_used = 0;
- shm_header_p->statistics.cells_system = 1;
-
- shm_header_p->consistent = True;
-
- return True;
-}
-
-static BOOL shm_close( void )
-{
- return True;
-}
-
-
-static int shm_get_userdef_off(void)
-{
- if (!shm_header_p)
- return 0;
- else
- return shm_header_p->userdef_off;
-}
-
-
-/*******************************************************************
- Lock a particular hash bucket entry.
- ******************************************************************/
-static BOOL shm_lock_hash_entry(unsigned int entry)
-{
- return sem_change(entry+1, -1);
-}
-
-/*******************************************************************
- Unlock a particular hash bucket entry.
- ******************************************************************/
-static BOOL shm_unlock_hash_entry(unsigned int entry)
-{
- return sem_change(entry+1, 1);
-}
-
-
-/*******************************************************************
- Gather statistics on shared memory usage.
- ******************************************************************/
-static BOOL shm_get_usage(int *bytes_free,
- int *bytes_used,
- int *bytes_overhead)
-{
- if(!shm_header_p) {
- /* not mapped yet */
- DEBUG(0,("ERROR shm_free : shmem not mapped\n"));
- return False;
- }
-
- *bytes_free = shm_header_p->statistics.cells_free * CellSize;
- *bytes_used = shm_header_p->statistics.cells_used * CellSize;
- *bytes_overhead = shm_header_p->statistics.cells_system * CellSize +
- AlignedHeaderSize;
-
- return True;
-}
-
-
-/*******************************************************************
-hash a number into a hash_entry
- ******************************************************************/
-static unsigned shm_hash_size(void)
-{
- return hash_size;
-}
-
-
-static struct shmem_ops shmops = {
- shm_close,
- shm_alloc,
- shm_free,
- shm_get_userdef_off,
- shm_offset2addr,
- shm_addr2offset,
- shm_lock_hash_entry,
- shm_unlock_hash_entry,
- shm_get_usage,
- shm_hash_size,
-};
-
-/*******************************************************************
- open the shared memory
- ******************************************************************/
-
-struct shmem_ops *sysv_shm_open(int ronly)
-{
- BOOL other_processes;
- struct shmid_ds shm_ds;
- struct semid_ds sem_ds;
- union semun su;
- int i;
- pid_t pid;
- struct passwd *root_pwd = sys_getpwuid((uid_t)0);
- gid_t root_gid = root_pwd ? root_pwd->pw_gid : (gid_t)0;
-
- read_only = ronly;
-
- shm_size = lp_shmem_size();
-
- DEBUG(4,("Trying sysv shmem open of size %d\n", shm_size));
-
- /* first the semaphore */
- sem_id = semget(SEMAPHORE_KEY, 0, 0);
- if (sem_id == -1) {
- if (read_only) return NULL;
-
- hash_size = SHMEM_HASH_SIZE;
-
- while (hash_size > 1) {
- sem_id = semget(SEMAPHORE_KEY, hash_size+1,
- IPC_CREAT|IPC_EXCL| SEMAPHORE_PERMS);
- if (sem_id != -1 ||
- (errno != EINVAL && errno != ENOSPC)) break;
- hash_size -= 5;
- }
-
- if (sem_id == -1) {
- DEBUG(0,("Can't create or use semaphore [1]. Error was %s\n",
- strerror(errno)));
- return NULL;
- }
-
- if (sem_id != -1) {
- su.val = 1;
- for (i=0;i<hash_size+1;i++) {
- if (semctl(sem_id, i, SETVAL, su) != 0) {
- DEBUG(1,("Failed to init semaphore %d. Error was %s\n",
- i, strerror(errno)));
- return NULL;
- }
- }
- }
- }
- if (shm_id == -1) {
- sem_id = semget(SEMAPHORE_KEY, 0, 0);
- }
- if (sem_id == -1) {
- DEBUG(0,("Can't create or use semaphore [2]. Error was %s\n",
- strerror(errno)));
- return NULL;
- }
-
- su.buf = &sem_ds;
- if (semctl(sem_id, 0, IPC_STAT, su) != 0) {
- DEBUG(0,("ERROR semctl: can't IPC_STAT. Error was %s\n",
- strerror(errno)));
- return NULL;
- }
- hash_size = sem_ds.sem_nsems-1;
-
- if (!read_only) {
- if (sem_ds.sem_perm.cuid != 0 || ((sem_ds.sem_perm.cgid != root_gid) && (sem_ds.sem_perm.cgid != 0))) {
- DEBUG(0,("ERROR: root did not create the semaphore: semgid=%u, rootgid=%u\n",
- (unsigned int)sem_ds.sem_perm.cgid, (unsigned int)root_gid));
- return NULL;
- }
-
- if (semctl(sem_id, 0, GETVAL, su) == 0 &&
- !process_exists((pid=(pid_t)semctl(sem_id, 0, GETPID, su)))) {
- DEBUG(0,("WARNING: clearing global IPC lock set by dead process %d\n",
- (int)pid));
- su.val = 1;
- if (semctl(sem_id, 0, SETVAL, su) != 0) {
- DEBUG(0,("ERROR: Failed to clear global lock. Error was %s\n",
- strerror(errno)));
- return NULL;
- }
- }
-
- sem_ds.sem_perm.mode = SEMAPHORE_PERMS;
- if (semctl(sem_id, 0, IPC_SET, su) != 0) {
- DEBUG(0,("ERROR shmctl : can't IPC_SET. Error was %s\n",
- strerror(errno)));
- return NULL;
- }
- }
-
- if (!global_lock())
- return NULL;
-
-
- for (i=1;i<hash_size+1;i++) {
- if (semctl(sem_id, i, GETVAL, su) == 0 &&
- !process_exists((pid=(pid_t)semctl(sem_id, i, GETPID, su)))) {
- DEBUG(1,("WARNING: clearing IPC lock %d set by dead process %d\n",
- i, (int)pid));
- su.val = 1;
- if (semctl(sem_id, i, SETVAL, su) != 0) {
- DEBUG(0,("ERROR: Failed to clear IPC lock %d. Error was %s\n",
- i, strerror(errno)));
- global_unlock();
- return NULL;
- }
- }
- }
-
- /*
- * Try to use an existing key. Note that
- * in order to use an existing key successfully
- * size must be zero else shmget returns EINVAL.
- * Thanks to Veselin Terzic <vterzic@systems.DHL.COM>
- * for pointing this out.
- */
-
- shm_id = shmget(SHMEM_KEY, 0, 0);
-
- /* if that failed then create one */
- if (shm_id == -1) {
- if (read_only) return NULL;
- while (shm_size > MIN_SHM_SIZE) {
- shm_id = shmget(SHMEM_KEY, shm_size,
- IPC_CREAT | IPC_EXCL | IPC_PERMS);
- if (shm_id != -1 ||
- (errno != EINVAL && errno != ENOSPC)) break;
- shm_size *= 0.8;
- }
- }
-
- if (shm_id == -1) {
- DEBUG(0,("Can't create or use IPC area. Error was %s\n", strerror(errno)));
- global_unlock();
- return NULL;
- }
-
-
- shm_header_p = (struct ShmHeader *)shmat(shm_id, 0,
- read_only?SHM_RDONLY:0);
- if ((long)shm_header_p == -1) {
- DEBUG(0,("Can't attach to IPC area. Error was %s\n", strerror(errno)));
- global_unlock();
- return NULL;
- }
-
- /* to find out if some other process is already mapping the file,
- we use a registration file containing the processids of the file
- mapping processes */
- if (shmctl(shm_id, IPC_STAT, &shm_ds) != 0) {
- DEBUG(0,("ERROR shmctl : can't IPC_STAT. Error was %s\n", strerror(errno)));
- global_unlock();
- return NULL;
- }
-
- if (!read_only) {
- if (shm_ds.shm_perm.cuid != 0 || ((shm_ds.shm_perm.cgid != root_gid) && (shm_ds.shm_perm.cgid != 0))) {
- DEBUG(0,("ERROR: root did not create the shmem\n"));
- global_unlock();
- return NULL;
- }
- }
-
- shm_size = shm_ds.shm_segsz;
-
- other_processes = (shm_ds.shm_nattch > 1);
-
- if (!read_only && !other_processes) {
- memset((char *)shm_header_p, 0, shm_size);
- shm_initialize(shm_size);
- shm_create_hash_table(hash_size);
- DEBUG(3,("Initialised IPC area of size %d\n", shm_size));
- } else if (!shm_validate_header(shm_size)) {
- /* existing file is corrupt, samba admin should remove
- it by hand */
- DEBUG(0,("ERROR shm_open : corrupt IPC area - remove it!\n"));
- global_unlock();
- return NULL;
- }
-
- global_unlock();
- return &shmops;
-}
-
-
-
-#else
- int ipc_dummy_procedure(void)
-{return 0;}
-#endif
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 8202960089..583b4bb4b8 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -628,7 +628,7 @@ BOOL change_trust_account_password( char *domain, char *remote_machine_list)
unsigned char old_trust_passwd_hash[16];
unsigned char new_trust_passwd_hash[16];
time_t lct;
- BOOL res;
+ BOOL res = False;
if(!get_trust_account_password( old_trust_passwd_hash, &lct)) {
DEBUG(0,("change_trust_account_password: unable to read the machine \
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index d06cb3b5bb..bfef7c5235 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -94,7 +94,6 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
{
SMB_DEV_T dev = fsp->fd_ptr->dev;
SMB_INO_T inode = fsp->fd_ptr->inode;
- int token;
BOOL last_reference = False;
BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
connection_struct *conn = fsp->conn;
@@ -109,8 +108,8 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
#endif
if (lp_share_modes(SNUM(conn))) {
- lock_share_entry(conn, dev, inode, &token);
- del_share_mode(token, fsp);
+ lock_share_entry(conn, dev, inode);
+ del_share_mode(fsp);
}
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
@@ -122,7 +121,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
fsp->fd_ptr = NULL;
if (lp_share_modes(SNUM(conn)))
- unlock_share_entry(conn, dev, inode, token);
+ unlock_share_entry(conn, dev, inode);
/* NT uses smbclose to start a print - weird */
if (normal_close && fsp->print_file)
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index f88d707983..5b5ab005c8 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -27,27 +27,6 @@ extern fstring remote_machine;
extern int DEBUGLEVEL;
/****************************************************************************
-open the connections database
-****************************************************************************/
-TDB_CONTEXT *open_db(char *name)
-{
- pstring fname;
-
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,"","/");
-
- if (!directory_exist(fname,NULL)) {
- mkdir(fname,0755);
- }
-
- pstrcat(fname,"/connections.tdb");
-
- return tdb_open(fname, 0, O_RDWR | O_CREAT, 0644);
-}
-
-
-
-/****************************************************************************
delete a connection record
****************************************************************************/
BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
@@ -56,7 +35,8 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
TDB_DATA kbuf;
TDB_CONTEXT *tdb;
- if (!(tdb = open_db(name))) return False;
+ tdb = tdb_open(lock_path("connections.tdb"), 0, O_RDWR | O_CREAT, 0644);
+ if (!tdb) return False;
DEBUG(3,("Yielding connection to %s\n",name));
@@ -100,7 +80,8 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
if (max_connections <= 0)
return(True);
- if (!(tdb = open_db(name))) return False;
+ tdb = tdb_open(lock_path("connections.tdb"), 0, O_RDWR | O_CREAT, 0644);
+ if (!tdb) return False;
DEBUG(5,("claiming %s %d\n",name,max_connections));
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 8b48a921fd..fa04e671f8 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -213,11 +213,11 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
int num_share_modes = 0;
int i;
- if (lock_share_entry(fsp->conn, dev, inode, &token) == False) {
+ if (lock_share_entry(fsp->conn, dev, inode) == False) {
DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name ));
}
- num_share_modes = get_share_modes(fsp->conn, token, dev, inode, &share_list);
+ num_share_modes = get_share_modes(fsp->conn, dev, inode, &share_list);
for(i = 0; i < num_share_modes; i++) {
share_mode_entry *share_entry = &share_list[i];
@@ -268,7 +268,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
}
free((char *)share_list);
- unlock_share_entry(fsp->conn, dev, inode, token);
+ unlock_share_entry(fsp->conn, dev, inode);
}
/* Paranoia check... */
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 4491082b2c..a940eda85d 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -602,7 +602,7 @@ static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, i
have the share entry locked. Unlock it before closing. */
if (*share_locked && lp_share_modes(SNUM(conn)))
unlock_share_entry( conn, fsp->fd_ptr->dev,
- fsp->fd_ptr->inode, token);
+ fsp->fd_ptr->inode);
close_file(fsp,False);
/* Share mode no longer locked. */
*share_locked = False;
@@ -858,9 +858,9 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int
{
dev = sbuf.st_dev;
inode = sbuf.st_ino;
- lock_share_entry(conn, dev, inode, &token);
+ lock_share_entry(conn, dev, inode);
share_locked = True;
- num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
}
/*
@@ -896,7 +896,7 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int
dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
/* Oplock break.... */
- unlock_share_entry(conn, dev, inode, token);
+ unlock_share_entry(conn, dev, inode);
if(request_oplock_break(share_entry, dev, inode) == False)
{
free((char *)old_shares);
@@ -909,7 +909,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
unix_ERR_code = ERRbadshare;
return;
}
- lock_share_entry(conn, dev, inode, &token);
+ lock_share_entry(conn, dev, inode);
broke_oplock = True;
all_current_opens_are_level_II = False;
break;
@@ -922,7 +922,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
{
free((char *)old_shares);
- unlock_share_entry(conn, dev, inode, token);
+ unlock_share_entry(conn, dev, inode);
errno = EACCES;
return;
}
@@ -932,7 +932,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
if(broke_oplock)
{
free((char *)old_shares);
- num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
oplock_contention_count++;
}
} while(broke_oplock);
@@ -973,7 +973,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
/* We created the file - thus we must now lock the share entry before creating it. */
dev = fsp->fd_ptr->dev;
inode = fsp->fd_ptr->inode;
- lock_share_entry(conn, dev, inode, &token);
+ lock_share_entry(conn, dev, inode);
share_locked = True;
}
@@ -1028,7 +1028,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
oplock_request = 0;
}
- set_share_mode(token, fsp, port, oplock_request);
+ set_share_mode(fsp, port, oplock_request);
}
if ((flags2&O_TRUNC) && file_existed)
@@ -1036,7 +1036,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
}
if (share_locked && lp_share_modes(SNUM(conn)))
- unlock_share_entry( conn, dev, inode, token);
+ unlock_share_entry( conn, dev, inode);
}
/****************************************************************************
@@ -1224,7 +1224,6 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
share_mode_entry *old_shares = 0;
int num_share_modes;
SMB_STRUCT_STAT sbuf;
- int token;
pid_t pid = getpid();
SMB_DEV_T dev;
SMB_INO_T inode;
@@ -1237,8 +1236,8 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
dev = sbuf.st_dev;
inode = sbuf.st_ino;
- lock_share_entry(conn, dev, inode, &token);
- num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
+ lock_share_entry(conn, dev, inode);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
/*
* Check if the share modes will give us access.
@@ -1308,7 +1307,7 @@ batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (do
dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
/* Oplock break.... */
- unlock_share_entry(conn, dev, inode, token);
+ unlock_share_entry(conn, dev, inode);
if(request_oplock_break(share_entry, dev, inode) == False)
{
free((char *)old_shares);
@@ -1318,7 +1317,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
return False;
}
- lock_share_entry(conn, dev, inode, &token);
+ lock_share_entry(conn, dev, inode);
broke_oplock = True;
break;
}
@@ -1345,7 +1344,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
if(broke_oplock)
{
free((char *)old_shares);
- num_share_modes = get_share_modes(conn, token, dev, inode, &old_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
}
} while(broke_oplock);
}
@@ -1364,7 +1363,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
free_and_exit:
- unlock_share_entry(conn, dev, inode, token);
+ unlock_share_entry(conn, dev, inode);
if(old_shares != NULL)
free((char *)old_shares);
return(ret);
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index a64dd2d0ef..c5cab8c225 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -406,13 +406,12 @@ static void downgrade_file_oplock(files_struct *fsp)
BOOL remove_oplock(files_struct *fsp)
{
- int token;
SMB_DEV_T dev = fsp->fd_ptr->dev;
SMB_INO_T inode = fsp->fd_ptr->inode;
BOOL ret = True;
/* Remove the oplock flag from the sharemode. */
- if (lock_share_entry(fsp->conn, dev, inode, &token) == False) {
+ if (lock_share_entry(fsp->conn, dev, inode) == False) {
DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
fsp->fsp_name ));
ret = False;
@@ -424,7 +423,7 @@ BOOL remove_oplock(files_struct *fsp)
* Deal with a reply when a break-to-none was sent.
*/
- if(remove_share_oplock(token, fsp)==False) {
+ if(remove_share_oplock(fsp)==False) {
DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
ret = False;
@@ -438,7 +437,7 @@ dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)
* Deal with a reply when a break-to-level II was sent.
*/
- if(downgrade_share_oplock(token, fsp)==False) {
+ if(downgrade_share_oplock(fsp)==False) {
DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
ret = False;
@@ -447,7 +446,7 @@ dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)
downgrade_file_oplock(fsp);
}
- unlock_share_entry(fsp->conn, dev, inode, token);
+ unlock_share_entry(fsp->conn, dev, inode);
return ret;
}
@@ -792,18 +791,18 @@ BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
* the existing lock on the shared memory area.
*/
- if(!local_request && lock_share_entry(fsp->conn, dev, inode, &token) == False) {
+ if(!local_request && lock_share_entry(fsp->conn, dev, inode) == False) {
DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
} else {
got_lock = True;
}
- if(remove_share_oplock(token, fsp)==False) {
+ if(remove_share_oplock(fsp)==False) {
DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
}
if (!local_request && got_lock)
- unlock_share_entry(fsp->conn, dev, inode, token);
+ unlock_share_entry(fsp->conn, dev, inode);
fsp->oplock_type = NO_OPLOCK;
level_II_oplocks_open--;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 5a8db7efda..bbbfda7468 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1800,7 +1800,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
{
- int token;
int i;
files_struct *iterate_fsp;
SMB_DEV_T dev = fsp->fd_ptr->dev;
@@ -1808,7 +1807,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
int num_share_modes;
share_mode_entry *current_shares = NULL;
- if(lock_share_entry(fsp->conn, dev, inode, &token) == False)
+ if(lock_share_entry(fsp->conn, dev, inode) == False)
return(ERROR(ERRDOS,ERRnoaccess));
/*
@@ -1818,7 +1817,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
* file at this point.
*/
- num_share_modes = get_share_modes(conn, token, dev, inode, &current_shares);
+ num_share_modes = get_share_modes(conn, dev, inode, &current_shares);
for(i = 0; i < num_share_modes; i++)
{
if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
@@ -1830,7 +1829,7 @@ file %s as a share exists that was not opened with FILE_DELETE access.\n",
* Release the lock.
*/
- unlock_share_entry(fsp->conn, dev, inode, token);
+ unlock_share_entry(fsp->conn, dev, inode);
/*
* current_shares was malloced by get_share_modes - free it here.
@@ -1875,7 +1874,7 @@ dev = %x, inode = %.0f from %x to %x\n",
iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
(double)inode, iterate_fsp->share_mode, new_share_mode ));
- if(modify_share_mode(token, iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
+ if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
}
@@ -1887,7 +1886,7 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
*/
fsp->fd_ptr->delete_on_close = delete_on_close;
- unlock_share_entry(fsp->conn, dev, inode, token);
+ unlock_share_entry(fsp->conn, dev, inode);
DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c
index 01d2e740f7..70880b5345 100644
--- a/source3/tdb/tdb.c
+++ b/source3/tdb/tdb.c
@@ -75,6 +75,26 @@ static char *memdup(char *d, int size)
}
#endif
+
+/* a byte range locking function - return 0 on success
+ this functions locks/unlocks 1 byte at the specified offset */
+static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, int set)
+{
+#if !NOLOCK
+ struct flock fl;
+
+ fl.l_type = set?F_WRLCK:F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = offset;
+ fl.l_len = 1;
+ fl.l_pid = 0;
+
+ if (fcntl(tdb->fd, F_SETLKW, &fl) != 0) return -1;
+#endif
+ return 0;
+}
+
+
/* the hash algorithm - turn a key into an integer
This is based on the hash agorithm from gdbm */
static unsigned tdb_hash(TDB_DATA *key)
@@ -991,42 +1011,25 @@ int tdb_close(TDB_CONTEXT *tdb)
/* lock the database. If we already have it locked then don't do anything */
int tdb_writelock(TDB_CONTEXT *tdb)
{
-#if !NOLOCK
- struct flock fl;
-
- if (tdb->write_locked) return 0;
-
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 1;
- fl.l_pid = 0;
-
- if (fcntl(tdb->fd, F_SETLKW, &fl) != 0) return -1;
-
- tdb->write_locked = 1;
-#endif
- return 0;
+ return tdb_brlock(tdb, 0, 1);
}
-/* unlock the database. If we don't have it locked then return -1 */
+/* unlock the database. */
int tdb_writeunlock(TDB_CONTEXT *tdb)
{
-#if !NOLOCK
- struct flock fl;
-
- if (!tdb->write_locked) return -1;
+ return tdb_brlock(tdb, 0, 0);
+}
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 1;
- fl.l_pid = 0;
+/* lock one hash chain. This is meant to be used to reduce locking
+ contention - it cannot guarantee how many records will be locked */
+int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ return tdb_brlock(tdb, tdb_hash_top(tdb, tdb_hash(&key)), 1);
+}
- if (fcntl(tdb->fd, F_SETLK, &fl) != 0) return -1;
- tdb->write_locked = 0;
-#endif
- return 0;
+/* unlock one hash chain */
+int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ return tdb_brlock(tdb, tdb_hash_top(tdb, tdb_hash(&key)), 0);
}
-
diff --git a/source3/utils/status.c b/source3/utils/status.c
index 594783bd39..8f3461c082 100644
--- a/source3/utils/status.c
+++ b/source3/utils/status.c
@@ -165,7 +165,6 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
static pid_t last_pid;
struct session_record *ptr;
struct connections_data crec;
- static int doneone;
memcpy(&crec, dbuf.dptr, sizeof(crec));
@@ -176,13 +175,6 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
}
if (brief) {
- if (!doneone) {
- printf("\nSamba version %s\n",VERSION);
- printf("PID Username Machine Time logged in\n");
- printf("-------------------------------------------------------------------\n");
- doneone = 1;
- }
-
ptr=srecs;
while (ptr!=NULL) {
if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0)) {
@@ -203,13 +195,6 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
srecs=ptr;
}
} else {
- if (!doneone) {
- printf("\nSamba version %s\n",VERSION);
- printf("Service uid gid pid machine\n");
- printf("----------------------------------------------\n");
- doneone = 1;
- }
-
Ucrit_addPid(crec.pid);
if (processes_only) {
if (last_pid != crec.pid)
@@ -292,19 +277,13 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
if (verbose) {
printf("using configfile = %s\n", servicesf);
- printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL");
}
if (profile_only) {
return profile_dump();
}
- pstrcpy(fname,lp_lockdir());
- standard_sub_basic(fname);
- trim_string(fname,"","/");
- pstrcat(fname,"/connections.tdb");
-
- tdb = tdb_open(fname, 0, O_RDONLY, 0);
+ tdb = tdb_open(lock_path("connections.tdb"), 0, O_RDONLY, 0);
if (!tdb) {
printf("Couldn't open status file %s\n",fname);
if (!lp_status(-1))
@@ -316,6 +295,14 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
if (locks_only) goto locks;
+ printf("\nSamba version %s\n",VERSION);
+ if (brief) {
+ printf("PID Username Machine Time logged in\n");
+ printf("-------------------------------------------------------------------\n");
+ } else {
+ printf("Service uid gid pid machine\n");
+ printf("----------------------------------------------\n");
+ }
tdb_traverse(tdb, traverse_fn1);
locks:
@@ -347,8 +334,6 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
printf("\n");
- share_status(stdout);
-
locking_end();
}
diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c
index 8b7108c0b5..e3e10f09d5 100644
--- a/source3/web/statuspage.c
+++ b/source3/web/statuspage.c
@@ -128,7 +128,6 @@ static int traverse_fn3(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf)
/* show the current server status */
void status_page(void)
{
- pstring fname;
char *v;
int autorefresh=0;
int refresh_interval=30;
@@ -173,12 +172,7 @@ void status_page(void)
refresh_interval = atoi(v);
}
- pstrcpy(fname,lp_lockdir());
- standard_sub_basic(fname);
- trim_string(fname,"","/");
- pstrcat(fname,"/connections.tdb");
-
- tdb = tdb_open(fname, 0, O_RDONLY, 0);
+ tdb = tdb_open(lock_path("connections.tdb"), 0, O_RDONLY, 0);
if (tdb) tdb_traverse(tdb, traverse_fn1);
printf("<H2>Server Status</H2>\n");