]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
Internal changes to the blkid library:
authorTheodore Ts'o <tytso@mit.edu>
Sat, 22 Feb 2003 22:15:20 +0000 (17:15 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 22 Feb 2003 22:15:20 +0000 (17:15 -0500)
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.

lib/blkid/ChangeLog
lib/blkid/blkid.h
lib/blkid/blkidP.h
lib/blkid/cache.c
lib/blkid/devname.c
lib/blkid/probe.c
lib/blkid/probe.h
lib/blkid/read.c
lib/blkid/resolve.c
lib/blkid/save.c
lib/blkid/tag.c

index 4cb7b9357b3f1100c5b2a5ac2146dab9d22d2904..8fcab4eb502ac4e76576821d7b8f3495df01d983 100644 (file)
@@ -1,5 +1,38 @@
 2003-02-22  Theodore Ts'o  <tytso@mit.edu>
 
+       * devname.c (blkid_probe_all), tag.c (blkid_find_dev_with_tag): 
+               Call blkid_read_cache to make sure the in-core version of
+               the data structure is the latest.  After probing all of
+               the devices in blkid_probe_all() force the cache file to
+               be written out, the probe_all represents a lot of effort
+               that shouldn't be lost.
+
+       * tag.c (blkid_set_tag): Always replace an existing tag with the
+               new value; we no longer suppor multiple tags with the same
+               value attached to a device, as this was never really
+               supported well, and significantly increased the code
+               complexity.
+
+       * probe.c (probe_ext2): Change handling of ext2/ext3 filesystems.
+               Ext3 filesystems are now always treated as ext2
+               filesystems, with a special SEC_TYPE tag set to ext3.
+               This was necessary because we now longer support multiple
+               tags with the same name attached to a device.
+
+       * save.c (save_dev): Don't special case the TYPE tag; just write
+               it out along with all of the normal tags.
+               (blkid_flush_cache): Eliminate special case code for stdout.
+
+       * cache.c (blkid_new_cache, blkid_get_cache): Eliminate
+               blkid_new_cache and fold into blkid_get_cache (moved to
+               cache.c)
+
+       * read.c (blkid_read_cache): New function created from
+               blkid_get_cache which used to be in read.c that only
+               updates the in-core cache data structure from the file.
+               Uses the file modification time of the cache file to
+               determine whether the cache file needs to be re-read.
+
        * cache.c, dev.c, devname.c, devno.c, probe.c, read.c, resolve.c,
                save.c, tag.c, blkidP.h: Add dynamic debugging
                capabilities, controlled by the environment variable
index de6a9825d25a862d25e10fb32b449b2116fde1ab..75b20ad586bb747ad6b490c7acae6bbaf8b3f1ae 100644 (file)
@@ -48,6 +48,7 @@ typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
 
 /* cache.c */
 extern void blkid_put_cache(blkid_cache cache);
+extern int blkid_get_cache(blkid_cache *cache, const char *filename);
 
 /* dev.c */
 extern const char *blkid_dev_devname(blkid_dev dev);
@@ -68,7 +69,6 @@ extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname,
 extern blkid_loff_t blkid_get_dev_size(int fd);
 
 /* read.c */
-int blkid_get_cache(blkid_cache *cache, const char *filename);
 
 /* resolve.c */
 extern char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
index db05675b8f6bea6d5aed2a0d7ccb77fd58cf2406..a121106cb25fa6b45cbc7a1a4a497685ceeb51b2 100644 (file)
@@ -42,7 +42,6 @@ struct blkid_struct_dev
 };
 
 #define BLKID_BID_FL_VERIFIED  0x0001  /* Device data validated from disk */
-#define BLKID_BID_FL_MTYPE     0x0002  /* Device has multiple type matches */
 #define BLKID_BID_FL_INVALID   0x0004  /* Device is invalid */
 
 /*
@@ -87,6 +86,7 @@ struct blkid_struct_cache
        struct list_head        bic_devs;       /* List head of all devices */
        struct list_head        bic_tags;       /* List head of all tag types */
        time_t                  bic_time;       /* Last probe time */
+       time_t                  bic_ftime;      /* Mod time of the cachefile */
        unsigned int            bic_flags;      /* Status flags of the cache */
        char                    *bic_filename;  /* filename of cache */
 };
@@ -96,7 +96,6 @@ struct blkid_struct_cache
 
 extern char *blkid_strdup(const char *s);
 extern char *blkid_strndup(const char *s, const int length);
-extern blkid_cache blkid_new_cache(void);
 
 #define BLKID_CACHE_FILE "/etc/blkid.tab"
 extern const char *blkid_devdirs[];
@@ -209,6 +208,9 @@ extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
 /* probe.c */
 extern blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev);
 
+/* read.c */
+extern void blkid_read_cache(blkid_cache cache);
+
 /* save.c */
 extern int blkid_flush_cache(blkid_cache cache);
 
@@ -218,7 +220,7 @@ extern int blkid_flush_cache(blkid_cache cache);
 extern void blkid_free_tag(blkid_tag tag);
 extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type);
 extern int blkid_set_tag(blkid_dev dev, const char *name,
-                        const char *value, const int vlength, int replace);
+                        const char *value, const int vlength);
 
 /*
  * Functions to create and find a specific tag type: dev.c
index 93124160af62ade386ce7e80d10ab9998127d284..50d52a02c269b20aed1d13c14dfde16d25664ec9 100644 (file)
@@ -15,7 +15,7 @@
 
 int blkid_debug_mask;
 
-blkid_cache blkid_new_cache(void)
+int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
 {
        blkid_cache cache;
 
@@ -29,15 +29,23 @@ blkid_cache blkid_new_cache(void)
        }
 #endif
 
-       DBG(DEBUG_CACHE, printf("initializing empty cache\n"));
+       DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
+                               filename ? filename : "default cache"));
 
        if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
-               return NULL;
+               return -BLKID_ERR_MEM;
 
        INIT_LIST_HEAD(&cache->bic_devs);
        INIT_LIST_HEAD(&cache->bic_tags);
 
-       return cache;
+       if (!filename || !strlen(filename))
+               filename = BLKID_CACHE_FILE;
+       cache->bic_filename = blkid_strdup(filename);
+       
+       blkid_read_cache(cache);
+       
+       *ret_cache = cache;
+       return 0;
 }
 
 void blkid_put_cache(blkid_cache cache)
@@ -97,8 +105,9 @@ int main(int argc, char** argv)
                        argv[1] ? argv[1] : BLKID_CACHE_FILE);
                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))
index 7d885515fb3bb7f42771f35e98245ff67b6d2e6c..27a9d0c0fab6bd0178f012a7ef6137a96bd7ac5b 100644 (file)
@@ -280,6 +280,7 @@ int blkid_probe_all(blkid_cache cache)
            time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
                return 0;
 
+       blkid_read_cache(cache);
        evms_probe_all(cache);
 #ifdef VG_DIR
        lvm_probe_all(cache);
@@ -340,6 +341,7 @@ int blkid_probe_all(blkid_cache cache)
 
        cache->bic_time = time(0);
        cache->bic_flags |= BLKID_BIC_FL_PROBED;
+       blkid_flush_cache(cache);
        return 0;
 }
 
@@ -347,6 +349,7 @@ int blkid_probe_all(blkid_cache cache)
 int main(int argc, char **argv)
 {
        blkid_cache cache = NULL;
+       int ret;
 
        blkid_debug_mask = DEBUG_ALL;
        if (argc != 1) {
@@ -354,8 +357,9 @@ int main(int argc, char **argv)
                        "Probe all devices and exit\n", argv[0]);
                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 (blkid_probe_all(cache) < 0)
index 4f76ba580cfabfa0578018d1901eaaa5ef3ddd2e..2484a5f9df5c0200e1300145dfdd6723396298ee 100644 (file)
@@ -74,15 +74,15 @@ static void set_uuid(blkid_dev dev, uuid_t uuid)
 
        if (!uuid_is_null(uuid)) {
                uuid_unparse(uuid, str);
-               blkid_set_tag(dev, "UUID", str, sizeof(str), 1);
+               blkid_set_tag(dev, "UUID", str, sizeof(str));
        }
 }
 
 static int probe_ext2(int fd, blkid_cache cache, blkid_dev dev,
-                     struct blkid_magic *id, unsigned char *buf,
-                     const char **ret_sectype)
+                     struct blkid_magic *id, unsigned char *buf)
 {
        struct ext2_super_block *es;
+       const char *sec_type = 0;
 
        es = (struct ext2_super_block *)buf;
 
@@ -91,26 +91,28 @@ static int probe_ext2(int fd, blkid_cache cache, blkid_dev dev,
                   blkid_le32(es->s_feature_incompat),
                   blkid_le32(es->s_feature_ro_compat)));
 
-       /* Make sure we don't keep re-probing as ext2 for a journaled fs */
-       if (!strcmp(id->bim_type, "ext2") &&
-           ((blkid_le32(es->s_feature_compat) &
-             EXT3_FEATURE_COMPAT_HAS_JOURNAL) ||
-            (blkid_le32(es->s_feature_incompat) &
-             EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)))
+       /* Distinguish between jbd and ext2/3 fs */
+       if (id && (blkid_le32(es->s_feature_incompat) &
+                  EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
                return -BLKID_ERR_PARAM;
 
        if (strlen(es->s_volume_name))
                blkid_set_tag(dev, "LABEL", es->s_volume_name,
-                             sizeof(es->s_volume_name), 1);
+                             sizeof(es->s_volume_name));
 
        set_uuid(dev, es->s_uuid);
 
+       if (blkid_le32(es->s_feature_compat) &
+           EXT3_FEATURE_COMPAT_HAS_JOURNAL)
+               sec_type = "ext3";
+       
+       blkid_set_tag(dev, "SEC_TYPE", sec_type, 0);
+
        return 0;
 }
 
 static int probe_jbd(int fd, blkid_cache cache, blkid_dev dev, 
-                    struct blkid_magic *id, unsigned char *buf,
-                    const char **ret_sectype)
+                    struct blkid_magic *id, unsigned char *buf)
 {
        struct ext2_super_block *es = (struct ext2_super_block *) buf;
 
@@ -118,33 +120,11 @@ static int probe_jbd(int fd, blkid_cache cache, blkid_dev dev,
              EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
                return -BLKID_ERR_PARAM;
 
-       return (probe_ext2(fd, cache, dev, id, buf, ret_sectype));
-}
-
-static int probe_ext3(int fd, blkid_cache cache, blkid_dev dev,
-                     struct blkid_magic *id, unsigned char *buf,
-                     const char **ret_sectype)
-{
-       struct ext2_super_block *es = (struct ext2_super_block *) buf;
-       int ret;
-
-       if (!(blkid_le32(es->s_feature_compat) &
-             EXT3_FEATURE_COMPAT_HAS_JOURNAL))
-               return -BLKID_ERR_PARAM;
-
-       if ((ret = probe_ext2(fd, cache, dev, id, buf, ret_sectype)) < 0)
-               return ret;
-
-       if (!(blkid_le32(es->s_feature_incompat) &
-             EXT3_FEATURE_INCOMPAT_RECOVER))
-               *ret_sectype = "ext2";
-
-       return 0;
+       return (probe_ext2(fd, cache, dev, 0, buf));
 }
 
 static int probe_vfat(int fd, blkid_cache cache, blkid_dev dev,
-                     struct blkid_magic *id, unsigned char *buf,
-                     const char **ret_sectype)
+                     struct blkid_magic *id, unsigned char *buf)
 {
        struct vfat_super_block *vs;
        char serno[10];
@@ -158,20 +138,19 @@ static int probe_vfat(int fd, blkid_cache cache, blkid_dev dev,
                        --end;
                if (end >= vs->vs_label)
                        blkid_set_tag(dev, "LABEL", vs->vs_label,
-                                     end - vs->vs_label + 1, 1);
+                                     end - vs->vs_label + 1);
        }
 
        /* We can't just print them as %04X, because they are unaligned */
        sprintf(serno, "%02X%02X-%02X%02X", vs->vs_serno[3], vs->vs_serno[2],
                vs->vs_serno[1], vs->vs_serno[0]);
-       blkid_set_tag(dev, "UUID", serno, sizeof(serno), 1);
+       blkid_set_tag(dev, "UUID", serno, sizeof(serno));
 
        return 0;
 }
 
 static int probe_msdos(int fd, blkid_cache cache, blkid_dev dev,
-                      struct blkid_magic *id, unsigned char *buf,
-                      const char **ret_sectype)
+                      struct blkid_magic *id, unsigned char *buf)
 {
        struct msdos_super_block *ms = (struct msdos_super_block *) buf;
        char serno[10];
@@ -183,20 +162,19 @@ static int probe_msdos(int fd, blkid_cache cache, blkid_dev dev,
                        --end;
                if (end >= ms->ms_label)
                        blkid_set_tag(dev, "LABEL", ms->ms_label,
-                                     end - ms->ms_label + 1, 1);
+                                     end - ms->ms_label + 1);
        }
 
        /* We can't just print them as %04X, because they are unaligned */
        sprintf(serno, "%02X%02X-%02X%02X", ms->ms_serno[3], ms->ms_serno[2],
                ms->ms_serno[1], ms->ms_serno[0]);
-       blkid_set_tag(dev, "UUID", serno, 0, 1);
+       blkid_set_tag(dev, "UUID", serno, 0);
 
        return 0;
 }
 
 static int probe_xfs(int fd, blkid_cache cache, blkid_dev dev,
-                    struct blkid_magic *id, unsigned char *buf,
-                    const char **ret_sectype)
+                    struct blkid_magic *id, unsigned char *buf)
 {
        struct xfs_super_block *xs;
 
@@ -204,14 +182,13 @@ static int probe_xfs(int fd, blkid_cache cache, blkid_dev dev,
 
        if (strlen(xs->xs_fname))
                blkid_set_tag(dev, "LABEL", xs->xs_fname,
-                             sizeof(xs->xs_fname), 1);
+                             sizeof(xs->xs_fname));
        set_uuid(dev, xs->xs_uuid);
        return 0;
 }
 
 static int probe_reiserfs(int fd, blkid_cache cache, blkid_dev dev,
-                         struct blkid_magic *id, unsigned char *buf,
-                         const char **ret_sectype)
+                         struct blkid_magic *id, unsigned char *buf)
 {
        struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf;
        unsigned int blocksize;
@@ -227,7 +204,7 @@ static int probe_reiserfs(int fd, blkid_cache cache, blkid_dev dev,
            !strcmp(id->bim_magic, "ReIsEr3Fs")) {
                if (strlen(rs->rs_label)) {
                        blkid_set_tag(dev, "LABEL", rs->rs_label,
-                                     sizeof(rs->rs_label), 1);
+                                     sizeof(rs->rs_label));
                }
 
                set_uuid(dev, rs->rs_uuid);
@@ -253,7 +230,6 @@ static int probe_reiserfs(int fd, blkid_cache cache, blkid_dev dev,
 static struct blkid_magic type_array[] = {
 /*  type     kboff   sboff len  magic                  probe */
   { "jbd",      1,   0x38,  2, "\123\357",             probe_jbd },
-  { "ext3",     1,   0x38,  2, "\123\357",             probe_ext3 },
   { "ext2",     1,   0x38,  2, "\123\357",             probe_ext2 },
   { "reiserfs",         8,   0x34,  8, "ReIsErFs",             probe_reiserfs },
   { "reiserfs", 64,   0x34,  9, "ReIsEr2Fs",           probe_reiserfs },
@@ -299,17 +275,6 @@ static struct blkid_magic type_array[] = {
   {   NULL,     0,      0,  0, NULL,                   NULL }
 };
 
-/*
- * If a device's filesystem no longer checks out, we need to nuke
- * information about it from the entry.
- */
-static void blkid_invalidate_fs(blkid_dev dev)
-{
-       blkid_set_tag(dev, "TYPE", 0, 0, 0);
-       blkid_set_tag(dev, "LABEL", 0, 0, 0);
-       blkid_set_tag(dev, "UUID", 0, 0, 0);
-}      
-
 /*
  * Verify that the data in dev is consistent with what is on the actual
  * block device (using the devname field only).  Normally this will be
@@ -323,7 +288,7 @@ blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
 {
        struct blkid_magic *id;
        unsigned char *bufs[BLKID_BLK_OFFS + 1], *buf;
-       const char *sec_type, *type;
+       const char *type;
        struct stat st;
        time_t diff;
        int fd, idx;
@@ -364,7 +329,6 @@ blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
         */
 try_again:
        type = 0;
-       sec_type = 0;
        if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) {
                uuid_t  uuid;
 
@@ -402,7 +366,7 @@ try_again:
                        continue;
 
                if ((id->bim_probe == NULL) ||
-                   (id->bim_probe(fd, cache, dev, id, buf, &sec_type) == 0)) {
+                   (id->bim_probe(fd, cache, dev, id, buf) == 0)) {
                        type = id->bim_type;
                        goto found_type;
                }
@@ -412,7 +376,10 @@ try_again:
                /*
                 * Zap the device filesystem type and try again
                 */
-               blkid_invalidate_fs(dev);
+               blkid_set_tag(dev, "TYPE", 0, 0);
+               blkid_set_tag(dev, "SEC_TYPE", 0, 0);
+               blkid_set_tag(dev, "LABEL", 0, 0);
+               blkid_set_tag(dev, "UUID", 0, 0);
                goto try_again;
        }
 
@@ -428,9 +395,7 @@ found_type:
                dev->bid_flags |= BLKID_BID_FL_VERIFIED;
                cache->bic_flags |= BLKID_BIC_FL_CHANGED;
 
-               blkid_set_tag(dev, "TYPE", type, 0, 1);
-               if (sec_type)
-                       blkid_set_tag(dev, "TYPE", sec_type, 0, 0);
+               blkid_set_tag(dev, "TYPE", type, 0);
                                
                DBG(DEBUG_PROBE, printf("%s: devno 0x%04Lx, type %s\n",
                           dev->bid_name, st.st_rdev, type));
@@ -446,6 +411,7 @@ int main(int argc, char **argv)
 {
        blkid_dev dev;
        blkid_cache cache;
+       int ret;
 
        blkid_debug_mask = DEBUG_ALL;
        if (argc != 2) {
@@ -453,7 +419,11 @@ int main(int argc, char **argv)
                        "Probe a single device to determine type\n", argv[0]);
                exit(1);
        }
-       cache = blkid_new_cache();
+       if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
+               fprintf(stderr, "%s: error creating cache (%d)\n",
+                       argv[0], ret);
+               exit(1);
+       }
        dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
        if (!dev) {
                printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
index 3e02604bcb267f6387e9f99608252121e2432f84..391428cab9ced3c1e0fdbeb54571ba939597c973 100644 (file)
@@ -19,8 +19,7 @@
 struct blkid_magic;
 
 typedef int (*blkid_probe_t)(int fd, blkid_cache cache, blkid_dev dev, 
-                            struct blkid_magic *id, unsigned char *buf,
-                            const char **ret_sectype);
+                            struct blkid_magic *id, unsigned char *buf);
 
 struct blkid_magic {
        const char      *bim_type;      /* type name for this magic */
index fdee756a27e097073cf1595c5e1409104a54d8df..71618e3d0c948208b04e5ed9a1897c0ec870a4f8 100644 (file)
@@ -14,7 +14,9 @@
 #include <ctype.h>
 #include <string.h>
 #include <time.h>
+#include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <unistd.h>
 #if HAVE_ERRNO_H
 #include <errno.h>
@@ -312,7 +314,7 @@ static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
                /* FIXME: need to parse a long long eventually */
                dev->bid_time = strtol(value, 0, 0);
        else
-               ret = blkid_set_tag(dev, name, value, strlen(value), 0);
+               ret = blkid_set_tag(dev, name, value, strlen(value));
 
        DBG(DEBUG_READ, printf("    tag: %s=\"%s\"\n", name, value));
 
@@ -367,40 +369,37 @@ static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
  * a newly allocated cache struct.  If the file doesn't exist, return a
  * new empty cache struct.
  */
-int blkid_get_cache(blkid_cache *cache, const char *filename)
+void blkid_read_cache(blkid_cache cache)
 {
        FILE *file;
        char buf[4096];
-       int lineno = 0;
+       int fd, lineno = 0;
+       struct stat st;
 
        if (!cache)
-               return -BLKID_ERR_PARAM;
-
-       if ((*cache = blkid_new_cache()) == NULL)
-               return -BLKID_ERR_MEM;
+               return;
 
-       if (!filename || !strlen(filename))
-               filename = BLKID_CACHE_FILE;
-       else
-               (*cache)->bic_filename = blkid_strdup(filename);
-
-       DBG(DEBUG_READ|DEBUG_CACHE, printf("reading cache file %s\n",
-                                          filename));
-
-       if (!strcmp(filename, "-"))
-               file = stdin;
-       else {
-               /*
-                * If the file doesn't exist, then we just return an empty
-                * struct so that the cache can be populated.
-                */
-               if (access(filename, R_OK) < 0)
-                       return 0;
-
-               file = fopen(filename, "r");
-               if (!file)
-                       return errno; /* Should never happen */
+       /*
+        * If the file doesn't exist, then we just return an empty
+        * struct so that the cache can be populated.
+        */
+       if ((fd = open(cache->bic_filename, O_RDONLY)) < 0)
+               return 0;
+       if (fstat(fd, &st) < 0)
+               goto errout;
+       if ((st.st_mtime == cache->bic_ftime) ||
+           (cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
+               DBG(DEBUG_CACHE, printf("skipping re-read of %s\n",
+                                       cache->bic_filename));
+               goto errout;
        }
+       
+       DBG(DEBUG_CACHE, printf("reading cache file %s\n",
+                               cache->bic_filename));
+
+       file = fdopen(fd, "r");
+       if (!file)
+               goto errout;
 
        while (fgets(buf, sizeof(buf), file)) {
                blkid_dev dev;
@@ -410,12 +409,12 @@ int blkid_get_cache(blkid_cache *cache, const char *filename)
                lineno++;
                /* Continue reading next line if it ends with a backslash */
                while (buf[end] == '\\' && end < sizeof(buf) - 2 &&
-                      fgets(buf + end, sizeof(buf) - end, stdin)) {
+                      fgets(buf + end, sizeof(buf) - end, file)) {
                        end = strlen(buf) - 1;
                        lineno++;
                }
 
-               if (blkid_parse_line(*cache, &dev, buf) < 0) {
+               if (blkid_parse_line(cache, &dev, buf) < 0) {
                        DBG(DEBUG_READ,
                            printf("blkid: bad format on line %d\n", lineno));
                        continue;
@@ -424,12 +423,13 @@ int blkid_get_cache(blkid_cache *cache, const char *filename)
        /*
         * Initially we do not need to write out the cache file.
         */
-       (*cache)->bic_flags &= ~BLKID_BIC_FL_CHANGED;
-
-       if (file != stdin)
-               fclose(file);
+       cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
+       cache->bic_ftime = st.st_mtime;
 
        return 0;
+errout:
+       close(fd);
+       return;
 }
 
 #ifdef TEST_PROGRAM
index 7e729cbc93020d9a8cdf018215de1dc2710334d3..62764c7d0845de5be26ee6fb8a9558af5f154b64 100644 (file)
@@ -70,8 +70,6 @@ char *blkid_get_devname(blkid_cache cache, const char *token,
 
        if (!cache) {
                if (blkid_get_cache(&c, NULL) < 0)
-                       c = blkid_new_cache();
-               if (!c)
                        return NULL;
        }
 
@@ -115,7 +113,7 @@ int main(int argc, char **argv)
                        argv[0], argv[0]);
                exit(1);
        }
-       if (blkid_get_cache(&cache, 0) < 0) {
+       if (blkid_get_cache(&cache, "/dev/null") < 0) {
                fprintf(stderr, "Couldn't get blkid cache\n");
                exit(1);
        }
index 82b9b775412d968382198fd382b742dedbdd926d..bed211a1a84fb8cce7ec8b16815c5e8d2de4d58f 100644 (file)
@@ -37,14 +37,13 @@ static int save_dev(blkid_dev dev, FILE *file)
            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,63 +61,59 @@ int blkid_flush_cache(blkid_cache cache)
        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;
-               }
+       /* 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);
+       /*
+        * 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 (!file) {
+               file = fopen(filename, "w");
+               opened = filename;
+       }
 
-               DBG(DEBUG_SAVE,
-                   printf("cache file %s (really %s)\n", filename, opened));
+       DBG(DEBUG_SAVE,
+           printf("writing cache file %s (really %s)\n",
+                  filename, opened));
 
-               if (!file) {
-                       ret = errno;
-                       goto errout;
-               }
+       if (!file) {
+               ret = errno;
+               goto errout;
        }
 
        list_for_each(p, &cache->bic_devs) {
@@ -134,27 +129,25 @@ int blkid_flush_cache(blkid_cache cache)
                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;
-
-                               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));
+       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));
                }
        }
 
@@ -177,8 +170,9 @@ int main(int argc, char **argv)
                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) {
index e8b54f49461292a2d4ea25d71d20c17d138bd559..d3db41c078a2d66fdec8b8b4dac9d6ef8ba8fe1e 100644 (file)
@@ -97,15 +97,10 @@ static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
 /*
  * Set a tag on an existing device.
  * 
- * If replace is non-zero, blkid_set_tag() will replace the existing
- * tag with the specified value.  Otherwise, it will add the specified
- * tag to the device.
- *
- * If value is NULL, then delete all tags with that name from the
- * device.
+ * If value is NULL, then delete the tagsfrom the device.
  */
 int blkid_set_tag(blkid_dev dev, const char *name,
-                 const char *value, const int vlength, int replace)
+                 const char *value, const int vlength)
 {
        blkid_tag       t = 0, head = 0;
        char            *val = 0;
@@ -113,64 +108,52 @@ int blkid_set_tag(blkid_dev dev, const char *name,
        if (!dev || !name)
                return -BLKID_ERR_PARAM;
 
-repeat:
+       if (!(val = blkid_strndup(value, vlength)))
+               return -BLKID_ERR_MEM;
        t = blkid_find_tag_dev(dev, name);
-       val = blkid_strndup(value, vlength);
        if (!value) {
-               if (t) {
+               if (t)
                        blkid_free_tag(t);
-                       goto repeat;
-               } else
-                       goto link_tags;
-       }
-       if (!val)
-               goto errout;
-       if (t) {
+       } else if (t) {
                if (!strcmp(t->bit_val, val)) {
                        /* Same thing, exit */
                        free(val);
                        return 0;
                }
-               if (replace) {
-                       free(t->bit_val);
-                       t->bit_val = val;
-                       goto link_tags;
-               }
-               dev->bid_flags |= BLKID_BID_FL_MTYPE;
-       }
-
-       /* Existing tag not present, add to device */
-       t = blkid_new_tag();
-       if (!t)
-               goto errout;
-       t->bit_name = blkid_strdup(name);
-       t->bit_val = val;
-       t->bit_dev = dev;
-
-       list_add_tail(&t->bit_tags, &dev->bid_tags);
+               free(t->bit_val);
+               t->bit_val = val;
+       } else {
+               /* Existing tag not present, add to device */
+               if (!(t = blkid_new_tag()))
+                       goto errout;
+               t->bit_name = blkid_strdup(name);
+               t->bit_val = val;
+               t->bit_dev = dev;
+
+               list_add_tail(&t->bit_tags, &dev->bid_tags);
                
-       if (dev->bid_cache) {
-               head = blkid_find_head_cache(dev->bid_cache, t->bit_name);
-               if (!head) {
-                       head = blkid_new_tag();
-                       if (!head)
-                               goto errout;
-
-                       DBG(DEBUG_TAG,
-                           printf("    creating new cache tag head %s\n",
-                                  name));
-                       head->bit_name = blkid_strdup(name);
-                       if (!head->bit_name)
-                               goto errout;
-                       list_add_tail(&head->bit_tags,
-                                     &dev->bid_cache->bic_tags);
+               if (dev->bid_cache) {
+                       head = blkid_find_head_cache(dev->bid_cache,
+                                                    t->bit_name);
+                       if (!head) {
+                               head = blkid_new_tag();
+                               if (!head)
+                                       goto errout;
+
+                               DBG(DEBUG_TAG,
+                                   printf("    creating new cache tag head %s\n", name));
+                               head->bit_name = blkid_strdup(name);
+                               if (!head->bit_name)
+                                       goto errout;
+                               list_add_tail(&head->bit_tags,
+                                             &dev->bid_cache->bic_tags);
+                       }
+                       list_add_tail(&t->bit_names, &head->bit_names);
                }
-               list_add_tail(&t->bit_names, &head->bit_names);
        }
        
-link_tags:
        /* Link common tags directly to the device struct */
-       if (!strcmp(name, "TYPE") && (!val || !dev->bid_type))
+       if (!strcmp(name, "TYPE"))
                dev->bid_type = val;
        else if (!strcmp(name, "LABEL"))
                dev->bid_label = val;
@@ -313,7 +296,7 @@ extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
                                         const char *type,
                                         const char *value)
 {
-       blkid_tag       head, found;
+       blkid_tag       head;
        blkid_dev       dev;
        int             pri;
        struct list_head *p;
@@ -321,11 +304,12 @@ extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
        if (!cache || !type || !value)
                return NULL;
 
+       blkid_read_cache(cache);
+       
        DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value));
        
 try_again:
        pri = -1;
-       found = 0;
        dev = 0;
        head = blkid_find_head_cache(cache, type);
 
@@ -336,15 +320,16 @@ try_again:
 
                        if (!strcmp(tmp->bit_val, value) &&
                            tmp->bit_dev->bid_pri > pri) {
-                               found = tmp;
-                               dev = found->bit_dev;
+                               dev = tmp->bit_dev;
                                pri = dev->bid_pri;
                        }
                }
        }
-       dev = blkid_verify_devname(cache, dev);
-       if (dev && strcmp(found->bit_val, value))
-               dev = 0;
+       if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
+               dev = blkid_verify_devname(cache, dev);
+               if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
+                       goto try_again;
+       }
 
        if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
                blkid_probe_all(cache);