1289177Speter/* util.h --- utility functions for FSFS repo access
2289177Speter *
3289177Speter * ====================================================================
4289177Speter *    Licensed to the Apache Software Foundation (ASF) under one
5289177Speter *    or more contributor license agreements.  See the NOTICE file
6289177Speter *    distributed with this work for additional information
7289177Speter *    regarding copyright ownership.  The ASF licenses this file
8289177Speter *    to you under the Apache License, Version 2.0 (the
9289177Speter *    "License"); you may not use this file except in compliance
10289177Speter *    with the License.  You may obtain a copy of the License at
11289177Speter *
12289177Speter *      http://www.apache.org/licenses/LICENSE-2.0
13289177Speter *
14289177Speter *    Unless required by applicable law or agreed to in writing,
15289177Speter *    software distributed under the License is distributed on an
16289177Speter *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17289177Speter *    KIND, either express or implied.  See the License for the
18289177Speter *    specific language governing permissions and limitations
19289177Speter *    under the License.
20289177Speter * ====================================================================
21289177Speter */
22289177Speter
23289177Speter#ifndef SVN_LIBSVN_FS__UTIL_H
24289177Speter#define SVN_LIBSVN_FS__UTIL_H
25289177Speter
26289177Speter#include "svn_fs.h"
27289177Speter#include "id.h"
28289177Speter
29289177Speter/* Functions for dealing with recoverable errors on mutable files
30289177Speter *
31289177Speter * Revprops, current, and txn-current files are mutable; that is, they
32289177Speter * change as part of normal fsfs operation, in constrat to revs files, or
33289177Speter * the format file, which are written once at create (or upgrade) time.
34289177Speter * When more than one host writes to the same repository, we will
35289177Speter * sometimes see these recoverable errors when accesssing these files.
36289177Speter *
37289177Speter * These errors all relate to NFS, and thus we only use this retry code if
38289177Speter * ESTALE is defined.
39289177Speter *
40289177Speter ** ESTALE
41289177Speter *
42289177Speter * In NFS v3 and under, the server doesn't track opened files.  If you
43289177Speter * unlink(2) or rename(2) a file held open by another process *on the
44289177Speter * same host*, that host's kernel typically renames the file to
45289177Speter * .nfsXXXX and automatically deletes that when it's no longer open,
46289177Speter * but this behavior is not required.
47289177Speter *
48289177Speter * For obvious reasons, this does not work *across hosts*.  No one
49289177Speter * knows about the opened file; not the server, and not the deleting
50289177Speter * client.  So the file vanishes, and the reader gets stale NFS file
51289177Speter * handle.
52289177Speter *
53289177Speter ** EIO, ENOENT
54289177Speter *
55289177Speter * Some client implementations (at least the 2.6.18.5 kernel that ships
56289177Speter * with Ubuntu Dapper) sometimes give spurious ENOENT (only on open) or
57289177Speter * even EIO errors when trying to read these files that have been renamed
58289177Speter * over on some other host.
59289177Speter *
60289177Speter ** Solution
61289177Speter *
62289177Speter * Try open and read of such files in try_stringbuf_from_file().  Call
63289177Speter * this function within a loop of SVN_FS_FS__RECOVERABLE_RETRY_COUNT
64289177Speter * iterations (though, realistically, the second try will succeed).
65289177Speter */
66289177Speter
67289177Speter#define SVN_FS_FS__RECOVERABLE_RETRY_COUNT 10
68289177Speter
69289177Speter/* Return TRUE is REV is packed in FS, FALSE otherwise. */
70289177Spetersvn_boolean_t
71289177Spetersvn_fs_fs__is_packed_rev(svn_fs_t *fs,
72289177Speter                         svn_revnum_t rev);
73289177Speter
74289177Speter/* Return TRUE is REV's props have been packed in FS, FALSE otherwise. */
75289177Spetersvn_boolean_t
76289177Spetersvn_fs_fs__is_packed_revprop(svn_fs_t *fs,
77289177Speter                             svn_revnum_t rev);
78289177Speter
79289177Speter/* Return the first revision in the pack / rev file containing REVISION in
80289177Speter * filesystem FS.  For non-packed revs, this will simply be REVISION. */
81289177Spetersvn_revnum_t
82289177Spetersvn_fs_fs__packed_base_rev(svn_fs_t *fs,
83289177Speter                           svn_revnum_t revision);
84289177Speter
85289177Speter/* Return the full path of the rev shard directory that will contain
86289177Speter * revision REV in FS.  Allocate the result in POOL.
87289177Speter */
88289177Speterconst char *
89289177Spetersvn_fs_fs__path_rev_shard(svn_fs_t *fs,
90289177Speter                          svn_revnum_t rev,
91289177Speter                          apr_pool_t *pool);
92289177Speter
93289177Speter/* Return the full path of the non-packed rev file containing revision REV
94289177Speter * in FS.  Allocate the result in POOL.
95289177Speter */
96289177Speterconst char *
97289177Spetersvn_fs_fs__path_rev(svn_fs_t *fs,
98289177Speter                    svn_revnum_t rev,
99289177Speter                    apr_pool_t *pool);
100289177Speter
101289177Speter/* Return the path of the pack-related file that for revision REV in FS.
102289177Speter * KIND specifies the file name base, e.g. "manifest" or "pack".
103289177Speter * The result will be allocated in POOL.
104289177Speter */
105289177Speterconst char *
106289177Spetersvn_fs_fs__path_rev_packed(svn_fs_t *fs,
107289177Speter                           svn_revnum_t rev,
108289177Speter                           const char *kind,
109289177Speter                           apr_pool_t *pool);
110289177Speter
111289177Speter/* Return the full path of the "txn-current" file in FS.
112289177Speter * The result will be allocated in POOL.
113289177Speter */
114289177Speterconst char *
115289177Spetersvn_fs_fs__path_txn_current(svn_fs_t *fs,
116289177Speter                            apr_pool_t *pool);
117289177Speter
118289177Speter/* Return the full path of the "txn-current-lock" file in FS.
119289177Speter * The result will be allocated in POOL.
120289177Speter */
121289177Speterconst char *
122289177Spetersvn_fs_fs__path_txn_current_lock(svn_fs_t *fs,
123289177Speter                                 apr_pool_t *pool);
124289177Speter
125289177Speter/* Return the full path of the global write lock file in FS.
126289177Speter * The result will be allocated in POOL.
127289177Speter */
128289177Speterconst char *
129289177Spetersvn_fs_fs__path_lock(svn_fs_t *fs,
130289177Speter                     apr_pool_t *pool);
131289177Speter
132289177Speter/* Return the full path of the pack operation lock file in FS.
133289177Speter * The result will be allocated in POOL.
134289177Speter */
135289177Speterconst char *
136289177Spetersvn_fs_fs__path_pack_lock(svn_fs_t *fs,
137289177Speter                          apr_pool_t *pool);
138289177Speter
139289177Speter/* Return the full path of the revprop generation file in FS.
140289177Speter * Allocate the result in POOL.
141289177Speter */
142289177Speterconst char *
143289177Spetersvn_fs_fs__path_revprop_generation(svn_fs_t *fs,
144289177Speter                                   apr_pool_t *pool);
145289177Speter
146289177Speter/* Return the full path of the revision properties pack shard directory
147289177Speter * that will contain the packed properties of revision REV in FS.
148289177Speter * Allocate the result in POOL.
149289177Speter */
150289177Speterconst char *
151289177Spetersvn_fs_fs__path_revprops_pack_shard(svn_fs_t *fs,
152289177Speter                                    svn_revnum_t rev,
153289177Speter                                    apr_pool_t *pool);
154289177Speter
155289177Speter/* Set *PATH to the path of REV in FS, whether in a pack file or not.
156289177Speter   Allocate *PATH in POOL.
157289177Speter
158289177Speter   Note: If the caller does not have the write lock on FS, then the path is
159289177Speter   not guaranteed to be correct or to remain correct after the function
160289177Speter   returns, because the revision might become packed before or after this
161289177Speter   call.  If a file exists at that path, then it is correct; if not, then
162289177Speter   the caller should call update_min_unpacked_rev() and re-try once. */
163289177Speterconst char *
164289177Spetersvn_fs_fs__path_rev_absolute(svn_fs_t *fs,
165289177Speter                             svn_revnum_t rev,
166289177Speter                             apr_pool_t *pool);
167289177Speter
168289177Speter/* Return the full path of the revision properties shard directory that
169289177Speter * will contain the properties of revision REV in FS.
170289177Speter * Allocate the result in POOL.
171289177Speter */
172289177Speterconst char *
173289177Spetersvn_fs_fs__path_revprops_shard(svn_fs_t *fs,
174289177Speter                               svn_revnum_t rev,
175289177Speter                               apr_pool_t *pool);
176289177Speter
177289177Speter/* Return the full path of the non-packed revision properties file that
178289177Speter * contains the props for revision REV in FS.  Allocate the result in POOL.
179289177Speter */
180289177Speterconst char *
181289177Spetersvn_fs_fs__path_revprops(svn_fs_t *fs,
182289177Speter                         svn_revnum_t rev,
183289177Speter                         apr_pool_t *pool);
184289177Speter
185289177Speter/* Return the path of the file storing the oldest non-packed revision in FS.
186289177Speter * The result will be allocated in POOL.
187289177Speter */
188289177Speterconst char *
189289177Spetersvn_fs_fs__path_min_unpacked_rev(svn_fs_t *fs,
190289177Speter                                 apr_pool_t *pool);
191289177Speter
192289177Speter/* Return the path of the 'transactions' directory in FS.
193289177Speter * The result will be allocated in POOL.
194289177Speter */
195289177Speterconst char *
196289177Spetersvn_fs_fs__path_txns_dir(svn_fs_t *fs,
197289177Speter                         apr_pool_t *pool);
198289177Speter
199289177Speter/* Return the path of the directory containing the transaction TXN_ID in FS.
200289177Speter * The result will be allocated in POOL.
201289177Speter */
202289177Speterconst char *
203289177Spetersvn_fs_fs__path_txn_dir(svn_fs_t *fs,
204289177Speter                        const svn_fs_fs__id_part_t *txn_id,
205289177Speter                        apr_pool_t *pool);
206289177Speter
207289177Speter/* Return the path of the 'txn-protorevs' directory in FS, even if that
208289177Speter * folder may not exist in FS.  The result will be allocated in POOL.
209289177Speter */
210289177Speterconst char *
211289177Spetersvn_fs_fs__path_txn_proto_revs(svn_fs_t *fs,
212289177Speter                               apr_pool_t *pool);
213289177Speter
214289177Speter/* Return the path of the proto-revision file for transaction TXN_ID in FS.
215289177Speter * The result will be allocated in POOL.
216289177Speter */
217289177Speterconst char *
218289177Spetersvn_fs_fs__path_txn_proto_rev(svn_fs_t *fs,
219289177Speter                              const svn_fs_fs__id_part_t *txn_id,
220289177Speter                              apr_pool_t *pool);
221289177Speter
222289177Speter/* Return the path of the proto-revision lock file for transaction TXN_ID
223289177Speter * in FS.  The result will be allocated in POOL.
224289177Speter */
225289177Speterconst char *
226289177Spetersvn_fs_fs__path_txn_proto_rev_lock(svn_fs_t *fs,
227289177Speter                                   const svn_fs_fs__id_part_t *txn_id,
228289177Speter                                   apr_pool_t *pool);
229289177Speter
230289177Speter/* Return the path of the file containing the in-transaction node revision
231289177Speter * identified by ID in FS.  The result will be allocated in POOL.
232289177Speter */
233289177Speterconst char *
234289177Spetersvn_fs_fs__path_txn_node_rev(svn_fs_t *fs,
235289177Speter                             const svn_fs_id_t *id,
236289177Speter                             apr_pool_t *pool);
237289177Speter
238289177Speter/* Return the path of the file containing the in-transaction properties of
239289177Speter * the node identified by ID in FS.  The result will be allocated in POOL.
240289177Speter */
241289177Speterconst char *
242289177Spetersvn_fs_fs__path_txn_node_props(svn_fs_t *fs,
243289177Speter                               const svn_fs_id_t *id,
244289177Speter                               apr_pool_t *pool);
245289177Speter
246289177Speter/* Return the path of the file containing the directory entries of the
247289177Speter * in-transaction directory node identified by ID in FS.
248289177Speter * The result will be allocated in POOL.
249289177Speter */
250289177Speterconst char *
251289177Spetersvn_fs_fs__path_txn_node_children(svn_fs_t *fs,
252289177Speter                                  const svn_fs_id_t *id,
253289177Speter                                  apr_pool_t *pool);
254289177Speter
255289177Speter/* Return the path of the file containing the log-to-phys index for
256289177Speter * the transaction identified by TXN_ID in FS.
257289177Speter * The result will be allocated in POOL.
258289177Speter */
259289177Speterconst char*
260289177Spetersvn_fs_fs__path_l2p_proto_index(svn_fs_t *fs,
261289177Speter                                const svn_fs_fs__id_part_t *txn_id,
262289177Speter                                apr_pool_t *pool);
263289177Speter
264289177Speter/* Return the path of the file containing the phys-to-log index for
265289177Speter * the transaction identified by TXN_ID in FS.
266289177Speter * The result will be allocated in POOL.
267289177Speter */
268289177Speterconst char*
269289177Spetersvn_fs_fs__path_p2l_proto_index(svn_fs_t *fs,
270289177Speter                                const svn_fs_fs__id_part_t *txn_id,
271289177Speter                                apr_pool_t *pool);
272289177Speter
273289177Speter/* Return the path of the file containing item_index counter for
274289177Speter * the transaction identified by TXN_ID in FS.
275289177Speter * The result will be allocated in POOL.
276289177Speter */
277289177Speterconst char *
278289177Spetersvn_fs_fs__path_txn_item_index(svn_fs_t *fs,
279289177Speter                               const svn_fs_fs__id_part_t *txn_id,
280289177Speter                               apr_pool_t *pool);
281289177Speter
282289177Speter/* Return the path of the file containing the node origins cachs for
283289177Speter * the given NODE_ID in FS.  The result will be allocated in POOL.
284289177Speter */
285289177Speterconst char *
286289177Spetersvn_fs_fs__path_node_origin(svn_fs_t *fs,
287289177Speter                            const svn_fs_fs__id_part_t *node_id,
288289177Speter                            apr_pool_t *pool);
289289177Speter
290289177Speter/* Set *MIN_UNPACKED_REV to the integer value read from the file returned
291289177Speter * by #svn_fs_fs__path_min_unpacked_rev() for FS.
292289177Speter * Use POOL for temporary allocations.
293289177Speter */
294289177Spetersvn_error_t *
295289177Spetersvn_fs_fs__read_min_unpacked_rev(svn_revnum_t *min_unpacked_rev,
296289177Speter                                 svn_fs_t *fs,
297289177Speter                                 apr_pool_t *pool);
298289177Speter
299289177Speter/* Check that BUF, a nul-terminated buffer of text from file PATH,
300289177Speter   contains only digits at OFFSET and beyond, raising an error if not.
301289177Speter   TITLE contains a user-visible description of the file, usually the
302289177Speter   short file name.
303289177Speter
304289177Speter   Uses POOL for temporary allocation. */
305289177Spetersvn_error_t *
306289177Spetersvn_fs_fs__check_file_buffer_numeric(const char *buf,
307289177Speter                                     apr_off_t offset,
308289177Speter                                     const char *path,
309289177Speter                                     const char *title,
310289177Speter                                     apr_pool_t *pool);
311289177Speter
312289177Speter/* Re-read the MIN_UNPACKED_REV member of FS from disk.
313289177Speter * Use POOL for temporary allocations.
314289177Speter */
315289177Spetersvn_error_t *
316289177Spetersvn_fs_fs__update_min_unpacked_rev(svn_fs_t *fs,
317289177Speter                                   apr_pool_t *pool);
318289177Speter
319289177Speter/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed
320289177Speter * REVNUM.  Perform temporary allocations in SCRATCH_POOL.
321289177Speter */
322289177Spetersvn_error_t *
323289177Spetersvn_fs_fs__write_min_unpacked_rev(svn_fs_t *fs,
324289177Speter                                  svn_revnum_t revnum,
325289177Speter                                  apr_pool_t *scratch_pool);
326289177Speter
327289177Speter/* Set *REV, *NEXT_NODE_ID and *NEXT_COPY_ID to the values read from the
328289177Speter * 'current' file.  For new FS formats, which only store the youngest
329289177Speter * revision, set the *NEXT_NODE_ID and *NEXT_COPY_ID to 0.  Perform
330289177Speter * temporary allocations in POOL.
331289177Speter */
332289177Spetersvn_error_t *
333289177Spetersvn_fs_fs__read_current(svn_revnum_t *rev,
334289177Speter                        apr_uint64_t *next_node_id,
335289177Speter                        apr_uint64_t *next_copy_id,
336289177Speter                        svn_fs_t *fs,
337289177Speter                        apr_pool_t *pool);
338289177Speter
339289177Speter/* Atomically update the 'current' file to hold the specifed REV,
340289177Speter   NEXT_NODE_ID, and NEXT_COPY_ID.  (The two next-ID parameters are
341289177Speter   ignored and may be 0 if the FS format does not use them.)
342289177Speter   Perform temporary allocations in POOL. */
343289177Spetersvn_error_t *
344289177Spetersvn_fs_fs__write_current(svn_fs_t *fs,
345289177Speter                         svn_revnum_t rev,
346289177Speter                         apr_uint64_t next_node_id,
347289177Speter                         apr_uint64_t next_copy_id,
348289177Speter                         apr_pool_t *pool);
349289177Speter
350289177Speter/* Read the file at PATH and return its content in *CONTENT. *CONTENT will
351289177Speter * not be modified unless the whole file was read successfully.
352289177Speter *
353289177Speter * ESTALE, EIO and ENOENT will not cause this function to return an error
354289177Speter * unless LAST_ATTEMPT has been set.  If MISSING is not NULL, indicate
355289177Speter * missing files (ENOENT) there.
356289177Speter *
357289177Speter * Use POOL for allocations.
358289177Speter */
359289177Spetersvn_error_t *
360289177Spetersvn_fs_fs__try_stringbuf_from_file(svn_stringbuf_t **content,
361289177Speter                                   svn_boolean_t *missing,
362289177Speter                                   const char *path,
363289177Speter                                   svn_boolean_t last_attempt,
364289177Speter                                   apr_pool_t *pool);
365289177Speter
366289177Speter/* Read the file FNAME and store the contents in *BUF.
367289177Speter   Allocations are performed in POOL. */
368289177Spetersvn_error_t *
369289177Spetersvn_fs_fs__read_content(svn_stringbuf_t **content,
370289177Speter                        const char *fname,
371289177Speter                        apr_pool_t *pool);
372289177Speter
373289177Speter/* Reads a line from STREAM and converts it to a 64 bit integer to be
374289177Speter * returned in *RESULT.  If we encounter eof, set *HIT_EOF and leave
375289177Speter * *RESULT unchanged.  If HIT_EOF is NULL, EOF causes an "corrupt FS"
376289177Speter * error return.
377289177Speter * SCRATCH_POOL is used for temporary allocations.
378289177Speter */
379289177Spetersvn_error_t *
380289177Spetersvn_fs_fs__read_number_from_stream(apr_int64_t *result,
381289177Speter                                   svn_boolean_t *hit_eof,
382289177Speter                                   svn_stream_t *stream,
383289177Speter                                   apr_pool_t *scratch_pool);
384289177Speter
385289177Speter/* Move a file into place from OLD_FILENAME in the transactions
386289177Speter   directory to its final location NEW_FILENAME in the repository.  On
387289177Speter   Unix, match the permissions of the new file to the permissions of
388289177Speter   PERMS_REFERENCE.  Temporary allocations are from POOL.
389289177Speter
390289177Speter   This function almost duplicates svn_io_file_move(), but it tries to
391362181Sdim   guarantee a flush if FLUSH_TO_DISK is non-zero. */
392289177Spetersvn_error_t *
393289177Spetersvn_fs_fs__move_into_place(const char *old_filename,
394289177Speter                           const char *new_filename,
395289177Speter                           const char *perms_reference,
396362181Sdim                           svn_boolean_t flush_to_disk,
397289177Speter                           apr_pool_t *pool);
398289177Speter
399289177Speter/* Return TRUE, iff FS uses logical addressing. */
400289177Spetersvn_boolean_t
401289177Spetersvn_fs_fs__use_log_addressing(svn_fs_t *fs);
402289177Speter
403289177Speter#endif
404