@@ -1211,43 +1211,38 @@ static int quick_has_loose(struct repository *r,
1211
1211
}
1212
1212
1213
1213
/*
1214
- * Map the loose object at " path" if it is not NULL, or the path found by
1215
- * searching for a loose object named "oid" .
1214
+ * Map and close the given loose object fd. The path argument is used for
1215
+ * error reporting .
1216
1216
*/
1217
- static void * map_loose_object_1 (struct repository * r , const char * path ,
1218
- const struct object_id * oid , unsigned long * size )
1217
+ static void * map_fd (int fd , const char * path , unsigned long * size )
1219
1218
{
1220
- void * map ;
1221
- int fd ;
1222
-
1223
- if (path )
1224
- fd = git_open (path );
1225
- else
1226
- fd = open_loose_object (r , oid , & path );
1227
- map = NULL ;
1228
- if (fd >= 0 ) {
1229
- struct stat st ;
1219
+ void * map = NULL ;
1220
+ struct stat st ;
1230
1221
1231
- if (!fstat (fd , & st )) {
1232
- * size = xsize_t (st .st_size );
1233
- if (!* size ) {
1234
- /* mmap() is forbidden on empty files */
1235
- error (_ ("object file %s is empty" ), path );
1236
- close (fd );
1237
- return NULL ;
1238
- }
1239
- map = xmmap (NULL , * size , PROT_READ , MAP_PRIVATE , fd , 0 );
1222
+ if (!fstat (fd , & st )) {
1223
+ * size = xsize_t (st .st_size );
1224
+ if (!* size ) {
1225
+ /* mmap() is forbidden on empty files */
1226
+ error (_ ("object file %s is empty" ), path );
1227
+ close (fd );
1228
+ return NULL ;
1240
1229
}
1241
- close ( fd );
1230
+ map = xmmap ( NULL , * size , PROT_READ , MAP_PRIVATE , fd , 0 );
1242
1231
}
1232
+ close (fd );
1243
1233
return map ;
1244
1234
}
1245
1235
1246
1236
void * map_loose_object (struct repository * r ,
1247
1237
const struct object_id * oid ,
1248
1238
unsigned long * size )
1249
1239
{
1250
- return map_loose_object_1 (r , NULL , oid , size );
1240
+ const char * p ;
1241
+ int fd = open_loose_object (r , oid , & p );
1242
+
1243
+ if (fd < 0 )
1244
+ return NULL ;
1245
+ return map_fd (fd , p , size );
1251
1246
}
1252
1247
1253
1248
enum unpack_loose_header_result unpack_loose_header (git_zstream * stream ,
@@ -1427,7 +1422,9 @@ static int loose_object_info(struct repository *r,
1427
1422
struct object_info * oi , int flags )
1428
1423
{
1429
1424
int status = 0 ;
1425
+ int fd ;
1430
1426
unsigned long mapsize ;
1427
+ const char * path ;
1431
1428
void * map ;
1432
1429
git_zstream stream ;
1433
1430
char hdr [MAX_HEADER_LEN ];
@@ -1448,7 +1445,6 @@ static int loose_object_info(struct repository *r,
1448
1445
* object even exists.
1449
1446
*/
1450
1447
if (!oi -> typep && !oi -> type_name && !oi -> sizep && !oi -> contentp ) {
1451
- const char * path ;
1452
1448
struct stat st ;
1453
1449
if (!oi -> disk_sizep && (flags & OBJECT_INFO_QUICK ))
1454
1450
return quick_has_loose (r , oid ) ? 0 : -1 ;
@@ -1459,7 +1455,13 @@ static int loose_object_info(struct repository *r,
1459
1455
return 0 ;
1460
1456
}
1461
1457
1462
- map = map_loose_object (r , oid , & mapsize );
1458
+ fd = open_loose_object (r , oid , & path );
1459
+ if (fd < 0 ) {
1460
+ if (errno != ENOENT )
1461
+ error_errno (_ ("unable to open loose object %s" ), oid_to_hex (oid ));
1462
+ return -1 ;
1463
+ }
1464
+ map = map_fd (fd , path , & mapsize );
1463
1465
if (!map )
1464
1466
return -1 ;
1465
1467
@@ -1497,6 +1499,10 @@ static int loose_object_info(struct repository *r,
1497
1499
break ;
1498
1500
}
1499
1501
1502
+ if (status && (flags & OBJECT_INFO_DIE_IF_CORRUPT ))
1503
+ die (_ ("loose object %s (stored in %s) is corrupt" ),
1504
+ oid_to_hex (oid ), path );
1505
+
1500
1506
git_inflate_end (& stream );
1501
1507
cleanup :
1502
1508
munmap (map , mapsize );
@@ -1575,9 +1581,6 @@ static int do_oid_object_info_extended(struct repository *r,
1575
1581
if (find_pack_entry (r , real , & e ))
1576
1582
break ;
1577
1583
1578
- if (flags & OBJECT_INFO_IGNORE_LOOSE )
1579
- return -1 ;
1580
-
1581
1584
/* Most likely it's a loose object. */
1582
1585
if (!loose_object_info (r , real , oi , flags ))
1583
1586
return 0 ;
@@ -1609,6 +1612,15 @@ static int do_oid_object_info_extended(struct repository *r,
1609
1612
continue ;
1610
1613
}
1611
1614
1615
+ if (flags & OBJECT_INFO_DIE_IF_CORRUPT ) {
1616
+ const struct packed_git * p ;
1617
+ if ((flags & OBJECT_INFO_LOOKUP_REPLACE ) && !oideq (real , oid ))
1618
+ die (_ ("replacement %s not found for %s" ),
1619
+ oid_to_hex (real ), oid_to_hex (oid ));
1620
+ if ((p = has_packed_and_bad (r , real )))
1621
+ die (_ ("packed object %s (stored in %s) is corrupt" ),
1622
+ oid_to_hex (real ), p -> pack_name );
1623
+ }
1612
1624
return -1 ;
1613
1625
}
1614
1626
@@ -1661,15 +1673,17 @@ int oid_object_info(struct repository *r,
1661
1673
1662
1674
static void * read_object (struct repository * r ,
1663
1675
const struct object_id * oid , enum object_type * type ,
1664
- unsigned long * size )
1676
+ unsigned long * size ,
1677
+ int die_if_corrupt )
1665
1678
{
1666
1679
struct object_info oi = OBJECT_INFO_INIT ;
1667
1680
void * content ;
1668
1681
oi .typep = type ;
1669
1682
oi .sizep = size ;
1670
1683
oi .contentp = & content ;
1671
1684
1672
- if (oid_object_info_extended (r , oid , & oi , 0 ) < 0 )
1685
+ if (oid_object_info_extended (r , oid , & oi , die_if_corrupt
1686
+ ? OBJECT_INFO_DIE_IF_CORRUPT : 0 ) < 0 )
1673
1687
return NULL ;
1674
1688
return content ;
1675
1689
}
@@ -1705,35 +1719,14 @@ void *read_object_file_extended(struct repository *r,
1705
1719
int lookup_replace )
1706
1720
{
1707
1721
void * data ;
1708
- const struct packed_git * p ;
1709
- const char * path ;
1710
- struct stat st ;
1711
1722
const struct object_id * repl = lookup_replace ?
1712
1723
lookup_replace_object (r , oid ) : oid ;
1713
1724
1714
1725
errno = 0 ;
1715
- data = read_object (r , repl , type , size );
1726
+ data = read_object (r , repl , type , size , 1 );
1716
1727
if (data )
1717
1728
return data ;
1718
1729
1719
- obj_read_lock ();
1720
- if (errno && errno != ENOENT )
1721
- die_errno (_ ("failed to read object %s" ), oid_to_hex (oid ));
1722
-
1723
- /* die if we replaced an object with one that does not exist */
1724
- if (repl != oid )
1725
- die (_ ("replacement %s not found for %s" ),
1726
- oid_to_hex (repl ), oid_to_hex (oid ));
1727
-
1728
- if (!stat_loose_object (r , repl , & st , & path ))
1729
- die (_ ("loose object %s (stored in %s) is corrupt" ),
1730
- oid_to_hex (repl ), path );
1731
-
1732
- if ((p = has_packed_and_bad (r , repl )))
1733
- die (_ ("packed object %s (stored in %s) is corrupt" ),
1734
- oid_to_hex (repl ), p -> pack_name );
1735
- obj_read_unlock ();
1736
-
1737
1730
return NULL ;
1738
1731
}
1739
1732
@@ -2269,7 +2262,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
2269
2262
2270
2263
if (has_loose_object (oid ))
2271
2264
return 0 ;
2272
- buf = read_object (the_repository , oid , & type , & len );
2265
+ buf = read_object (the_repository , oid , & type , & len , 0 );
2273
2266
if (!buf )
2274
2267
return error (_ ("cannot read object for %s" ), oid_to_hex (oid ));
2275
2268
hdrlen = format_object_header (hdr , sizeof (hdr ), type , len );
@@ -2785,13 +2778,16 @@ int read_loose_object(const char *path,
2785
2778
struct object_info * oi )
2786
2779
{
2787
2780
int ret = -1 ;
2781
+ int fd ;
2788
2782
void * map = NULL ;
2789
2783
unsigned long mapsize ;
2790
2784
git_zstream stream ;
2791
2785
char hdr [MAX_HEADER_LEN ];
2792
2786
unsigned long * size = oi -> sizep ;
2793
2787
2794
- map = map_loose_object_1 (the_repository , path , NULL , & mapsize );
2788
+ fd = git_open (path );
2789
+ if (fd >= 0 )
2790
+ map = map_fd (fd , path , & mapsize );
2795
2791
if (!map ) {
2796
2792
error_errno (_ ("unable to mmap %s" ), path );
2797
2793
goto out ;
0 commit comments