Internal changes to the blkid library:

1) Only one tag with a particular name can be attached to a device
at a time.  This significantly simplifies the library, and was needed
to allow the cache file to be re-read and changes integrated into the 
in-core version of the data structure in a simpler fashion than earlier
versions of the library. 

2)  To accomodate this, the ext2/ext3 filesystems are now always tagged
as "ext2" type filesystems.  Ext3 filesystems are tagged with a 
SEC_TYPE tag with the value ext3.

3)  The new blkid_read_cache() function checks the mod time of the
cache file, and if the file has been changed since the last time the
cache file was read into memory, it is re-read.  This function is now
called before probing all of the devices in the system or searching
all devices in the cache for a specific tag value.

4)  After probing all devices, blkid_flush_cache() is called to write
out the cache file.  This assures that all of the hard work involved
in doing a blkid_probe_all() is saved to disk.

diff --git a/lib/blkid/save.c b/lib/blkid/save.c
index 82b9b77..bed211a 100644
--- a/lib/blkid/save.c
+++ b/lib/blkid/save.c
@@ -37,14 +37,13 @@
 	    printf("device %s, type %s\n", dev->bid_name, dev->bid_type));
 
 	fprintf(file,
-		"<device TYPE=\"%s\" DEVNO=\"0x%04lx\" TIME=\"%lu\"",
-		dev->bid_type, (unsigned long) dev->bid_devno, dev->bid_time);
+		"<device DEVNO=\"0x%04lx\" TIME=\"%lu\"",
+		(unsigned long) dev->bid_devno, dev->bid_time);
 	if (dev->bid_pri)
 		fprintf(file, " PRI=\"%d\"", dev->bid_pri);
 	list_for_each(p, &dev->bid_tags) {
 		blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
-		if (strcmp(tag->bit_name, "TYPE"))
-			fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
+		fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
 	}
 	fprintf(file, ">%s</device>\n", dev->bid_name);
 
@@ -62,65 +61,61 @@
 	const char *filename;
 	FILE *file = NULL;
 	int fd, ret = 0;
+	struct stat st;
 
 	if (!cache)
 		return -BLKID_ERR_PARAM;
 
 	if (list_empty(&cache->bic_devs) ||
 	    !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
-		DBG(DEBUG_SAVE, printf("empty cache, not saving\n"));
+		DBG(DEBUG_SAVE, printf("skipping cache file write\n"));
 		return 0;
 	}
 
 	filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE;
 
-	if (!strcmp(filename, "-"))
-		file = stdout;
-	else {
-		struct stat st;
-
-		/* If we can't write to the cache file, then don't even try */
-		if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
-		    (ret == 0 && access(filename, W_OK) < 0)) {
-			DBG(DEBUG_SAVE,
-			    printf("can't write to cache file %s\n", filename));
-			return 0;
-		}
-
-		/*
-		 * Try and create a temporary file in the same directory so
-		 * that in case of error we don't overwrite the cache file.
-		 * If the cache file doesn't yet exist, it isn't a regular
-		 * file (e.g. /dev/null or a socket), or we couldn't create
-		 * a temporary file then we open it directly.
-		 */
-		if (ret == 0 && S_ISREG(st.st_mode)) {
-			tmp = malloc(strlen(filename) + 8);
-			if (tmp) {
-				sprintf(tmp, "%s-XXXXXX", filename);
-				fd = mkstemp(tmp);
-				if (fd >= 0) {
-					file = fdopen(fd, "w");
-					opened = tmp;
-				}
-				fchmod(fd, 0644);
-			}
-		}
-
-		if (!file) {
-			file = fopen(filename, "w");
-			opened = filename;
-		}
-
+	/* If we can't write to the cache file, then don't even try */
+	if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
+	    (ret == 0 && access(filename, W_OK) < 0)) {
 		DBG(DEBUG_SAVE,
-		    printf("cache file %s (really %s)\n", filename, opened));
+		    printf("can't write to cache file %s\n", filename));
+		return 0;
+	}
 
-		if (!file) {
-			ret = errno;
-			goto errout;
+	/*
+	 * Try and create a temporary file in the same directory so
+	 * that in case of error we don't overwrite the cache file.
+	 * If the cache file doesn't yet exist, it isn't a regular
+	 * file (e.g. /dev/null or a socket), or we couldn't create
+	 * a temporary file then we open it directly.
+	 */
+	if (ret == 0 && S_ISREG(st.st_mode)) {
+		tmp = malloc(strlen(filename) + 8);
+		if (tmp) {
+			sprintf(tmp, "%s-XXXXXX", filename);
+			fd = mkstemp(tmp);
+			if (fd >= 0) {
+				file = fdopen(fd, "w");
+				opened = tmp;
+			}
+			fchmod(fd, 0644);
 		}
 	}
 
+	if (!file) {
+		file = fopen(filename, "w");
+		opened = filename;
+	}
+
+	DBG(DEBUG_SAVE,
+	    printf("writing cache file %s (really %s)\n",
+		   filename, opened));
+
+	if (!file) {
+		ret = errno;
+		goto errout;
+	}
+
 	list_for_each(p, &cache->bic_devs) {
 		blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
 		if (!dev->bid_type)
@@ -134,27 +129,25 @@
 		ret = 1;
 	}
 
-	if (file != stdout) {
-		fclose(file);
-		if (opened != filename) {
-			if (ret < 0) {
-				unlink(opened);
-				DBG(DEBUG_SAVE,
-				    printf("unlinked temp cache %s\n", opened));
-			} else {
-				char *backup;
+	fclose(file);
+	if (opened != filename) {
+		if (ret < 0) {
+			unlink(opened);
+			DBG(DEBUG_SAVE,
+			    printf("unlinked temp cache %s\n", opened));
+		} else {
+			char *backup;
 
-				backup = malloc(strlen(filename) + 5);
-				if (backup) {
-					sprintf(backup, "%s.old", filename);
-					unlink(backup);
-					link(filename, backup);
-					free(backup);
-				}
-				rename(opened, filename);
-				DBG(DEBUG_SAVE,
-				    printf("moved temp cache %s\n", opened));
+			backup = malloc(strlen(filename) + 5);
+			if (backup) {
+				sprintf(backup, "%s.old", filename);
+				unlink(backup);
+				link(filename, backup);
+				free(backup);
 			}
+			rename(opened, filename);
+			DBG(DEBUG_SAVE,
+			    printf("moved temp cache %s\n", opened));
 		}
 	}
 
@@ -177,8 +170,9 @@
 		exit(1);
 	}
 
-	if ((cache = blkid_new_cache()) == NULL) {
-		fprintf(stderr, "%s: error creating cache\n", argv[0]);
+	if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+		fprintf(stderr, "%s: error creating cache (%d)\n",
+			argv[0], ret);
 		exit(1);
 	}
 	if ((ret = blkid_probe_all(cache)) < 0) {