blkid: If the device mtime is newer that the cache time, force a revalidation

This fixes problems turned up by a test case written by Erez Zadok's
group which constantly reformats filesystems.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
bitmap-optimize
Theodore Ts'o 2008-05-20 17:28:54 -04:00
parent e5ea6b14eb
commit 492ea6556e
1 changed files with 26 additions and 20 deletions

View File

@ -1214,33 +1214,39 @@ blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
now = time(0); now = time(0);
diff = now - dev->bid_time; diff = now - dev->bid_time;
if ((now > dev->bid_time) && (diff > 0) && if (stat(dev->bid_name, &st) < 0) {
DBG(DEBUG_PROBE,
printf("blkid_verify: error %s (%d) while "
"trying to stat %s\n", strerror(errno), errno,
dev->bid_name));
open_err:
if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) {
/* We don't have read permission, just return cache data. */
DBG(DEBUG_PROBE, printf("returning unverified data for %s\n",
dev->bid_name));
return dev;
}
blkid_free_dev(dev);
return NULL;
}
if ((now >= dev->bid_time) &&
(st.st_mtime <= dev->bid_time) &&
((diff < BLKID_PROBE_MIN) || ((diff < BLKID_PROBE_MIN) ||
(dev->bid_flags & BLKID_BID_FL_VERIFIED && (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
diff < BLKID_PROBE_INTERVAL))) diff < BLKID_PROBE_INTERVAL)))
return dev; return dev;
DBG(DEBUG_PROBE, DBG(DEBUG_PROBE,
printf("need to revalidate %s (time since last check %llu)\n", printf("need to revalidate %s (cache time %d, stat time %d,\n\t"
dev->bid_name, (unsigned long long)diff)); "time since last check %lu)\n",
dev->bid_name, dev->bid_time, st.st_mtime, (unsigned long)diff));
if (((probe.fd = open(dev->bid_name, O_RDONLY)) < 0) || if ((probe.fd = open(dev->bid_name, O_RDONLY)) < 0) {
(fstat(probe.fd, &st) < 0)) { DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while "
if (probe.fd >= 0) close(probe.fd); "opening %s\n", strerror(errno), errno,
if ((errno != EPERM) && (errno != EACCES) && dev->bid_name));
(errno != ENOENT)) { goto open_err;
DBG(DEBUG_PROBE,
printf("blkid_verify: error %s (%d) while "
"opening %s\n", strerror(errno), errno,
dev->bid_name));
blkid_free_dev(dev);
return NULL;
}
/* We don't have read permission, just return cache data. */
DBG(DEBUG_PROBE,
printf("returning unverified data for %s\n",
dev->bid_name));
return dev;
} }
probe.cache = cache; probe.cache = cache;