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