Skip to content

Commit 26429b4

Browse files
jeffhostetlerdscho
authored andcommitted
gvfs-helper: add prefetch .keep file for last packfile
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
1 parent bf736ee commit 26429b4

File tree

2 files changed

+109
-3
lines changed

2 files changed

+109
-3
lines changed

gvfs-helper.c

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,7 @@ static void my_run_index_pack(struct gh__request_params *params UNUSED,
18801880

18811881
static void my_finalize_packfile(struct gh__request_params *params,
18821882
struct gh__response_status *status,
1883+
int b_keep,
18831884
const struct strbuf *temp_path_pack,
18841885
const struct strbuf *temp_path_idx,
18851886
struct strbuf *final_path_pack,
@@ -1899,6 +1900,21 @@ static void my_finalize_packfile(struct gh__request_params *params,
18991900
return;
19001901
}
19011902

1903+
if (b_keep) {
1904+
struct strbuf keep = STRBUF_INIT;
1905+
int fd_keep;
1906+
1907+
strbuf_addbuf(&keep, final_path_pack);
1908+
strbuf_strip_suffix(&keep, ".pack");
1909+
strbuf_addstr(&keep, ".keep");
1910+
1911+
fd_keep = xopen(keep.buf, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1912+
if (fd_keep >= 0)
1913+
close(fd_keep);
1914+
1915+
strbuf_release(&keep);
1916+
}
1917+
19021918
if (params->result_list) {
19031919
struct strbuf result_msg = STRBUF_INIT;
19041920

@@ -1951,7 +1967,7 @@ static void install_packfile(struct gh__request_params *params,
19511967
create_final_packfile_pathnames("vfs", packfile_checksum.buf, NULL,
19521968
&final_path_pack, &final_path_idx,
19531969
&final_filename);
1954-
my_finalize_packfile(params, status,
1970+
my_finalize_packfile(params, status, 0,
19551971
&temp_path_pack, &temp_path_idx,
19561972
&final_path_pack, &final_path_idx,
19571973
&final_filename);
@@ -2047,6 +2063,12 @@ struct ph {
20472063

20482064
/*
20492065
* Extract the next packfile from the multipack.
2066+
* Install {.pack, .idx, .keep} set.
2067+
*
2068+
* Mark each successfully installed prefetch pack as .keep it as installed
2069+
* in case we have errors decoding/indexing later packs within the received
2070+
* multipart file. (A later pass can delete the unnecessary .keep files
2071+
* from this and any previous invocations.)
20502072
*/
20512073
static void extract_packfile_from_multipack(
20522074
struct gh__request_params *params,
@@ -2143,7 +2165,7 @@ static void extract_packfile_from_multipack(
21432165

21442166
} else {
21452167
/*
2146-
* Server send the .idx immediately after the .pack in the
2168+
* Server sent the .idx immediately after the .pack in the
21472169
* data stream. I'm tempted to verify it, but that defeats
21482170
* the purpose of having it cached...
21492171
*/
@@ -2165,7 +2187,7 @@ static void extract_packfile_from_multipack(
21652187
&final_path_pack, &final_path_idx,
21662188
&final_filename);
21672189

2168-
my_finalize_packfile(params, status,
2190+
my_finalize_packfile(params, status, 1,
21692191
&temp_path_pack, &temp_path_idx,
21702192
&final_path_pack, &final_path_idx,
21712193
&final_filename);
@@ -2180,6 +2202,56 @@ static void extract_packfile_from_multipack(
21802202
strbuf_release(&final_filename);
21812203
}
21822204

2205+
struct keep_files_data {
2206+
timestamp_t max_timestamp;
2207+
int pos_of_max;
2208+
struct string_list *keep_files;
2209+
};
2210+
2211+
static void cb_keep_files(const char *full_path, size_t full_path_len UNUSED,
2212+
const char *file_path, void *void_data)
2213+
{
2214+
struct keep_files_data *data = void_data;
2215+
const char *val;
2216+
timestamp_t t;
2217+
2218+
/*
2219+
* We expect prefetch packfiles named like:
2220+
*
2221+
* prefetch-<seconds>-<checksum>.keep
2222+
*/
2223+
if (!skip_prefix(file_path, "prefetch-", &val))
2224+
return;
2225+
if (!ends_with(val, ".keep"))
2226+
return;
2227+
2228+
t = strtol(val, NULL, 10);
2229+
if (t > data->max_timestamp) {
2230+
data->pos_of_max = data->keep_files->nr;
2231+
data->max_timestamp = t;
2232+
}
2233+
2234+
string_list_append(data->keep_files, full_path);
2235+
}
2236+
2237+
static void delete_stale_keep_files(
2238+
struct gh__request_params *params UNUSED,
2239+
struct gh__response_status *status UNUSED)
2240+
{
2241+
struct string_list keep_files = STRING_LIST_INIT_DUP;
2242+
struct keep_files_data data = { 0, 0, &keep_files };
2243+
int k;
2244+
2245+
for_each_file_in_pack_dir(gh__global.buf_odb_path.buf,
2246+
cb_keep_files, &data);
2247+
for (k = 0; k < keep_files.nr; k++) {
2248+
if (k != data.pos_of_max)
2249+
unlink(keep_files.items[k].string);
2250+
}
2251+
2252+
string_list_clear(&keep_files, 0);
2253+
}
2254+
21832255
/*
21842256
* Cut apart the received multipart response into individual packfiles
21852257
* and install each one.
@@ -2198,6 +2270,7 @@ static void install_prefetch(struct gh__request_params *params,
21982270
unsigned short np;
21992271
unsigned short k;
22002272
int fd = -1;
2273+
int nr_installed = 0;
22012274

22022275
struct strbuf temp_path_mp = STRBUF_INIT;
22032276

@@ -2242,9 +2315,13 @@ static void install_prefetch(struct gh__request_params *params,
22422315
display_progress(params->progress, k + 1);
22432316
if (status->ec != GH__ERROR_CODE__OK)
22442317
break;
2318+
nr_installed++;
22452319
}
22462320
stop_progress(&params->progress);
22472321

2322+
if (nr_installed)
2323+
delete_stale_keep_files(params, status);
2324+
22482325
cleanup:
22492326
if (fd != -1)
22502327
close(fd);

t/t5799-gvfs-helper.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,30 @@ verify_received_packfile_count () {
390390
return 0
391391
}
392392

393+
# Verify that we have exactly 1 prefetch .keep file.
394+
# Optionally, verify that it has the given timestamp.
395+
#
396+
verify_prefetch_keeps () {
397+
count=$(( $(ls -1 "$SHARED_CACHE_T1"/pack/prefetch-*.keep | wc -l) ))
398+
if test $count -ne 1
399+
then
400+
echo "verify_prefetch_keep_file_count: found $count, expected 1."
401+
return 1
402+
fi
403+
404+
if test $# -eq 1
405+
then
406+
count=$(( $(ls -1 "$SHARED_CACHE_T1"/pack/prefetch-$1-*.keep | wc -l) ))
407+
if test $count -ne 1
408+
then
409+
echo "verify_prefetch_keep_file_count: did not find expected keep file."
410+
return 1
411+
fi
412+
fi
413+
414+
return 0
415+
}
416+
393417
per_test_cleanup () {
394418
stop_gvfs_protocol_server
395419

@@ -643,6 +667,7 @@ test_expect_success 'basic: PREFETCH w/o arg gets all' '
643667
# packfile.
644668
#
645669
verify_received_packfile_count 3 &&
670+
verify_prefetch_keeps 1200000000 &&
646671
647672
stop_gvfs_protocol_server &&
648673
verify_connection_count 1
@@ -664,6 +689,7 @@ test_expect_success 'basic: PREFETCH w/ arg' '
664689
# packfile.
665690
#
666691
verify_received_packfile_count 2 &&
692+
verify_prefetch_keeps 1200000000 &&
667693
668694
stop_gvfs_protocol_server &&
669695
verify_connection_count 1
@@ -686,6 +712,7 @@ test_expect_success 'basic: PREFETCH mayhem no_prefetch_idx' '
686712
# packfile.
687713
#
688714
verify_received_packfile_count 2 &&
715+
verify_prefetch_keeps 1200000000 &&
689716
690717
stop_gvfs_protocol_server &&
691718
verify_connection_count 1
@@ -707,6 +734,7 @@ test_expect_success 'basic: PREFETCH up-to-date' '
707734
# packfile.
708735
#
709736
verify_received_packfile_count 2 &&
737+
verify_prefetch_keeps 1200000000 &&
710738
711739
# Ask again for any packfiles newer than what we have cached locally.
712740
#
@@ -720,6 +748,7 @@ test_expect_success 'basic: PREFETCH up-to-date' '
720748
# packfile.
721749
#
722750
verify_received_packfile_count 0 &&
751+
verify_prefetch_keeps 1200000000 &&
723752
724753
stop_gvfs_protocol_server &&
725754
verify_connection_count 2

0 commit comments

Comments
 (0)