{
unsigned int changed = 0;
- /* 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. */
- if (ce->mtime.sec != (unsigned int)st->st_mtim.tv_sec
-#ifdef NSEC
- || ce->mtime.nsec != (unsigned int)st->st_mtim.tv_nsec
-#endif
- )
+ if (ce->ce_mtime.sec != htonl(st->st_mtime))
changed |= MTIME_CHANGED;
- if (ce->ctime.sec != (unsigned int)st->st_ctim.tv_sec
+ if (ce->ce_ctime.sec != htonl(st->st_ctime))
+ changed |= CTIME_CHANGED;
+
#ifdef NSEC
- || ce->ctime.nsec != (unsigned int)st->st_ctim.tv_nsec
-#endif
- )
+ /*
+ * 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.
+ */
+ if (ce->ce_mtime.nsec != htonl(st->st_mtim.tv_nsec)
+ changed |= MTIME_CHANGED;
+ if (ce->ce_ctime.nsec != htonl(st->st_ctim.tv_nsec)
changed |= CTIME_CHANGED;
- if (ce->st_uid != (unsigned int)st->st_uid ||
- ce->st_gid != (unsigned int)st->st_gid)
+#endif
+
+ if (ce->ce_uid != htonl(st->st_uid) ||
+ ce->ce_gid != htonl(st->st_gid))
changed |= OWNER_CHANGED;
- if (ce->st_mode != (unsigned int)st->st_mode)
+ /* 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;
- if (ce->st_dev != (unsigned int)st->st_dev ||
- ce->st_ino != (unsigned int)st->st_ino)
+ if (ce->ce_dev != htonl(st->st_dev) ||
+ ce->ce_ino != htonl(st->st_ino))
changed |= INODE_CHANGED;
- if (ce->st_size != (unsigned int)st->st_size)
+ if (ce->ce_size != htonl(st->st_size))
changed |= DATA_CHANGED;
return changed;
}
-int cache_name_compare(const char *name1, int len1, const char *name2, int len2)
+int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2)
{
+ int len1 = flags1 & CE_NAMEMASK;
+ int len2 = flags2 & CE_NAMEMASK;
int len = len1 < len2 ? len1 : len2;
int cmp;
return -1;
if (len1 > len2)
return 1;
+ if (flags1 < flags2)
+ return -1;
+ if (flags1 > flags2)
+ return 1;
return 0;
}
while (last > first) {
int next = (last + first) >> 1;
struct cache_entry *ce = active_cache[next];
- int cmp = cache_name_compare(name, namelen, ce->name, ce->namelen);
+ int cmp = cache_name_compare(name, namelen, ce->name, htons(ce->ce_flags));
if (!cmp)
return next;
if (cmp < 0) {
return -first-1;
}
+/* Remove entry, return true if there are more entries to go.. */
+static int remove_entry_at(int pos)
+{
+ 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;
+}
+
int remove_file_from_cache(char *path)
{
int pos = cache_name_pos(path, strlen(path));
- if (pos >= 0) {
- active_nr--;
- if (pos < active_nr)
- memmove(active_cache + pos, active_cache + pos + 1, (active_nr - pos) * sizeof(struct cache_entry *));
- }
+ if (pos < 0)
+ pos = -pos-1;
+ while (pos < active_nr && !strcmp(active_cache[pos]->name, path))
+ remove_entry_at(pos);
return 0;
}
+static int same_name(struct cache_entry *a, struct cache_entry *b)
+{
+ int len = ce_namelen(a);
+ return ce_namelen(b) == len && !memcmp(a->name, b->name, len);
+}
+
int add_cache_entry(struct cache_entry *ce, int ok_to_add)
{
int pos;
- pos = cache_name_pos(ce->name, ce->namelen);
+ pos = cache_name_pos(ce->name, htons(ce->ce_flags));
/* existing match? Just replace it */
if (pos >= 0) {
}
pos = -pos-1;
+ /*
+ * 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;
+ active_nr--;
+ if (!remove_entry_at(pos))
+ break;
+ }
+ }
+
if (!ok_to_add)
return -1;
SHA_CTX c;
unsigned char sha1[20];
- if (hdr->signature != CACHE_SIGNATURE)
+ if (hdr->hdr_signature != htonl(CACHE_SIGNATURE))
return error("bad signature");
- if (hdr->version != 1)
+ if (hdr->hdr_version != htonl(1))
return error("bad version");
SHA1_Init(&c);
SHA1_Update(&c, hdr, offsetof(struct cache_header, sha1));
if (verify_hdr(hdr, size) < 0)
goto unmap;
- active_nr = hdr->entries;
+ active_nr = ntohl(hdr->hdr_entries);
active_alloc = alloc_nr(active_nr);
active_cache = calloc(active_alloc, sizeof(struct cache_entry *));
offset = sizeof(*hdr);
- for (i = 0; i < hdr->entries; i++) {
+ for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = map + offset;
offset = offset + ce_size(ce);
active_cache[i] = ce;
struct cache_header hdr;
int i;
- hdr.signature = CACHE_SIGNATURE;
- hdr.version = 1;
- hdr.entries = entries;
+ hdr.hdr_signature = htonl(CACHE_SIGNATURE);
+ hdr.hdr_version = htonl(1);
+ hdr.hdr_entries = htonl(entries);
SHA1_Init(&c);
SHA1_Update(&c, &hdr, offsetof(struct cache_header, sha1));