From: Karel Zak Date: Wed, 17 Mar 2010 13:49:14 +0000 (+0100) Subject: libblkid: add microsecond resolution for cache entries X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6c2f2b9d62b196296e827f8bb7336a39e80695a9;p=util-linux 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="" the new format: TIME="." 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 --- 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 ]]) +AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec],,, + [#include ]) + 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 #include #include +#include #include #include #include @@ -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: * unique (within this file) ID number of this device - * (ascii time_t) time this entry was last read from disk + * (time_t and suseconds_t) time this entry was last + * read from disk * (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, - "bid_devno, (long) dev->bid_time); + fprintf(file, "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 #include #include +#include #include #ifdef HAVE_SYS_STAT_H #include @@ -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;