diff options
-rw-r--r-- | source4/ntvfs/common/opendb.c | 145 | ||||
-rw-r--r-- | source4/ntvfs/posix/config.mk | 1 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.c | 8 | ||||
-rw-r--r-- | source4/ntvfs/posix/vfs_posix.h | 1 |
4 files changed, 155 insertions, 0 deletions
diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c new file mode 100644 index 0000000000..cf0177e333 --- /dev/null +++ b/source4/ntvfs/common/opendb.c @@ -0,0 +1,145 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2004 + + 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. +*/ + +/* + this is the open files database. It implements shared storage of + what files are open between server instances, and implements the rules + of shared access to files. + + The caller needs to provide a file_key, which specifies what file + they are talking about. This needs to be a unique key across all + filesystems, and is usually implemented in terms of a device/inode + pair. + + Before any operations can be performed the caller needs to establish + a lock on the record associated with file_key. That is done by + calling odb_lock(). The caller releases this lock by calling + talloc_free() on the returned handle. + + All other operations on a record are done by passing the odb_lock() + handle back to this module. The handle contains internal + intformation about what file_key is being operated on. +*/ + +#include "includes.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; +}; + + +/* + an odb lock handle. You must obtain one of these using odb_lock() before doing + any other operations. +*/ +struct odb_lock { + struct odb_context *odb; + TDB_DATA key; +}; + +/* + 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) +{ + char *path; + struct odb_context *odb; + + odb = talloc_p(mem_ctx, struct odb_context); + if (odb == NULL) { + return NULL; + } + + 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; + + return odb; +} + +/* + destroy a lock on the database +*/ +static int odb_lock_destructor(void *ptr) +{ + struct odb_lock *lck = ptr; + tdb_chainunlock(lck->odb->w->tdb, lck->key); + return 0; +} + +/* + get a lock on a entry in the odb. This call returns a lock handle, + which the caller should unlock using talloc_free(). +*/ +struct odb_lock *odb_lock(struct odb_context *odb, DATA_BLOB *file_key) +{ + struct odb_lock *lck; + + lck = talloc_p(odb, 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; + } + + if (tdb_chainlock(odb->w->tdb, lck->key) != 0) { + talloc_free(lck); + return NULL; + } + + talloc_set_destructor(lck, odb_lock_destructor); + + return lck; +} diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index b6ba073a99..0d6f295097 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -22,6 +22,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ + ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 8aa028919c..383dbf7a16 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -94,6 +94,14 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + pvfs->odb_context = odb_init(pvfs, + pvfs->tcon->smb_conn->connection->server_id, + pvfs->tcon->service, + pvfs->tcon->smb_conn->connection->messaging_ctx); + if (pvfs->odb_context == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + /* allocate the fnum id -> ptr tree */ pvfs->idtree_fnum = idr_init(pvfs); if (pvfs->idtree_fnum == NULL) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a0aacf3786..5b6685b753 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -37,6 +37,7 @@ struct pvfs_state { struct pvfs_mangle_context *mangle_ctx; struct brl_context *brl_context; + struct odb_context *odb_context; /* an id tree mapping open search ID to a pvfs_search_state structure */ void *idtree_search; |