Skip to content

Commit 3fa2e91

Browse files
avargitster
authored andcommitted
refs file backend: move raceproof_create_file() here
Move the raceproof_create_file() API added to cache.h and object-file.c in 177978f (raceproof_create_file(): new function, 2017-01-06) to its only user, refs/files-backend.c. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 48cdcd9 commit 3fa2e91

File tree

3 files changed

+109
-111
lines changed

3 files changed

+109
-111
lines changed

cache.h

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,49 +1202,6 @@ enum scld_error safe_create_leading_directories(char *path);
12021202
enum scld_error safe_create_leading_directories_const(const char *path);
12031203
enum scld_error safe_create_leading_directories_no_share(char *path);
12041204

1205-
/*
1206-
* Callback function for raceproof_create_file(). This function is
1207-
* expected to do something that makes dirname(path) permanent despite
1208-
* the fact that other processes might be cleaning up empty
1209-
* directories at the same time. Usually it will create a file named
1210-
* path, but alternatively it could create another file in that
1211-
* directory, or even chdir() into that directory. The function should
1212-
* return 0 if the action was completed successfully. On error, it
1213-
* should return a nonzero result and set errno.
1214-
* raceproof_create_file() treats two errno values specially:
1215-
*
1216-
* - ENOENT -- dirname(path) does not exist. In this case,
1217-
* raceproof_create_file() tries creating dirname(path)
1218-
* (and any parent directories, if necessary) and calls
1219-
* the function again.
1220-
*
1221-
* - EISDIR -- the file already exists and is a directory. In this
1222-
* case, raceproof_create_file() removes the directory if
1223-
* it is empty (and recursively any empty directories that
1224-
* it contains) and calls the function again.
1225-
*
1226-
* Any other errno causes raceproof_create_file() to fail with the
1227-
* callback's return value and errno.
1228-
*
1229-
* Obviously, this function should be OK with being called again if it
1230-
* fails with ENOENT or EISDIR. In other scenarios it will not be
1231-
* called again.
1232-
*/
1233-
typedef int create_file_fn(const char *path, void *cb);
1234-
1235-
/*
1236-
* Create a file in dirname(path) by calling fn, creating leading
1237-
* directories if necessary. Retry a few times in case we are racing
1238-
* with another process that is trying to clean up the directory that
1239-
* contains path. See the documentation for create_file_fn for more
1240-
* details.
1241-
*
1242-
* Return the value and set the errno that resulted from the most
1243-
* recent call of fn. fn is always called at least once, and will be
1244-
* called more than once if it returns ENOENT or EISDIR.
1245-
*/
1246-
int raceproof_create_file(const char *path, create_file_fn fn, void *cb);
1247-
12481205
int mkdir_in_gitdir(const char *path);
12491206
char *expand_user_path(const char *path, int real_home);
12501207
const char *enter_repo(const char *path, int strict);

object-file.c

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -414,74 +414,6 @@ enum scld_error safe_create_leading_directories_const(const char *path)
414414
return result;
415415
}
416416

417-
int raceproof_create_file(const char *path, create_file_fn fn, void *cb)
418-
{
419-
/*
420-
* The number of times we will try to remove empty directories
421-
* in the way of path. This is only 1 because if another
422-
* process is racily creating directories that conflict with
423-
* us, we don't want to fight against them.
424-
*/
425-
int remove_directories_remaining = 1;
426-
427-
/*
428-
* The number of times that we will try to create the
429-
* directories containing path. We are willing to attempt this
430-
* more than once, because another process could be trying to
431-
* clean up empty directories at the same time as we are
432-
* trying to create them.
433-
*/
434-
int create_directories_remaining = 3;
435-
436-
/* A scratch copy of path, filled lazily if we need it: */
437-
struct strbuf path_copy = STRBUF_INIT;
438-
439-
int ret, save_errno;
440-
441-
/* Sanity check: */
442-
assert(*path);
443-
444-
retry_fn:
445-
ret = fn(path, cb);
446-
save_errno = errno;
447-
if (!ret)
448-
goto out;
449-
450-
if (errno == EISDIR && remove_directories_remaining-- > 0) {
451-
/*
452-
* A directory is in the way. Maybe it is empty; try
453-
* to remove it:
454-
*/
455-
if (!path_copy.len)
456-
strbuf_addstr(&path_copy, path);
457-
458-
if (!remove_dir_recursively(&path_copy, REMOVE_DIR_EMPTY_ONLY))
459-
goto retry_fn;
460-
} else if (errno == ENOENT && create_directories_remaining-- > 0) {
461-
/*
462-
* Maybe the containing directory didn't exist, or
463-
* maybe it was just deleted by a process that is
464-
* racing with us to clean up empty directories. Try
465-
* to create it:
466-
*/
467-
enum scld_error scld_result;
468-
469-
if (!path_copy.len)
470-
strbuf_addstr(&path_copy, path);
471-
472-
do {
473-
scld_result = safe_create_leading_directories(path_copy.buf);
474-
if (scld_result == SCLD_OK)
475-
goto retry_fn;
476-
} while (scld_result == SCLD_VANISHED && create_directories_remaining-- > 0);
477-
}
478-
479-
out:
480-
strbuf_release(&path_copy);
481-
errno = save_errno;
482-
return ret;
483-
}
484-
485417
static void fill_loose_path(struct strbuf *buf, const struct object_id *oid)
486418
{
487419
int i;

refs/files-backend.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,115 @@ static struct ref_iterator *files_ref_iterator_begin(
852852
return ref_iterator;
853853
}
854854

855+
/*
856+
* Callback function for raceproof_create_file(). This function is
857+
* expected to do something that makes dirname(path) permanent despite
858+
* the fact that other processes might be cleaning up empty
859+
* directories at the same time. Usually it will create a file named
860+
* path, but alternatively it could create another file in that
861+
* directory, or even chdir() into that directory. The function should
862+
* return 0 if the action was completed successfully. On error, it
863+
* should return a nonzero result and set errno.
864+
* raceproof_create_file() treats two errno values specially:
865+
*
866+
* - ENOENT -- dirname(path) does not exist. In this case,
867+
* raceproof_create_file() tries creating dirname(path)
868+
* (and any parent directories, if necessary) and calls
869+
* the function again.
870+
*
871+
* - EISDIR -- the file already exists and is a directory. In this
872+
* case, raceproof_create_file() removes the directory if
873+
* it is empty (and recursively any empty directories that
874+
* it contains) and calls the function again.
875+
*
876+
* Any other errno causes raceproof_create_file() to fail with the
877+
* callback's return value and errno.
878+
*
879+
* Obviously, this function should be OK with being called again if it
880+
* fails with ENOENT or EISDIR. In other scenarios it will not be
881+
* called again.
882+
*/
883+
typedef int create_file_fn(const char *path, void *cb);
884+
885+
/*
886+
* Create a file in dirname(path) by calling fn, creating leading
887+
* directories if necessary. Retry a few times in case we are racing
888+
* with another process that is trying to clean up the directory that
889+
* contains path. See the documentation for create_file_fn for more
890+
* details.
891+
*
892+
* Return the value and set the errno that resulted from the most
893+
* recent call of fn. fn is always called at least once, and will be
894+
* called more than once if it returns ENOENT or EISDIR.
895+
*/
896+
static int raceproof_create_file(const char *path, create_file_fn fn, void *cb)
897+
{
898+
/*
899+
* The number of times we will try to remove empty directories
900+
* in the way of path. This is only 1 because if another
901+
* process is racily creating directories that conflict with
902+
* us, we don't want to fight against them.
903+
*/
904+
int remove_directories_remaining = 1;
905+
906+
/*
907+
* The number of times that we will try to create the
908+
* directories containing path. We are willing to attempt this
909+
* more than once, because another process could be trying to
910+
* clean up empty directories at the same time as we are
911+
* trying to create them.
912+
*/
913+
int create_directories_remaining = 3;
914+
915+
/* A scratch copy of path, filled lazily if we need it: */
916+
struct strbuf path_copy = STRBUF_INIT;
917+
918+
int ret, save_errno;
919+
920+
/* Sanity check: */
921+
assert(*path);
922+
923+
retry_fn:
924+
ret = fn(path, cb);
925+
save_errno = errno;
926+
if (!ret)
927+
goto out;
928+
929+
if (errno == EISDIR && remove_directories_remaining-- > 0) {
930+
/*
931+
* A directory is in the way. Maybe it is empty; try
932+
* to remove it:
933+
*/
934+
if (!path_copy.len)
935+
strbuf_addstr(&path_copy, path);
936+
937+
if (!remove_dir_recursively(&path_copy, REMOVE_DIR_EMPTY_ONLY))
938+
goto retry_fn;
939+
} else if (errno == ENOENT && create_directories_remaining-- > 0) {
940+
/*
941+
* Maybe the containing directory didn't exist, or
942+
* maybe it was just deleted by a process that is
943+
* racing with us to clean up empty directories. Try
944+
* to create it:
945+
*/
946+
enum scld_error scld_result;
947+
948+
if (!path_copy.len)
949+
strbuf_addstr(&path_copy, path);
950+
951+
do {
952+
scld_result = safe_create_leading_directories(path_copy.buf);
953+
if (scld_result == SCLD_OK)
954+
goto retry_fn;
955+
} while (scld_result == SCLD_VANISHED && create_directories_remaining-- > 0);
956+
}
957+
958+
out:
959+
strbuf_release(&path_copy);
960+
errno = save_errno;
961+
return ret;
962+
}
963+
855964
static int remove_empty_directories(struct strbuf *path)
856965
{
857966
/*

0 commit comments

Comments
 (0)