summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2010-03-17 14:49:14 +0100
committerKarel Zak <kzak@redhat.com>2010-03-17 14:49:14 +0100
commit6c2f2b9d62b196296e827f8bb7336a39e80695a9 (patch)
treeb4da6079a7a7af0080989e37782cc07465d5d760
parentabbd79ac35ca4ad65f2bba55288652db907a514e (diff)
downloadutil-linux-old-6c2f2b9d62b196296e827f8bb7336a39e80695a9.tar.gz
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.ac3
-rw-r--r--shlibs/blkid/src/blkidP.h2
-rw-r--r--shlibs/blkid/src/dev.c2
-rw-r--r--shlibs/blkid/src/read.c14
-rw-r--r--shlibs/blkid/src/save.c8
-rw-r--r--shlibs/blkid/src/verify.c38
6 files changed, 51 insertions, 16 deletions
diff --git a/configure.ac b/configure.ac
index 9cc20b7a..96d7219f 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 1de6dd06..db5da5e8 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 e02f170c..24d989dd 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 b5e9cd02..e6aa0836 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 a1583ecc..c04c2242 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 27360260..a0cb3fea 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;