From patchwork Mon Aug 5 16:46:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: shejialuo X-Patchwork-Id: 13753834 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B438815B57B for ; Mon, 5 Aug 2024 16:45:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722876341; cv=none; b=IuCpZb+Gfs5bFLIzkToPtcpnKxYwT3kiJv0empiDpXceWo4P0VWmGgsjI5i80cfp4gROxHV7GnMhlJKRlPWYpwAc839leQadDxZ5RT1UL34R9Ta2BuM1ntIjYM96Va7Zw9Pyk+5pqO5mHbS3LfsvQeDaXNVyirjNuy1NSgvGd0A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722876341; c=relaxed/simple; bh=d0U+zfe5Q3f7g3/LK0qr2DuDHFPH6/t3E6P5vC5/Uks=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=JFzQJKeHoarLzp/7vNBhzvK0X9Jz5NTbgEcEgSAf0isPWtekB1cHKN/Rr6LACMv4Bvs7KUbkB6ZmySPPVYbsDF52FPsj8ZepjfbyFLmNmsV3rdblidx/zfFow4pJbNWXMV4HwK/UOTqKXQz3RWwCTpdJrvuixsECGE+BXYUdpq4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=GxaIoHe/; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GxaIoHe/" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1fd9e6189d5so85097085ad.3 for ; Mon, 05 Aug 2024 09:45:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722876338; x=1723481138; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=gXSYuUIlc1sLEM0xmW8Sg4+1Dl1cviP9OhmRc0x8Q40=; b=GxaIoHe/7awUx+3RAqnBtnV3c4IUSCIWqDjhHdEo9EdfGgJW1ANPaWKOMYiNKN7X61 feMu/XPIm64GFaDNDPDkNrGWfbZmppagFp4h+t67q5xIr8hXMVAdM+Ne6P/9DSJYJxGz MCjZszlKHgtlrt8AEUnWO3NaDkRz4ytRAM96mCf5H7e3lDMB0TgsWI+zCYzwWFdl965K 6DaQJ7nyqy5k9NrRuUbUDjLDugJjYfDhrYEymYa0qp3fXzxEdfsVpGMdkxxfxmpkt0EW iDSNc1lREQrSR8u+bbcNRiVsDMEvdiWLAGg8EdGP/tjHcJ7b/JtJSX+9QATqid6qYUne NPRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722876338; x=1723481138; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=gXSYuUIlc1sLEM0xmW8Sg4+1Dl1cviP9OhmRc0x8Q40=; b=JwhYO8TK+BxHmS9qWNecDF6q8c6tpHOc5NauqrrTt2y4VNIiFiwmuB1yndGBxvpLTA zQs3AzGSZbUKUrZys0siesLmAGcCyTZEH7xTcBxANNJx86bikVYQawreRcT7U2JLmKF6 /8yYZ6RfEcGNuIYfieNRIPoBy39hVxwDIXsNaP3USQyH8R28z5mq0+DbYSuWyyovRN64 8z3CIfvnE6bBpIl3wsv8KZK5wQGsUQe+NtVHEhjkLyCARyH865JzU/z9xTArnkZ/TkE3 s0AvI17hTS6pcYIkBPTFqf+lZAKUzexrNPBeWZ2aXjUpDRk7O72WohyvsCXQauFfXjuV 2vPw== X-Gm-Message-State: AOJu0Yx62a6rkJskVk/REG63Yb8ReClGvdosLthIMd4pyyrROg0qNum6 ueB/XpVB28QrhYLbQCNSFqoGIZv2l5OE2+BvpwKjD6H8+/ZUNJBqQcHVLQ== X-Google-Smtp-Source: AGHT+IFw3yeOuiMNucL6kYdctaHr9azInUcwJJWnZqoVTV3WkNyX+SlTjJMEzHwe9dgn0r7vhiKexg== X-Received: by 2002:a17:902:d4c2:b0:1fd:73e6:83dc with SMTP id d9443c01a7336-1ff571149a9mr145922045ad.0.1722876338521; Mon, 05 Aug 2024 09:45:38 -0700 (PDT) Received: from localhost ([2605:52c0:1:4cf:6c5a:92ff:fe25:ceff]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-1ff5905b52bsm70688345ad.176.2024.08.05.09.45.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Aug 2024 09:45:38 -0700 (PDT) Date: Tue, 6 Aug 2024 00:46:06 +0800 From: shejialuo To: git@vger.kernel.org Cc: Patrick Steinhardt , Karthik Nayak , Junio C Hamano , Eric Sunshine , Justin Tobler Subject: [GSoC][PATCH v15 6/9] refs: set up ref consistency check infrastructure Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The "struct ref_store" is the base class which contains the "be" pointer which provides backend-specific functions whose interfaces are defined in the "ref_storage_be". We could reuse this polymorphism to define only one interface. For every backend, we need to provide its own function pointer. The interfaces defined in the `ref_storage_be` are carefully structured in semantic. It's organized as the five parts: 1. The name and the initialization interfaces. 2. The ref transaction interfaces. 3. The ref internal interfaces (pack, rename and copy). 4. The ref filesystem interfaces. 5. The reflog related interfaces. To keep consistent with the git-fsck(1), add a new interface named "fsck_refs_fn" to the end of "ref_storage_be". This semantic cannot be grouped into any above five categories. Explicitly add blank line to make it different from others. Last, implement placeholder functions for each ref backends. Mentored-by: Patrick Steinhardt Mentored-by: Karthik Nayak Signed-off-by: shejialuo --- refs.c | 5 +++++ refs.h | 8 ++++++++ refs/debug.c | 11 +++++++++++ refs/files-backend.c | 13 ++++++++++++- refs/packed-backend.c | 8 ++++++++ refs/refs-internal.h | 6 ++++++ refs/reftable-backend.c | 8 ++++++++ 7 files changed, 58 insertions(+), 1 deletion(-) diff --git a/refs.c b/refs.c index 915aeb4d1d..6f642dc681 100644 --- a/refs.c +++ b/refs.c @@ -318,6 +318,11 @@ int check_refname_format(const char *refname, int flags) return check_or_sanitize_refname(refname, flags, NULL); } +int refs_fsck(struct ref_store *refs, struct fsck_options *o) +{ + return refs->be->fsck(refs, o); +} + void sanitize_refname_component(const char *refname, struct strbuf *out) { if (check_or_sanitize_refname(refname, REFNAME_ALLOW_ONELEVEL, out)) diff --git a/refs.h b/refs.h index b3e39bc257..405073621a 100644 --- a/refs.h +++ b/refs.h @@ -4,6 +4,7 @@ #include "commit.h" #include "repository.h" +struct fsck_options; struct object_id; struct ref_store; struct strbuf; @@ -541,6 +542,13 @@ int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_dat */ int check_refname_format(const char *refname, int flags); +/* + * Check the reference database for consistency. Return 0 if refs and + * reflogs are consistent, and non-zero otherwise. The errors will be + * written to stderr. + */ +int refs_fsck(struct ref_store *refs, struct fsck_options *o); + /* * Apply the rules from check_refname_format, but mutate the result until it * is acceptable, and place the result in "out". diff --git a/refs/debug.c b/refs/debug.c index 547d9245b9..45e2e784a0 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -419,6 +419,15 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname, return res; } +static int debug_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; + int res = drefs->refs->be->fsck(drefs->refs, o); + trace_printf_key(&trace_refs, "fsck: %d\n", res); + return res; +} + struct ref_storage_be refs_be_debug = { .name = "debug", .init = NULL, @@ -451,4 +460,6 @@ struct ref_storage_be refs_be_debug = { .create_reflog = debug_create_reflog, .delete_reflog = debug_delete_reflog, .reflog_expire = debug_reflog_expire, + + .fsck = debug_fsck, }; diff --git a/refs/files-backend.c b/refs/files-backend.c index aa52d9be7c..4630eb1f80 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3408,6 +3408,15 @@ static int files_ref_store_remove_on_disk(struct ref_store *ref_store, return ret; } +static int files_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + struct files_ref_store *refs = + files_downcast(ref_store, REF_STORE_READ, "fsck"); + + return refs->packed_ref_store->be->fsck(refs->packed_ref_store, o); +} + struct ref_storage_be refs_be_files = { .name = "files", .init = files_ref_store_init, @@ -3434,5 +3443,7 @@ struct ref_storage_be refs_be_files = { .reflog_exists = files_reflog_exists, .create_reflog = files_create_reflog, .delete_reflog = files_delete_reflog, - .reflog_expire = files_reflog_expire + .reflog_expire = files_reflog_expire, + + .fsck = files_fsck, }; diff --git a/refs/packed-backend.c b/refs/packed-backend.c index a0666407cd..5209b0b212 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1735,6 +1735,12 @@ static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s return empty_ref_iterator_begin(); } +static int packed_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + return 0; +} + struct ref_storage_be refs_be_packed = { .name = "packed", .init = packed_ref_store_init, @@ -1762,4 +1768,6 @@ struct ref_storage_be refs_be_packed = { .create_reflog = NULL, .delete_reflog = NULL, .reflog_expire = NULL, + + .fsck = packed_fsck, }; diff --git a/refs/refs-internal.h b/refs/refs-internal.h index fa975d69aa..a905e187cd 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -4,6 +4,7 @@ #include "refs.h" #include "iterator.h" +struct fsck_options; struct ref_transaction; /* @@ -650,6 +651,9 @@ typedef int read_raw_ref_fn(struct ref_store *ref_store, const char *refname, typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refname, struct strbuf *referent); +typedef int fsck_fn(struct ref_store *ref_store, + struct fsck_options *o); + struct ref_storage_be { const char *name; ref_store_init_fn *init; @@ -677,6 +681,8 @@ struct ref_storage_be { create_reflog_fn *create_reflog; delete_reflog_fn *delete_reflog; reflog_expire_fn *reflog_expire; + + fsck_fn *fsck; }; extern struct ref_storage_be refs_be_files; diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index fbe74c239d..b5a1a526df 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -2303,6 +2303,12 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, return ret; } +static int reftable_be_fsck(struct ref_store *ref_store, + struct fsck_options *o) +{ + return 0; +} + struct ref_storage_be refs_be_reftable = { .name = "reftable", .init = reftable_be_init, @@ -2330,4 +2336,6 @@ struct ref_storage_be refs_be_reftable = { .create_reflog = reftable_be_create_reflog, .delete_reflog = reftable_be_delete_reflog, .reflog_expire = reftable_be_reflog_expire, + + .fsck = reftable_be_fsck, };