read-cache.c 9.23 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5
/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 */
6
#include <stdarg.h>
7 8 9
#include "cache.h"

struct cache_entry **active_cache = NULL;
10
unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0;
11

12 13 14 15
int cache_match_stat(struct cache_entry *ce, struct stat *st)
{
	unsigned int changed = 0;

16 17 18
	switch (ntohl(ce->ce_mode) & S_IFMT) {
	case S_IFREG:
		changed |= !S_ISREG(st->st_mode) ? TYPE_CHANGED : 0;
19 20 21
		/* We consider only the owner x bit to be relevant for "mode changes" */
		if (0100 & (ntohl(ce->ce_mode) ^ st->st_mode))
			changed |= MODE_CHANGED;
22 23 24 25 26 27 28
		break;
	case S_IFLNK:
		changed |= !S_ISLNK(st->st_mode) ? TYPE_CHANGED : 0;
		break;
	default:
		die("internal error: ce_mode is %o", ntohl(ce->ce_mode));
	}
29
	if (ce->ce_mtime.sec != htonl(st->st_mtime))
30
		changed |= MTIME_CHANGED;
31 32 33
	if (ce->ce_ctime.sec != htonl(st->st_ctime))
		changed |= CTIME_CHANGED;

34
#ifdef NSEC
35 36 37 38 39
	/*
	 * nsec seems unreliable - not all filesystems support it, so
	 * as long as it is in the inode cache you get right nsec
	 * but after it gets flushed, you get zero nsec.
	 */
40
	if (ce->ce_mtime.nsec != htonl(st->st_mtim.tv_nsec))
41
		changed |= MTIME_CHANGED;
42
	if (ce->ce_ctime.nsec != htonl(st->st_ctim.tv_nsec))
43
		changed |= CTIME_CHANGED;
44 45 46 47
#endif	

	if (ce->ce_uid != htonl(st->st_uid) ||
	    ce->ce_gid != htonl(st->st_gid))
48
		changed |= OWNER_CHANGED;
49 50
	if (ce->ce_dev != htonl(st->st_dev) ||
	    ce->ce_ino != htonl(st->st_ino))
51
		changed |= INODE_CHANGED;
52
	if (ce->ce_size != htonl(st->st_size))
53 54 55 56
		changed |= DATA_CHANGED;
	return changed;
}

57
int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2)
58
{
59 60
	int len1 = flags1 & CE_NAMEMASK;
	int len2 = flags2 & CE_NAMEMASK;
61 62 63 64 65 66 67 68 69 70
	int len = len1 < len2 ? len1 : len2;
	int cmp;

	cmp = memcmp(name1, name2, len);
	if (cmp)
		return cmp;
	if (len1 < len2)
		return -1;
	if (len1 > len2)
		return 1;
71 72 73 74
	if (flags1 < flags2)
		return -1;
	if (flags1 > flags2)
		return 1;
75 76 77 78 79 80 81 82 83 84 85 86
	return 0;
}

int cache_name_pos(const char *name, int namelen)
{
	int first, last;

	first = 0;
	last = active_nr;
	while (last > first) {
		int next = (last + first) >> 1;
		struct cache_entry *ce = active_cache[next];
87
		int cmp = cache_name_compare(name, namelen, ce->name, htons(ce->ce_flags));
88
		if (!cmp)
89
			return next;
90 91 92 93 94 95
		if (cmp < 0) {
			last = next;
			continue;
		}
		first = next+1;
	}
96
	return -first-1;
97 98
}

99
/* Remove entry, return true if there are more entries to go.. */
100
int remove_entry_at(int pos)
101
{
102
	active_cache_changed = 1;
103 104 105 106 107 108 109
	active_nr--;
	if (pos >= active_nr)
		return 0;
	memmove(active_cache + pos, active_cache + pos + 1, (active_nr - pos) * sizeof(struct cache_entry *));
	return 1;
}

110 111 112
int remove_file_from_cache(char *path)
{
	int pos = cache_name_pos(path, strlen(path));
113 114 115
	if (pos < 0)
		pos = -pos-1;
	while (pos < active_nr && !strcmp(active_cache[pos]->name, path))
116
		remove_entry_at(pos);
117 118 119
	return 0;
}

120
int same_name(struct cache_entry *a, struct cache_entry *b)
121 122 123 124 125
{
	int len = ce_namelen(a);
	return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
/* We may be in a situation where we already have path/file and path
 * is being added, or we already have path and path/file is being
 * added.  Either one would result in a nonsense tree that has path
 * twice when git-write-tree tries to write it out.  Prevent it.
 */
static int check_file_directory_conflict(const struct cache_entry *ce)
{
	int pos;
	const char *path = ce->name;
	int namelen = strlen(path);
	int stage = ce_stage(ce);
	char *pathbuf = xmalloc(namelen + 1);
	char *cp;

	memcpy(pathbuf, path, namelen + 1);

	/*
	 * We are inserting path/file.  Do they have path registered at
	 * the same stage?  We need to do this for all the levels of our
	 * subpath.
	 */
	cp = pathbuf;
	while (1) {
		char *ep = strchr(cp, '/');
		if (ep == 0)
			break;
		*ep = 0;    /* first cut it at slash */
		pos = cache_name_pos(pathbuf,
				     htons(create_ce_flags(ep-cp, stage)));
		if (0 <= pos) {
			/* Our leading path component is registered as a file,
			 * and we are trying to make it a directory.  This is
			 * bad.
			 */
			free(pathbuf);
			return -1;
		}
		*ep = '/';  /* then restore it and go downwards */
		cp = ep + 1;
	}
	free(pathbuf);

	/* Do we have an entry in the cache that makes our path a prefix
	 * of it?  That is, are we creating a file where they already expect
	 * a directory there?
	 */
	pos = cache_name_pos(path,
			     htons(create_ce_flags(namelen, stage)));

	/* (0 <= pos) cannot happen because add_cache_entry()
	 * should have taken care of that case.
	 */
	pos = -pos-1;

	/* pos would point at an existing entry that would come immediately
	 * after our path.  It could be the same as our path in higher stage,
	 * or different path but in a lower stage.
	 *
	 * E.g. when we are inserting path at stage 2,
	 *
	 *        1 path
	 * pos->  3 path
	 *        2 path/file
	 *        3 path/file
	 *
	 * We need to examine pos, ignore it because it is at different
	 * stage, examine next to find the path/file at stage 2, and
	 * complain.
	 */

	while (pos < active_nr) {
		struct cache_entry *other = active_cache[pos];
		if (strncmp(other->name, path, namelen))
			break; /* it is not our "subdirectory" anymore */
		if ((ce_stage(other) == stage) && other->name[namelen] == '/')
			return -1;
		pos++;
	}

	return 0;
}

208
int add_cache_entry(struct cache_entry *ce, int ok_to_add)
209 210 211
{
	int pos;

212
	pos = cache_name_pos(ce->name, htons(ce->ce_flags));
213 214

	/* existing match? Just replace it */
215
	if (pos >= 0) {
216
		active_cache_changed = 1;
217
		active_cache[pos] = ce;
218 219
		return 0;
	}
220
	pos = -pos-1;
221

222 223 224 225 226 227 228 229 230 231 232 233
	/*
	 * Inserting a merged entry ("stage 0") into the index
	 * will always replace all non-merged entries..
	 */
	if (pos < active_nr && ce_stage(ce) == 0) {
		while (same_name(active_cache[pos], ce)) {
			ok_to_add = 1;
			if (!remove_entry_at(pos))
				break;
		}
	}

234 235 236
	if (!ok_to_add)
		return -1;

237 238 239
	if (check_file_directory_conflict(ce))
		return -1;

240 241 242
	/* Make sure the array is big enough .. */
	if (active_nr == active_alloc) {
		active_alloc = alloc_nr(active_alloc);
243
		active_cache = xrealloc(active_cache, active_alloc * sizeof(struct cache_entry *));
244 245 246 247 248 249 250
	}

	/* Add it in.. */
	active_nr++;
	if (active_nr > pos)
		memmove(active_cache + pos + 1, active_cache + pos, (active_nr - pos - 1) * sizeof(ce));
	active_cache[pos] = ce;
251
	active_cache_changed = 1;
252 253 254
	return 0;
}

255 256 257 258 259
static int verify_hdr(struct cache_header *hdr, unsigned long size)
{
	SHA_CTX c;
	unsigned char sha1[20];

260
	if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
261
		return error("bad signature");
262 263
	if (hdr->hdr_version != htonl(2))
		return error("bad index version");
264
	SHA1_Init(&c);
265
	SHA1_Update(&c, hdr, size - 20);
266
	SHA1_Final(sha1, &c);
267 268
	if (memcmp(sha1, (void *)hdr + size - 20, 20))
		return error("bad index file sha1 signature");
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
	return 0;
}

int read_cache(void)
{
	int fd, i;
	struct stat st;
	unsigned long size, offset;
	void *map;
	struct cache_header *hdr;

	errno = EBUSY;
	if (active_cache)
		return error("more than one cachefile");
	errno = ENOENT;
284
	fd = open(get_index_file(), O_RDONLY);
285 286 287
	if (fd < 0)
		return (errno == ENOENT) ? 0 : error("open failed");

288
	size = 0; // avoid gcc warning
289 290 291 292
	map = (void *)-1;
	if (!fstat(fd, &st)) {
		size = st.st_size;
		errno = EINVAL;
293
		if (size >= sizeof(struct cache_header) + 20)
294
			map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
295 296 297 298 299 300 301 302 303
	}
	close(fd);
	if (-1 == (int)(long)map)
		return error("mmap failed");

	hdr = map;
	if (verify_hdr(hdr, size) < 0)
		goto unmap;

304
	active_nr = ntohl(hdr->hdr_entries);
305 306 307 308
	active_alloc = alloc_nr(active_nr);
	active_cache = calloc(active_alloc, sizeof(struct cache_entry *));

	offset = sizeof(*hdr);
309
	for (i = 0; i < active_nr; i++) {
310 311 312 313 314 315 316 317 318 319 320 321
		struct cache_entry *ce = map + offset;
		offset = offset + ce_size(ce);
		active_cache[i] = ce;
	}
	return active_nr;

unmap:
	munmap(map, size);
	errno = EINVAL;
	return error("verify header failed");
}

322 323 324 325
#define WRITE_BUFFER_SIZE 8192
static char write_buffer[WRITE_BUFFER_SIZE];
static unsigned long write_buffer_len;

326
static int ce_write(SHA_CTX *context, int fd, void *data, unsigned int len)
327 328 329 330 331 332 333 334 335
{
	while (len) {
		unsigned int buffered = write_buffer_len;
		unsigned int partial = WRITE_BUFFER_SIZE - buffered;
		if (partial > len)
			partial = len;
		memcpy(write_buffer + buffered, data, partial);
		buffered += partial;
		if (buffered == WRITE_BUFFER_SIZE) {
336
			SHA1_Update(context, write_buffer, WRITE_BUFFER_SIZE);
337 338 339 340 341 342 343 344 345 346 347
			if (write(fd, write_buffer, WRITE_BUFFER_SIZE) != WRITE_BUFFER_SIZE)
				return -1;
			buffered = 0;
		}
		write_buffer_len = buffered;
		len -= partial;
		data += partial;
 	}
 	return 0;
}

348
static int ce_flush(SHA_CTX *context, int fd)
349 350
{
	unsigned int left = write_buffer_len;
351

352 353
	if (left) {
		write_buffer_len = 0;
354
		SHA1_Update(context, write_buffer, left);
355
	}
356 357 358 359 360 361

	/* Append the SHA1 signature at the end */
	SHA1_Final(write_buffer + left, context);
	left += 20;
	if (write(fd, write_buffer, left) != left)
		return -1;
362 363 364
	return 0;
}

365 366 367 368 369 370
int write_cache(int newfd, struct cache_entry **cache, int entries)
{
	SHA_CTX c;
	struct cache_header hdr;
	int i;

371
	hdr.hdr_signature = htonl(CACHE_SIGNATURE);
372
	hdr.hdr_version = htonl(2);
373
	hdr.hdr_entries = htonl(entries);
374 375

	SHA1_Init(&c);
376
	if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
377 378 379 380
		return -1;

	for (i = 0; i < entries; i++) {
		struct cache_entry *ce = cache[i];
381
		if (ce_write(&c, newfd, ce, ce_size(ce)) < 0)
382 383
			return -1;
	}
384
	return ce_flush(&c, newfd);
385
}