libblkid: add microsecond resolution for cache entries
The libblkid library uses stat.st_mtine to detect changes on the device. The last update time of of the device in the cache is stored as TIME= tag in the /etc/blkid.tab file. Linux since 2.5.48 supports nanosecond resolution and more precise time is available in the stat.st_mtim timespec struct. This patch add microsecond precision to TIME= tag in the cache file, old format: TIME="<sec>" the new format: TIME="<sec>.<usec>" This change is backwardly compatible. Now, the blkid_verify() function checks stat.st_mtime and stat.st_mtim.tv_nsec/1000. Test: # e2label /dev/sdb1 AAAA old version: # blkid -s LABEL /dev/sdb1; e2label /dev/sdb1 BBBB; blkid -s LABEL /dev/sdb1 /dev/sdb1: LABEL="AAAA" /dev/sdb1: LABEL="AAAA" new version: # blkid -s LABEL /dev/sdb1; e2label /dev/sdb1 BBBB; blkid -s LABEL /dev/sdb1 /dev/sdb1: LABEL="AAAA" /dev/sdb1: LABEL="BBBB" Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
abbd79ac35
commit
6c2f2b9d62
|
@ -601,6 +601,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|||
AC_CHECK_MEMBERS([struct termios.c_line],,,
|
||||
[[#include <termios.h>]])
|
||||
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec],,,
|
||||
[#include <sys/stat.h>])
|
||||
|
||||
AC_CHECK_DECLS([
|
||||
ADDR_NO_RANDOMIZE,
|
||||
FDPIC_FUNCPTRS,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
@ -45,6 +46,7 @@ struct blkid_struct_dev
|
|||
int bid_pri; /* Device priority */
|
||||
dev_t bid_devno; /* Device major/minor number */
|
||||
time_t bid_time; /* Last update time of device */
|
||||
suseconds_t bid_utime; /* Last update time (microseconds) */
|
||||
unsigned int bid_flags; /* Device status bitflags */
|
||||
char *bid_label; /* Shortcut to device LABEL */
|
||||
char *bid_uuid; /* Shortcut to binary UUID */
|
||||
|
|
|
@ -84,7 +84,7 @@ void blkid_debug_dump_dev(blkid_dev dev)
|
|||
|
||||
printf(" dev: name = %s\n", dev->bid_name);
|
||||
printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
|
||||
printf(" dev: TIME=\"%ld\"\n", (long)dev->bid_time);
|
||||
printf(" dev: TIME=\"%ld.%ld\"\n", (long)dev->bid_time, (long)dev->bid_utime);
|
||||
printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
|
||||
printf(" dev: flags = 0x%08X\n", dev->bid_flags);
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ static void debug_dump_dev(blkid_dev dev);
|
|||
*
|
||||
* The following tags are required for each entry:
|
||||
* <ID="id"> unique (within this file) ID number of this device
|
||||
* <TIME="time"> (ascii time_t) time this entry was last read from disk
|
||||
* <TIME="sec.usec"> (time_t and suseconds_t) time this entry was last
|
||||
* read from disk
|
||||
* <TYPE="type"> (detected) type of filesystem/data for this partition
|
||||
*
|
||||
* The following tags may be present, depending on the device contents
|
||||
|
@ -318,9 +319,12 @@ static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
|
|||
dev->bid_devno = STRTOULL(value, 0, 0);
|
||||
else if (!strcmp(name, "PRI"))
|
||||
dev->bid_pri = strtol(value, 0, 0);
|
||||
else if (!strcmp(name, "TIME"))
|
||||
dev->bid_time = STRTOULL(value, 0, 0);
|
||||
else
|
||||
else if (!strcmp(name, "TIME")) {
|
||||
char *end = NULL;
|
||||
dev->bid_time = STRTOULL(value, &end, 0);
|
||||
if (end && *end == '.')
|
||||
dev->bid_utime = STRTOULL(end + 1, 0, 0);
|
||||
} else
|
||||
ret = blkid_set_tag(dev, name, value, strlen(value));
|
||||
|
||||
DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value));
|
||||
|
@ -455,7 +459,7 @@ static void debug_dump_dev(blkid_dev dev)
|
|||
|
||||
printf(" dev: name = %s\n", dev->bid_name);
|
||||
printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
|
||||
printf(" dev: TIME=\"%lld\"\n", (long long)dev->bid_time);
|
||||
printf(" dev: TIME=\"%ld.%ld\"\n", (long)dev->bid_time, (long)dev->bid_utime);
|
||||
printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
|
||||
printf(" dev: flags = 0x%08X\n", dev->bid_flags);
|
||||
|
||||
|
|
|
@ -37,9 +37,11 @@ static int save_dev(blkid_dev dev, FILE *file)
|
|||
printf("device %s, type %s\n", dev->bid_name, dev->bid_type ?
|
||||
dev->bid_type : "(null)"));
|
||||
|
||||
fprintf(file,
|
||||
"<device DEVNO=\"0x%04lx\" TIME=\"%ld\"",
|
||||
(unsigned long) dev->bid_devno, (long) dev->bid_time);
|
||||
fprintf(file, "<device DEVNO=\"0x%04lx\" TIME=\"%ld.%ld\"",
|
||||
(unsigned long) dev->bid_devno,
|
||||
(long) dev->bid_time,
|
||||
(long) dev->bid_utime);
|
||||
|
||||
if (dev->bid_pri)
|
||||
fprintf(file, " PRI=\"%d\"", dev->bid_pri);
|
||||
list_for_each(p, &dev->bid_tags) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
|
@ -73,19 +74,34 @@ blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ((now >= dev->bid_time) &&
|
||||
(st.st_mtime <= dev->bid_time) &&
|
||||
((diff < BLKID_PROBE_MIN) ||
|
||||
(dev->bid_flags & BLKID_BID_FL_VERIFIED &&
|
||||
diff < BLKID_PROBE_INTERVAL)))
|
||||
if (now >= dev->bid_time &&
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
(st.st_mtime < dev->bid_time ||
|
||||
(st.st_mtime == dev->bid_time &&
|
||||
st.st_mtim.tv_nsec / 1000 <= dev->bid_utime)) &&
|
||||
#else
|
||||
st.st_mtime <= dev->bid_time &&
|
||||
#endif
|
||||
(diff < BLKID_PROBE_MIN ||
|
||||
(dev->bid_flags & BLKID_BID_FL_VERIFIED &&
|
||||
diff < BLKID_PROBE_INTERVAL)))
|
||||
return dev;
|
||||
|
||||
#ifndef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
DBG(DEBUG_PROBE,
|
||||
printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t"
|
||||
"time since last check %lu)\n",
|
||||
dev->bid_name, (unsigned long)dev->bid_time,
|
||||
(unsigned long)st.st_mtime, (unsigned long)diff));
|
||||
|
||||
#else
|
||||
DBG(DEBUG_PROBE,
|
||||
printf("need to revalidate %s (cache time %lu.%lu, stat time %lu.%lu,\n\t"
|
||||
"time since last check %lu)\n",
|
||||
dev->bid_name,
|
||||
(unsigned long)dev->bid_time, (unsigned long)dev->bid_utime,
|
||||
(unsigned long)st.st_mtime, (unsigned long)st.st_mtim.tv_nsec / 1000,
|
||||
(unsigned long)diff));
|
||||
#endif
|
||||
|
||||
if (!cache->probe) {
|
||||
cache->probe = blkid_new_probe();
|
||||
|
@ -156,8 +172,16 @@ blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
|
|||
|
||||
found_type:
|
||||
if (dev) {
|
||||
#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
struct timeval tv;
|
||||
if (!gettimeofday(&tv, NULL)) {
|
||||
dev->bid_time = tv.tv_sec;
|
||||
dev->bid_utime = tv.tv_usec;
|
||||
} else
|
||||
#endif
|
||||
dev->bid_time = time(0);
|
||||
|
||||
dev->bid_devno = st.st_rdev;
|
||||
dev->bid_time = time(0);
|
||||
dev->bid_flags |= BLKID_BID_FL_VERIFIED;
|
||||
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
|
||||
|
||||
|
|
Loading…
Reference in New Issue