diff options
author | Karel Zak | 2010-03-17 14:49:14 +0100 |
---|---|---|
committer | Karel Zak | 2010-03-17 14:49:14 +0100 |
commit | 6c2f2b9d62b196296e827f8bb7336a39e80695a9 (patch) | |
tree | b4da6079a7a7af0080989e37782cc07465d5d760 | |
parent | lib: fix blkdev_find_size() (diff) | |
download | kernel-qcow2-util-linux-6c2f2b9d62b196296e827f8bb7336a39e80695a9.tar.gz kernel-qcow2-util-linux-6c2f2b9d62b196296e827f8bb7336a39e80695a9.tar.xz kernel-qcow2-util-linux-6c2f2b9d62b196296e827f8bb7336a39e80695a9.zip |
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>
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | shlibs/blkid/src/blkidP.h | 2 | ||||
-rw-r--r-- | shlibs/blkid/src/dev.c | 2 | ||||
-rw-r--r-- | shlibs/blkid/src/read.c | 14 | ||||
-rw-r--r-- | shlibs/blkid/src/save.c | 8 | ||||
-rw-r--r-- | shlibs/blkid/src/verify.c | 38 |
6 files changed, 51 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac index 9cc20b7ac..96d7219f9 100644 --- a/configure.ac +++ b/configure.ac @@ -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, diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h index 1de6dd064..db5da5e80 100644 --- a/shlibs/blkid/src/blkidP.h +++ b/shlibs/blkid/src/blkidP.h @@ -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 */ diff --git a/shlibs/blkid/src/dev.c b/shlibs/blkid/src/dev.c index e02f170c7..24d989ddc 100644 --- a/shlibs/blkid/src/dev.c +++ b/shlibs/blkid/src/dev.c @@ -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); diff --git a/shlibs/blkid/src/read.c b/shlibs/blkid/src/read.c index b5e9cd024..e6aa08368 100644 --- a/shlibs/blkid/src/read.c +++ b/shlibs/blkid/src/read.c @@ -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); diff --git a/shlibs/blkid/src/save.c b/shlibs/blkid/src/save.c index a1583ecca..c04c22427 100644 --- a/shlibs/blkid/src/save.c +++ b/shlibs/blkid/src/save.c @@ -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) { diff --git a/shlibs/blkid/src/verify.c b/shlibs/blkid/src/verify.c index 273602600..a0cb3fea2 100644 --- a/shlibs/blkid/src/verify.c +++ b/shlibs/blkid/src/verify.c @@ -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; |