git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 02/24] read-cache: split index file version specific functionality

From
Thomas Gummerer <t.gummerer@gmail.com>
Date
Nov 27, 2013, 12:00 UTC
Message-ID
<1385553659-9928-3-git-send-email-t.gummerer@gmail.com>
In-Reply-To
<1385553659-9928-1-git-send-email-t.gummerer@gmail.com>

Split index file version specific functionality to their own functions, to prepare for moving the index file version specific parts to their own file. This makes it easier to add a new index file format later.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
---
 read-cache.c | 114 ++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 74 insertions(+), 40 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index 33dd676..5a8f405 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1269,10 +1269,8 @@ struct ondisk_cache_entry_extended {
 			    ondisk_cache_entry_extended_size(ce_namelen(ce)) : \
 			    ondisk_cache_entry_size(ce_namelen(ce)))
 
-static int verify_hdr(struct cache_header *hdr, unsigned long size)
+static int verify_hdr_version(struct cache_header *hdr, unsigned long size)
 {
-	git_SHA_CTX c;
-	unsigned char sha1[20];
 	int hdr_version;
 
 	if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
@@ -1280,10 +1278,21 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
 	hdr_version = ntohl(hdr->hdr_version);
 	if (hdr_version < INDEX_FORMAT_LB || INDEX_FORMAT_UB < hdr_version)
 		return error("bad index version %d", hdr_version);
+	return 0;
+}
+
+static int verify_hdr(void *mmap, unsigned long size)
+{
+	git_SHA_CTX c;
+	unsigned char sha1[20];
+
+	if (size < sizeof(struct cache_header) + 20)
+		die("index file smaller than expected");
+
 	git_SHA1_Init(&c);
-	git_SHA1_Update(&c, hdr, size - 20);
+	git_SHA1_Update(&c, mmap, size - 20);
 	git_SHA1_Final(sha1, &c);
-	if (hashcmp(sha1, (unsigned char *)hdr + size - 20))
+	if (hashcmp(sha1, (unsigned char *)mmap + size - 20))
 		return error("bad index file sha1 signature");
 	return 0;
 }
@@ -1425,44 +1434,14 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk,
 	return ce;
 }
 
-/* remember to discard_cache() before reading a different cache! */
-int read_index_from(struct index_state *istate, const char *path)
+static int read_index_v2(struct index_state *istate, void *mmap, unsigned long mmap_size)
 {
-	int fd, i;
-	struct stat st;
+	int i;
 	unsigned long src_offset;
 	struct cache_header *hdr;
-	void *mmap;
-	size_t mmap_size;
 	struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
 
-	if (istate->initialized)
-		return istate->cache_nr;
-
-	istate->timestamp.sec = 0;
-	istate->timestamp.nsec = 0;
-	fd = open(path, O_RDONLY);
-	if (fd < 0) {
-		if (errno == ENOENT)
-			return 0;
-		die_errno("index file open failed");
-	}
-
-	if (fstat(fd, &st))
-		die_errno("cannot stat the open index");
-
-	mmap_size = xsize_t(st.st_size);
-	if (mmap_size < sizeof(struct cache_header) + 20)
-		die("index file smaller than expected");
-
-	mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
-	if (mmap == MAP_FAILED)
-		die_errno("unable to map index file");
-	close(fd);
-
 	hdr = mmap;
-	if (verify_hdr(hdr, mmap_size) < 0)
-		goto unmap;
 
 	istate->version = ntohl(hdr->hdr_version);
 	istate->cache_nr = ntohl(hdr->hdr_entries);
@@ -1488,8 +1467,6 @@ int read_index_from(struct index_state *istate, const char *path)
 		src_offset += consumed;
 	}
 	strbuf_release(&previous_name_buf);
-	istate->timestamp.sec = st.st_mtime;
-	istate->timestamp.nsec = ST_MTIME_NSEC(st);
 
 	while (src_offset <= mmap_size - 20 - 8) {
 		/* After an array of active_nr index entries,
@@ -1509,6 +1486,58 @@ int read_index_from(struct index_state *istate, const char *path)
 		src_offset += 8;
 		src_offset += extsize;
 	}
+	return 0;
+unmap:
+	munmap(mmap, mmap_size);
+	die("index file corrupt");
+}
+
+/* remember to discard_cache() before reading a different cache! */
+int read_index_from(struct index_state *istate, const char *path)
+{
+	int fd;
+	struct stat st;
+	struct cache_header *hdr;
+	void *mmap;
+	size_t mmap_size;
+
+	errno = EBUSY;
+	if (istate->initialized)
+		return istate->cache_nr;
+
+	errno = ENOENT;
+	istate->timestamp.sec = 0;
+	istate->timestamp.nsec = 0;
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		if (errno == ENOENT)
+			return 0;
+		die_errno("index file open failed");
+	}
+
+	if (fstat(fd, &st))
+		die_errno("cannot stat the open index");
+
+	errno = EINVAL;
+	mmap_size = xsize_t(st.st_size);
+	if (mmap_size < sizeof(struct cache_header) + 20)
+		die("index file smaller than expected");
+
+	mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+	close(fd);
+	if (mmap == MAP_FAILED)
+		die_errno("unable to map index file");
+
+	hdr = mmap;
+	if (verify_hdr_version(hdr, mmap_size) < 0)
+		goto unmap;
+
+	if (verify_hdr(mmap, mmap_size) < 0)
+		goto unmap;
+
+	read_index_v2(istate, mmap, mmap_size);
+	istate->timestamp.sec = st.st_mtime;
+	istate->timestamp.nsec = ST_MTIME_NSEC(st);
 	munmap(mmap, mmap_size);
 	return istate->cache_nr;
 
@@ -1772,7 +1801,7 @@ void update_index_if_able(struct index_state *istate, struct lock_file *lockfile
 		rollback_lock_file(lockfile);
 }
 
-int write_index(struct index_state *istate, int newfd)
+static int write_index_v2(struct index_state *istate, int newfd)
 {
 	git_SHA_CTX c;
 	struct cache_header hdr;
@@ -1864,6 +1893,11 @@ int write_index(struct index_state *istate, int newfd)
 	return 0;
 }
 
+int write_index(struct index_state *istate, int newfd)
+{
+	return write_index_v2(istate, newfd);
+}
+
 /*
  * Read the index file that is potentially unmerged into given
  * index_state, dropping any unmerged entries.  Returns true if
-- 
1.8.4.2
Previous: Thomas GummererNext: Thomas Gummerer
Message 3 of 41 in “Index-v5”
  1. 00/24 Index-v5Thomas Gummerer, Nov 27, 2013
  2. 01/24 t2104: Don't fail for index versions other than [23]Thomas Gummerer, Nov 27, 2013
  3. 02/24 read-cache: split index file version specific functionalityThomas Gummerer, Nov 27, 2013
  4. 03/24 read-cache: move index v2 specific functions to their own fileThomas Gummerer, Nov 27, 2013
  5. 04/24 read-cache: Re-read index if index file changedThomas Gummerer, Nov 27, 2013
  6. 05/24 add documentation for the index apiThomas Gummerer, Nov 27, 2013
  7. 06/24 read-cache: add index reading apiThomas Gummerer, Nov 27, 2013
  8. 07/24 make sure partially read index is not changedThomas Gummerer, Nov 27, 2013
  9. 08/24 grep.c: use index apiThomas Gummerer, Nov 27, 2013
  10. 09/24 ls-files.c: use index apiThomas Gummerer, Nov 27, 2013
  11. Duy NguyenNov 30, 2013
  12. Thomas GummererNov 30, 2013
  13. Antoine PelisseNov 30, 2013
  14. Thomas GummererNov 30, 2013
  15. 10/24 documentation: add documentation of the index-v5 file formatThomas Gummerer, Nov 27, 2013
  16. 11/24 read-cache: make in-memory format aware of stat_crcThomas Gummerer, Nov 27, 2013
  17. 12/24 read-cache: read index-v5Thomas Gummerer, Nov 27, 2013
  18. Duy NguyenNov 30, 2013
  19. Thomas GummererNov 30, 2013
  20. Antoine PelisseNov 30, 2013
  21. Thomas GummererNov 30, 2013
  22. Antoine PelisseNov 30, 2013
  23. Thomas GummererNov 30, 2013
  24. 13/24 read-cache: read resolve-undo dataThomas Gummerer, Nov 27, 2013
  25. 14/24 read-cache: read cache-tree in index-v5Thomas Gummerer, Nov 27, 2013
  26. 15/24 read-cache: write index-v5Thomas Gummerer, Nov 27, 2013
  27. 16/24 read-cache: write index-v5 cache-tree dataThomas Gummerer, Nov 27, 2013
  28. 17/24 read-cache: write resolve-undo data for index-v5Thomas Gummerer, Nov 27, 2013
  29. 18/24 update-index.c: rewrite index when index-version is givenThomas Gummerer, Nov 27, 2013
  30. 19/24 p0003-index.sh: add perf test for the index formatsThomas Gummerer, Nov 27, 2013
  31. 20/24 introduce GIT_INDEX_VERSION environment variableThomas Gummerer, Nov 27, 2013
  32. Eric SunshineNov 27, 2013
  33. Junio C HamanoNov 27, 2013
  34. Thomas GummererNov 28, 2013
  35. 21/24 test-lib: allow setting the index format versionThomas Gummerer, Nov 27, 2013
  36. 22/24 t1600: add index v5 specific testsThomas Gummerer, Nov 27, 2013
  37. 23/24 POC for partial writingThomas Gummerer, Nov 27, 2013
  38. Duy NguyenNov 30, 2013
  39. Thomas GummererNov 30, 2013
  40. 24/24 perf: add partial writing testThomas Gummerer, Nov 27, 2013
  41. Thomas GummererDec 9, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.