Skip to content

Commit 0288b11

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

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

18831883
static void my_finalize_packfile(struct gh__request_params *params,
18841884
struct gh__response_status *status,
1885+
int b_keep,
18851886
const struct strbuf *temp_path_pack,
18861887
const struct strbuf *temp_path_idx,
18871888
struct strbuf *final_path_pack,
@@ -1901,6 +1902,21 @@ static void my_finalize_packfile(struct gh__request_params *params,
19011902
return;
19021903
}
19031904

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

@@ -1953,7 +1969,7 @@ static void install_packfile(struct gh__request_params *params,
19531969
create_final_packfile_pathnames("vfs", packfile_checksum.buf, NULL,
19541970
&final_path_pack, &final_path_idx,
19551971
&final_filename);
1956-
my_finalize_packfile(params, status,
1972+
my_finalize_packfile(params, status, 0,
19571973
&temp_path_pack, &temp_path_idx,
19581974
&final_path_pack, &final_path_idx,
19591975
&final_filename);
@@ -2049,6 +2065,12 @@ struct ph {
20492065

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

21462168
} else {
21472169
/*
2148-
* Server send the .idx immediately after the .pack in the
2170+
* Server sent the .idx immediately after the .pack in the
21492171
* data stream. I'm tempted to verify it, but that defeats
21502172
* the purpose of having it cached...
21512173
*/
@@ -2168,7 +2190,7 @@ static void extract_packfile_from_multipack(
21682190
&final_filename);
21692191
strbuf_release(&buf_timestamp);
21702192

2171-
my_finalize_packfile(params, status,
2193+
my_finalize_packfile(params, status, 1,
21722194
&temp_path_pack, &temp_path_idx,
21732195
&final_path_pack, &final_path_idx,
21742196
&final_filename);
@@ -2183,6 +2205,56 @@ static void extract_packfile_from_multipack(
21832205
strbuf_release(&final_filename);
21842206
}
21852207

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

22052278
struct strbuf temp_path_mp = STRBUF_INIT;
22062279

@@ -2245,9 +2318,13 @@ static void install_prefetch(struct gh__request_params *params,
22452318
display_progress(params->progress, k + 1);
22462319
if (status->ec != GH__ERROR_CODE__OK)
22472320
break;
2321+
nr_installed++;
22482322
}
22492323
stop_progress(&params->progress);
22502324

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