@@ -418,6 +418,8 @@ static unsigned int pack_used_ctr;
418
418
static unsigned int pack_mmap_calls ;
419
419
static unsigned int peak_pack_open_windows ;
420
420
static unsigned int pack_open_windows ;
421
+ static unsigned int pack_open_fds ;
422
+ static unsigned int pack_max_fds ;
421
423
static size_t peak_pack_mapped ;
422
424
static size_t pack_mapped ;
423
425
struct packed_git * packed_git ;
@@ -595,8 +597,10 @@ static int unuse_one_window(struct packed_git *current, int keep_fd)
595
597
lru_l -> next = lru_w -> next ;
596
598
else {
597
599
lru_p -> windows = lru_w -> next ;
598
- if (!lru_p -> windows && lru_p -> pack_fd != keep_fd ) {
600
+ if (!lru_p -> windows && lru_p -> pack_fd != -1
601
+ && lru_p -> pack_fd != keep_fd ) {
599
602
close (lru_p -> pack_fd );
603
+ pack_open_fds -- ;
600
604
lru_p -> pack_fd = -1 ;
601
605
}
602
606
}
@@ -681,8 +685,10 @@ void free_pack_by_name(const char *pack_name)
681
685
if (strcmp (pack_name , p -> pack_name ) == 0 ) {
682
686
clear_delta_base_cache ();
683
687
close_pack_windows (p );
684
- if (p -> pack_fd != -1 )
688
+ if (p -> pack_fd != -1 ) {
685
689
close (p -> pack_fd );
690
+ pack_open_fds -- ;
691
+ }
686
692
close_pack_index (p );
687
693
free (p -> bad_object_sha1 );
688
694
* pp = p -> next ;
@@ -708,9 +714,29 @@ static int open_packed_git_1(struct packed_git *p)
708
714
if (!p -> index_data && open_pack_index (p ))
709
715
return error ("packfile %s index unavailable" , p -> pack_name );
710
716
717
+ if (!pack_max_fds ) {
718
+ struct rlimit lim ;
719
+ unsigned int max_fds ;
720
+
721
+ if (getrlimit (RLIMIT_NOFILE , & lim ))
722
+ die_errno ("cannot get RLIMIT_NOFILE" );
723
+
724
+ max_fds = lim .rlim_cur ;
725
+
726
+ /* Save 3 for stdin/stdout/stderr, 22 for work */
727
+ if (25 < max_fds )
728
+ pack_max_fds = max_fds - 25 ;
729
+ else
730
+ pack_max_fds = 1 ;
731
+ }
732
+
733
+ while (pack_max_fds <= pack_open_fds && unuse_one_window (NULL , -1 ))
734
+ ; /* nothing */
735
+
711
736
p -> pack_fd = git_open_noatime (p -> pack_name , p );
712
737
if (p -> pack_fd < 0 || fstat (p -> pack_fd , & st ))
713
738
return -1 ;
739
+ pack_open_fds ++ ;
714
740
715
741
/* If we created the struct before we had the pack we lack size. */
716
742
if (!p -> pack_size ) {
@@ -762,6 +788,7 @@ static int open_packed_git(struct packed_git *p)
762
788
return 0 ;
763
789
if (p -> pack_fd != -1 ) {
764
790
close (p -> pack_fd );
791
+ pack_open_fds -- ;
765
792
p -> pack_fd = -1 ;
766
793
}
767
794
return -1 ;
@@ -787,14 +814,13 @@ unsigned char *use_pack(struct packed_git *p,
787
814
{
788
815
struct pack_window * win = * w_cursor ;
789
816
790
- if (p -> pack_fd == -1 && open_packed_git (p ))
791
- die ("packfile %s cannot be accessed" , p -> pack_name );
792
-
793
817
/* Since packfiles end in a hash of their content and it's
794
818
* pointless to ask for an offset into the middle of that
795
819
* hash, and the in_window function above wouldn't match
796
820
* don't allow an offset too close to the end of the file.
797
821
*/
822
+ if (!p -> pack_size && p -> pack_fd == -1 && open_packed_git (p ))
823
+ die ("packfile %s cannot be accessed" , p -> pack_name );
798
824
if (offset > (p -> pack_size - 20 ))
799
825
die ("offset beyond end of packfile (truncated pack?)" );
800
826
@@ -808,6 +834,10 @@ unsigned char *use_pack(struct packed_git *p,
808
834
if (!win ) {
809
835
size_t window_align = packed_git_window_size / 2 ;
810
836
off_t len ;
837
+
838
+ if (p -> pack_fd == -1 && open_packed_git (p ))
839
+ die ("packfile %s cannot be accessed" , p -> pack_name );
840
+
811
841
win = xcalloc (1 , sizeof (* win ));
812
842
win -> offset = (offset / window_align ) * window_align ;
813
843
len = p -> pack_size - win -> offset ;
@@ -825,6 +855,12 @@ unsigned char *use_pack(struct packed_git *p,
825
855
die ("packfile %s cannot be mapped: %s" ,
826
856
p -> pack_name ,
827
857
strerror (errno ));
858
+ if (!win -> offset && win -> len == p -> pack_size
859
+ && !p -> do_not_close ) {
860
+ close (p -> pack_fd );
861
+ pack_open_fds -- ;
862
+ p -> pack_fd = -1 ;
863
+ }
828
864
pack_mmap_calls ++ ;
829
865
pack_open_windows ++ ;
830
866
if (pack_mapped > peak_pack_mapped )
@@ -919,6 +955,9 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
919
955
920
956
void install_packed_git (struct packed_git * pack )
921
957
{
958
+ if (pack -> pack_fd != -1 )
959
+ pack_open_fds ++ ;
960
+
922
961
pack -> next = packed_git ;
923
962
packed_git = pack ;
924
963
}
@@ -936,8 +975,6 @@ static void prepare_packed_git_one(char *objdir, int local)
936
975
sprintf (path , "%s/pack" , objdir );
937
976
len = strlen (path );
938
977
dir = opendir (path );
939
- while (!dir && errno == EMFILE && unuse_one_window (NULL , -1 ))
940
- dir = opendir (path );
941
978
if (!dir ) {
942
979
if (errno != ENOENT )
943
980
error ("unable to open object pack directory: %s: %s" ,
@@ -1093,14 +1130,6 @@ static int git_open_noatime(const char *name, struct packed_git *p)
1093
1130
if (fd >= 0 )
1094
1131
return fd ;
1095
1132
1096
- /* Might the failure be insufficient file descriptors? */
1097
- if (errno == EMFILE ) {
1098
- if (unuse_one_window (p , -1 ))
1099
- continue ;
1100
- else
1101
- return -1 ;
1102
- }
1103
-
1104
1133
/* Might the failure be due to O_NOATIME? */
1105
1134
if (errno != ENOENT && sha1_file_open_flag ) {
1106
1135
sha1_file_open_flag = 0 ;
@@ -1932,6 +1961,27 @@ off_t find_pack_entry_one(const unsigned char *sha1,
1932
1961
return 0 ;
1933
1962
}
1934
1963
1964
+ static int is_pack_valid (struct packed_git * p )
1965
+ {
1966
+ /* An already open pack is known to be valid. */
1967
+ if (p -> pack_fd != -1 )
1968
+ return 1 ;
1969
+
1970
+ /* If the pack has one window completely covering the
1971
+ * file size, the pack is known to be valid even if
1972
+ * the descriptor is not currently open.
1973
+ */
1974
+ if (p -> windows ) {
1975
+ struct pack_window * w = p -> windows ;
1976
+
1977
+ if (!w -> offset && w -> len == p -> pack_size )
1978
+ return 1 ;
1979
+ }
1980
+
1981
+ /* Force the pack to open to prove its valid. */
1982
+ return !open_packed_git (p );
1983
+ }
1984
+
1935
1985
static int find_pack_entry (const unsigned char * sha1 , struct pack_entry * e )
1936
1986
{
1937
1987
static struct packed_git * last_found = (void * )1 ;
@@ -1961,7 +2011,7 @@ static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
1961
2011
* it may have been deleted since the index
1962
2012
* was loaded!
1963
2013
*/
1964
- if (p -> pack_fd == -1 && open_packed_git (p )) {
2014
+ if (! is_pack_valid (p )) {
1965
2015
error ("packfile %s cannot be accessed" , p -> pack_name );
1966
2016
goto next ;
1967
2017
}
@@ -2360,8 +2410,6 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
2360
2410
2361
2411
filename = sha1_file_name (sha1 );
2362
2412
fd = create_tmpfile (tmpfile , sizeof (tmpfile ), filename );
2363
- while (fd < 0 && errno == EMFILE && unuse_one_window (NULL , -1 ))
2364
- fd = create_tmpfile (tmpfile , sizeof (tmpfile ), filename );
2365
2413
if (fd < 0 ) {
2366
2414
if (errno == EACCES )
2367
2415
return error ("insufficient permission for adding an object to repository database %s\n" , get_object_directory ());
0 commit comments