@@ -67,22 +67,69 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
6767 add_index_entry (istate , new , ADD_CACHE_OK_TO_ADD |ADD_CACHE_OK_TO_REPLACE );
6868}
6969
70+ void fill_stat_data (struct stat_data * sd , struct stat * st )
71+ {
72+ sd -> sd_ctime .sec = (unsigned int )st -> st_ctime ;
73+ sd -> sd_mtime .sec = (unsigned int )st -> st_mtime ;
74+ sd -> sd_ctime .nsec = ST_CTIME_NSEC (* st );
75+ sd -> sd_mtime .nsec = ST_MTIME_NSEC (* st );
76+ sd -> sd_dev = st -> st_dev ;
77+ sd -> sd_ino = st -> st_ino ;
78+ sd -> sd_uid = st -> st_uid ;
79+ sd -> sd_gid = st -> st_gid ;
80+ sd -> sd_size = st -> st_size ;
81+ }
82+
83+ int match_stat_data (const struct stat_data * sd , struct stat * st )
84+ {
85+ int changed = 0 ;
86+
87+ if (sd -> sd_mtime .sec != (unsigned int )st -> st_mtime )
88+ changed |= MTIME_CHANGED ;
89+ if (trust_ctime && check_stat &&
90+ sd -> sd_ctime .sec != (unsigned int )st -> st_ctime )
91+ changed |= CTIME_CHANGED ;
92+
93+ #ifdef USE_NSEC
94+ if (check_stat && sd -> sd_mtime .nsec != ST_MTIME_NSEC (* st ))
95+ changed |= MTIME_CHANGED ;
96+ if (trust_ctime && check_stat &&
97+ sd -> sd_ctime .nsec != ST_CTIME_NSEC (* st ))
98+ changed |= CTIME_CHANGED ;
99+ #endif
100+
101+ if (check_stat ) {
102+ if (sd -> sd_uid != (unsigned int ) st -> st_uid ||
103+ sd -> sd_gid != (unsigned int ) st -> st_gid )
104+ changed |= OWNER_CHANGED ;
105+ if (sd -> sd_ino != (unsigned int ) st -> st_ino )
106+ changed |= INODE_CHANGED ;
107+ }
108+
109+ #ifdef USE_STDEV
110+ /*
111+ * st_dev breaks on network filesystems where different
112+ * clients will have different views of what "device"
113+ * the filesystem is on
114+ */
115+ if (check_stat && sd -> sd_dev != (unsigned int ) st -> st_dev )
116+ changed |= INODE_CHANGED ;
117+ #endif
118+
119+ if (sd -> sd_size != (unsigned int ) st -> st_size )
120+ changed |= DATA_CHANGED ;
121+
122+ return changed ;
123+ }
124+
70125/*
71126 * This only updates the "non-critical" parts of the directory
72127 * cache, ie the parts that aren't tracked by GIT, and only used
73128 * to validate the cache.
74129 */
75130void fill_stat_cache_info (struct cache_entry * ce , struct stat * st )
76131{
77- ce -> ce_ctime .sec = (unsigned int )st -> st_ctime ;
78- ce -> ce_mtime .sec = (unsigned int )st -> st_mtime ;
79- ce -> ce_ctime .nsec = ST_CTIME_NSEC (* st );
80- ce -> ce_mtime .nsec = ST_MTIME_NSEC (* st );
81- ce -> ce_dev = st -> st_dev ;
82- ce -> ce_ino = st -> st_ino ;
83- ce -> ce_uid = st -> st_uid ;
84- ce -> ce_gid = st -> st_gid ;
85- ce -> ce_size = st -> st_size ;
132+ fill_stat_data (& ce -> ce_stat_data , st );
86133
87134 if (assume_unchanged )
88135 ce -> ce_flags |= CE_VALID ;
@@ -195,43 +242,11 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
195242 default :
196243 die ("internal error: ce_mode is %o" , ce -> ce_mode );
197244 }
198- if (ce -> ce_mtime .sec != (unsigned int )st -> st_mtime )
199- changed |= MTIME_CHANGED ;
200- if (trust_ctime && check_stat &&
201- ce -> ce_ctime .sec != (unsigned int )st -> st_ctime )
202- changed |= CTIME_CHANGED ;
203-
204- #ifdef USE_NSEC
205- if (check_stat && ce -> ce_mtime .nsec != ST_MTIME_NSEC (* st ))
206- changed |= MTIME_CHANGED ;
207- if (trust_ctime && check_stat &&
208- ce -> ce_ctime .nsec != ST_CTIME_NSEC (* st ))
209- changed |= CTIME_CHANGED ;
210- #endif
211-
212- if (check_stat ) {
213- if (ce -> ce_uid != (unsigned int ) st -> st_uid ||
214- ce -> ce_gid != (unsigned int ) st -> st_gid )
215- changed |= OWNER_CHANGED ;
216- if (ce -> ce_ino != (unsigned int ) st -> st_ino )
217- changed |= INODE_CHANGED ;
218- }
219245
220- #ifdef USE_STDEV
221- /*
222- * st_dev breaks on network filesystems where different
223- * clients will have different views of what "device"
224- * the filesystem is on
225- */
226- if (check_stat && ce -> ce_dev != (unsigned int ) st -> st_dev )
227- changed |= INODE_CHANGED ;
228- #endif
229-
230- if (ce -> ce_size != (unsigned int ) st -> st_size )
231- changed |= DATA_CHANGED ;
246+ changed |= match_stat_data (& ce -> ce_stat_data , st );
232247
233248 /* Racily smudged entry? */
234- if (!ce -> ce_size ) {
249+ if (!ce -> ce_stat_data . sd_size ) {
235250 if (!is_empty_blob_sha1 (ce -> sha1 ))
236251 changed |= DATA_CHANGED ;
237252 }
@@ -246,11 +261,11 @@ static int is_racy_timestamp(const struct index_state *istate,
246261 istate -> timestamp .sec &&
247262#ifdef USE_NSEC
248263 /* nanosecond timestamped files can also be racy! */
249- (istate -> timestamp .sec < ce -> ce_mtime .sec ||
250- (istate -> timestamp .sec == ce -> ce_mtime .sec &&
251- istate -> timestamp .nsec <= ce -> ce_mtime .nsec ))
264+ (istate -> timestamp .sec < ce -> ce_stat_data . sd_mtime .sec ||
265+ (istate -> timestamp .sec == ce -> ce_stat_data . sd_mtime .sec &&
266+ istate -> timestamp .nsec <= ce -> ce_stat_data . sd_mtime .nsec ))
252267#else
253- istate -> timestamp .sec <= ce -> ce_mtime .sec
268+ istate -> timestamp .sec <= ce -> ce_stat_data . sd_mtime .sec
254269#endif
255270 );
256271}
@@ -342,7 +357,7 @@ int ie_modified(const struct index_state *istate,
342357 * then we know it is.
343358 */
344359 if ((changed & DATA_CHANGED ) &&
345- (S_ISGITLINK (ce -> ce_mode ) || ce -> ce_size != 0 ))
360+ (S_ISGITLINK (ce -> ce_mode ) || ce -> ce_stat_data . sd_size != 0 ))
346361 return changed ;
347362
348363 changed_fs = ce_modified_check_fs (ce , st );
@@ -1324,16 +1339,16 @@ static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *on
13241339{
13251340 struct cache_entry * ce = xmalloc (cache_entry_size (len ));
13261341
1327- ce -> ce_ctime .sec = ntoh_l (ondisk -> ctime .sec );
1328- ce -> ce_mtime .sec = ntoh_l (ondisk -> mtime .sec );
1329- ce -> ce_ctime .nsec = ntoh_l (ondisk -> ctime .nsec );
1330- ce -> ce_mtime .nsec = ntoh_l (ondisk -> mtime .nsec );
1331- ce -> ce_dev = ntoh_l (ondisk -> dev );
1332- ce -> ce_ino = ntoh_l (ondisk -> ino );
1342+ ce -> ce_stat_data . sd_ctime .sec = ntoh_l (ondisk -> ctime .sec );
1343+ ce -> ce_stat_data . sd_mtime .sec = ntoh_l (ondisk -> mtime .sec );
1344+ ce -> ce_stat_data . sd_ctime .nsec = ntoh_l (ondisk -> ctime .nsec );
1345+ ce -> ce_stat_data . sd_mtime .nsec = ntoh_l (ondisk -> mtime .nsec );
1346+ ce -> ce_stat_data . sd_dev = ntoh_l (ondisk -> dev );
1347+ ce -> ce_stat_data . sd_ino = ntoh_l (ondisk -> ino );
13331348 ce -> ce_mode = ntoh_l (ondisk -> mode );
1334- ce -> ce_uid = ntoh_l (ondisk -> uid );
1335- ce -> ce_gid = ntoh_l (ondisk -> gid );
1336- ce -> ce_size = ntoh_l (ondisk -> size );
1349+ ce -> ce_stat_data . sd_uid = ntoh_l (ondisk -> uid );
1350+ ce -> ce_stat_data . sd_gid = ntoh_l (ondisk -> gid );
1351+ ce -> ce_stat_data . sd_size = ntoh_l (ondisk -> size );
13371352 ce -> ce_flags = flags & ~CE_NAMEMASK ;
13381353 ce -> ce_namelen = len ;
13391354 hashcpy (ce -> sha1 , ondisk -> sha1 );
@@ -1611,7 +1626,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
16111626 * The only thing we care about in this function is to smudge the
16121627 * falsely clean entry due to touch-update-touch race, so we leave
16131628 * everything else as they are. We are called for entries whose
1614- * ce_mtime match the index file mtime.
1629+ * ce_stat_data.sd_mtime match the index file mtime.
16151630 *
16161631 * Note that this actually does not do much for gitlinks, for
16171632 * which ce_match_stat_basic() always goes to the actual
@@ -1650,7 +1665,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
16501665 * file, and never calls us, so the cached size information
16511666 * for "frotz" stays 6 which does not match the filesystem.
16521667 */
1653- ce -> ce_size = 0 ;
1668+ ce -> ce_stat_data . sd_size = 0 ;
16541669 }
16551670}
16561671
@@ -1660,16 +1675,16 @@ static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
16601675{
16611676 short flags ;
16621677
1663- ondisk -> ctime .sec = htonl (ce -> ce_ctime .sec );
1664- ondisk -> mtime .sec = htonl (ce -> ce_mtime .sec );
1665- ondisk -> ctime .nsec = htonl (ce -> ce_ctime .nsec );
1666- ondisk -> mtime .nsec = htonl (ce -> ce_mtime .nsec );
1667- ondisk -> dev = htonl (ce -> ce_dev );
1668- ondisk -> ino = htonl (ce -> ce_ino );
1678+ ondisk -> ctime .sec = htonl (ce -> ce_stat_data . sd_ctime .sec );
1679+ ondisk -> mtime .sec = htonl (ce -> ce_stat_data . sd_mtime .sec );
1680+ ondisk -> ctime .nsec = htonl (ce -> ce_stat_data . sd_ctime .nsec );
1681+ ondisk -> mtime .nsec = htonl (ce -> ce_stat_data . sd_mtime .nsec );
1682+ ondisk -> dev = htonl (ce -> ce_stat_data . sd_dev );
1683+ ondisk -> ino = htonl (ce -> ce_stat_data . sd_ino );
16691684 ondisk -> mode = htonl (ce -> ce_mode );
1670- ondisk -> uid = htonl (ce -> ce_uid );
1671- ondisk -> gid = htonl (ce -> ce_gid );
1672- ondisk -> size = htonl (ce -> ce_size );
1685+ ondisk -> uid = htonl (ce -> ce_stat_data . sd_uid );
1686+ ondisk -> gid = htonl (ce -> ce_stat_data . sd_gid );
1687+ ondisk -> size = htonl (ce -> ce_stat_data . sd_size );
16731688 hashcpy (ondisk -> sha1 , ce -> sha1 );
16741689
16751690 flags = ce -> ce_flags ;
@@ -1936,3 +1951,33 @@ void *read_blob_data_from_index(struct index_state *istate, const char *path, un
19361951 * size = sz ;
19371952 return data ;
19381953}
1954+
1955+ void stat_validity_clear (struct stat_validity * sv )
1956+ {
1957+ free (sv -> sd );
1958+ sv -> sd = NULL ;
1959+ }
1960+
1961+ int stat_validity_check (struct stat_validity * sv , const char * path )
1962+ {
1963+ struct stat st ;
1964+
1965+ if (stat (path , & st ) < 0 )
1966+ return sv -> sd == NULL ;
1967+ if (!sv -> sd )
1968+ return 0 ;
1969+ return S_ISREG (st .st_mode ) && !match_stat_data (sv -> sd , & st );
1970+ }
1971+
1972+ void stat_validity_update (struct stat_validity * sv , int fd )
1973+ {
1974+ struct stat st ;
1975+
1976+ if (fstat (fd , & st ) < 0 || !S_ISREG (st .st_mode ))
1977+ stat_validity_clear (sv );
1978+ else {
1979+ if (!sv -> sd )
1980+ sv -> sd = xcalloc (1 , sizeof (struct stat_data ));
1981+ fill_stat_data (sv -> sd , & st );
1982+ }
1983+ }
0 commit comments