@matheusbsbs / matheus-bagliano / commits / cac4b8e22e
Fork 0

shallow: use struct 'shallow_lock' for additional safety

In previous patches, the functions 'commit_shallow_file' and 'rollback_shallow_file' were introduced to reset the shallowness validity checks on a repository after potentially modifying '.git/shallow'. These functions can be made safer by wrapping the 'struct lockfile *' in a new type, 'shallow_lock', so that they cannot be called with a raw lock (and potentially misused by other code that happens to possess a lockfile, but has nothing to do with shallowness). This patch introduces that type as a thin wrapper around 'struct lockfile', and updates the two aforementioned functions and their callers to use it. Suggested-by: Junio C Hamano <gitster@pobox.com> Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Apr 30, 2020 at 13:48 UTC cac4b8e22ee39e52341d718450f8e4055c4dc16f
4 files changed +31 -16
builtin/receive-pack.c
+1 -1
@@ -856,7 +856,7 @@ static void refuse_unconfigured_deny_delete_current(void)
856 static int command_singleton_iterator(void *cb_data, struct object_id *oid);
857 static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
858 {
859 - struct lock_file shallow_lock = LOCK_INIT;
859 + struct shallow_lock shallow_lock = SHALLOW_LOCK_INIT;
860 struct oid_array extra = OID_ARRAY_INIT;
861 struct check_connected_options opt = CHECK_CONNECTED_INIT;
862 uint32_t mask = 1 << (cmd->index % 32);
fetch-pack.c
+1 -1
@@ -35,7 +35,7 @@ static int fetch_fsck_objects = -1;
35 static int transfer_fsck_objects = -1;
36 static int agent_supported;
37 static int server_supports_filtering;
38 -static struct lock_file shallow_lock;
38 +static struct shallow_lock shallow_lock;
39 static const char *alternate_shallow_file;
40 static struct strbuf fsck_msg_types = STRBUF_INIT;
41
shallow.c
+11 -11
@@ -92,16 +92,16 @@ static void reset_repository_shallow(struct repository *r)
92 stat_validity_clear(r->parsed_objects->shallow_stat);
93 }
94
95 -int commit_shallow_file(struct repository *r, struct lock_file *lk)
95 +int commit_shallow_file(struct repository *r, struct shallow_lock *lk)
96 {
97 - int res = commit_lock_file(lk);
97 + int res = commit_lock_file(&lk->lock);
98 reset_repository_shallow(r);
99 return res;
100 }
101
102 -void rollback_shallow_file(struct repository *r, struct lock_file *lk)
102 +void rollback_shallow_file(struct repository *r, struct shallow_lock *lk)
103 {
104 - rollback_lock_file(lk);
104 + rollback_lock_file(&lk->lock);
105 reset_repository_shallow(r);
106 }
107
@@ -366,22 +366,22 @@ const char *setup_temporary_shallow(const struct oid_array *extra)
366 return "";
367 }
368
369 -void setup_alternate_shallow(struct lock_file *shallow_lock,
369 +void setup_alternate_shallow(struct shallow_lock *shallow_lock,
370 const char **alternate_shallow_file,
371 const struct oid_array *extra)
372 {
373 struct strbuf sb = STRBUF_INIT;
374 int fd;
375
376 - fd = hold_lock_file_for_update(shallow_lock,
376 + fd = hold_lock_file_for_update(&shallow_lock->lock,
377 git_path_shallow(the_repository),
378 LOCK_DIE_ON_ERROR);
379 check_shallow_file_for_update(the_repository);
380 if (write_shallow_commits(&sb, 0, extra)) {
381 if (write_in_full(fd, sb.buf, sb.len) < 0)
382 die_errno("failed to write to %s",
383 - get_lock_file_path(shallow_lock));
384 - *alternate_shallow_file = get_lock_file_path(shallow_lock);
383 + get_lock_file_path(&shallow_lock->lock));
384 + *alternate_shallow_file = get_lock_file_path(&shallow_lock->lock);
385 } else
386 /*
387 * is_repository_shallow() sees empty string as "no
@@ -414,7 +414,7 @@ void advertise_shallow_grafts(int fd)
414 */
415 void prune_shallow(unsigned options)
416 {
417 - struct lock_file shallow_lock = LOCK_INIT;
417 + struct shallow_lock shallow_lock = SHALLOW_LOCK_INIT;
418 struct strbuf sb = STRBUF_INIT;
419 unsigned flags = SEEN_ONLY;
420 int fd;
@@ -428,14 +428,14 @@ void prune_shallow(unsigned options)
428 strbuf_release(&sb);
429 return;
430 }
431 - fd = hold_lock_file_for_update(&shallow_lock,
431 + fd = hold_lock_file_for_update(&shallow_lock.lock,
432 git_path_shallow(the_repository),
433 LOCK_DIE_ON_ERROR);
434 check_shallow_file_for_update(the_repository);
435 if (write_shallow_commits_1(&sb, 0, NULL, flags)) {
436 if (write_in_full(fd, sb.buf, sb.len) < 0)
437 die_errno("failed to write to %s",
438 - get_lock_file_path(&shallow_lock));
438 + get_lock_file_path(&shallow_lock.lock));
439 commit_shallow_file(the_repository, &shallow_lock);
440 } else {
441 unlink(git_path_shallow(the_repository));
shallow.h
+18 -3
@@ -10,10 +10,25 @@ void set_alternate_shallow_file(struct repository *r, const char *path, int over
10 int register_shallow(struct repository *r, const struct object_id *oid);
11 int unregister_shallow(const struct object_id *oid);
12 int is_repository_shallow(struct repository *r);
13 +
14 +/*
15 + * Lock for updating the $GIT_DIR/shallow file.
16 + *
17 + * Use `commit_shallow_file()` to commit an update, or
18 + * `rollback_shallow_file()` to roll it back. In either case, any
19 + * in-memory cached information about which commits are shallow will be
20 + * appropriately invalidated so that future operations reflect the new
21 + * state.
22 + */
23 +struct shallow_lock {
24 + struct lock_file lock;
25 +};
26 +#define SHALLOW_LOCK_INIT { LOCK_INIT }
27 +
28 /* commit $GIT_DIR/shallow and reset stat-validity checks */
14 -int commit_shallow_file(struct repository *r, struct lock_file *lk);
29 +int commit_shallow_file(struct repository *r, struct shallow_lock *lk);
30 /* rollback $GIT_DIR/shallow and reset stat-validity checks */
16 -void rollback_shallow_file(struct repository *r, struct lock_file *lk);
31 +void rollback_shallow_file(struct repository *r, struct shallow_lock *lk);
32
33 struct commit_list *get_shallow_commits(struct object_array *heads,
34 int depth, int shallow_flag, int not_shallow_flag);
@@ -22,7 +37,7 @@ struct commit_list *get_shallow_commits_by_rev_list(
37 int write_shallow_commits(struct strbuf *out, int use_pack_protocol,
38 const struct oid_array *extra);
39
25 -void setup_alternate_shallow(struct lock_file *shallow_lock,
40 +void setup_alternate_shallow(struct shallow_lock *shallow_lock,
41 const char **alternate_shallow_file,
42 const struct oid_array *extra);
43