Commit a29c6b5f by Vicent Marti

odb: Do not allow duplicate on-disk backends

parent 2b63dbfb
...@@ -29,7 +29,8 @@ typedef struct ...@@ -29,7 +29,8 @@ typedef struct
{ {
git_odb_backend *backend; git_odb_backend *backend;
int priority; int priority;
int is_alternate; bool is_alternate;
ino_t disk_inode;
} backend_internal; } backend_internal;
size_t git_odb__cache_size = GIT_DEFAULT_CACHE_SIZE; size_t git_odb__cache_size = GIT_DEFAULT_CACHE_SIZE;
...@@ -365,7 +366,9 @@ int git_odb_new(git_odb **out) ...@@ -365,7 +366,9 @@ int git_odb_new(git_odb **out)
return 0; return 0;
} }
static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int priority, int is_alternate) static int add_backend_internal(
git_odb *odb, git_odb_backend *backend,
int priority, bool is_alternate, ino_t disk_inode)
{ {
backend_internal *internal; backend_internal *internal;
...@@ -382,6 +385,7 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio ...@@ -382,6 +385,7 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio
internal->backend = backend; internal->backend = backend;
internal->priority = priority; internal->priority = priority;
internal->is_alternate = is_alternate; internal->is_alternate = is_alternate;
internal->disk_inode = disk_inode;
if (git_vector_insert(&odb->backends, internal) < 0) { if (git_vector_insert(&odb->backends, internal) < 0) {
git__free(internal); git__free(internal);
...@@ -395,26 +399,41 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio ...@@ -395,26 +399,41 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio
int git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority) int git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority)
{ {
return add_backend_internal(odb, backend, priority, 0); return add_backend_internal(odb, backend, priority, false, 0);
} }
int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority) int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
{ {
return add_backend_internal(odb, backend, priority, 1); return add_backend_internal(odb, backend, priority, true, 0);
} }
static int add_default_backends(git_odb *db, const char *objects_dir, int as_alternates, int alternate_depth) static int add_default_backends(
git_odb *db, const char *objects_dir,
bool as_alternates, int alternate_depth)
{ {
size_t i;
struct stat st;
git_odb_backend *loose, *packed; git_odb_backend *loose, *packed;
if (p_stat(objects_dir, &st) < 0) {
giterr_set(GITERR_ODB, "Failed to load object database in '%s'", objects_dir);
return -1;
}
for (i = 0; i < db->backends.length; ++i) {
backend_internal *backend = git_vector_get(&db->backends, i);
if (backend->disk_inode == st.st_ino)
return 0;
}
/* add the loose object backend */ /* add the loose object backend */
if (git_odb_backend_loose(&loose, objects_dir, -1, 0) < 0 || if (git_odb_backend_loose(&loose, objects_dir, -1, 0) < 0 ||
add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates) < 0) add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, st.st_ino) < 0)
return -1; return -1;
/* add the packed file backend */ /* add the packed file backend */
if (git_odb_backend_pack(&packed, objects_dir) < 0 || if (git_odb_backend_pack(&packed, objects_dir) < 0 ||
add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates) < 0) add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, st.st_ino) < 0)
return -1; return -1;
return load_alternates(db, objects_dir, alternate_depth); return load_alternates(db, objects_dir, alternate_depth);
...@@ -464,7 +483,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ ...@@ -464,7 +483,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_
alternate = git_buf_cstr(&alternates_path); alternate = git_buf_cstr(&alternates_path);
} }
if ((result = add_default_backends(odb, alternate, 1, alternate_depth + 1)) < 0) if ((result = add_default_backends(odb, alternate, true, alternate_depth + 1)) < 0)
break; break;
} }
...@@ -476,7 +495,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_ ...@@ -476,7 +495,7 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_
int git_odb_add_disk_alternate(git_odb *odb, const char *path) int git_odb_add_disk_alternate(git_odb *odb, const char *path)
{ {
return add_default_backends(odb, path, 1, 0); return add_default_backends(odb, path, true, 0);
} }
int git_odb_open(git_odb **out, const char *objects_dir) int git_odb_open(git_odb **out, const char *objects_dir)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment