1/*
2 * fs_loader.h:  Declarations for the FS loader library
3 *
4 * ====================================================================
5 *    Licensed to the Apache Software Foundation (ASF) under one
6 *    or more contributor license agreements.  See the NOTICE file
7 *    distributed with this work for additional information
8 *    regarding copyright ownership.  The ASF licenses this file
9 *    to you under the Apache License, Version 2.0 (the
10 *    "License"); you may not use this file except in compliance
11 *    with the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 *    Unless required by applicable law or agreed to in writing,
16 *    software distributed under the License is distributed on an
17 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 *    KIND, either express or implied.  See the License for the
19 *    specific language governing permissions and limitations
20 *    under the License.
21 * ====================================================================
22 */
23
24
25#ifndef LIBSVN_FS_FS_H
26#define LIBSVN_FS_FS_H
27
28#include "svn_types.h"
29#include "svn_fs.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif /* __cplusplus */
34
35
36/* The FS loader library implements the a front end to "filesystem
37   abstract providers" (FSAPs), which implement the svn_fs API.
38
39   The loader library divides up the FS API into several categories:
40
41     - Top-level functions, which operate on paths to an FS
42     - Functions which operate on an FS object
43     - Functions which operate on a transaction object
44     - Functions which operate on a root object
45     - Functions which operate on a history object
46     - Functions which operate on a noderev-ID object
47
48   Some generic fields of the FS, transaction, root, and history
49   objects are defined by the loader library; the rest are stored in
50   the "fsap_data" field which is defined by the FSAP.  Likewise, some
51   of the very simple svn_fs API functions (such as svn_fs_root_fs)
52   are defined by the loader library, while the rest are implemented
53   through vtable calls defined by the FSAP.
54
55   If you are considering writing a new database-backed filesystem
56   implementation, it may be appropriate to add a second, lower-level
57   abstraction to the libsvn_fs_base library which currently
58   implements the BDB filesystem type.  Consult the dev list for
59   details on the "FSP-level" abstraction concept.
60*/
61
62
63
64/*** Top-level library vtable type ***/
65
66typedef struct fs_library_vtable_t
67{
68  /* This field should always remain first in the vtable.
69     Apart from that, it can be changed however you like, since exact
70     version equality is required between loader and module.  This policy
71     was weaker during 1.1.x, but only in ways which do not conflict with
72     this statement, now that the minor version has increased. */
73  const svn_version_t *(*get_version)(void);
74
75  /* The open_fs/create/open_fs_for_recovery/upgrade_fs functions are
76     serialized so that they may use the common_pool parameter to
77     allocate fs-global objects such as the bdb env cache. */
78  svn_error_t *(*create)(svn_fs_t *fs, const char *path, apr_pool_t *pool,
79                         apr_pool_t *common_pool);
80  svn_error_t *(*open_fs)(svn_fs_t *fs, const char *path, apr_pool_t *pool,
81                          apr_pool_t *common_pool);
82  /* open_for_recovery() is like open(), but used to fill in an fs pointer
83     that will be passed to recover().  We assume that the open() method
84     might not be immediately appropriate for recovery. */
85  svn_error_t *(*open_fs_for_recovery)(svn_fs_t *fs, const char *path,
86                                       apr_pool_t *pool,
87                                       apr_pool_t *common_pool);
88  svn_error_t *(*upgrade_fs)(svn_fs_t *fs, const char *path, apr_pool_t *pool,
89                             apr_pool_t *common_pool);
90  svn_error_t *(*verify_fs)(svn_fs_t *fs, const char *path,
91                            svn_revnum_t start,
92                            svn_revnum_t end,
93                            svn_fs_progress_notify_func_t notify_func,
94                            void *notify_baton,
95                            svn_cancel_func_t cancel_func,
96                            void *cancel_baton,
97                            apr_pool_t *pool,
98                            apr_pool_t *common_pool);
99  svn_error_t *(*delete_fs)(const char *path, apr_pool_t *pool);
100  svn_error_t *(*hotcopy)(svn_fs_t *src_fs, svn_fs_t *dst_fs,
101                          const char *src_path, const char *dst_path,
102                          svn_boolean_t clean, svn_boolean_t incremental,
103                          svn_cancel_func_t cancel_func, void *cancel_baton,
104                          apr_pool_t *pool);
105  const char *(*get_description)(void);
106  svn_error_t *(*recover)(svn_fs_t *fs,
107                          svn_cancel_func_t cancel_func, void *cancel_baton,
108                          apr_pool_t *pool);
109  svn_error_t *(*pack_fs)(svn_fs_t *fs, const char *path,
110                          svn_fs_pack_notify_t notify_func, void *notify_baton,
111                          svn_cancel_func_t cancel_func, void *cancel_baton,
112                          apr_pool_t *pool, apr_pool_t *common_pool);
113
114  /* Provider-specific functions should go here, even if they could go
115     in an object vtable, so that they are all kept together. */
116  svn_error_t *(*bdb_logfiles)(apr_array_header_t **logfiles,
117                               const char *path, svn_boolean_t only_unused,
118                               apr_pool_t *pool);
119
120  /* This is to let the base provider implement the deprecated
121     svn_fs_parse_id, which we've decided doesn't belong in the FS
122     API.  If we change our minds and decide to add a real
123     svn_fs_parse_id variant which takes an FS object, it should go
124     into the FS vtable. */
125  svn_fs_id_t *(*parse_id)(const char *data, apr_size_t len,
126                           apr_pool_t *pool);
127  /* Allow an FSAP to call svn_fs_open(), which is in a higher-level library
128     (libsvn_fs-1.so) and cannot easily be moved to libsvn_fs_util. */
129  svn_error_t *(*set_svn_fs_open)(svn_fs_t *fs,
130                                  svn_error_t *(*svn_fs_open_)(svn_fs_t **,
131                                                               const char *,
132                                                               apr_hash_t *,
133                                                               apr_pool_t *));
134
135} fs_library_vtable_t;
136
137/* This is the type of symbol an FS module defines to fetch the
138   library vtable. The LOADER_VERSION parameter must remain first in
139   the list, and the function must use the C calling convention on all
140   platforms, so that the init functions can safely read the version
141   parameter.  The COMMON_POOL parameter must be a pool with a greater
142   lifetime than the fs module so that fs global state can be kept
143   in it and cleaned up on termination before the fs module is unloaded.
144   Calls to these functions are globally serialized so that they have
145   exclusive access to the COMMON_POOL parameter.
146
147   ### need to force this to be __cdecl on Windows... how?? */
148typedef svn_error_t *(*fs_init_func_t)(const svn_version_t *loader_version,
149                                       fs_library_vtable_t **vtable,
150                                       apr_pool_t* common_pool);
151
152/* Here are the declarations for the FS module init functions.  If we
153   are using DSO loading, they won't actually be linked into
154   libsvn_fs.  Note that these private functions have a common_pool
155   parameter that may be used for fs module scoped variables such as
156   the bdb cache.  This will be the same common_pool that is passed
157   to the create and open functions and these init functions (as well
158   as the open and create functions) are globally serialized so that
159   they have exclusive access to the common_pool. */
160svn_error_t *svn_fs_base__init(const svn_version_t *loader_version,
161                               fs_library_vtable_t **vtable,
162                               apr_pool_t* common_pool);
163svn_error_t *svn_fs_fs__init(const svn_version_t *loader_version,
164                             fs_library_vtable_t **vtable,
165                             apr_pool_t* common_pool);
166
167
168
169/*** vtable types for the abstract FS objects ***/
170
171typedef struct fs_vtable_t
172{
173  svn_error_t *(*youngest_rev)(svn_revnum_t *youngest_p, svn_fs_t *fs,
174                               apr_pool_t *pool);
175  svn_error_t *(*revision_prop)(svn_string_t **value_p, svn_fs_t *fs,
176                                svn_revnum_t rev, const char *propname,
177                                apr_pool_t *pool);
178  svn_error_t *(*revision_proplist)(apr_hash_t **table_p, svn_fs_t *fs,
179                                    svn_revnum_t rev, apr_pool_t *pool);
180  svn_error_t *(*change_rev_prop)(svn_fs_t *fs, svn_revnum_t rev,
181                                  const char *name,
182                                  const svn_string_t *const *old_value_p,
183                                  const svn_string_t *value,
184                                  apr_pool_t *pool);
185  /* There is no get_uuid(); see svn_fs_t.uuid docstring. */
186  svn_error_t *(*set_uuid)(svn_fs_t *fs, const char *uuid, apr_pool_t *pool);
187  svn_error_t *(*revision_root)(svn_fs_root_t **root_p, svn_fs_t *fs,
188                                svn_revnum_t rev, apr_pool_t *pool);
189  svn_error_t *(*begin_txn)(svn_fs_txn_t **txn_p, svn_fs_t *fs,
190                            svn_revnum_t rev, apr_uint32_t flags,
191                            apr_pool_t *pool);
192  svn_error_t *(*open_txn)(svn_fs_txn_t **txn, svn_fs_t *fs,
193                           const char *name, apr_pool_t *pool);
194  svn_error_t *(*purge_txn)(svn_fs_t *fs, const char *txn_id,
195                            apr_pool_t *pool);
196  svn_error_t *(*list_transactions)(apr_array_header_t **names_p,
197                                    svn_fs_t *fs, apr_pool_t *pool);
198  svn_error_t *(*deltify)(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool);
199  svn_error_t *(*lock)(svn_lock_t **lock, svn_fs_t *fs,
200                       const char *path, const char *token,
201                       const char *comment, svn_boolean_t is_dav_comment,
202                       apr_time_t expiration_date,
203                       svn_revnum_t current_rev, svn_boolean_t steal_lock,
204                       apr_pool_t *pool);
205  svn_error_t *(*generate_lock_token)(const char **token, svn_fs_t *fs,
206                                      apr_pool_t *pool);
207  svn_error_t *(*unlock)(svn_fs_t *fs, const char *path, const char *token,
208                         svn_boolean_t break_lock, apr_pool_t *pool);
209  svn_error_t *(*get_lock)(svn_lock_t **lock, svn_fs_t *fs,
210                           const char *path, apr_pool_t *pool);
211  svn_error_t *(*get_locks)(svn_fs_t *fs, const char *path, svn_depth_t depth,
212                            svn_fs_get_locks_callback_t get_locks_func,
213                            void *get_locks_baton,
214                            apr_pool_t *pool);
215  svn_error_t *(*verify_root)(svn_fs_root_t *root,
216                              apr_pool_t *pool);
217  svn_error_t *(*freeze)(svn_fs_t *fs,
218                         svn_fs_freeze_func_t freeze_func,
219                         void *freeze_baton, apr_pool_t *pool);
220  svn_error_t *(*bdb_set_errcall)(svn_fs_t *fs,
221                                  void (*handler)(const char *errpfx,
222                                                  char *msg));
223} fs_vtable_t;
224
225
226typedef struct txn_vtable_t
227{
228  svn_error_t *(*commit)(const char **conflict_p, svn_revnum_t *new_rev,
229                         svn_fs_txn_t *txn, apr_pool_t *pool);
230  svn_error_t *(*abort)(svn_fs_txn_t *txn, apr_pool_t *pool);
231  svn_error_t *(*get_prop)(svn_string_t **value_p, svn_fs_txn_t *txn,
232                           const char *propname, apr_pool_t *pool);
233  svn_error_t *(*get_proplist)(apr_hash_t **table_p, svn_fs_txn_t *txn,
234                               apr_pool_t *pool);
235  svn_error_t *(*change_prop)(svn_fs_txn_t *txn, const char *name,
236                              const svn_string_t *value, apr_pool_t *pool);
237  svn_error_t *(*root)(svn_fs_root_t **root_p, svn_fs_txn_t *txn,
238                       apr_pool_t *pool);
239  svn_error_t *(*change_props)(svn_fs_txn_t *txn, const apr_array_header_t *props,
240                               apr_pool_t *pool);
241} txn_vtable_t;
242
243
244/* Some of these operations accept multiple root arguments.  Since the
245   roots may not all have the same vtable, we need a rule to determine
246   which root's vtable is used.  The rule is: if one of the roots is
247   named "target", we use that root's vtable; otherwise, we use the
248   first root argument's vtable.
249   These callbacks correspond to svn_fs_* functions in include/svn_fs.h,
250   see there for details.
251   Note: delete_node() corresponds to svn_fs_delete(). */
252typedef struct root_vtable_t
253{
254  /* Determining what has changed in a root */
255  svn_error_t *(*paths_changed)(apr_hash_t **changed_paths_p,
256                                svn_fs_root_t *root,
257                                apr_pool_t *pool);
258
259  /* Generic node operations */
260  svn_error_t *(*check_path)(svn_node_kind_t *kind_p, svn_fs_root_t *root,
261                             const char *path, apr_pool_t *pool);
262  svn_error_t *(*node_history)(svn_fs_history_t **history_p,
263                               svn_fs_root_t *root, const char *path,
264                               apr_pool_t *pool);
265  svn_error_t *(*node_id)(const svn_fs_id_t **id_p, svn_fs_root_t *root,
266                          const char *path, apr_pool_t *pool);
267  svn_error_t *(*node_created_rev)(svn_revnum_t *revision,
268                                   svn_fs_root_t *root, const char *path,
269                                   apr_pool_t *pool);
270  svn_error_t *(*node_origin_rev)(svn_revnum_t *revision,
271                                  svn_fs_root_t *root, const char *path,
272                                  apr_pool_t *pool);
273  svn_error_t *(*node_created_path)(const char **created_path,
274                                    svn_fs_root_t *root, const char *path,
275                                    apr_pool_t *pool);
276  svn_error_t *(*delete_node)(svn_fs_root_t *root, const char *path,
277                              apr_pool_t *pool);
278  svn_error_t *(*copied_from)(svn_revnum_t *rev_p, const char **path_p,
279                              svn_fs_root_t *root, const char *path,
280                              apr_pool_t *pool);
281  svn_error_t *(*closest_copy)(svn_fs_root_t **root_p, const char **path_p,
282                               svn_fs_root_t *root, const char *path,
283                               apr_pool_t *pool);
284
285  /* Property operations */
286  svn_error_t *(*node_prop)(svn_string_t **value_p, svn_fs_root_t *root,
287                            const char *path, const char *propname,
288                            apr_pool_t *pool);
289  svn_error_t *(*node_proplist)(apr_hash_t **table_p, svn_fs_root_t *root,
290                                const char *path, apr_pool_t *pool);
291  svn_error_t *(*change_node_prop)(svn_fs_root_t *root, const char *path,
292                                   const char *name,
293                                   const svn_string_t *value,
294                                   apr_pool_t *pool);
295  svn_error_t *(*props_changed)(int *changed_p, svn_fs_root_t *root1,
296                                const char *path1, svn_fs_root_t *root2,
297                                const char *path2, apr_pool_t *pool);
298
299  /* Directories */
300  svn_error_t *(*dir_entries)(apr_hash_t **entries_p, svn_fs_root_t *root,
301                              const char *path, apr_pool_t *pool);
302  svn_error_t *(*make_dir)(svn_fs_root_t *root, const char *path,
303                           apr_pool_t *pool);
304  svn_error_t *(*copy)(svn_fs_root_t *from_root, const char *from_path,
305                       svn_fs_root_t *to_root, const char *to_path,
306                       apr_pool_t *pool);
307  svn_error_t *(*revision_link)(svn_fs_root_t *from_root,
308                                svn_fs_root_t *to_root,
309                                const char *path,
310                                apr_pool_t *pool);
311
312  /* Files */
313  svn_error_t *(*file_length)(svn_filesize_t *length_p, svn_fs_root_t *root,
314                              const char *path, apr_pool_t *pool);
315  svn_error_t *(*file_checksum)(svn_checksum_t **checksum,
316                                svn_checksum_kind_t kind, svn_fs_root_t *root,
317                                const char *path, apr_pool_t *pool);
318  svn_error_t *(*file_contents)(svn_stream_t **contents,
319                                svn_fs_root_t *root, const char *path,
320                                apr_pool_t *pool);
321  svn_error_t *(*try_process_file_contents)(svn_boolean_t *success,
322                                            svn_fs_root_t *target_root,
323                                            const char *target_path,
324                                            svn_fs_process_contents_func_t processor,
325                                            void* baton,
326                                            apr_pool_t *pool);
327  svn_error_t *(*make_file)(svn_fs_root_t *root, const char *path,
328                            apr_pool_t *pool);
329  svn_error_t *(*apply_textdelta)(svn_txdelta_window_handler_t *contents_p,
330                                  void **contents_baton_p,
331                                  svn_fs_root_t *root, const char *path,
332                                  svn_checksum_t *base_checksum,
333                                  svn_checksum_t *result_checksum,
334                                  apr_pool_t *pool);
335  svn_error_t *(*apply_text)(svn_stream_t **contents_p, svn_fs_root_t *root,
336                             const char *path, svn_checksum_t *result_checksum,
337                             apr_pool_t *pool);
338  svn_error_t *(*contents_changed)(int *changed_p, svn_fs_root_t *root1,
339                                   const char *path1, svn_fs_root_t *root2,
340                                   const char *path2, apr_pool_t *pool);
341  svn_error_t *(*get_file_delta_stream)(svn_txdelta_stream_t **stream_p,
342                                        svn_fs_root_t *source_root,
343                                        const char *source_path,
344                                        svn_fs_root_t *target_root,
345                                        const char *target_path,
346                                        apr_pool_t *pool);
347
348  /* Merging. */
349  svn_error_t *(*merge)(const char **conflict_p,
350                        svn_fs_root_t *source_root,
351                        const char *source_path,
352                        svn_fs_root_t *target_root,
353                        const char *target_path,
354                        svn_fs_root_t *ancestor_root,
355                        const char *ancestor_path,
356                        apr_pool_t *pool);
357  /* Mergeinfo. */
358  svn_error_t *(*get_mergeinfo)(svn_mergeinfo_catalog_t *catalog,
359                                svn_fs_root_t *root,
360                                const apr_array_header_t *paths,
361                                svn_mergeinfo_inheritance_t inherit,
362                                svn_boolean_t include_descendants,
363                                svn_boolean_t adjust_inherited_mergeinfo,
364                                apr_pool_t *result_pool,
365                                apr_pool_t *scratch_pool);
366} root_vtable_t;
367
368
369typedef struct history_vtable_t
370{
371  svn_error_t *(*prev)(svn_fs_history_t **prev_history_p,
372                       svn_fs_history_t *history, svn_boolean_t cross_copies,
373                       apr_pool_t *pool);
374  svn_error_t *(*location)(const char **path, svn_revnum_t *revision,
375                           svn_fs_history_t *history, apr_pool_t *pool);
376} history_vtable_t;
377
378
379typedef struct id_vtable_t
380{
381  svn_string_t *(*unparse)(const svn_fs_id_t *id, apr_pool_t *pool);
382  int (*compare)(const svn_fs_id_t *a, const svn_fs_id_t *b);
383} id_vtable_t;
384
385
386
387/*** Definitions of the abstract FS object types ***/
388
389/* These are transaction properties that correspond to the bitfields
390   in the 'flags' argument to svn_fs_lock().  */
391#define SVN_FS__PROP_TXN_CHECK_LOCKS           SVN_PROP_PREFIX "check-locks"
392#define SVN_FS__PROP_TXN_CHECK_OOD             SVN_PROP_PREFIX "check-ood"
393
394struct svn_fs_t
395{
396  /* The pool in which this fs object is allocated */
397  apr_pool_t *pool;
398
399  /* The path to the repository's top-level directory */
400  char *path;
401
402  /* A callback for printing warning messages */
403  svn_fs_warning_callback_t warning;
404  void *warning_baton;
405
406  /* The filesystem configuration */
407  apr_hash_t *config;
408
409  /* An access context indicating who's using the fs */
410  svn_fs_access_t *access_ctx;
411
412  /* FSAP-specific vtable and private data */
413  fs_vtable_t *vtable;
414  void *fsap_data;
415
416  /* UUID, stored by open(), create(), and set_uuid(). */
417  const char *uuid;
418};
419
420
421struct svn_fs_txn_t
422{
423  /* The filesystem to which this transaction belongs */
424  svn_fs_t *fs;
425
426  /* The revision on which this transaction is based, or
427     SVN_INVALID_REVISION if the transaction is not based on a
428     revision at all */
429  svn_revnum_t base_rev;
430
431  /* The ID of this transaction */
432  const char *id;
433
434  /* FSAP-specific vtable and private data */
435  txn_vtable_t *vtable;
436  void *fsap_data;
437};
438
439
440struct svn_fs_root_t
441{
442  /* A pool managing this root (and only this root!) */
443  apr_pool_t *pool;
444
445  /* The filesystem to which this root belongs */
446  svn_fs_t *fs;
447
448  /* The kind of root this is */
449  svn_boolean_t is_txn_root;
450
451  /* For transaction roots, the name of the transaction  */
452  const char *txn;
453
454  /* For transaction roots, flags describing the txn's behavior. */
455  apr_uint32_t txn_flags;
456
457  /* For revision roots, the number of the revision; for transaction
458     roots, the number of the revision on which the transaction is
459     based. */
460  svn_revnum_t rev;
461
462  /* FSAP-specific vtable and private data */
463  root_vtable_t *vtable;
464  void *fsap_data;
465};
466
467
468struct svn_fs_history_t
469{
470  /* FSAP-specific vtable and private data */
471  history_vtable_t *vtable;
472  void *fsap_data;
473};
474
475
476struct svn_fs_id_t
477{
478  /* FSAP-specific vtable and private data */
479  id_vtable_t *vtable;
480  void *fsap_data;
481};
482
483
484struct svn_fs_access_t
485{
486  /* An authenticated username using the fs */
487  const char *username;
488
489  /* A collection of lock-tokens supplied by the fs caller.
490     Hash maps (const char *) UUID --> (void *) 1
491     fs functions should really only be interested whether a UUID
492     exists as a hash key at all;  the value is irrelevant. */
493  apr_hash_t *lock_tokens;
494};
495
496
497
498#ifdef __cplusplus
499}
500#endif /* __cplusplus */
501
502#endif
503