r3129: typo
[bbaumbach/samba-autobuild/.git] / source4 / ntvfs / common / opendb.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Andrew Tridgell 2004
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /*
22   this is the open files database. It implements shared storage of
23   what files are open between server instances, and implements the rules
24   of shared access to files.
25
26   The caller needs to provide a file_key, which specifies what file
27   they are talking about. This needs to be a unique key across all
28   filesystems, and is usually implemented in terms of a device/inode
29   pair.
30
31   Before any operations can be performed the caller needs to establish
32   a lock on the record associated with file_key. That is done by
33   calling odb_lock(). The caller releases this lock by calling
34   talloc_free() on the returned handle.
35
36   All other operations on a record are done by passing the odb_lock()
37   handle back to this module. The handle contains internal
38   information about what file_key is being operated on.
39 */
40
41 #include "includes.h"
42
43 struct odb_context {
44         struct tdb_wrap *w;
45         servid_t server;
46         uint16_t tid;
47         void *messaging_ctx;
48 };
49
50 /* 
51    the database is indexed by a file_key, and contains entries of the
52    following form
53 */
54 struct odb_entry {
55         servid_t server;
56         uint16_t tid;
57         uint16_t fnum;
58         uint32_t share_access;
59         uint32_t desired_access;
60         uint32_t create_options;
61 };
62
63
64 /*
65   an odb lock handle. You must obtain one of these using odb_lock() before doing
66   any other operations. 
67 */
68 struct odb_lock {
69         struct odb_context *odb;
70         TDB_DATA key;
71 };
72
73 /*
74   Open up the openfiles.tdb database. Close it down using
75   talloc_free(). We need the messaging_ctx to allow for pending open
76   notifications.
77 */
78 struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, 
79                              void *messaging_ctx)
80 {
81         char *path;
82         struct odb_context *odb;
83
84         odb = talloc_p(mem_ctx, struct odb_context);
85         if (odb == NULL) {
86                 return NULL;
87         }
88
89         path = lock_path(odb, "openfiles.tdb");
90         odb->w = tdb_wrap_open(odb, path, 0,  
91                                TDB_DEFAULT|TDB_CLEAR_IF_FIRST,
92                                O_RDWR|O_CREAT, 0600);
93         talloc_free(path);
94         if (odb->w == NULL) {
95                 talloc_free(odb);
96                 return NULL;
97         }
98
99         odb->server = server;
100         odb->tid = tid;
101         odb->messaging_ctx = messaging_ctx;
102
103         return odb;
104 }
105
106 /*
107   destroy a lock on the database
108 */
109 static int odb_lock_destructor(void *ptr)
110 {
111         struct odb_lock *lck = ptr;
112         tdb_chainunlock(lck->odb->w->tdb, lck->key);
113         return 0;
114 }
115
116 /*
117   get a lock on a entry in the odb. This call returns a lock handle,
118   which the caller should unlock using talloc_free().
119 */
120 struct odb_lock *odb_lock(struct odb_context *odb, DATA_BLOB *file_key)
121 {
122         struct odb_lock *lck;
123
124         lck = talloc_p(odb, struct odb_lock);
125         if (lck == NULL) {
126                 return NULL;
127         }
128
129         lck->odb = odb;
130         lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length);
131         lck->key.dsize = file_key->length;
132         if (lck->key.dptr == NULL) {
133                 talloc_free(lck);
134                 return NULL;
135         }
136
137         if (tdb_chainlock(odb->w->tdb, lck->key) != 0) {
138                 talloc_free(lck);
139                 return NULL;
140         }
141
142         talloc_set_destructor(lck, odb_lock_destructor);
143         
144         return lck;
145 }