From 473935188cc9b0363b30553f23d816231a66cb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 7 Nov 2011 09:59:24 +0700 Subject: verify_packfile(): check as many object as possible in a pack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit verify_packfile() checks for whole pack integerity first, then each object individually. Once we get past whole pack check, we can identify all objects in the pack. If there's an error with one object, we should continue to check the next objects to salvage as many objects as possible instead of stopping the process. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- pack-check.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'pack-check.c') diff --git a/pack-check.c b/pack-check.c index 0c19b6e5a5..7ac9b3a681 100644 --- a/pack-check.c +++ b/pack-check.c @@ -113,18 +113,13 @@ static int verify_packfile(struct packed_git *p, p->pack_name, (uintmax_t)offset); } data = unpack_entry(p, entries[i].offset, &type, &size); - if (!data) { + if (!data) err = error("cannot unpack %s from %s at offset %"PRIuMAX"", sha1_to_hex(entries[i].sha1), p->pack_name, (uintmax_t)entries[i].offset); - break; - } - if (check_sha1_signature(entries[i].sha1, data, size, typename(type))) { + else if (check_sha1_signature(entries[i].sha1, data, size, typename(type))) err = error("packed %s from %s is corrupt", sha1_to_hex(entries[i].sha1), p->pack_name); - free(data); - break; - } free(data); } free(entries); -- cgit v1.2.3 From c9486eb04dd99fc00df3e68f9b908f9ad7ff9728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 7 Nov 2011 09:59:25 +0700 Subject: fsck: avoid reading every object twice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During verify_pack() all objects are read for SHA-1 check. Then fsck_sha1() is called on every object, which read the object again (fsck_sha1 -> parse_object -> read_sha1_file). Avoid reading an object twice, do fsck_sha1 while we have an object uncompressed data in verify_pack. On git.git, with this patch I got: $ /usr/bin/time ./git fsck >/dev/null 98.97user 0.90system 1:40.01elapsed 99%CPU (0avgtext+0avgdata 616624maxresident)k 0inputs+0outputs (0major+194186minor)pagefaults 0swaps Without it: $ /usr/bin/time ./git fsck >/dev/null 231.23user 2.35system 3:53.82elapsed 99%CPU (0avgtext+0avgdata 636688maxresident)k 0inputs+0outputs (0major+461629minor)pagefaults 0swaps Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- pack-check.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'pack-check.c') diff --git a/pack-check.c b/pack-check.c index 7ac9b3a681..3b48b86156 100644 --- a/pack-check.c +++ b/pack-check.c @@ -42,7 +42,8 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, } static int verify_packfile(struct packed_git *p, - struct pack_window **w_curs) + struct pack_window **w_curs, + verify_fn fn) { off_t index_size = p->index_size; const unsigned char *index_base = p->index_data; @@ -120,6 +121,12 @@ static int verify_packfile(struct packed_git *p, else if (check_sha1_signature(entries[i].sha1, data, size, typename(type))) err = error("packed %s from %s is corrupt", sha1_to_hex(entries[i].sha1), p->pack_name); + else if (fn) { + int eaten = 0; + fn(entries[i].sha1, type, size, data, &eaten); + if (eaten) + data = NULL; + } free(data); } free(entries); @@ -150,7 +157,7 @@ int verify_pack_index(struct packed_git *p) return err; } -int verify_pack(struct packed_git *p) +int verify_pack(struct packed_git *p, verify_fn fn) { int err = 0; struct pack_window *w_curs = NULL; @@ -159,7 +166,7 @@ int verify_pack(struct packed_git *p) if (!p->index_data) return -1; - err |= verify_packfile(p, &w_curs); + err |= verify_packfile(p, &w_curs, fn); unuse_pack(&w_curs); return err; -- cgit v1.2.3 From 1e49f22f07881dffc04f8f09d4ad4e4a65b85b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Th=C3=A1i=20Ng=E1=BB=8Dc=20Duy?= Date: Mon, 7 Nov 2011 09:59:26 +0700 Subject: fsck: print progress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fsck is usually a long process and it would be nice if it prints progress from time to time. Progress meter is not printed when --verbose is given because --verbose prints a lot, there's no need for "alive" indicator. Progress meter may provide "% complete" information but it would be lost anyway in the flood of text. Signed-off-by: Nguyễn Thái Ngọc Duy Signed-off-by: Junio C Hamano --- pack-check.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'pack-check.c') diff --git a/pack-check.c b/pack-check.c index 3b48b86156..63a595c45c 100644 --- a/pack-check.c +++ b/pack-check.c @@ -1,6 +1,7 @@ #include "cache.h" #include "pack.h" #include "pack-revindex.h" +#include "progress.h" struct idx_entry { off_t offset; @@ -43,7 +44,9 @@ int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, static int verify_packfile(struct packed_git *p, struct pack_window **w_curs, - verify_fn fn) + verify_fn fn, + struct progress *progress, uint32_t base_count) + { off_t index_size = p->index_size; const unsigned char *index_base = p->index_data; @@ -127,8 +130,12 @@ static int verify_packfile(struct packed_git *p, if (eaten) data = NULL; } + if (((base_count + i) & 1023) == 0) + display_progress(progress, base_count + i); free(data); + } + display_progress(progress, base_count + i); free(entries); return err; @@ -157,7 +164,8 @@ int verify_pack_index(struct packed_git *p) return err; } -int verify_pack(struct packed_git *p, verify_fn fn) +int verify_pack(struct packed_git *p, verify_fn fn, + struct progress *progress, uint32_t base_count) { int err = 0; struct pack_window *w_curs = NULL; @@ -166,7 +174,7 @@ int verify_pack(struct packed_git *p, verify_fn fn) if (!p->index_data) return -1; - err |= verify_packfile(p, &w_curs, fn); + err |= verify_packfile(p, &w_curs, fn, progress, base_count); unuse_pack(&w_curs); return err; -- cgit v1.2.3