refs file backend: move raceproof_create_file() here
Move the raceproof_create_file() API added to cache.h and object-file.c in 177978f56ad (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>
Ævar Arnfjörð Bjarmason committed
Aug 23, 2021 at 13:52 UTC
3fa2e91d173b260c19f19af8edd3907e65bf85f7
3 files changed
+109
-111
cache.h
-43
@@ -1202,49 +1202,6 @@ enum scld_error safe_create_leading_directories(char *path);
1202
enum scld_error safe_create_leading_directories_const(const char *path);
1203
enum scld_error safe_create_leading_directories_no_share(char *path);
1204
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
-
1205
int mkdir_in_gitdir(const char *path);
1206
char *expand_user_path(const char *path, int real_home);
1207
const char *enter_repo(const char *path, int strict);
object-file.c
-68
@@ -414,74 +414,6 @@ enum scld_error safe_create_leading_directories_const(const char *path)
414
return result;
415
}
416
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
-
417
static void fill_loose_path(struct strbuf *buf, const struct object_id *oid)
418
{
419
int i;
refs/files-backend.c
+109
@@ -852,6 +852,115 @@ static struct ref_iterator *files_ref_iterator_begin(
852
return ref_iterator;
853
}
854
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
+
964
static int remove_empty_directories(struct strbuf *path)
965
{
966
/*