Skip to content

Commit d60c49c

Browse files
committed
read-cache.c: allow unaligned mapping of the index file
Both the on-disk format v2 and v3 pads the "name" field to the multiple of eight to make sure that various quantities in network long/short type can be accessed with ntohl/ntohs without having to worry about alignment, but this forces us to waste disk I/O bandwidth. Introduce ntoh_s()/ntoh_l() macros that the callers can use as if they were the regular ntohs()/ntohl() on a field that may not be aligned correctly. Signed-off-by: Junio C Hamano <[email protected]>
1 parent db3b313 commit d60c49c

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

read-cache.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,26 @@ int read_index(struct index_state *istate)
12851285
return read_index_from(istate, get_index_file());
12861286
}
12871287

1288+
#ifndef NEEDS_ALIGNED_ACCESS
1289+
#define ntoh_s(var) ntohs(var)
1290+
#define ntoh_l(var) ntohl(var)
1291+
#else
1292+
static inline uint16_t ntoh_s_force_align(void *p)
1293+
{
1294+
uint16_t x;
1295+
memcpy(&x, p, sizeof(x));
1296+
return ntohs(x);
1297+
}
1298+
static inline uint32_t ntoh_l_force_align(void *p)
1299+
{
1300+
uint32_t x;
1301+
memcpy(&x, p, sizeof(x));
1302+
return ntohl(x);
1303+
}
1304+
#define ntoh_s(var) ntoh_s_force_align(&(var))
1305+
#define ntoh_l(var) ntoh_l_force_align(&(var))
1306+
#endif
1307+
12881308
static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk)
12891309
{
12901310
struct cache_entry *ce;
@@ -1293,14 +1313,14 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk)
12931313
unsigned int flags;
12941314

12951315
/* On-disk flags are just 16 bits */
1296-
flags = ntohs(ondisk->flags);
1316+
flags = ntoh_s(ondisk->flags);
12971317
len = flags & CE_NAMEMASK;
12981318

12991319
if (flags & CE_EXTENDED) {
13001320
struct ondisk_cache_entry_extended *ondisk2;
13011321
int extended_flags;
13021322
ondisk2 = (struct ondisk_cache_entry_extended *)ondisk;
1303-
extended_flags = ntohs(ondisk2->flags2) << 16;
1323+
extended_flags = ntoh_s(ondisk2->flags2) << 16;
13041324
/* We do not yet understand any bit out of CE_EXTENDED_FLAGS */
13051325
if (extended_flags & ~CE_EXTENDED_FLAGS)
13061326
die("Unknown index entry format %08x", extended_flags);
@@ -1315,16 +1335,16 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk)
13151335

13161336
ce = xmalloc(cache_entry_size(len));
13171337

1318-
ce->ce_ctime.sec = ntohl(ondisk->ctime.sec);
1319-
ce->ce_mtime.sec = ntohl(ondisk->mtime.sec);
1320-
ce->ce_ctime.nsec = ntohl(ondisk->ctime.nsec);
1321-
ce->ce_mtime.nsec = ntohl(ondisk->mtime.nsec);
1322-
ce->ce_dev = ntohl(ondisk->dev);
1323-
ce->ce_ino = ntohl(ondisk->ino);
1324-
ce->ce_mode = ntohl(ondisk->mode);
1325-
ce->ce_uid = ntohl(ondisk->uid);
1326-
ce->ce_gid = ntohl(ondisk->gid);
1327-
ce->ce_size = ntohl(ondisk->size);
1338+
ce->ce_ctime.sec = ntoh_l(ondisk->ctime.sec);
1339+
ce->ce_mtime.sec = ntoh_l(ondisk->mtime.sec);
1340+
ce->ce_ctime.nsec = ntoh_l(ondisk->ctime.nsec);
1341+
ce->ce_mtime.nsec = ntoh_l(ondisk->mtime.nsec);
1342+
ce->ce_dev = ntoh_l(ondisk->dev);
1343+
ce->ce_ino = ntoh_l(ondisk->ino);
1344+
ce->ce_mode = ntoh_l(ondisk->mode);
1345+
ce->ce_uid = ntoh_l(ondisk->uid);
1346+
ce->ce_gid = ntoh_l(ondisk->gid);
1347+
ce->ce_size = ntoh_l(ondisk->size);
13281348
ce->ce_flags = flags;
13291349

13301350
hashcpy(ce->sha1, ondisk->sha1);

0 commit comments

Comments
 (0)