summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/locking/posix.c256
1 files changed, 130 insertions, 126 deletions
diff --git a/source3/locking/posix.c b/source3/locking/posix.c
index 4b0b91bd19..aef5c1784f 100644
--- a/source3/locking/posix.c
+++ b/source3/locking/posix.c
@@ -30,7 +30,7 @@
* The pending close database handle.
*/
-static TDB_CONTEXT *posix_pending_close_tdb;
+static struct db_context *posix_pending_close_db;
/****************************************************************************
First - the functions that deal with the underlying system locks - these
@@ -349,20 +349,18 @@ static TDB_DATA fd_array_key_fsp(files_struct *fsp)
bool posix_locking_init(bool read_only)
{
- if (posix_pending_close_tdb) {
- return True;
- }
-
- if (!posix_pending_close_tdb) {
- posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL,
- read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
+ if (posix_pending_close_db != NULL) {
+ return true;
}
- if (!posix_pending_close_tdb) {
+
+ posix_pending_close_db = db_open_rbt(NULL);
+
+ if (posix_pending_close_db == NULL) {
DEBUG(0,("Failed to open POSIX pending close database.\n"));
- return False;
+ return false;
}
- return True;
+ return true;
}
/*******************************************************************
@@ -371,10 +369,11 @@ bool posix_locking_init(bool read_only)
bool posix_locking_end(void)
{
- if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0) {
- return False;
- }
- return True;
+ /*
+ * Shouldn't we close all fd's here?
+ */
+ TALLOC_FREE(posix_pending_close_db);
+ return true;
}
/****************************************************************************
@@ -399,60 +398,33 @@ bool posix_locking_end(void)
static void increment_windows_lock_ref_count(files_struct *fsp)
{
struct lock_ref_count_key tmp;
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
- TDB_DATA dbuf;
- int lock_ref_count;
-
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (dbuf.dptr == NULL) {
- dbuf.dptr = (uint8 *)SMB_MALLOC_P(int);
- if (!dbuf.dptr) {
- smb_panic("increment_windows_lock_ref_count: malloc fail");
- }
- memset(dbuf.dptr, '\0', sizeof(int));
- dbuf.dsize = sizeof(int);
- }
+ struct db_record *rec;
+ int lock_ref_count = 0;
+ NTSTATUS status;
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
- lock_ref_count++;
- memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("increment_windows_lock_ref_count: tdb_store_fail");
- }
- SAFE_FREE(dbuf.dptr);
-
- DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
-}
+ rec = posix_pending_close_db->fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ locking_ref_count_key_fsp(fsp, &tmp));
-static void decrement_windows_lock_ref_count(files_struct *fsp)
-{
- struct lock_ref_count_key tmp;
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
- TDB_DATA dbuf;
- int lock_ref_count;
+ SMB_ASSERT(rec != NULL);
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
- smb_panic("decrement_windows_lock_ref_count: logic error");
+ if (rec->value.dptr != NULL) {
+ SMB_ASSERT(rec->value.dsize == sizeof(lock_ref_count));
+ memcpy(&lock_ref_count, rec->value.dptr,
+ sizeof(lock_ref_count));
}
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
- lock_ref_count--;
- memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
+ lock_ref_count++;
- if (lock_ref_count < 0) {
- smb_panic("decrement_windows_lock_ref_count: lock_count logic error");
- }
+ status = rec->store(rec, make_tdb_data((uint8 *)&lock_ref_count,
+ sizeof(lock_ref_count)), 0);
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("decrement_windows_lock_ref_count: tdb_store_fail");
- }
- SAFE_FREE(dbuf.dptr);
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
+
+ TALLOC_FREE(rec);
- DEBUG(10,("decrement_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
+ fsp->fsp_name, lock_ref_count ));
}
/****************************************************************************
@@ -462,30 +434,38 @@ static void decrement_windows_lock_ref_count(files_struct *fsp)
void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
{
struct lock_ref_count_key tmp;
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
- TDB_DATA dbuf;
- int lock_ref_count;
+ struct db_record *rec;
+ int lock_ref_count = 0;
+ NTSTATUS status;
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
- return;
- }
+ rec = posix_pending_close_db->fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ locking_ref_count_key_fsp(fsp, &tmp));
+
+ SMB_ASSERT((rec != NULL)
+ && (rec->value.dptr != NULL)
+ && (rec->value.dsize == sizeof(lock_ref_count)));
+
+ memcpy(&lock_ref_count, rec->value.dptr, sizeof(lock_ref_count));
+
+ SMB_ASSERT(lock_ref_count > 0);
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
lock_ref_count -= dcount;
- if (lock_ref_count < 0) {
- smb_panic("reduce_windows_lock_ref_count: lock_count logic error");
- }
- memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("reduce_windows_lock_ref_count: tdb_store_fail");
- }
- SAFE_FREE(dbuf.dptr);
+ status = rec->store(rec, make_tdb_data((uint8 *)&lock_ref_count,
+ sizeof(lock_ref_count)), 0);
+
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
+
+ TALLOC_FREE(rec);
DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp->fsp_name, lock_ref_count ));
+}
+
+static void decrement_windows_lock_ref_count(files_struct *fsp)
+{
+ reduce_windows_lock_ref_count(fsp, 1);
}
/****************************************************************************
@@ -495,20 +475,25 @@ void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
static int get_windows_lock_ref_count(files_struct *fsp)
{
struct lock_ref_count_key tmp;
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
TDB_DATA dbuf;
- int lock_ref_count;
+ int res;
+ int lock_ref_count = 0;
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
- if (!dbuf.dptr) {
- lock_ref_count = 0;
- } else {
- memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+ res = posix_pending_close_db->fetch(
+ posix_pending_close_db, talloc_tos(),
+ locking_ref_count_key_fsp(fsp, &tmp), &dbuf);
+
+ SMB_ASSERT(res == 0);
+
+ if (dbuf.dsize != 0) {
+ SMB_ASSERT(dbuf.dsize == sizeof(lock_ref_count));
+ memcpy(&lock_ref_count, dbuf.dptr, sizeof(lock_ref_count));
+ TALLOC_FREE(dbuf.dptr);
}
- SAFE_FREE(dbuf.dptr);
DEBUG(10,("get_windows_lock_count for file %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp->fsp_name, lock_ref_count ));
+
return lock_ref_count;
}
@@ -519,11 +504,21 @@ static int get_windows_lock_ref_count(files_struct *fsp)
static void delete_windows_lock_ref_count(files_struct *fsp)
{
struct lock_ref_count_key tmp;
- TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
+ struct db_record *rec;
+
+ rec = posix_pending_close_db->fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ locking_ref_count_key_fsp(fsp, &tmp));
+
+ SMB_ASSERT(rec != NULL);
/* Not a bug if it doesn't exist - no locks were ever granted. */
- tdb_delete(posix_pending_close_tdb, kbuf);
- DEBUG(10,("delete_windows_lock_ref_count for file %s\n", fsp->fsp_name));
+
+ rec->delete_rec(rec);
+ TALLOC_FREE(rec);
+
+ DEBUG(10,("delete_windows_lock_ref_count for file %s\n",
+ fsp->fsp_name));
}
/****************************************************************************
@@ -532,30 +527,35 @@ static void delete_windows_lock_ref_count(files_struct *fsp)
static void add_fd_to_close_entry(files_struct *fsp)
{
- TDB_DATA kbuf = fd_array_key_fsp(fsp);
- TDB_DATA dbuf;
+ struct db_record *rec;
+ uint8_t *new_data;
+ NTSTATUS status;
- dbuf.dptr = NULL;
- dbuf.dsize = 0;
+ rec = posix_pending_close_db->fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ fd_array_key_fsp(fsp));
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ SMB_ASSERT(rec != NULL);
- dbuf.dptr = (uint8 *)SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int));
- if (!dbuf.dptr) {
- smb_panic("add_fd_to_close_entry: SMB_REALLOC failed");
- }
+ new_data = TALLOC_ARRAY(
+ rec, uint8_t, rec->value.dsize + sizeof(fsp->fh->fd));
- memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
- dbuf.dsize += sizeof(int);
+ SMB_ASSERT(new_data != NULL);
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- smb_panic("add_fd_to_close_entry: tdb_store_fail");
- }
+ memcpy(new_data, rec->value.dptr, rec->value.dsize);
+ memcpy(new_data + rec->value.dsize,
+ &fsp->fh->fd, sizeof(fsp->fh->fd));
- DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
- fsp->fh->fd, fsp->fsp_name ));
+ status = rec->store(
+ rec, make_tdb_data(new_data,
+ rec->value.dsize + sizeof(fsp->fh->fd)), 0);
+
+ SMB_ASSERT(NT_STATUS_IS_OK(status));
- SAFE_FREE(dbuf.dptr);
+ TALLOC_FREE(rec);
+
+ DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
+ fsp->fh->fd, fsp->fsp_name ));
}
/****************************************************************************
@@ -564,37 +564,41 @@ static void add_fd_to_close_entry(files_struct *fsp)
static void delete_close_entries(files_struct *fsp)
{
- TDB_DATA kbuf = fd_array_key_fsp(fsp);
+ struct db_record *rec;
- if (tdb_delete(posix_pending_close_tdb, kbuf) == -1) {
- smb_panic("delete_close_entries: tdb_delete failed");
- }
+ rec = posix_pending_close_db->fetch_locked(
+ posix_pending_close_db, talloc_tos(),
+ fd_array_key_fsp(fsp));
+
+ SMB_ASSERT(rec != NULL);
+ rec->delete_rec(rec);
+ TALLOC_FREE(rec);
}
/****************************************************************************
- Get the array of POSIX pending close records for an open fsp. Caller must
- free. Returns number of entries.
+ Get the array of POSIX pending close records for an open fsp. Returns number
+ of entries.
****************************************************************************/
-static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries)
+static size_t get_posix_pending_close_entries(TALLOC_CTX *mem_ctx,
+ files_struct *fsp, int **entries)
{
- TDB_DATA kbuf = fd_array_key_fsp(fsp);
TDB_DATA dbuf;
- size_t count = 0;
+ int res;
- *entries = NULL;
- dbuf.dptr = NULL;
+ res = posix_pending_close_db->fetch(
+ posix_pending_close_db, mem_ctx, fd_array_key_fsp(fsp),
+ &dbuf);
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ SMB_ASSERT(res == 0);
- if (!dbuf.dptr) {
+ if (dbuf.dsize == 0) {
+ *entries = NULL;
return 0;
}
*entries = (int *)dbuf.dptr;
- count = (size_t)(dbuf.dsize / sizeof(int));
-
- return count;
+ return (size_t)(dbuf.dsize / sizeof(int));
}
/****************************************************************************
@@ -641,7 +645,7 @@ NTSTATUS fd_close_posix(struct connection_struct *conn, files_struct *fsp)
* from the tdb and close them all.
*/
- count = get_posix_pending_close_entries(fsp, &fd_array);
+ count = get_posix_pending_close_entries(talloc_tos(), fsp, &fd_array);
if (count) {
DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
@@ -660,7 +664,7 @@ NTSTATUS fd_close_posix(struct connection_struct *conn, files_struct *fsp)
delete_close_entries(fsp);
}
- SAFE_FREE(fd_array);
+ TALLOC_FREE(fd_array);
/* Don't need a lock ref count on this dev/ino anymore. */
delete_windows_lock_ref_count(fsp);