Skip to content

Commit 031b41c

Browse files
jeffhostetlerdscho
authored andcommitted
gvfs-helper: add prefetch .keep file for last packfile
Signed-off-by: Jeff Hostetler <[email protected]>
1 parent 4d6957d commit 031b41c

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
@@ -1883,6 +1883,7 @@ static void my_run_index_pack(struct gh__request_params *params UNUSED,
18831883

18841884
static void my_finalize_packfile(struct gh__request_params *params,
18851885
struct gh__response_status *status,
1886+
int b_keep,
18861887
const struct strbuf *temp_path_pack,
18871888
const struct strbuf *temp_path_idx,
18881889
struct strbuf *final_path_pack,
@@ -1902,6 +1903,21 @@ static void my_finalize_packfile(struct gh__request_params *params,
19021903
return;
19031904
}
19041905

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

@@ -1954,7 +1970,7 @@ static void install_packfile(struct gh__request_params *params,
19541970
create_final_packfile_pathnames("vfs", packfile_checksum.buf, NULL,
19551971
&final_path_pack, &final_path_idx,
19561972
&final_filename);
1957-
my_finalize_packfile(params, status,
1973+
my_finalize_packfile(params, status, 0,
19581974
&temp_path_pack, &temp_path_idx,
19591975
&final_path_pack, &final_path_idx,
19601976
&final_filename);
@@ -2050,6 +2066,12 @@ struct ph {
20502066

20512067
/*
20522068
* Extract the next packfile from the multipack.
2069+
* Install {.pack, .idx, .keep} set.
2070+
*
2071+
* Mark each successfully installed prefetch pack as .keep it as installed
2072+
* in case we have errors decoding/indexing later packs within the received
2073+
* multipart file. (A later pass can delete the unnecessary .keep files
2074+
* from this and any previous invocations.)
20532075
*/
20542076
static void extract_packfile_from_multipack(
20552077
struct gh__request_params *params,
@@ -2146,7 +2168,7 @@ static void extract_packfile_from_multipack(
21462168

21472169
} else {
21482170
/*
2149-
* Server send the .idx immediately after the .pack in the
2171+
* Server sent the .idx immediately after the .pack in the
21502172
* data stream. I'm tempted to verify it, but that defeats
21512173
* the purpose of having it cached...
21522174
*/
@@ -2169,7 +2191,7 @@ static void extract_packfile_from_multipack(
21692191
&final_filename);
21702192
strbuf_release(&buf_timestamp);
21712193

2172-
my_finalize_packfile(params, status,
2194+
my_finalize_packfile(params, status, 1,
21732195
&temp_path_pack, &temp_path_idx,
21742196
&final_path_pack, &final_path_idx,
21752197
&final_filename);
@@ -2184,6 +2206,56 @@ static void extract_packfile_from_multipack(
21842206
strbuf_release(&final_filename);
21852207
}
21862208

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

22062279
struct strbuf temp_path_mp = STRBUF_INIT;
22072280

@@ -2246,9 +2319,13 @@ static void install_prefetch(struct gh__request_params *params,
22462319
display_progress(params->progress, k + 1);
22472320
if (status->ec != GH__ERROR_CODE__OK)
22482321
break;
2322+
nr_installed++;
22492323
}
22502324
stop_progress(&params->progress);
22512325

2326+
if (nr_installed)
2327+
delete_stale_keep_files(params, status);
2328+
22522329
cleanup:
22532330
if (fd != -1)
22542331
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)