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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
*/
#include "includes.h"
+#include "ntvfs/ntvfs.h"
+#include "ntvfs/common/ntvfs_common.h"
+#include "cluster/cluster.h"
+#include "param/param.h"
-struct odb_context {
- struct tdb_wrap *w;
- servid_t server;
- uint16_t tid;
- void *messaging_ctx;
-};
-
-/*
- the database is indexed by a file_key, and contains entries of the
- following form
-*/
-struct odb_entry {
- servid_t server;
- uint16_t tid;
- uint16_t fnum;
- uint32_t share_access;
- uint32_t desired_access;
- uint32_t create_options;
-};
-
+static const struct opendb_ops *ops;
/*
- an odb lock handle. You must obtain one of these using odb_lock() before doing
- any other operations.
+ set the odb backend ops
*/
-struct odb_lock {
- struct odb_context *odb;
- TDB_DATA key;
-};
+void odb_set_ops(const struct opendb_ops *new_ops)
+{
+ ops = new_ops;
+}
/*
Open up the openfiles.tdb database. Close it down using
talloc_free(). We need the messaging_ctx to allow for pending open
notifications.
*/
-struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid,
- void *messaging_ctx)
+_PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx,
+ struct ntvfs_context *ntvfs_ctx)
{
- char *path;
- struct odb_context *odb;
-
- odb = talloc_p(mem_ctx, struct odb_context);
- if (odb == NULL) {
- return NULL;
+ if (ops == NULL) {
+ if (lp_parm_bool(global_loadparm, NULL, "ctdb", "opendb", false)) {
+ odb_ctdb_init_ops();
+ } else {
+ odb_tdb_init_ops();
+ }
}
+ return ops->odb_init(mem_ctx, ntvfs_ctx);
+}
+
+/*
+ get a lock on a entry in the odb. This call returns a lock handle,
+ which the caller should unlock using talloc_free().
+*/
+_PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx,
+ struct odb_context *odb, DATA_BLOB *file_key)
+{
+ return ops->odb_lock(mem_ctx, odb, file_key);
+}
- path = lock_path(odb, "openfiles.tdb");
- odb->w = tdb_wrap_open(odb, path, 0,
- TDB_DEFAULT|TDB_CLEAR_IF_FIRST,
- O_RDWR|O_CREAT, 0600);
- talloc_free(path);
- if (odb->w == NULL) {
- talloc_free(odb);
- return NULL;
- }
- odb->server = server;
- odb->tid = tid;
- odb->messaging_ctx = messaging_ctx;
+/*
+ register an open file in the open files database. This implements the share_access
+ rules
- return odb;
+ Note that the path is only used by the delete on close logic, not
+ for comparing with other filenames
+*/
+_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle,
+ uint32_t stream_id, uint32_t share_access,
+ uint32_t access_mask, bool delete_on_close,
+ const char *path,
+ uint32_t oplock_level, uint32_t *oplock_granted)
+{
+ return ops->odb_open_file(lck, file_handle, stream_id, share_access,
+ access_mask, delete_on_close, path, oplock_level,
+ oplock_granted);
}
+
/*
- destroy a lock on the database
+ register a pending open file in the open files database
*/
-static int odb_lock_destructor(void *ptr)
+_PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private)
{
- struct odb_lock *lck = ptr;
- tdb_chainunlock(lck->odb->w->tdb, lck->key);
- return 0;
+ return ops->odb_open_file_pending(lck, private);
}
+
/*
- get a lock on a entry in the odb. This call returns a lock handle,
- which the caller should unlock using talloc_free().
+ remove a opendb entry
*/
-struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx,
- struct odb_context *odb, DATA_BLOB *file_key)
+_PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle)
{
- struct odb_lock *lck;
+ return ops->odb_close_file(lck, file_handle);
+}
- lck = talloc_p(mem_ctx, struct odb_lock);
- if (lck == NULL) {
- return NULL;
- }
- lck->odb = odb;
- lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length);
- lck->key.dsize = file_key->length;
- if (lck->key.dptr == NULL) {
- talloc_free(lck);
- return NULL;
- }
+/*
+ remove a pending opendb entry
+*/
+_PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private)
+{
+ return ops->odb_remove_pending(lck, private);
+}
- if (tdb_chainlock(odb->w->tdb, lck->key) != 0) {
- talloc_free(lck);
- return NULL;
- }
- talloc_set_destructor(lck, odb_lock_destructor);
-
- return lck;
+/*
+ rename the path in a open file
+*/
+_PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path)
+{
+ return ops->odb_rename(lck, path);
+}
+
+/*
+ update delete on close flag on an open file
+*/
+_PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close)
+{
+ return ops->odb_set_delete_on_close(lck, del_on_close);
+}
+
+/*
+ return the current value of the delete_on_close bit, and how many
+ people still have the file open
+*/
+_PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb,
+ DATA_BLOB *key, bool *del_on_close,
+ int *open_count, char **path)
+{
+ return ops->odb_get_delete_on_close(odb, key, del_on_close, open_count, path);
+}
+
+
+/*
+ determine if a file can be opened with the given share_access,
+ create_options and access_mask
+*/
+_PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck,
+ uint32_t share_access, uint32_t create_options,
+ uint32_t access_mask)
+{
+ return ops->odb_can_open(lck, share_access, create_options, access_mask);
}