Extract a struct stat_data from cache_entry
Add public functions fill_stat_data() and match_stat_data() to work with it. This infrastructure will later be used to check the validity of other types of file. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Michael Haggerty committed
Jun 20, 2013 at 10:37 UTC
c21d39d7c7eb07eed0be301a72856bff65201256
3 files changed
+116
-80
builtin/ls-files.c
+7
-5
@@ -165,11 +165,13 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
165
}
166
write_name(ce->name, ce_namelen(ce));
167
if (debug_mode) {
168
- printf(" ctime: %d:%d\n", ce->ce_ctime.sec, ce->ce_ctime.nsec);
169
- printf(" mtime: %d:%d\n", ce->ce_mtime.sec, ce->ce_mtime.nsec);
170
- printf(" dev: %d\tino: %d\n", ce->ce_dev, ce->ce_ino);
171
- printf(" uid: %d\tgid: %d\n", ce->ce_uid, ce->ce_gid);
172
- printf(" size: %d\tflags: %x\n", ce->ce_size, ce->ce_flags);
168
+ struct stat_data *sd = &ce->ce_stat_data;
169
+
170
+ printf(" ctime: %d:%d\n", sd->sd_ctime.sec, sd->sd_ctime.nsec);
171
+ printf(" mtime: %d:%d\n", sd->sd_mtime.sec, sd->sd_mtime.nsec);
172
+ printf(" dev: %d\tino: %d\n", sd->sd_dev, sd->sd_ino);
173
+ printf(" uid: %d\tgid: %d\n", sd->sd_uid, sd->sd_gid);
174
+ printf(" size: %d\tflags: %x\n", sd->sd_size, ce->ce_flags);
175
}
176
}
177
cache.h
+26
-7
@@ -119,15 +119,19 @@ struct cache_time {
119
unsigned int nsec;
120
};
121
122
+struct stat_data {
123
+ struct cache_time sd_ctime;
124
+ struct cache_time sd_mtime;
125
+ unsigned int sd_dev;
126
+ unsigned int sd_ino;
127
+ unsigned int sd_uid;
128
+ unsigned int sd_gid;
129
+ unsigned int sd_size;
130
+};
131
+
132
struct cache_entry {
123
- struct cache_time ce_ctime;
124
- struct cache_time ce_mtime;
125
- unsigned int ce_dev;
126
- unsigned int ce_ino;
133
+ struct stat_data ce_stat_data;
134
unsigned int ce_mode;
128
- unsigned int ce_uid;
129
- unsigned int ce_gid;
130
- unsigned int ce_size;
135
unsigned int ce_flags;
136
unsigned int ce_namelen;
137
unsigned char sha1[20];
@@ -511,6 +515,21 @@ extern int limit_pathspec_to_literal(void);
515
#define HASH_FORMAT_CHECK 2
516
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags);
517
extern int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned flags);
518
+
519
+/*
520
+ * Record to sd the data from st that we use to check whether a file
521
+ * might have changed.
522
+ */
523
+extern void fill_stat_data(struct stat_data *sd, struct stat *st);
524
+
525
+/*
526
+ * Return 0 if st is consistent with a file not having been changed
527
+ * since sd was filled. If there are differences, return a
528
+ * combination of MTIME_CHANGED, CTIME_CHANGED, OWNER_CHANGED,
529
+ * INODE_CHANGED, and DATA_CHANGED.
530
+ */
531
+extern int match_stat_data(const struct stat_data *sd, struct stat *st);
532
+
533
extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st);
534
535
#define REFRESH_REALLY 0x0001 /* ignore_valid */
read-cache.c
+83
-68
@@ -67,6 +67,61 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
67
add_index_entry(istate, new, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
68
}
69
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
+
125
/*
126
* This only updates the "non-critical" parts of the directory
127
* cache, ie the parts that aren't tracked by GIT, and only used
@@ -74,15 +129,7 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
129
*/
130
void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
131
{
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);
133
134
if (assume_unchanged)
135
ce->ce_flags |= CE_VALID;
@@ -195,43 +242,11 @@ static int ce_match_stat_basic(const struct cache_entry *ce, struct stat *st)
242
default:
243
die("internal error: ce_mode is %o", ce->ce_mode);
244
}
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;
245
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
- }
219
-
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);
247
248
/* Racily smudged entry? */
234
- if (!ce->ce_size) {
249
+ if (!ce->ce_stat_data.sd_size) {
250
if (!is_empty_blob_sha1(ce->sha1))
251
changed |= DATA_CHANGED;
252
}
@@ -246,11 +261,11 @@ static int is_racy_timestamp(const struct index_state *istate,
261
istate->timestamp.sec &&
262
#ifdef USE_NSEC
263
/* 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))
267
#else
253
- istate->timestamp.sec <= ce->ce_mtime.sec
268
+ istate->timestamp.sec <= ce->ce_stat_data.sd_mtime.sec
269
#endif
270
);
271
}
@@ -342,7 +357,7 @@ int ie_modified(const struct index_state *istate,
357
* then we know it is.
358
*/
359
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))
361
return changed;
362
363
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
1339
{
1340
struct cache_entry *ce = xmalloc(cache_entry_size(len));
1341
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);
1348
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);
1352
ce->ce_flags = flags & ~CE_NAMEMASK;
1353
ce->ce_namelen = len;
1354
hashcpy(ce->sha1, ondisk->sha1);
@@ -1610,7 +1625,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
1625
* The only thing we care about in this function is to smudge the
1626
* falsely clean entry due to touch-update-touch race, so we leave
1627
* everything else as they are. We are called for entries whose
1613
- * ce_mtime match the index file mtime.
1628
+ * ce_stat_data.sd_mtime match the index file mtime.
1629
*
1630
* Note that this actually does not do much for gitlinks, for
1631
* which ce_match_stat_basic() always goes to the actual
@@ -1649,7 +1664,7 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce)
1664
* file, and never calls us, so the cached size information
1665
* for "frotz" stays 6 which does not match the filesystem.
1666
*/
1652
- ce->ce_size = 0;
1667
+ ce->ce_stat_data.sd_size = 0;
1668
}
1669
}
1670
@@ -1659,16 +1674,16 @@ static char *copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
1674
{
1675
short flags;
1676
1662
- ondisk->ctime.sec = htonl(ce->ce_ctime.sec);
1663
- ondisk->mtime.sec = htonl(ce->ce_mtime.sec);
1664
- ondisk->ctime.nsec = htonl(ce->ce_ctime.nsec);
1665
- ondisk->mtime.nsec = htonl(ce->ce_mtime.nsec);
1666
- ondisk->dev = htonl(ce->ce_dev);
1667
- ondisk->ino = htonl(ce->ce_ino);
1677
+ ondisk->ctime.sec = htonl(ce->ce_stat_data.sd_ctime.sec);
1678
+ ondisk->mtime.sec = htonl(ce->ce_stat_data.sd_mtime.sec);
1679
+ ondisk->ctime.nsec = htonl(ce->ce_stat_data.sd_ctime.nsec);
1680
+ ondisk->mtime.nsec = htonl(ce->ce_stat_data.sd_mtime.nsec);
1681
+ ondisk->dev = htonl(ce->ce_stat_data.sd_dev);
1682
+ ondisk->ino = htonl(ce->ce_stat_data.sd_ino);
1683
ondisk->mode = htonl(ce->ce_mode);
1669
- ondisk->uid = htonl(ce->ce_uid);
1670
- ondisk->gid = htonl(ce->ce_gid);
1671
- ondisk->size = htonl(ce->ce_size);
1684
+ ondisk->uid = htonl(ce->ce_stat_data.sd_uid);
1685
+ ondisk->gid = htonl(ce->ce_stat_data.sd_gid);
1686
+ ondisk->size = htonl(ce->ce_stat_data.sd_size);
1687
hashcpy(ondisk->sha1, ce->sha1);
1688
1689
flags = ce->ce_flags;