Skip to content

Commit 3fa2346

Browse files
jeffhostetlerderrickstolee
authored andcommitted
gvfs-helper: add prefetch .keep file for last packfile
Signed-off-by: Jeff Hostetler <[email protected]>
1 parent 1da3d9d commit 3fa2346

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

18651865
static void my_finalize_packfile(struct gh__request_params *params,
18661866
struct gh__response_status *status,
1867+
int b_keep,
18671868
const struct strbuf *temp_path_pack,
18681869
const struct strbuf *temp_path_idx,
18691870
struct strbuf *final_path_pack,
@@ -1883,6 +1884,21 @@ static void my_finalize_packfile(struct gh__request_params *params,
18831884
return;
18841885
}
18851886

1887+
if (b_keep) {
1888+
struct strbuf keep = STRBUF_INIT;
1889+
int fd_keep;
1890+
1891+
strbuf_addbuf(&keep, final_path_pack);
1892+
strbuf_strip_suffix(&keep, ".pack");
1893+
strbuf_addstr(&keep, ".keep");
1894+
1895+
fd_keep = xopen(keep.buf, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1896+
if (fd_keep >= 0)
1897+
close(fd_keep);
1898+
1899+
strbuf_release(&keep);
1900+
}
1901+
18861902
if (params->result_list) {
18871903
struct strbuf result_msg = STRBUF_INIT;
18881904

@@ -1935,7 +1951,7 @@ static void install_packfile(struct gh__request_params *params,
19351951
create_final_packfile_pathnames("vfs", packfile_checksum.buf, NULL,
19361952
&final_path_pack, &final_path_idx,
19371953
&final_filename);
1938-
my_finalize_packfile(params, status,
1954+
my_finalize_packfile(params, status, 0,
19391955
&temp_path_pack, &temp_path_idx,
19401956
&final_path_pack, &final_path_idx,
19411957
&final_filename);
@@ -2031,6 +2047,12 @@ struct ph {
20312047

20322048
/*
20332049
* Extract the next packfile from the multipack.
2050+
* Install {.pack, .idx, .keep} set.
2051+
*
2052+
* Mark each successfully installed prefetch pack as .keep it as installed
2053+
* in case we have errors decoding/indexing later packs within the received
2054+
* multipart file. (A later pass can delete the unnecessary .keep files
2055+
* from this and any previous invocations.)
20342056
*/
20352057
static void extract_packfile_from_multipack(
20362058
struct gh__request_params *params,
@@ -2125,7 +2147,7 @@ static void extract_packfile_from_multipack(
21252147

21262148
} else {
21272149
/*
2128-
* Server send the .idx immediately after the .pack in the
2150+
* Server sent the .idx immediately after the .pack in the
21292151
* data stream. I'm tempted to verify it, but that defeats
21302152
* the purpose of having it cached...
21312153
*/
@@ -2147,7 +2169,7 @@ static void extract_packfile_from_multipack(
21472169
&final_path_pack, &final_path_idx,
21482170
&final_filename);
21492171

2150-
my_finalize_packfile(params, status,
2172+
my_finalize_packfile(params, status, 1,
21512173
&temp_path_pack, &temp_path_idx,
21522174
&final_path_pack, &final_path_idx,
21532175
&final_filename);
@@ -2162,6 +2184,56 @@ static void extract_packfile_from_multipack(
21622184
strbuf_release(&final_filename);
21632185
}
21642186

2187+
struct keep_files_data {
2188+
timestamp_t max_timestamp;
2189+
int pos_of_max;
2190+
struct string_list *keep_files;
2191+
};
2192+
2193+
static void cb_keep_files(const char *full_path, size_t full_path_len,
2194+
const char *file_path, void *void_data)
2195+
{
2196+
struct keep_files_data *data = void_data;
2197+
const char *val;
2198+
timestamp_t t;
2199+
2200+
/*
2201+
* We expect prefetch packfiles named like:
2202+
*
2203+
* prefetch-<seconds>-<checksum>.keep
2204+
*/
2205+
if (!skip_prefix(file_path, "prefetch-", &val))
2206+
return;
2207+
if (!ends_with(val, ".keep"))
2208+
return;
2209+
2210+
t = strtol(val, NULL, 10);
2211+
if (t > data->max_timestamp) {
2212+
data->pos_of_max = data->keep_files->nr;
2213+
data->max_timestamp = t;
2214+
}
2215+
2216+
string_list_append(data->keep_files, full_path);
2217+
}
2218+
2219+
static void delete_stale_keep_files(
2220+
struct gh__request_params *params,
2221+
struct gh__response_status *status)
2222+
{
2223+
struct string_list keep_files = STRING_LIST_INIT_DUP;
2224+
struct keep_files_data data = { 0, 0, &keep_files };
2225+
int k;
2226+
2227+
for_each_file_in_pack_dir(gh__global.buf_odb_path.buf,
2228+
cb_keep_files, &data);
2229+
for (k = 0; k < keep_files.nr; k++) {
2230+
if (k != data.pos_of_max)
2231+
unlink(keep_files.items[k].string);
2232+
}
2233+
2234+
string_list_clear(&keep_files, 0);
2235+
}
2236+
21652237
/*
21662238
* Cut apart the received multipart response into individual packfiles
21672239
* and install each one.
@@ -2180,6 +2252,7 @@ static void install_prefetch(struct gh__request_params *params,
21802252
unsigned short np;
21812253
unsigned short k;
21822254
int fd = -1;
2255+
int nr_installed = 0;
21832256

21842257
struct strbuf temp_path_mp = STRBUF_INIT;
21852258

@@ -2220,8 +2293,12 @@ static void install_prefetch(struct gh__request_params *params,
22202293
extract_packfile_from_multipack(params, status, fd, k);
22212294
if (status->ec != GH__ERROR_CODE__OK)
22222295
break;
2296+
nr_installed++;
22232297
}
22242298

2299+
if (nr_installed)
2300+
delete_stale_keep_files(params, status);
2301+
22252302
cleanup:
22262303
if (fd != -1)
22272304
close(fd);

t/t5799-gvfs-helper.sh

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

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

@@ -641,6 +665,7 @@ test_expect_success 'basic: PREFETCH w/o arg gets all' '
641665
# packfile.
642666
#
643667
verify_received_packfile_count 3 &&
668+
verify_prefetch_keeps 1200000000 &&
644669
645670
stop_gvfs_protocol_server &&
646671
verify_connection_count 1
@@ -662,6 +687,7 @@ test_expect_success 'basic: PREFETCH w/ arg' '
662687
# packfile.
663688
#
664689
verify_received_packfile_count 2 &&
690+
verify_prefetch_keeps 1200000000 &&
665691
666692
stop_gvfs_protocol_server &&
667693
verify_connection_count 1
@@ -684,6 +710,7 @@ test_expect_success 'basic: PREFETCH mayhem no_prefetch_idx' '
684710
# packfile.
685711
#
686712
verify_received_packfile_count 2 &&
713+
verify_prefetch_keeps 1200000000 &&
687714
688715
stop_gvfs_protocol_server &&
689716
verify_connection_count 1
@@ -705,6 +732,7 @@ test_expect_success 'basic: PREFETCH up-to-date' '
705732
# packfile.
706733
#
707734
verify_received_packfile_count 2 &&
735+
verify_prefetch_keeps 1200000000 &&
708736
709737
# Ask again for any packfiles newer than what we have cached locally.
710738
#
@@ -718,6 +746,7 @@ test_expect_success 'basic: PREFETCH up-to-date' '
718746
# packfile.
719747
#
720748
verify_received_packfile_count 0 &&
749+
verify_prefetch_keeps 1200000000 &&
721750
722751
stop_gvfs_protocol_server &&
723752
verify_connection_count 2

0 commit comments

Comments
 (0)