summaryrefslogtreecommitdiff
path: root/lib/blkid
diff options
context:
space:
mode:
Diffstat (limited to 'lib/blkid')
-rw-r--r--lib/blkid/ChangeLog7
-rw-r--r--lib/blkid/Makefile.in53
-rw-r--r--lib/blkid/blkid.h49
-rw-r--r--lib/blkid/blkidP.h61
-rw-r--r--lib/blkid/cache.c24
-rw-r--r--lib/blkid/dev.c213
-rw-r--r--lib/blkid/devname.c179
-rw-r--r--lib/blkid/devno.c118
-rw-r--r--lib/blkid/libblkid.3.in6
-rw-r--r--lib/blkid/probe.c818
-rw-r--r--lib/blkid/probe.h12
-rw-r--r--lib/blkid/read.c149
-rw-r--r--lib/blkid/resolve.c17
-rw-r--r--lib/blkid/save.c80
-rw-r--r--lib/blkid/tag.c195
15 files changed, 669 insertions, 1312 deletions
diff --git a/lib/blkid/ChangeLog b/lib/blkid/ChangeLog
index 827a685c..b73e5aa3 100644
--- a/lib/blkid/ChangeLog
+++ b/lib/blkid/ChangeLog
@@ -1,3 +1,10 @@
+2003-02-12 Theodore Ts'o <tytso@mit.edu>
+
+ * blkid.h, blkidP.h, cache.c, dev.c, devname.c, devno.c, probe.c,
+ probe.h, read.c, resolve.c, save.c, tag.c: Wholesale
+ changes to library to simplify the implementation and
+ shrink its size. Change library version to be 1.0.
+
2003-01-27 Theodore Ts'o <tytso@mit.edu>
* read.c (parse_tag): Do not return that blkid_tag when parsing
diff --git a/lib/blkid/Makefile.in b/lib/blkid/Makefile.in
index 6d8a7767..42528357 100644
--- a/lib/blkid/Makefile.in
+++ b/lib/blkid/Makefile.in
@@ -31,8 +31,8 @@ HFILES_IN= blkid_types.h
LIBRARY= libblkid
LIBDIR= blkid
-ELF_VERSION = 2.0
-ELF_SO_VERSION = 2
+ELF_VERSION = 1.0
+ELF_SO_VERSION = 1
ELF_IMAGE = libblkid
ELF_MYDIR = blkid
ELF_INSTALL_DIR = $(root_libdir)
@@ -97,7 +97,14 @@ tst_resolve: $(srcdir)/resolve.c $(DEPLIBS_BLKID)
tst_save: $(srcdir)/save.c $(DEPLIBS_BLKID)
$(CC) -Wall -o tst_save -DTEST_PROGRAM $(srcdir)/save.c $(LIBS_BLKID) $(LIBUUID) $(ALL_CFLAGS)
-check:: tst_cache tst_dev tst_devname tst_devno tst_getsize tst_probe \
+../../misc/blkid.o: $(top_srcdir)/misc/blkid.c blkid.h
+ $(CC) -Wall $(ALL_CFLAGS) -c $(top_srcdir)/misc/blkid.c \
+ -o ../../misc/blkid.o
+
+blkid: ../../misc/blkid.o libblkid.a $(LIBBLKID) $(LIBUUID)
+ $(CC) -Wall -o blkid ../../misc/blkid.o libblkid.a $(LIBBLKID) $(LIBUUID)
+
+check:: tst_cache tst_devname tst_devno tst_getsize tst_probe \
tst_read tst_resolve tst_save
installdirs::
@@ -129,7 +136,7 @@ uninstall::
clean::
$(RM) -f \#* *.s *.o *.orig *.a *~ *.bak tst_* core profiled/* \
checker/* blkid_types.h ../libblkid.a ../libblkid_p.a \
- $(SMANPAGES)
+ $(SMANPAGES) blkid
mostlyclean:: clean
distclean:: clean
@@ -140,21 +147,27 @@ distclean:: clean
# Makefile dependencies follow. This must be the last section in
# the Makefile.in file
#
-cache.o: $(srcdir)/cache.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h
-dev.o: $(srcdir)/dev.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h
-devname.o: $(srcdir)/devname.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h
-devno.o: $(srcdir)/devno.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h
-getsize.o: $(srcdir)/getsize.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h
-llseek.o: $(srcdir)/llseek.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h
-read.o: $(srcdir)/read.c $(srcdir)/blkid.h $(srcdir)/list.h \
- $(top_builddir)/lib/blkid/blkid_types.h $(top_srcdir)/lib/uuid/uuid.h
-save.o: $(srcdir)/save.c $(srcdir)/blkid.h $(srcdir)/list.h \
+cache.o: $(srcdir)/cache.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h
+dev.o: $(srcdir)/dev.c $(srcdir)/blkidP.h $(srcdir)/blkid.h $(srcdir)/list.h \
$(top_builddir)/lib/blkid/blkid_types.h
-tag.o: $(srcdir)/tag.c $(srcdir)/blkid.h $(srcdir)/list.h \
+devname.o: $(srcdir)/devname.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h
+devno.o: $(srcdir)/devno.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h
+getsize.o: $(srcdir)/getsize.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h
+llseek.o: $(srcdir)/llseek.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h
+probe.o: $(srcdir)/probe.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h \
+ $(top_srcdir)/lib/uuid/uuid.h $(srcdir)/probe.h
+read.o: $(srcdir)/read.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h \
+ $(top_srcdir)/lib/uuid/uuid.h
+resolve.o: $(srcdir)/resolve.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h $(srcdir)/probe.h
+save.o: $(srcdir)/save.c $(srcdir)/blkidP.h $(srcdir)/blkid.h \
+ $(srcdir)/list.h $(top_builddir)/lib/blkid/blkid_types.h
+tag.o: $(srcdir)/tag.c $(srcdir)/blkidP.h $(srcdir)/blkid.h $(srcdir)/list.h \
$(top_builddir)/lib/blkid/blkid_types.h
diff --git a/lib/blkid/blkid.h b/lib/blkid/blkid.h
index f8faa0dd..c0ec660e 100644
--- a/lib/blkid/blkid.h
+++ b/lib/blkid/blkid.h
@@ -13,34 +13,62 @@
#ifndef _BLKID_BLKID_H
#define _BLKID_BLKID_H
+#include <blkid/blkid_types.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-#define BLKID_VERSION "1.2.0"
-#define BLKID_DATE "22-Nov-2001"
+#define BLKID_VERSION "1.0.0"
+#define BLKID_DATE "12-Feb-2003"
typedef struct blkid_struct_dev *blkid_dev;
-typedef struct blkid_struct_tag *blkid_tag;
typedef struct blkid_struct_cache *blkid_cache;
+typedef __s64 blkid_loff_t;
+
+typedef struct blkid_struct_tag_iterate *blkid_tag_iterate;
+typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
+
+/*
+ * Flags for blkid_get_devname
+ *
+ * BLKID_DEV_CREATE Create an empty device structure if not found
+ * in the cache.
+ * BLKID_DEV_VERIFY Make sure the device structure corresponds
+ * with reality.
+ * BLKID_DEV_FIND Just look up a device entry, and return NULL
+ * if it is not found.
+ * BLKID_DEV_NORMAL Get a valid device structure, either from the
+ * cache or by probing the device.
+ */
+#define BLKID_DEV_FIND 0x0000
+#define BLKID_DEV_CREATE 0x0001
+#define BLKID_DEV_VERIFY 0x0002
+#define BLKID_DEV_NORMAL (BLKID_DEV_CREATE | BLKID_DEV_VERIFY)
/* cache.c */
-extern void blkid_free_cache(blkid_cache cache);
+extern void blkid_put_cache(blkid_cache cache);
/* dev.c */
extern const char *blkid_devname_name(blkid_dev dev);
-typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache);
extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev);
extern void blkid_dev_iterate_end(blkid_dev_iterate iterate);
+/* devno.c */
+extern char *blkid_devno_to_devname(dev_t devno);
+
/* devname.c */
-extern int blkid_probe_all(blkid_cache *cache);
-extern blkid_dev blkid_get_devname(blkid_cache cache, const char *devname);
+extern int blkid_probe_all(blkid_cache cache);
+extern blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
+ int flags);
+
+/* getsize.c */
+extern blkid_loff_t blkid_get_dev_size(int fd);
/* read.c */
-int blkid_read_cache(blkid_cache *cache, const char *filename);
+int blkid_get_cache(blkid_cache *cache, const char *filename);
/* resolve.c */
extern char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
@@ -48,15 +76,12 @@ extern char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
extern char *blkid_get_token(blkid_cache cache, const char *token,
const char *value);
-/* save.c */
-extern int blkid_save_cache(blkid_cache cache, const char *filename);
-
/* tag.c */
-typedef struct blkid_struct_tag_iterate *blkid_tag_iterate;
extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev);
extern int blkid_tag_next(blkid_tag_iterate iterate,
const char **type, const char **value);
extern void blkid_tag_iterate_end(blkid_tag_iterate iterate);
+
extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
const char *type,
const char *value);
diff --git a/lib/blkid/blkidP.h b/lib/blkid/blkidP.h
index 6b300610..5a998029 100644
--- a/lib/blkid/blkidP.h
+++ b/lib/blkid/blkidP.h
@@ -19,9 +19,6 @@
#include <blkid/blkid.h>
#include <blkid/list.h>
-#include <blkid/blkid_types.h>
-
-typedef __s64 blkid_loff_t;
/*
* This describes the attributes of a specific device.
@@ -33,6 +30,7 @@ struct blkid_struct_dev
{
struct list_head bid_devs; /* All devices in the cache */
struct list_head bid_tags; /* All tags for this device */
+ blkid_cache bid_cache; /* Dev belongs to this cache */
char *bid_name; /* Device inode pathname */
char *bid_type; /* Preferred device TYPE */
blkid_loff_t bid_size; /* Filesystem size in bytes */
@@ -47,6 +45,7 @@ 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 */
/*
* Each tag defines a NAME=value pair for a particular device. The tags
@@ -63,6 +62,7 @@ struct blkid_struct_tag
char *bit_val; /* value of tag */
blkid_dev bit_dev; /* pointer to device */
};
+typedef struct blkid_struct_tag *blkid_tag;
/*
* Minimum number of seconds between device probes, even when reading
@@ -91,19 +91,18 @@ struct blkid_struct_cache
time_t bic_time; /* Last probe time */
unsigned int bic_idmax; /* Highest ID assigned */
unsigned int bic_flags; /* Status flags of the cache */
+ char *bic_filename; /* filename of cache */
};
-#define BLKID_BIC_FL_PARSED 0x0001 /* We parsed a cache file */
#define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */
#define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */
-extern char *string_copy(const char *s);
-extern char *stringn_copy(const char *s, const int length);
-extern void string_free(char *s);
+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 *devdirs[];
+extern const char *blkid_devdirs[];
#define BLKID_ERR_IO 5
#define BLKID_ERR_PROC 9
@@ -193,60 +192,28 @@ static inline void DEB_DUMP_CACHE(blkid_cache cache)
#define DEB_DUMP_CACHE(cache) do {} while (0)
#endif
-/*
- * Primitive disk functions: llseek.c, getsize.c
- */
+/* lseek.c */
extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
-extern blkid_loff_t blkid_get_dev_size(int fd);
-
-/*
- * Getting data from the cache file: read.c
- */
-int blkid_read_cache_line(blkid_cache cache, blkid_dev *dev_p, char *cp);
-int blkid_read_cache_file(blkid_cache *cache, FILE *file);
-
-/*
- * Save data to the cache file: save.c
- */
-int blkid_save_cache_file(blkid_cache cache, FILE *file);
-
-/*
- * Identify a device by inode name: probe.c
- */
-extern blkid_dev blkid_devname_to_dev(const char *devname,
- blkid_loff_t size);
-/*
- * Locate a device by inode name: devname.c
- */
-extern blkid_dev blkid_find_devname(blkid_cache cache, const char *devname);
+/* probe.c */
extern blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev);
-extern blkid_dev blkid_get_devname(blkid_cache cache, const char *devname);
-/*
- * Locate a device by device major/minor number: devno.c
- */
-extern char *blkid_devno_to_devname(dev_t devno);
-extern blkid_dev blkid_find_devno(blkid_cache cache, dev_t devno);
-extern blkid_dev blkid_get_devno(blkid_cache cache, dev_t devno);
+/* save.c */
+extern int blkid_flush_cache(blkid_cache cache);
/*
* Functions to create and find a specific tag type: tag.c
*/
-extern blkid_tag blkid_new_tag(void);
extern void blkid_free_tag(blkid_tag tag);
-extern int blkid_create_tag(blkid_dev dev, const char *name,
- const char *value, const int vlength);
-extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type,
- const char *value);
-extern blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type);
+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);
/*
* Functions to create and find a specific tag type: dev.c
*/
extern blkid_dev blkid_new_dev(void);
extern void blkid_free_dev(blkid_dev dev);
-extern blkid_dev blkid_add_dev_to_cache(blkid_cache cache, blkid_dev dev);
#ifdef __cplusplus
}
diff --git a/lib/blkid/cache.c b/lib/blkid/cache.c
index 188dc82c..0e1fc8e5 100644
--- a/lib/blkid/cache.c
+++ b/lib/blkid/cache.c
@@ -2,6 +2,7 @@
* cache.c - allocation/initialization/free routines for cache
*
* Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
@@ -32,12 +33,15 @@ blkid_cache blkid_new_cache(void)
return cache;
}
-void blkid_free_cache(blkid_cache cache)
+void blkid_put_cache(blkid_cache cache)
{
if (!cache)
return;
+ (void) blkid_flush_cache(cache);
+
DBG(printf("freeing cache struct\n"));
+
/* DEB_DUMP_CACHE(cache); */
while (!list_empty(&cache->bic_devs)) {
@@ -63,6 +67,9 @@ void blkid_free_cache(blkid_cache cache)
}
blkid_free_tag(tag);
}
+ if (cache->bic_filename)
+ free(cache->bic_filename);
+
free(cache);
}
@@ -77,16 +84,19 @@ int main(int argc, char** argv)
exit(1);
}
- if ((ret = blkid_read_cache(&cache, argv[1])) < 0)
+ if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
fprintf(stderr, "error %d parsing cache file %s\n", ret,
argv[1] ? argv[1] : BLKID_CACHE_FILE);
- else if ((ret = blkid_probe_all(&cache) < 0))
+ exit(1);
+ }
+ if ((cache = blkid_new_cache()) == NULL) {
+ fprintf(stderr, "%s: error creating cache\n", argv[0]);
+ exit(1);
+ }
+ if ((ret = blkid_probe_all(cache) < 0))
fprintf(stderr, "error probing devices\n");
- else if ((ret = blkid_save_cache(cache, argv[1])) < 0)
- fprintf(stderr, "error %d saving cache to %s\n", ret,
- argv[1] ? argv[1] : BLKID_CACHE_FILE);
- blkid_free_cache(cache);
+ blkid_put_cache(cache);
return ret;
}
diff --git a/lib/blkid/dev.c b/lib/blkid/dev.c
index 2075d451..b6e675ae 100644
--- a/lib/blkid/dev.c
+++ b/lib/blkid/dev.c
@@ -2,6 +2,7 @@
* dev.c - allocation/initialization/free routines for dev
*
* Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
@@ -50,78 +51,11 @@ void blkid_free_dev(blkid_dev dev)
blkid_free_tag(tag);
}
if (dev->bid_name)
- string_free(dev->bid_name);
+ free(dev->bid_name);
free(dev);
}
/*
- * This is kind of ugly, but I want to be able to compare two strings in
- * several different ways. For example, in some cases, if both strings
- * are NULL, those would be considered different, but in other cases
- * they would be considered the same. Hence the ugliness.
- *
- * Use as: "ret == SC_SAME" if both strings exist and are equal
- * this is equivalent to "!(ret & SC_DIFF)"
- * "ret & SC_SAME" if both strings being NULL is also equal
- * this is equivalent to "!(ret == SC_DIFF)"
- * "ret == SC_DIFF" if both strings exist and are different
- * this is equivalent to "!(ret & SC_SAME)"
- * "ret & SC_DIFF" if both strings being NULL is also different
- * this is equivalent to "!(ret == SC_SAME)"
- * "ret == SC_NONE" to see if both strings do not exist
- */
-#define SC_DIFF 0x0001
-#define SC_NONE 0x0003
-#define SC_SAME 0x0002
-
-static int string_compare(char *s1, char *s2)
-{
- if (!s1 && !s2)
- return SC_NONE;
-
- if (!s1 || !s2)
- return SC_DIFF;
-
- if (strcmp(s1, s2))
- return SC_DIFF;
-
- return SC_SAME;
-}
-
-/*
- * Add a tag to the global cache tag list.
- */
-static int add_tag_to_cache(blkid_cache cache, blkid_tag tag)
-{
- blkid_tag head = NULL;
-
- if (!cache || !tag)
- return 0;
-
- DBG(printf(" adding tag %s=%s to cache\n", tag->bit_name, tag->bit_val));
-
- if (!(head = blkid_find_head_cache(cache, tag->bit_name))) {
- head = blkid_new_tag();
- if (!head)
- return -BLKID_ERR_MEM;
-
- DBG(printf(" creating new cache tag head %s\n",tag->bit_name));
- head->bit_name = string_copy(tag->bit_name);
- if (!head->bit_name) {
- blkid_free_tag(head);
- return -BLKID_ERR_MEM;
- }
-
- list_add_tail(&head->bit_tags, &cache->bic_tags);
- }
-
- /* Add this tag to global list */
- list_add_tail(&tag->bit_names, &head->bit_names);
-
- return 0;
-}
-
-/*
* Given a blkid device, return its name
*/
extern const char *blkid_devname_name(blkid_dev dev)
@@ -188,146 +122,3 @@ extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
free(iter);
}
-/*
- * Add a device to the global cache list, along with all its tags.
- */
-blkid_dev blkid_add_dev_to_cache(blkid_cache cache, blkid_dev dev)
-{
- struct list_head *p;
-
- if (!cache || !dev)
- return dev;
-
- if (!dev->bid_id)
- dev->bid_id = ++(cache->bic_idmax);
-
- list_for_each(p, &cache->bic_devs) {
- blkid_dev odev = list_entry(p, struct blkid_struct_dev, bid_devs);
- int dup_uuid, dup_label, dup_name, dup_type;
-
- dup_name = string_compare(odev->bid_name, dev->bid_name);
- dup_label = string_compare(odev->bid_label, dev->bid_label);
- dup_uuid = string_compare(odev->bid_uuid, dev->bid_uuid);
-
- if (odev->bid_id == dev->bid_id)
- dev->bid_id = ++(cache->bic_idmax);
-
- /* Fields different, do nothing (check more fields?) */
- if ((dup_name & SC_DIFF) && (dup_uuid & SC_DIFF) &&
- (dup_label & SC_DIFF))
- continue;
-
- /* We can't simply allow duplicate fields if the bid_type is
- * different, given that a filesystem may change from ext2
- * to ext3 but it will have the same UUID and LABEL fields.
- * We need to discard the old cache entry in this case.
- */
-
- /* If the UUIDs are the same but one is unverified discard it */
- if (dup_uuid == SC_SAME) {
- DBG(printf(" duplicate uuid %s\n", dev->bid_uuid));
- if (!(odev->bid_flags & BLKID_BID_FL_VERIFIED)) {
- dev->bid_id = odev->bid_id; /* keep old id */
- blkid_free_dev(odev);
- goto exit_new;
- } else if (!(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
- blkid_free_dev(dev);
- dev = odev;
- goto exit_old;
- }
-
- /* This shouldn't happen */
- fprintf(stderr, "blkid: same UUID for %s and %s\n",
- dev->bid_name, odev->bid_name);
- }
-
- /* If the device name is the same, discard one of them
- * (prefer one that has been validated, or the first one).
- */
- if (dup_name == SC_SAME) {
- DBG(printf(" duplicate devname %s\n", dev->bid_name));
- if (odev->bid_flags & BLKID_BID_FL_VERIFIED ||
- !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
- if ((dup_uuid & SC_SAME) &&
- (dup_label & SC_SAME)) /* use old id */
- dev->bid_id = odev->bid_id;
- blkid_free_dev(dev);
- dev = odev;
- goto exit_old;
- } else {
- blkid_free_dev(odev);
- goto exit_new;
- }
- }
-
- dup_type = string_compare(odev->bid_type, dev->bid_type);
-
- if (dup_label == SC_SAME && dup_type == SC_SAME) {
- DBG(printf(" duplicate label %s\n", dev->bid_label));
- if (!(odev->bid_flags & BLKID_BID_FL_VERIFIED)) {
- blkid_free_dev(odev);
- goto exit_new;
- } else if (!(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
- blkid_free_dev(dev);
- dev = odev;
- goto exit_old;
- }
- fprintf(stderr, "blkid: same LABEL for %s and %s\n",
- dev->bid_name, odev->bid_name);
- }
- }
-
-exit_new:
- DBG(printf(" adding new devname %s to cache\n", dev->bid_name));
-
- cache->bic_flags |= BLKID_BIC_FL_CHANGED;
-
- list_add_tail(&dev->bid_devs, &cache->bic_devs);
- list_for_each(p, &dev->bid_tags) {
- blkid_tag tag = list_entry(p, struct blkid_struct_tag,
- bit_tags);
- add_tag_to_cache(cache, tag);
- }
- return dev;
-
-exit_old:
- DBG(printf(" using old devname %s from cache\n", dev->bid_name));
- return dev;
-}
-
-#ifdef TEST_PROGRAM
-int main(int argc, char** argv)
-{
- blkid_cache cache;
- blkid_dev dev, newdev;
-
- if ((argc != 3)) {
- fprintf(stderr, "Usage:\t%s dev1 dev2\n"
- "Test that adding the same device to the cache fails\n",
- argv[0]);
- exit(1);
- }
-
- cache = blkid_new_cache();
- if (!cache) {
- perror(argv[0]);
- return 1;
- }
- dev = blkid_devname_to_dev(argv[1], 0);
- newdev = blkid_add_dev_to_cache(cache, dev);
- if (newdev != dev)
- printf("devices changed for %s (unexpected)\n", argv[1]);
- dev = blkid_devname_to_dev(argv[2], 0);
- newdev = blkid_add_dev_to_cache(cache, dev);
- if (newdev != dev)
- printf("devices changed for %s (unexpected)\n", argv[2]);
- dev = blkid_devname_to_dev(argv[2], 0);
- newdev = blkid_add_dev_to_cache(cache, dev);
- if (newdev != dev)
- printf("devices changed for %s (expected)\n", argv[2]);
-
- blkid_free_cache(cache);
-
- return 0;
-}
-#endif
diff --git a/lib/blkid/devname.c b/lib/blkid/devname.c
index 2c8681df..6cb3a8e8 100644
--- a/lib/blkid/devname.c
+++ b/lib/blkid/devname.c
@@ -44,57 +44,66 @@
/*
* Find a dev struct in the cache by device name, if available.
+ *
+ * If there is no entry with the specified device name, and the create
+ * flag is set, then create an empty device entry.
*/
-blkid_dev blkid_find_devname(blkid_cache cache, const char *devname)
+blkid_dev blkid_get_devname(blkid_cache cache, const char *devname,
+ int flags)
{
- blkid_dev dev = NULL;
+ blkid_dev dev = NULL, tmp;
struct list_head *p;
if (!cache || !devname)
return NULL;
list_for_each(p, &cache->bic_devs) {
- blkid_dev tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
-
+ tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
if (strcmp(tmp->bid_name, devname))
continue;
DBG(printf("found devname %s in cache\n", tmp->bid_name));
- dev = blkid_verify_devname(cache, tmp);
+ dev = tmp;
break;
}
- return dev;
-}
-
-/*
- * Return a pointer to an dev struct, either from cache or by probing.
- */
-blkid_dev blkid_get_devname(blkid_cache cache, const char *devname)
-{
- blkid_dev dev;
-
- if ((dev = blkid_find_devname(cache, devname)))
- return dev;
+ if (!dev && (flags & BLKID_DEV_CREATE)) {
+ dev = blkid_new_dev();
+ if (!dev)
+ return NULL;
+ dev->bid_name = blkid_strdup(devname);
+ dev->bid_cache = cache;
+ dev->bid_id = ++(cache->bic_idmax);
+ list_add_tail(&dev->bid_devs, &cache->bic_devs);
+ cache->bic_flags |= BLKID_BIC_FL_CHANGED;
+ }
- dev = blkid_devname_to_dev(devname, 0);
- return blkid_add_dev_to_cache(cache, dev);
+ if (flags & BLKID_DEV_VERIFY)
+ dev = blkid_verify_devname(cache, dev);
+ return dev;
}
/*
* Probe a single block device to add to the device cache.
- * If the size is not specified, it will be found in blkid_devname_to_dev().
*/
static blkid_dev probe_one(blkid_cache cache, const char *ptname,
- int major, int minor, unsigned long long size)
+ dev_t devno)
{
- dev_t devno = makedev(major, minor);
- blkid_dev dev;
+ blkid_dev dev = NULL;
+ struct list_head *p;
const char **dir;
char *devname = NULL;
/* See if we already have this device number in the cache. */
- if ((dev = blkid_find_devno(cache, devno)))
+ list_for_each(p, &cache->bic_devs) {
+ blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
+ bid_devs);
+ if (tmp->bid_devno == devno) {
+ dev = blkid_verify_devname(cache, tmp);
+ break;
+ }
+ }
+ if (dev && dev->bid_devno == devno)
return dev;
/*
@@ -103,17 +112,17 @@ static blkid_dev probe_one(blkid_cache cache, const char *ptname,
* the stat information doesn't check out, use blkid_devno_to_devname()
* to find it via an exhaustive search for the device major/minor.
*/
- for (dir = devdirs; *dir; dir++) {
+ for (dir = blkid_devdirs; *dir; dir++) {
struct stat st;
char device[256];
sprintf(device, "%s/%s", *dir, ptname);
- if ((dev = blkid_find_devname(cache, device)) &&
+ if ((dev = blkid_get_devname(cache, device, BLKID_DEV_FIND)) &&
dev->bid_devno == devno)
return dev;
if (stat(device, &st) == 0 && st.st_rdev == devno) {
- devname = string_copy(device);
+ devname = blkid_strdup(device);
break;
}
}
@@ -122,10 +131,10 @@ static blkid_dev probe_one(blkid_cache cache, const char *ptname,
if (!devname)
return NULL;
}
- dev = blkid_devname_to_dev(devname, size);
- string_free(devname);
+ dev = blkid_get_devname(cache, devname, BLKID_DEV_NORMAL);
+ free(devname);
- return blkid_add_dev_to_cache(cache, dev);
+ return dev;
}
#define PROC_PARTITIONS "/proc/partitions"
@@ -139,29 +148,23 @@ static blkid_dev probe_one(blkid_cache cache, const char *ptname,
*/
#ifdef VG_DIR
#include <dirent.h>
-static int lvm_get_devno(const char *lvm_device, int *major, int *minor,
- blkid_loff_t *size)
+static dev_t lvm_get_devno(const char *lvm_device)
{
FILE *lvf;
char buf[1024];
- int ret = 1;
-
- *major = *minor = 0;
- *size = 0;
+ int ma, mi;
+ dev_t ret = 0;
DBG(printf("opening %s\n", lvm_device));
if ((lvf = fopen(lvm_device, "r")) == NULL) {
- ret = errno;
- DBG(printf("%s: (%d) %s\n", lvm_device, ret, strerror(ret)));
- return -ret;
+ DBG(printf("%s: (%d) %s\n", lvm_device, errno,
+ strerror(errno)));
+ return 0;
}
while (fgets(buf, sizeof(buf), lvf)) {
- if (sscanf(buf, "size: %llu", size) == 1) { /* sectors */
- *size <<= 9;
- }
- if (sscanf(buf, "device: %d:%d", major, minor) == 2) {
- ret = 0;
+ if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
+ ret = makedev(ma, mi);
break;
}
}
@@ -170,11 +173,12 @@ static int lvm_get_devno(const char *lvm_device, int *major, int *minor,
return ret;
}
-static void lvm_probe_all(blkid_cache *cache)
+static void lvm_probe_all(blkid_cache cache)
{
DIR *vg_list;
struct dirent *vg_iter;
int vg_len = strlen(VG_DIR);
+ dev_t dev;
if ((vg_list = opendir(VG_DIR)) == NULL)
return;
@@ -202,8 +206,6 @@ static void lvm_probe_all(blkid_cache *cache)
while ((lv_iter = readdir(lv_list)) != NULL) {
char *lv_name, *lvm_device;
- int major, minor;
- blkid_loff_t size;
lv_name = lv_iter->d_name;
if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
@@ -217,14 +219,11 @@ static void lvm_probe_all(blkid_cache *cache)
}
sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
lv_name);
- if (lvm_get_devno(lvm_device, &major, &minor, &size)) {
- free(lvm_device);
- continue;
- }
+ dev = lvm_get_devno(lvm_device);
sprintf(lvm_device, "%s/%s", vg_name, lv_name);
- DBG(printf("LVM dev %s: devno 0x%02X%02X, size %Ld\n",
- lvm_device, major, minor, size));
- probe_one(*cache, lvm_device, major, minor, size);
+ DBG(printf("LVM dev %s: devno 0x%04X\n",
+ lvm_device, dev));
+ probe_one(cache, lvm_device, dev);
free(lvm_device);
}
closedir(lv_list);
@@ -237,7 +236,7 @@ exit:
#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
static int
-evms_probe_all(blkid_cache *cache)
+evms_probe_all(blkid_cache cache)
{
char line[100];
int ma, mi, sz, num = 0;
@@ -255,7 +254,7 @@ evms_probe_all(blkid_cache *cache)
DBG(printf("Checking partition %s (%d, %d)\n",
device, ma, mi));
- probe_one(*cache, device, ma, mi, sz << 10);
+ probe_one(cache, device, makedev(ma, mi));
num++;
}
fclose(procpt);
@@ -265,7 +264,7 @@ evms_probe_all(blkid_cache *cache)
/*
* Read the device data for all available block devices in the system.
*/
-int blkid_probe_all(blkid_cache *cache)
+int blkid_probe_all(blkid_cache cache)
{
FILE *proc;
int firstPass;
@@ -273,14 +272,8 @@ int blkid_probe_all(blkid_cache *cache)
if (!cache)
return -BLKID_ERR_PARAM;
- if (!*cache)
- *cache = blkid_new_cache();
-
- if (!*cache)
- return -BLKID_ERR_MEM;
-
- if ((*cache)->bic_flags & BLKID_BIC_FL_PROBED &&
- time(0) - (*cache)->bic_time < BLKID_PROBE_INTERVAL)
+ if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
+ time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
return 0;
if (evms_probe_all(cache))
@@ -296,10 +289,11 @@ int blkid_probe_all(blkid_cache *cache)
for (firstPass = 1; firstPass >= 0; firstPass--) {
char line[1024];
- char ptname0[128], ptname1[128];
+ char ptname0[128], ptname1[128], *ptname = 0;
char *ptnames[2] = { ptname0, ptname1 };
- int majors[2], minors[2];
- unsigned long long sizes[2];
+ dev_t devs[2];
+ int ma, mi;
+ unsigned long long sz;
int lens[2] = { 0, 0 };
int handleOnFirst;
int which = 0, last = 0;
@@ -309,16 +303,17 @@ int blkid_probe_all(blkid_cache *cache)
while (fgets(line, sizeof(line), proc)) {
last = which;
which ^= 1;
+ ptname = ptnames[which];
if (sscanf(line, " %d %d %lld %128[^\n ]",
- &majors[which], &minors[which],
- &sizes[which], ptnames[which]) != 4)
+ &ma, &mi, &sz, ptname) != 4)
continue;
+ devs[which] = makedev(ma, mi);
- DBG(printf("read partition name %s\n", ptnames[which]));
+ DBG(printf("read partition name %s\n", ptname));
/* look only at md devices on first pass */
- handleOnFirst = !strncmp(ptnames[which], "md", 2);
+ handleOnFirst = !strncmp(ptname, "md", 2);
if (firstPass != handleOnFirst)
continue;
@@ -333,40 +328,34 @@ int blkid_probe_all(blkid_cache *cache)
* FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
*/
- lens[which] = strlen(ptnames[which]);
- if (isdigit(ptnames[which][lens[which] - 1])) {
- DBG(printf("partition dev %s, devno 0x%02X%02X\n",
- ptnames[which], majors[which],
- minors[which]));
+ lens[which] = strlen(ptname);
+ if (isdigit(ptname[lens[which] - 1])) {
+ DBG(printf("partition dev %s, devno 0x%04X\n",
+ ptname, devs[which]));
- if (sizes[which] > 1)
- probe_one(*cache, ptnames[which],
- majors[which], minors[which],
- sizes[which] << 10);
+ if (sz > 1)
+ probe_one(cache, ptname, devs[which]);
lens[which] = 0;
lens[last] = 0;
} else if (lens[last] &&
- strncmp(ptnames[last], ptnames[which],
+ strncmp(ptnames[last], ptname,
lens[last])) {
- DBG(printf("whole dev %s, devno 0x%02X%02X\n",
- ptnames[last], majors[last],
- minors[last]));
- probe_one(*cache, ptnames[last], majors[last],
- minors[last], sizes[last] << 10);
+ DBG(printf("whole dev %s, devno 0x%04X\n",
+ ptname, devs[last]));
+ probe_one(cache, ptname, devs[last]);
lens[last] = 0;
}
}
/* Handle the last device if it wasn't partitioned */
if (lens[which])
- probe_one(*cache, ptnames[which], majors[which],
- minors[which], sizes[which] << 10);
+ probe_one(cache, ptname, devs[which]);
}
fclose(proc);
finish:
- (*cache)->bic_time = time(0);
- (*cache)->bic_flags |= BLKID_BIC_FL_PROBED;
+ cache->bic_time = time(0);
+ cache->bic_flags |= BLKID_BIC_FL_PROBED;
return 0;
}
@@ -381,10 +370,14 @@ int main(int argc, char **argv)
"Probe all devices and exit\n", argv[0]);
exit(1);
}
- if (blkid_probe_all(&cache) < 0)
+ if ((cache = blkid_new_cache()) == NULL) {
+ fprintf(stderr, "%s: error creating cache\n", argv[0]);
+ exit(1);
+ }
+ if (blkid_probe_all(cache) < 0)
printf("%s: error probing devices\n", argv[0]);
- blkid_free_cache(cache);
+ blkid_put_cache(cache);
return (0);
}
#endif
diff --git a/lib/blkid/devno.c b/lib/blkid/devno.c
index 1fe7309d..41fdc3de 100644
--- a/lib/blkid/devno.c
+++ b/lib/blkid/devno.c
@@ -1,7 +1,7 @@
/*
* devno.c - find a particular device by its device number (major/minor)
*
- * Copyright (C) 2000, 2001 Theodore Ts'o
+ * Copyright (C) 2000, 2001, 2003 Theodore Ts'o
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
@@ -44,13 +44,16 @@ struct dir_list {
struct dir_list *next;
};
-char *stringn_copy(const char *s, const int length)
+char *blkid_strndup(const char *s, int length)
{
char *ret;
if (!s)
return NULL;
+ if (!length)
+ length = strlen(s);
+
ret = malloc(length + 1);
if (ret) {
strncpy(ret, s, length);
@@ -59,18 +62,9 @@ char *stringn_copy(const char *s, const int length)
return ret;
}
-char *string_copy(const char *s)
+char *blkid_strdup(const char *s)
{
- if (!s)
- return NULL;
-
- return stringn_copy(s, strlen(s));
-}
-
-void string_free(char *s)
-{
- if (s)
- free(s);
+ return blkid_strndup(s, 0);
}
/*
@@ -83,7 +77,7 @@ static void add_to_dirlist(const char *name, struct dir_list **list)
dp = malloc(sizeof(struct dir_list));
if (!dp)
return;
- dp->name = string_copy(name);
+ dp->name = blkid_strdup(name);
if (!dp->name) {
free(dp);
return;
@@ -101,58 +95,52 @@ static void free_dirlist(struct dir_list **list)
for (dp = *list; dp; dp = next) {
next = dp->next;
- string_free(dp->name);
+ free(dp->name);
free(dp);
}
*list = NULL;
}
-static int scan_dir(char *dirname, dev_t devno, struct dir_list **list,
- char **devname)
+static void scan_dir(char *dirname, dev_t devno, struct dir_list **list,
+ char **devname)
{
DIR *dir;
struct dirent *dp;
char path[1024];
int dirlen;
struct stat st;
- int ret = 0;
- dirlen = strlen(dirname);
if ((dir = opendir(dirname)) == NULL)
- return errno;
- dp = readdir(dir);
- while (dp) {
- if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
- goto skip_to_next;
+ return;
+ dirlen = strlen(dirname) + 2;
+ while ((dp = readdir(dir)) != 0) {
+ if (dirlen + strlen(dp->d_name) >= sizeof(path))
+ continue;
if (dp->d_name[0] == '.' &&
((dp->d_name[1] == 0) ||
((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
- goto skip_to_next;
+ continue;
sprintf(path, "%s/%s", dirname, dp->d_name);
if (stat(path, &st) < 0)
- goto skip_to_next;
+ continue;
if (S_ISDIR(st.st_mode))
add_to_dirlist(path, list);
else if (S_ISBLK(st.st_mode) && st.st_rdev == devno) {
- *devname = string_copy(path);
+ *devname = blkid_strdup(path);
DBG(printf("found 0x%Lx at %s (%p)\n", devno,
- *devname, *devname));
- if (!*devname)
- ret = -BLKID_ERR_MEM;
+ path, *devname));
break;
}
- skip_to_next:
- dp = readdir(dir);
}
closedir(dir);
- return ret;
+ return;
}
/* Directories where we will try to search for device numbers */
-const char *devdirs[] = { "/dev", "/devfs", "/devices", NULL };
+const char *blkid_devdirs[] = { "/devices", "/devfs", "/dev", NULL };
/*
* This function finds the pathname to a block device with a given
@@ -169,13 +157,8 @@ char *blkid_devno_to_devname(dev_t devno)
* Add the starting directories to search in reverse order of
* importance, since we are using a stack...
*/
- for (dir = devdirs; *dir; dir++)
- /* go to end of list */;
-
- do {
- --dir;
+ for (dir = blkid_devdirs; *dir; dir++)
add_to_dirlist(*dir, &list);
- } while (dir != devdirs);
while (list) {
struct dir_list *current = list;
@@ -183,7 +166,7 @@ char *blkid_devno_to_devname(dev_t devno)
list = list->next;
DBG(printf("directory %s\n", current->name));
scan_dir(current->name, devno, &new_list, &devname);
- string_free(current->name);
+ free(current->name);
free(current);
if (devname)
break;
@@ -200,61 +183,14 @@ char *blkid_devno_to_devname(dev_t devno)
free_dirlist(&new_list);
if (!devname)
- fprintf(stderr, "blkid: couldn't find devno 0x%04lx\n",
- (unsigned long) devno);
+ DBG(printf("blkid: couldn't find devno 0x%04lx\n",
+ (unsigned long) devno));
else
DBG(printf("found devno 0x%04Lx as %s\n", devno, devname));
return devname;
}
-blkid_dev blkid_find_devno(blkid_cache cache, dev_t devno)
-{
- blkid_dev dev = NULL;
- struct list_head *p, *n;
-
- if (!cache)
- return NULL;
-
- /* This cannot be a standard list_for_each() because we may be
- * deleting the referenced struct in blkid_verify_devname() and
- * pointing to another one that was probed from disk, and "p"
- * would point to freed memory.
- */
- list_for_each_safe(p, n, &cache->bic_devs) {
- blkid_dev tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
- if (tmp->bid_devno != devno)
- continue;
-
- tmp = blkid_verify_devname(cache, tmp);
- if (!tmp || tmp->bid_devno != devno)
- continue;
-
- dev = tmp;
- break;
- }
-
- if (dev)
- DBG(printf("found devno 0x%04LX in cache as %s\n",
- devno, dev->bid_name));
-
- return dev;
-}
-
-blkid_dev blkid_get_devno(blkid_cache cache, dev_t devno)
-{
- char *devname;
- blkid_dev dev;
-
- if (!(dev = blkid_find_devno(cache, devno)) &&
- (devname = blkid_devno_to_devname(devno))) {
- dev = blkid_get_devname(cache, devname);
- string_free(devname);
- }
-
- return dev;
-}
-
#ifdef TEST_PROGRAM
int main(int argc, char** argv)
{
@@ -291,7 +227,7 @@ int main(int argc, char** argv)
printf("Looking for device 0x%04Lx\n", devno);
devname = blkid_devno_to_devname(devno);
if (devname)
- string_free(devname);
+ free(devname);
return 0;
}
#endif
diff --git a/lib/blkid/libblkid.3.in b/lib/blkid/libblkid.3.in
index 98f487f0..78d17628 100644
--- a/lib/blkid/libblkid.3.in
+++ b/lib/blkid/libblkid.3.in
@@ -80,11 +80,9 @@ or visit
http://www.gnu.org/licenses/licenses.html#LGPL
.UE
.SH "SEE ALSO"
-.BR blkid_read_cache (3),
-.BR blkid_save_cache (3),
-.BR blkid_free_cache (3),
+.BR blkid_get_cache (3),
+.BR blkid_put_cache (3),
.BR blkid_get_devname (3),
-.BR blkid_get_devno (3),
.BR blkid_probe_all (3),
.BR blkid_free_dev (3),
.BR blkid_find_tag_dev (3),
diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c
index 9969a97c..eeb544c6 100644
--- a/lib/blkid/probe.c
+++ b/lib/blkid/probe.c
@@ -3,7 +3,7 @@
* struct with the details
*
* Copyright (C) 1999 by Andries Brouwer
- * Copyright (C) 1999, 2000 by Theodore Ts'o
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
* Copyright (C) 2001 by Andreas Dilger
*
* %Begin-Header%
@@ -39,242 +39,149 @@
#endif
/*
- * Do the required things for instantiating a new device. This is called if
- * there is nor a probe handler for a filesystem type, and is also called by
- * the filesystem-specific types to do common initialization tasks.
- *
- * The devname, dev_p, and id fields are required. The buf is
- * a buffer to return superblock data in.
+ * This is a special case code to check for an MDRAID device. We do
+ * this special since it requires checking for a superblock at the end
+ * of the device.
*/
-static int probe_default(int fd, blkid_dev *dev_p, const char *devname,
- struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+static int check_mdraid(int fd, unsigned char *ret_uuid)
{
- blkid_loff_t offset;
- blkid_dev dev;
- struct stat st;
- int ret;
-
- if (!devname || !dev_p || !id || !buf || fd < 0)
+ struct mdp_superblock_s *md;
+ blkid_loff_t offset;
+ char buf[4096];
+
+ if (fd < 0)
return -BLKID_ERR_PARAM;
- if (fstat(fd, &st) < 0 || !S_ISBLK(st.st_mode))
- return -BLKID_ERR_DEV;
-
- offset = (blkid_loff_t)id->bim_kboff << 10;
- if (id->bim_kboff < 0)
- offset += (size & ~((blkid_loff_t)(id->bim_align - 1)));
+ offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536;
if (blkid_llseek(fd, offset, 0) < 0 ||
- read(fd, buf, id->bim_kbsize << 10) != id->bim_kbsize << 10)
+ read(fd, buf, 4096) != 4096)
return -BLKID_ERR_IO;
- /* Revalidate magic for blkid_validate_devname */
- if (memcmp(id->bim_magic, buf + id->bim_sboff, id->bim_len))
+ /* Check for magic number */
+ if (memcmp("\251+N\374", buf, 4))
return -BLKID_ERR_PARAM;
- dev = blkid_new_dev();
- if (!dev)
- return -BLKID_ERR_MEM;
+ if (!ret_uuid)
+ return 0;
+ *ret_uuid = 0;
- dev->bid_name = string_copy(devname);
- if (!dev->bid_name) {
- ret = -BLKID_ERR_MEM;
- goto exit_dev;
+ /* The MD UUID is not contiguous in the superblock, make it so */
+ md = (struct mdp_superblock_s *)buf;
+ if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) {
+ memcpy(ret_uuid, &md->set_uuid0, 4);
+ memcpy(ret_uuid, &md->set_uuid1, 12);
}
+ return 0;
+}
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
- dev->bid_devno = st.st_rdev;
- dev->bid_devsize = size;
- dev->bid_time = time(0);
- dev->bid_flags |= BLKID_BID_FL_VERIFIED;
-
- if (id->bim_type)
- blkid_create_tag(dev, "TYPE", id->bim_type,
- strlen(id->bim_type));
-
- DBG(printf("%s: devno 0x%04Lx, type %s\n", devname,
- st.st_rdev, id->bim_type));
+static void set_uuid(blkid_dev dev, uuid_t uuid)
+{
+ char str[37];
- return 0;
-exit_dev:
- blkid_free_dev(dev);
- return ret;
+ if (!uuid_is_null(uuid)) {
+ uuid_unparse(uuid, str);
+ blkid_set_tag(dev, "UUID", str, sizeof(str), 1);
+ }
}
-static int probe_ext2(int fd, blkid_dev *dev_p, const char *devname,
+static int probe_ext2(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+ const char **ret_sectype)
{
- blkid_dev dev;
struct ext2_super_block *es;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
es = (struct ext2_super_block *)buf;
- DBG(printf("size = %Ld, ext2_sb.compat = %08X:%08X:%08X\n", size,
+ DBG(printf("ext2_sb.compat = %08X:%08X:%08X\n",
blkid_le32(es->s_feature_compat),
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)) {
- blkid_free_dev(dev);
+ ((blkid_le32(es->s_feature_compat) &
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL) ||
+ (blkid_le32(es->s_feature_incompat) &
+ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)))
return -BLKID_ERR_PARAM;
- }
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
- dev->bid_size = (blkid_loff_t)blkid_le32(es->s_blocks_count) <<
- (blkid_le32(es->s_log_block_size) + 10);
+ if (strlen(es->s_volume_name))
+ blkid_set_tag(dev, "LABEL", es->s_volume_name,
+ sizeof(es->s_volume_name), 1);
- if (strlen(es->s_volume_name)) {
- blkid_create_tag(dev, "LABEL", es->s_volume_name,
- sizeof(es->s_volume_name));
- }
-
- if (!uuid_is_null(es->s_uuid)) {
- char uuid[37];
- uuid_unparse(es->s_uuid, uuid);
- blkid_create_tag(dev, "UUID", uuid, sizeof(uuid));
- }
+ set_uuid(dev, es->s_uuid);
return 0;
}
-static int probe_jbd(int fd, blkid_dev *dev_p, const char *devname,
+static int probe_jbd(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+ const char **ret_sectype)
{
- blkid_dev dev;
- struct ext2_super_block *es;
- int ret;
-
- if ((ret = probe_ext2(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- es = (struct ext2_super_block *)buf;
+ struct ext2_super_block *es = (struct ext2_super_block *) buf;
if (!(blkid_le32(es->s_feature_incompat) &
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
- blkid_free_dev(dev);
+ EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
return -BLKID_ERR_PARAM;
- }
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
- return 0;
+ return (probe_ext2(fd, cache, dev, id, buf, ret_sectype));
}
-static int probe_ext3(int fd, blkid_dev *dev_p, const char *devname,
- struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+static int probe_ext3(int fd, blkid_cache cache, blkid_dev dev,
+ struct blkid_magic *id, unsigned char *buf,
+ const char **ret_sectype)
{
- blkid_dev dev;
- struct ext2_super_block *es;
+ struct ext2_super_block *es = (struct ext2_super_block *) buf;
int ret;
- if ((ret = probe_ext2(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- es = (struct ext2_super_block *)buf;
-
if (!(blkid_le32(es->s_feature_compat) &
- EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
- blkid_free_dev(dev);
- *dev_p = NULL;
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL))
return -BLKID_ERR_PARAM;
- }
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
+
+ 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)) {
- blkid_create_tag(dev, "TYPE", "ext2", 4);
- dev->bid_flags |= BLKID_BID_FL_MTYPE;
- }
+ EXT3_FEATURE_INCOMPAT_RECOVER))
+ *ret_sectype = "ext2";
return 0;
}
-static int probe_vfat(int fd, blkid_dev *dev_p, const char *devname,
+static int probe_vfat(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+ const char **ret_sectype)
{
- blkid_dev dev;
struct vfat_super_block *vs;
char serno[10];
- blkid_loff_t sectors;
- int cluster_size;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
vs = (struct vfat_super_block *)buf;
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
-
- sectors = ((vs->vs_sectors[1] << 8) | vs->vs_sectors[0]);
- if (sectors == 0)
- sectors = vs->vs_total_sect;
- cluster_size = ((vs->vs_sector_size[1] << 8) | vs->vs_sector_size[0]);
- dev->bid_size = sectors * cluster_size;
- DBG(printf("%lld %d byte sectors\n", sectors, cluster_size));
-
if (strncmp(vs->vs_label, "NO NAME", 7)) {
char *end = vs->vs_label + sizeof(vs->vs_label) - 1;
while (*end == ' ' && end >= vs->vs_label)
--end;
if (end >= vs->vs_label)
- blkid_create_tag(dev, "LABEL", vs->vs_label,
- end - vs->vs_label + 1);
+ blkid_set_tag(dev, "LABEL", vs->vs_label,
+ end - vs->vs_label + 1, 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_create_tag(dev, "UUID", serno, sizeof(serno));
+ blkid_set_tag(dev, "UUID", serno, sizeof(serno), 1);
return 0;
}
-static int probe_msdos(int fd, blkid_dev *dev_p, const char *devname,
+static int probe_msdos(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+ const char **ret_sectype)
{
- blkid_dev dev;
- struct msdos_super_block *ms;
+ struct msdos_super_block *ms = (struct msdos_super_block *) buf;
char serno[10];
- int cluster_size;
- blkid_loff_t sectors;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- ms = (struct msdos_super_block *)buf;
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
-
- sectors = ((ms->ms_sectors[1] << 8) | ms->ms_sectors[0]);
- if (sectors == 0)
- sectors = ms->ms_total_sect;
- cluster_size = ((ms->ms_sector_size[1] << 8) | ms->ms_sector_size[0]);
- dev->bid_size = sectors * cluster_size;
- DBG(printf("%Ld %d byte sectors\n", sectors, cluster_size));
if (strncmp(ms->ms_label, "NO NAME", 7)) {
char *end = ms->ms_label + sizeof(ms->ms_label) - 1;
@@ -282,445 +189,133 @@ static int probe_msdos(int fd, blkid_dev *dev_p, const char *devname,
while (*end == ' ' && end >= ms->ms_label)
--end;
if (end >= ms->ms_label)
- blkid_create_tag(dev, "LABEL", ms->ms_label,
- end - ms->ms_label + 1);
+ blkid_set_tag(dev, "LABEL", ms->ms_label,
+ end - ms->ms_label + 1, 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_create_tag(dev, "UUID", serno, sizeof(serno));
+ blkid_set_tag(dev, "UUID", serno, 0, 1);
return 0;
}
-static int probe_xfs(int fd, blkid_dev *dev_p, const char *devname,
+static int probe_xfs(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+ const char **ret_sectype)
{
- blkid_dev dev;
struct xfs_super_block *xs;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
xs = (struct xfs_super_block *)buf;
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
- /* If the filesystem size is larger than the device, this is bad */
- dev->bid_size = blkid_be64(xs->xs_dblocks) *
- blkid_be32(xs->xs_blocksize);
-
if (strlen(xs->xs_fname))
- blkid_create_tag(dev, "LABEL", xs->xs_fname,
- sizeof(xs->xs_fname));
-
- if (!uuid_is_null(xs->xs_uuid)) {
- char uuid[37];
- uuid_unparse(xs->xs_uuid, uuid);
- blkid_create_tag(dev, "UUID", uuid, sizeof(uuid));
- }
+ blkid_set_tag(dev, "LABEL", xs->xs_fname,
+ sizeof(xs->xs_fname), 1);
+ set_uuid(dev, xs->xs_uuid);
return 0;
}
-static int probe_reiserfs(int fd, blkid_dev *dev_p, const char *devname,
+static int probe_reiserfs(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
+ const char **ret_sectype)
{
- blkid_dev dev;
- struct reiserfs_super_block *rs;
+ struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf;
unsigned int blocksize;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- rs = (struct reiserfs_super_block *)buf;
blocksize = blkid_le16(rs->rs_blocksize);
/* If the superblock is inside the journal, we have the wrong one */
- if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block)) {
- blkid_free_dev(dev);
+ if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block))
return -BLKID_ERR_BIG;
- }
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
-
- /* If the filesystem size is larger than the device, this is bad */
- dev->bid_size = blkid_le32(rs->rs_blocks_count) * blocksize;
/* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
if (!strcmp(id->bim_magic, "ReIsEr2Fs") ||
!strcmp(id->bim_magic, "ReIsEr3Fs")) {
if (strlen(rs->rs_label)) {
- blkid_create_tag(dev, "LABEL", rs->rs_label,
- sizeof(rs->rs_label));
- }
-
- if (!uuid_is_null(rs->rs_uuid)) {
- char uuid[37];
- uuid_unparse(rs->rs_uuid, uuid);
- blkid_create_tag(dev, "UUID", uuid, sizeof(uuid));
+ blkid_set_tag(dev, "LABEL", rs->rs_label,
+ sizeof(rs->rs_label), 1);
}
- }
-
- return 0;
-}
-static int probe_minix(int fd, blkid_dev *dev_p, const char *devname,
- struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
-{
- blkid_dev dev;
- struct minix_super_block *ms;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- ms = (struct minix_super_block *)buf;
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
- dev->bid_size = ms->ms_nzones << ms->ms_log_zone_size;
- return 0;
-}
-
-static int probe_swap(int fd, blkid_dev *dev_p, const char *devname,
- struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
-{
- blkid_dev dev;
- struct swap_header *sh;
- int psize;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- /* PAGE_SIZE can be found by where the magic is located */
- psize = (id->bim_kboff << 10) + (id->bim_sboff + 10);
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
-
- sh = (struct swap_header *)buf;
- /* Is swap data in local endian format? */
- dev->bid_size = (blkid_loff_t)(sh->sh_last_page + 1) * psize;
-
- /* A label can not exist on the old (128MB max) swap format */
- if (!strcmp(id->bim_magic, "SWAPSPACE2") && sh->sh_label[0]) {
- blkid_create_tag(dev, "LABEL", sh->sh_label,
- sizeof(sh->sh_label));
+ set_uuid(dev, rs->rs_uuid);
}
return 0;
}
-static int probe_mdraid(int fd, blkid_dev *dev_p, const char *devname,
- struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
-{
- blkid_dev dev;
- struct mdp_superblock_s *md;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
-
- md = (struct mdp_superblock_s *)buf;
- /* What units is md->size in? Assume 512-byte sectors? */
- dev->bid_size = md->size * 512;
-
- /* The MD UUID is not contiguous in the superblock, make it so */
- if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) {
- unsigned char md_uuid[16];
- char uuid[37];
-
- memcpy(md_uuid, &md->set_uuid0, 4);
- memcpy(md_uuid + 4, &md->set_uuid1, 12);
-
- uuid_unparse(md_uuid, uuid);
- blkid_create_tag(dev, "UUID", uuid, sizeof(uuid));
- }
- return 0;
-}
-
-static int probe_hfs(int fd, blkid_dev *dev_p, const char *devname,
- struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size)
-{
- blkid_dev dev;
- struct hfs_super_block *hfs;
- int ret;
-
- if ((ret = probe_default(fd, &dev, devname, id, buf, size)) < 0)
- return ret;
-
- hfs = (struct hfs_super_block *)buf;
-
- if (blkid_be32(hfs->h_blksize) != 512)
- return -BLKID_ERR_PARAM;
-
- /* Don't set this until there is no chance of error */
- *dev_p = dev;
-
- return 0;
-}
-
-
/*
* BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
- * in the type_array table below + bim_kbalign. If we ever start looking for magics
- * relative to the end of a device, we can start using negative offsets
- * in type_array.
+ * in the type_array table below + bim_kbalign.
+ *
+ * When probing for a lot of magics, we handle everything in 1kB buffers so
+ * that we don't have to worry about reading each combination of block sizes.
*/
-#define BLKID_BLK_BITS (10)
-#define BLKID_BLK_KBITS (BLKID_BLK_BITS - 10)
-#define BLKID_BLK_SIZE (1024 << BLKID_BLK_KBITS)
-#define BLKID_BLK_MASK (BLKID_BLK_SIZE - 1)
-#define BLKID_BLK_OFFS 128 /* currently MDRAID kboff + align */
+#define BLKID_BLK_OFFS 64 /* currently reiserfs */
/*
* Various filesystem magics that we can check for. Note that kboff and
* sboff are in kilobytes and bytes respectively. All magics are in
* byte strings so we don't worry about endian issues.
*/
-struct blkid_magic type_array[] = {
-/* type kboff sboff len magic align kbsize probe */
- { "MDRAID", -64, 0, 4, "\251+N\374", 65536, 4, probe_mdraid },
-/*{ "LVM", 0, 0, 4, "HM\001\000", 1, 4, probe_lvm },*/
- { "jbd", 1, 0x38, 2, "\123\357", 1, 1, probe_jbd },
- { "ext3", 1, 0x38, 2, "\123\357", 1, 1, probe_ext3 },
- { "ext2", 1, 0x38, 2, "\123\357", 1, 1, probe_ext2 },
- { "reiserfs", 8, 0x34, 8, "ReIsErFs", 1, 1, probe_reiserfs },
- { "reiserfs", 64, 0x34, 9, "ReIsEr2Fs", 1, 1, probe_reiserfs },
- { "reiserfs", 64, 0x34, 9, "ReIsEr3Fs", 1, 1, probe_reiserfs },
- { "reiserfs", 64, 0x34, 8, "ReIsErFs", 1, 1, probe_reiserfs },
- { "reiserfs", 8, 20, 8, "ReIsErFs", 1, 1, probe_reiserfs },
- { "ntfs", 0, 3, 8, "NTFS ", 1, 1, probe_default },
- { "vfat", 0, 0x52, 5, "MSWIN", 1, 1, probe_vfat },
- { "vfat", 0, 0x52, 8, "FAT32 ", 1, 1, probe_vfat },
- { "msdos", 0, 0x36, 5, "MSDOS", 1, 1, probe_msdos },
- { "msdos", 0, 0x36, 8, "FAT16 ", 1, 1, probe_msdos },
- { "msdos", 0, 0x36, 8, "FAT12 ", 1, 1, probe_msdos },
- { "minix", 1, 0x10, 2, "\177\023", 1, 1, probe_minix },
- { "minix", 1, 0x10, 2, "\217\023", 1, 1, probe_minix },
- { "minix", 1, 0x10, 2, "\150\044", 1, 1, probe_minix },
- { "minix", 1, 0x10, 2, "\170\044", 1, 1, probe_minix },
- { "vxfs", 1, 0, 4, "\365\374\001\245", 1, 1, probe_default },
- { "xfs", 0, 0, 4, "XFSB", 1, 1, probe_xfs },
- { "romfs", 0, 0, 8, "-rom1fs-", 1, 1, probe_default },
- { "bfs", 0, 0, 4, "\316\372\173\033", 1, 1, probe_default },
- { "cramfs", 0, 0, 4, "E=\315\034", 1, 1, probe_default },
- { "qnx4", 0, 4, 6, "QNX4FS", 1, 1, probe_default },
- { "iso9660", 32, 1, 5, "CD001", 1, 1, probe_default },
- { "iso9660", 32, 9, 5, "CDROM", 1, 1, probe_default },
- { "udf", 32, 1, 5, "BEA01", 1, 1, probe_default },
- { "udf", 32, 1, 5, "BOOT2", 1, 1, probe_default },
- { "udf", 32, 1, 5, "CD001", 1, 1, probe_default },
- { "udf", 32, 1, 5, "CDW02", 1, 1, probe_default },
- { "udf", 32, 1, 5, "NSR02", 1, 1, probe_default },
- { "udf", 32, 1, 5, "NSR03", 1, 1, probe_default },
- { "udf", 32, 1, 5, "TEA01", 1, 1, probe_default },
- { "jfs", 32, 0, 4, "JFS1", 1, 1, probe_default },
- { "hfs", 1, 0, 2, "BD", 1, 1, probe_hfs },
- { "ufs", 8, 0x55c, 4, "T\031\001\000", 1, 1, probe_default },
- { "hpfs", 8, 0, 4, "I\350\225\371", 1, 1, probe_default },
- { "sysv", 0, 0x3f8, 4, "\020~\030\375", 1, 1, probe_default },
- { "swap", 0, 0xff6, 10, "SWAP-SPACE", 1, 4, probe_swap },
- { "swap", 0, 0xff6, 10, "SWAPSPACE2", 1, 4, probe_swap },
- { "swap", 0, 0x1ff6, 10, "SWAP-SPACE", 1, 8, probe_swap },
- { "swap", 0, 0x1ff6, 10, "SWAPSPACE2", 1, 8, probe_swap },
- { "swap", 0, 0x3ff6, 10, "SWAP-SPACE", 1, 16, probe_swap },
- { "swap", 0, 0x3ff6, 10, "SWAPSPACE2", 1, 16, probe_swap },
- { NULL, 0, 0, 0, NULL, 1, 0, NULL }
+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 },
+ { "reiserfs", 64, 0x34, 9, "ReIsEr3Fs", probe_reiserfs },
+ { "reiserfs", 64, 0x34, 8, "ReIsErFs", probe_reiserfs },
+ { "reiserfs", 8, 20, 8, "ReIsErFs", probe_reiserfs },
+ { "ntfs", 0, 3, 8, "NTFS ", 0 },
+ { "vfat", 0, 0x52, 5, "MSWIN", probe_vfat },
+ { "vfat", 0, 0x52, 8, "FAT32 ", probe_vfat },
+ { "msdos", 0, 0x36, 5, "MSDOS", probe_msdos },
+ { "msdos", 0, 0x36, 8, "FAT16 ", probe_msdos },
+ { "msdos", 0, 0x36, 8, "FAT12 ", probe_msdos },
+ { "minix", 1, 0x10, 2, "\177\023", 0 },
+ { "minix", 1, 0x10, 2, "\217\023", 0 },
+ { "minix", 1, 0x10, 2, "\150\044", 0 },
+ { "minix", 1, 0x10, 2, "\170\044", 0 },
+ { "vxfs", 1, 0, 4, "\365\374\001\245", 0 },
+ { "xfs", 0, 0, 4, "XFSB", probe_xfs },
+ { "romfs", 0, 0, 8, "-rom1fs-", 0 },
+ { "bfs", 0, 0, 4, "\316\372\173\033", 0 },
+ { "cramfs", 0, 0, 4, "E=\315\034", 0 },
+ { "qnx4", 0, 4, 6, "QNX4FS", 0 },
+ { "iso9660", 32, 1, 5, "CD001", 0 },
+ { "iso9660", 32, 9, 5, "CDROM", 0 },
+ { "udf", 32, 1, 5, "BEA01", 0 },
+ { "udf", 32, 1, 5, "BOOT2", 0 },
+ { "udf", 32, 1, 5, "CD001", 0 },
+ { "udf", 32, 1, 5, "CDW02", 0 },
+ { "udf", 32, 1, 5, "NSR02", 0 },
+ { "udf", 32, 1, 5, "NSR03", 0 },
+ { "udf", 32, 1, 5, "TEA01", 0 },
+ { "jfs", 32, 0, 4, "JFS1", 0 },
+ { "hfs", 1, 0, 2, "BD", 0 },
+ { "ufs", 8, 0x55c, 4, "T\031\001\000", 0 },
+ { "hpfs", 8, 0, 4, "I\350\225\371", 0 },
+ { "sysv", 0, 0x3f8, 4, "\020~\030\375", 0 },
+ { "swap", 0, 0xff6, 10, "SWAP-SPACE", 0 },
+ { "swap", 0, 0xff6, 10, "SWAPSPACE2", 0 },
+ { "swap", 0, 0x1ff6, 10, "SWAP-SPACE", 0 },
+ { "swap", 0, 0x1ff6, 10, "SWAPSPACE2", 0 },
+ { "swap", 0, 0x3ff6, 10, "SWAP-SPACE", 0 },
+ { "swap", 0, 0x3ff6, 10, "SWAPSPACE2", 0 },
+ { NULL, 0, 0, 0, NULL, NULL }
};
-
-/*
- * When probing for a lot of magics, we handle everything in 1kB buffers so
- * that we don't have to worry about reading each combination of block sizes.
- */
-static unsigned char *read_one_buf(int fd, blkid_loff_t offset)
-{
- unsigned char *buf;
-
- if (lseek(fd, offset, SEEK_SET) < 0)
- return NULL;
-
- if (!(buf = (unsigned char *)malloc(BLKID_BLK_SIZE)))
- return NULL;
-
- if (read(fd, buf, BLKID_BLK_SIZE) != BLKID_BLK_SIZE) {
- free(buf);
- return NULL;
- }
-
- return buf;
-}
-
-static unsigned char *read_sb_buf(int fd, unsigned char **bufs, int kboff,
- blkid_loff_t start)
-{
- int idx = kboff >> BLKID_BLK_KBITS;
- unsigned char **buf;
-
- if (idx > BLKID_BLK_OFFS || idx < -BLKID_BLK_OFFS) {
- fprintf(stderr, "reading from invalid offset %d (%d)!\n",
- kboff, idx);
- return NULL;
- }
-
- buf = bufs + idx;
- if (!*buf)
- *buf = read_one_buf(fd, start);
-
- return *buf;
-}
-
-static struct blkid_magic *devname_to_magic(const char *devname, int fd,
- unsigned char **bufs,
- struct blkid_magic *id,
- blkid_loff_t size)
-{
- struct blkid_magic *ret = NULL;
-
- if (!bufs || fd < 0)
- return NULL;
-
- if (id >= type_array + sizeof(type_array) / sizeof(*id))
- return NULL;
-
- for (id = id < type_array ? type_array : id + 1; id->bim_type; ++id) {
- unsigned char *buf;
- blkid_loff_t start = 0LL;
- blkid_loff_t offset = 0LL;
- int kboff;
-
- offset = ((blkid_loff_t)id->bim_kboff << 10) +
- (id->bim_sboff & ~0x3ffULL);
- /*
- * We index negative buffers by their actual offset (including
- * superblock offsets > 1kB, not the aligned offset, so that
- * we correctly access negative buffers with different
- * alignment requirements.
- */
- if (id->bim_kboff < 0) {
- start = (size & ~((blkid_loff_t)(id->bim_align - 1))) +
- offset;
- if (start < 0) /* Device too small for alignment */
- continue;
- kboff = (start - size) >> 10;
- } else {
- start = offset;
- kboff = offset >> 10;
- }
-
- if ((buf =
- read_sb_buf(fd, bufs, kboff, start)) &&
- !memcmp(id->bim_magic, buf + (id->bim_sboff&0x3ffULL),
- id->bim_len)) {
- ret = id;
- break;
- }
- }
-
- return ret;
-}
-
/*
- * Get data from a single block special device.
- *
- * Return a blkid_dev with at least the device type and size set.
- * If the passed-in size is zero, then we get the device size here.
+ * If a device's filesystem no longer checks out, we need to nuke
+ * information about it from the entry.
*/
-blkid_dev blkid_devname_to_dev(const char *devname, blkid_loff_t size)
+static void blkid_invalidate_fs(blkid_dev dev)
{
- unsigned char *buf_array[BLKID_BLK_OFFS * 2 + 1];
- unsigned char **bufs = buf_array + BLKID_BLK_OFFS;
- blkid_dev dev = NULL, last = NULL;
- unsigned char *sb_buf = NULL;
- int sb_size = 0;
- struct blkid_magic *id = NULL;
- blkid_loff_t diff_last = 0xf000000000000000ULL;
- int fd;
-
- if (!devname)
- return NULL;
-
- fd = open(devname, O_RDONLY);
- if (fd < 0)
- return NULL;
-
- if (!size)
- size = blkid_get_dev_size(fd);
- if (size < 1024)
- goto exit_fd;
-
- memset(buf_array, 0, sizeof(buf_array));
-
- while ((id = devname_to_magic(devname, fd, bufs, id, size)) &&
- diff_last) {
- int new_sb;
- blkid_loff_t diff_dev;
-
- DBG(printf("found type %s (#%d) on %s, probing\n",
- id->bim_type, id - type_array, devname));
-
- new_sb = id->bim_kbsize << 10;
- if (sb_size < new_sb) {
- unsigned char *sav = sb_buf;
- if (!(sb_buf = realloc(sb_buf, new_sb))) {
- sb_buf = sav;
- continue;
- }
- sb_size = new_sb;
- }
-
- if (id->bim_probe(fd, &dev, devname, id, sb_buf, size) < 0)
- continue;
-
- diff_dev = size - dev->bid_size;
- DBG(printf("size = %Lu, fs size = %Lu\n", size, dev->bid_size));
- DBG(printf("checking best match: old %Ld, new %Ld\n",
- diff_last, diff_dev));
- /* See which type is a better match by checking size */
- if ((diff_last < 0 && diff_dev > diff_last) ||
- (diff_last > 0 && diff_dev >= 0 && diff_dev < diff_last)) {
- if (last)
- blkid_free_dev(last);
- last = dev;
- diff_last = diff_dev;
- } else
- blkid_free_dev(dev);
- }
-
- if (!last)
- DBG(printf("unknown device type on %s\n", devname));
- else
- DBG(printf(last));
-
- /* Free up any buffers we allocated */
- for (bufs = buf_array; bufs - buf_array < sizeof(buf_array) /
- sizeof(buf_array[0]); bufs++) {
- if (*bufs)
- free(*bufs);
- }
-
- if (sb_buf)
- free(sb_buf);
-exit_fd:
- close(fd);
- return last;
-}
+ 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
@@ -733,13 +328,12 @@ exit_fd:
*/
blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
{
- blkid_loff_t size;
struct blkid_magic *id;
- blkid_dev new = NULL;
- unsigned char *sb_buf = NULL;
- int sb_size = 0;
+ unsigned char *bufs[BLKID_BLK_OFFS + 1], *buf;
+ const char *sec_type, *type;
+ struct stat st;
time_t diff;
- int fd;
+ int fd, idx;
if (!dev)
return NULL;
@@ -752,10 +346,9 @@ blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
DBG(printf("need to revalidate %s\n", dev->bid_name));
- if ((fd = open(dev->bid_name, O_RDONLY)) < 0) {
+ if (((fd = open(dev->bid_name, O_RDONLY)) < 0) ||
+ (fstat(fd, &st) < 0) || !S_ISBLK(st.st_mode)) {
if (errno == ENXIO || errno == ENODEV) {
- fprintf(stderr, "unable to open %s for revalidation\n",
- dev->bid_name);
blkid_free_dev(dev);
return NULL;
}
@@ -764,68 +357,117 @@ blkid_dev blkid_verify_devname(blkid_cache cache, blkid_dev dev)
return dev;
}
- size = blkid_get_dev_size(fd);
-
- /* See if we can probe this device by its existing type directly */
+ memset(bufs, 0, sizeof(bufs));
+
+ /*
+ * Iterate over the type array. If we already know the type,
+ * then try that first. If it doesn't work, then blow away
+ * the type information, and try again.
+ *
+ */
+try_again:
+ type = 0;
+ sec_type = 0;
+ if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) {
+ uuid_t uuid;
+
+ if (check_mdraid(fd, uuid) == 0) {
+ set_uuid(dev, uuid);
+ type = "mdraid";
+ goto found_type;
+ }
+ }
for (id = type_array; id->bim_type; id++) {
- if (!strcmp(id->bim_type, dev->bid_type)) {
- int new_sb = id->bim_kbsize << 10;
- /* See if we need to allocate a larger sb buffer */
- if (sb_size < new_sb) {
- unsigned char *sav = sb_buf;
-
- /* We can't revalidate, return old dev */
- if (!(sb_buf = realloc(sb_buf, new_sb))) {
- fprintf(stderr, "not enough memory for "
- "%s revalidation\n",
- dev->bid_name);
- free(sav);
- goto exit_fd;
- }
- sb_size = new_sb;
+ if (dev->bid_type &&
+ strcmp(id->bim_type, dev->bid_type))
+ continue;
+
+ idx = id->bim_kboff + (id->bim_sboff >> 10);
+ if (idx > BLKID_BLK_OFFS || idx < 0)
+ continue;
+ buf = bufs[idx];
+ if (!buf) {
+ if (lseek(fd, idx << 10, SEEK_SET) < 0)
+ continue;
+
+ if (!(buf = (unsigned char *)malloc(1024)))
+ continue;
+
+ if (read(fd, buf, 1024) != 1024) {
+ free(buf);
+ continue;
}
+ bufs[idx] = buf;
+ }
- if (id->bim_probe(fd, &new, dev->bid_name, id, sb_buf,
- size) == 0)
- break;
+ if (memcmp(id->bim_magic, buf + (id->bim_sboff&0x3ff),
+ id->bim_len))
+ continue;
+
+ if ((id->bim_probe == NULL) ||
+ (id->bim_probe(fd, cache, dev, id, buf, &sec_type) == 0)) {
+ type = id->bim_type;
+ goto found_type;
}
}
- if (sb_buf)
- free(sb_buf);
+ if (!id->bim_type && dev->bid_type) {
+ /*
+ * Zap the device filesystem type and try again
+ */
+ blkid_invalidate_fs(dev);
+ goto try_again;
+ }
- /* Otherwise we need to determine the device type first */
- if (new || (new = blkid_devname_to_dev(dev->bid_name, size))) {
- new->bid_id = dev->bid_id; /* save old id for cache */
+ if (!dev->bid_type) {
blkid_free_dev(dev);
- dev = blkid_add_dev_to_cache(cache, new);
+ return NULL;
+ }
+
+found_type:
+ if (dev && type) {
+ dev->bid_devno = st.st_rdev;
+ dev->bid_time = time(0);
+ dev->bid_flags |= BLKID_BID_FL_VERIFIED;
+
+ blkid_set_tag(dev, "TYPE", type, 0, 1);
+ if (sec_type)
+ blkid_set_tag(dev, "TYPE", sec_type, 0, 0);
+
+ DBG(printf("%s: devno 0x%04Lx, type %s\n",
+ dev->bid_name, st.st_rdev, type));
}
-exit_fd:
close(fd);
- /* In case the cache is missing the device size */
- if (dev->bid_devsize == 0)
- dev->bid_devsize = size;
return dev;
-
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
blkid_dev dev;
+ blkid_cache cache;
if (argc != 2) {
fprintf(stderr, "Usage: %s device\n"
"Probe a single device to determine type\n", argv[0]);
exit(1);
}
- dev = blkid_devname_to_dev(argv[1], 0);
- if (dev)
- blkid_free_dev(dev);
- else
+ cache = blkid_new_cache();
+ dev = blkid_get_devname(cache, argv[1], BLKID_DEV_NORMAL);
+ if (!dev) {
printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
+ return (1);
+ }
+ printf("%s is type %s\n", argv[1], dev->bid_type ?
+ dev->bid_type : "(null)");
+ if (dev->bid_label)
+ printf("\tlabel is '%s'\n", dev->bid_label);
+ if (dev->bid_uuid)
+ printf("\tuuid is %s\n", dev->bid_uuid);
+
+ blkid_free_dev(dev);
return (0);
}
#endif
diff --git a/lib/blkid/probe.h b/lib/blkid/probe.h
index 23dd07f3..3e02604b 100644
--- a/lib/blkid/probe.h
+++ b/lib/blkid/probe.h
@@ -2,7 +2,7 @@
* probe.h - constants and on-disk structures for extracting device data
*
* Copyright (C) 1999 by Andries Brouwer
- * Copyright (C) 1999, 2000 by Theodore Ts'o
+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
* Copyright (C) 2001 by Andreas Dilger
*
* %Begin-Header%
@@ -18,9 +18,9 @@
struct blkid_magic;
-typedef int (*blkid_probe_t)(int fd, blkid_dev *dev_p, const char *devname,
+typedef int (*blkid_probe_t)(int fd, blkid_cache cache, blkid_dev dev,
struct blkid_magic *id, unsigned char *buf,
- blkid_loff_t size);
+ const char **ret_sectype);
struct blkid_magic {
const char *bim_type; /* type name for this magic */
@@ -28,8 +28,6 @@ struct blkid_magic {
unsigned bim_sboff; /* byte offset within superblock */
unsigned bim_len; /* length of magic */
const char *bim_magic; /* magic string */
- unsigned bim_align; /* byte alignment of superblock */
- unsigned bim_kbsize; /* size of superblock in kilobytes */
blkid_probe_t bim_probe; /* probe function */
};
@@ -202,6 +200,10 @@ struct hfs_super_block {
#define _INLINE_ extern inline
#endif
+extern __u16 blkid_swab16(__u16 val);
+extern __u32 blkid_swab32(__u32 val);
+extern __u64 blkid_swab64(__u64 val);
+
#if ((defined __GNUC__) && \
(defined(__i386__) || defined(__i486__) || defined(__i586__)))
diff --git a/lib/blkid/read.c b/lib/blkid/read.c
index 89a7bfdf..7c9c4d42 100644
--- a/lib/blkid/read.c
+++ b/lib/blkid/read.c
@@ -1,7 +1,7 @@
/*
* read.c - read the blkid cache from disk, to avoid scanning all devices
*
- * Copyright (C) 2001 Theodore Y. Ts'o
+ * Copyright (C) 2001, 2003 Theodore Y. Ts'o
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
@@ -179,10 +179,9 @@ static int parse_end(char **cp)
* <device foo=bar>devname</device>
* <device>devname<foo>bar</foo></device>
*/
-static int parse_dev(blkid_dev *dev, char **cp)
+static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp)
{
- char **name;
- char *start, *tmp, *end;
+ char *start, *tmp, *end, *name;
int ret;
if ((ret = parse_start(cp)) <= 0)
@@ -190,7 +189,7 @@ static int parse_dev(blkid_dev *dev, char **cp)
start = tmp = strchr(*cp, '>');
if (!start) {
- fprintf(stderr, "blkid: short line parsing dev: %s\n", *cp);
+ DBG(printf("blkid: short line parsing dev: %s\n", *cp));
return -BLKID_ERR_CACHE;
}
start = skip_over_blank(start + 1);
@@ -206,30 +205,25 @@ static int parse_dev(blkid_dev *dev, char **cp)
*tmp = '\0';
if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0)
- fprintf(stderr, "blkid: missing </device> ending: %s\n", end);
+ DBG(printf("blkid: missing </device> ending: %s\n", end));
else if (tmp)
*tmp = '\0';
if (end - start <= 1) {
- fprintf(stderr, "blkid: empty device name: %s\n", *cp);
+ DBG(printf("blkid: empty device name: %s\n", *cp));
return -BLKID_ERR_CACHE;
}
- if (!(*dev = blkid_new_dev()))
+ name = blkid_strndup(start, end-start);
+ if (name == NULL)
return -BLKID_ERR_MEM;
- name = &(*dev)->bid_name;
- *name = (char *)malloc(end - start + 1);
- if (*name == NULL) {
- blkid_free_dev(*dev);
- return -BLKID_ERR_MEM;
- }
-
- memcpy(*name, start, end - start);
- (*name)[end - start] = '\0';
+ DBG(printf("found dev %s\n", name));
- DBG(printf("found dev %s\n", *name));
+ if (!(*dev = blkid_get_devname(cache, name, BLKID_DEV_CREATE)))
+ return -BLKID_ERR_MEM;
+ free(name);
return 1;
}
@@ -253,7 +247,7 @@ static int parse_token(char **name, char **value, char **cp)
if (**value == '"') {
end = strchr(*value + 1, '"');
if (!end) {
- fprintf(stderr, "unbalanced quotes at: %s\n", *value);
+ DBG(printf("unbalanced quotes at: %s\n", *value));
*cp = *value;
return -BLKID_ERR_CACHE;
}
@@ -319,13 +313,11 @@ static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
cache->bic_idmax = dev->bid_id;
} else if (!strcmp(name, "DEVNO"))
dev->bid_devno = STRTOULL(value, 0, 0);
- else if (!strcmp(name, "DEVSIZE"))
- dev->bid_devno = STRTOULL(value, 0, 0);
else if (!strcmp(name, "TIME"))
/* FIXME: need to parse a long long eventually */
dev->bid_time = strtol(value, 0, 0);
else
- ret = blkid_create_tag(dev, name, value, strlen(value));
+ ret = blkid_set_tag(dev, name, value, strlen(value), 0);
DBG(printf(" tag: %s=\"%s\"\n", name, value));
@@ -355,7 +347,7 @@ static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
DBG(printf("line: %s\n", cp));
- if ((ret = parse_dev(dev_p, &cp)) <= 0)
+ if ((ret = parse_dev(cache, dev_p, &cp)) <= 0)
return ret;
dev = *dev_p;
@@ -365,37 +357,54 @@ static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
}
if (dev->bid_type == NULL) {
- fprintf(stderr, "blkid: device %s has no TYPE\n",dev->bid_name);
+ DBG(printf("blkid: device %s has no TYPE\n",dev->bid_name));
blkid_free_dev(dev);
}
DEB_DUMP_DEV(dev);
- *dev_p = blkid_add_dev_to_cache(cache, dev);
-
return ret;
}
/*
- * Read the given file stream for cached device data, and return it
- * in a newly allocated cache struct.
- *
- * Returns 0 on success, or -ve error value.
+ * Parse the specified filename, and return the data in the supplied or
+ * a newly allocated cache struct. If the file doesn't exist, return a
+ * new empty cache struct.
*/
-int blkid_read_cache_file(blkid_cache *cache, FILE *file)
+int blkid_get_cache(blkid_cache *cache, const char *filename)
{
+ FILE *file;
char buf[4096];
int lineno = 0;
- if (!file || !cache)
+ if (!cache)
return -BLKID_ERR_PARAM;
- if (!*cache)
- *cache = blkid_new_cache();
-
- if (!*cache)
+ if ((*cache = blkid_new_cache()) == NULL)
return -BLKID_ERR_MEM;
+ if (!filename || !strlen(filename))
+ filename = BLKID_CACHE_FILE;
+ else
+ (*cache)->bic_filename = blkid_strdup(filename);
+
+ DBG(printf("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 */
+ }
+
while (fgets(buf, sizeof(buf), file)) {
blkid_dev dev;
@@ -410,77 +419,19 @@ int blkid_read_cache_file(blkid_cache *cache, FILE *file)
}
if (blkid_parse_line(*cache, &dev, buf) < 0) {
- fprintf(stderr, "blkid: bad format on line %d\n",
- lineno);
+ DBG(printf("blkid: bad format on line %d\n", lineno));
continue;
}
}
-
/*
- * Initially assume that we do not need to write out the cache file.
- * This would be incorrect if we probed first, and parsed the cache
- * afterwards, or parsed two caches and wanted to write it out, but
- * the alternative is to force manually marking the cache dirty when
- * any device is added, and that is also prone to error.
+ * Initially we do not need to write out the cache file.
*/
(*cache)->bic_flags &= ~BLKID_BIC_FL_CHANGED;
- return 0;
-}
-
-/*
- * Parse the specified filename, and return the data in the supplied or
- * a newly allocated cache struct. If the file doesn't exist, return a
- * new empty cache struct.
- */
-int blkid_read_cache(blkid_cache *cache, const char *filename)
-{
- FILE *file;
- int ret;
-
- if (!cache)
- return -BLKID_ERR_PARAM;
-
- if (!filename || !strlen(filename))
- filename = BLKID_CACHE_FILE;
-
- DBG(printf("cache file %s\n", filename));
-
- /* If we read the standard cache file, do not do so again */
- if (!strcmp(filename, BLKID_CACHE_FILE) && (*cache) &&
- ((*cache)->bic_flags & BLKID_BIC_FL_PARSED))
- return 0;
-
- if (!strcmp(filename, "-") || !strcmp(filename, "stdin"))
- 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) {
- *cache = blkid_new_cache();
-
- return *cache ? 0 : -BLKID_ERR_MEM;
- }
-
- file = fopen(filename, "r");
- if (!file) {
- perror(filename);
- return errno;
- }
- }
-
- ret = blkid_read_cache_file(cache, file);
-
if (file != stdin)
fclose(file);
- /* Mark us as having read the standard cache file */
- if (!strcmp(filename, BLKID_CACHE_FILE))
- (*cache)->bic_flags |= BLKID_BIC_FL_PARSED;
-
- return ret;
+ return 0;
}
#ifdef TEST_PROGRAM
@@ -494,11 +445,11 @@ int main(int argc, char**argv)
"Test parsing of the cache (filename)\n", argv[0]);
exit(1);
}
- if ((ret = blkid_read_cache(&cache, argv[1])) < 0)
+ if ((ret = blkid_get_cache(&cache, argv[1])) < 0)
fprintf(stderr, "error %d reading cache file %s\n", ret,
argv[1] ? argv[1] : BLKID_CACHE_FILE);
- blkid_free_cache(cache);
+ blkid_put_cache(cache);
return ret;
}
diff --git a/lib/blkid/resolve.c b/lib/blkid/resolve.c
index 04ce1495..19478ed3 100644
--- a/lib/blkid/resolve.c
+++ b/lib/blkid/resolve.c
@@ -1,7 +1,7 @@
/*
* resolve.c - resolve names and tags into specific devices
*
- * Copyright (C) 2001 Theodore Ts'o.
+ * Copyright (C) 2001, 2003 Theodore Ts'o.
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
@@ -47,9 +47,9 @@ char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
if (!cache)
DBG(printf("no cache given, direct device probe\n"));
- if ((dev = blkid_get_devname(cache, devname)) &&
- (found = blkid_find_tag_dev(dev, tagname, NULL)))
- ret = string_copy(found->bit_val);
+ if ((dev = blkid_get_devname(cache, devname, BLKID_DEV_NORMAL)) &&
+ (found = blkid_find_tag_dev(dev, tagname)))
+ ret = blkid_strdup(found->bit_val);
if (!cache)
blkid_free_dev(dev);
@@ -62,8 +62,6 @@ char *blkid_get_tagname_devname(blkid_cache cache, const char *tagname,
* pair. In the case of a token, value is ignored. If the "token" is not
* of the form "NAME=value" and there is no value given, then it is assumed
* to be the actual devname and a copy is returned.
- *
- * The string returned must be freed with string_free().
*/
char *blkid_get_token(blkid_cache cache, const char *token,
const char *value)
@@ -80,7 +78,7 @@ char *blkid_get_token(blkid_cache cache, const char *token,
value ? value : "", cache ? "in cache" : "from disk"));
if (!cache) {
- if (blkid_read_cache(&c, NULL) < 0)
+ if (blkid_get_cache(&c, NULL) < 0)
c = blkid_new_cache();
if (!c)
return NULL;
@@ -98,7 +96,7 @@ char *blkid_get_token(blkid_cache cache, const char *token,
if (!dev)
goto errout;
- ret = string_copy(blkid_devname_name(dev));
+ ret = blkid_strdup(blkid_devname_name(dev));
errout:
if (t)
@@ -106,8 +104,7 @@ errout:
if (v)
free(v);
if (!cache) {
- blkid_save_cache(c, NULL);
- blkid_free_cache(c);
+ blkid_put_cache(c);
}
return (ret);
}
diff --git a/lib/blkid/save.c b/lib/blkid/save.c
index e888d0c5..5a8771e7 100644
--- a/lib/blkid/save.c
+++ b/lib/blkid/save.c
@@ -2,6 +2,7 @@
* save.c - write the cache struct to disk
*
* Copyright (C) 2001 by Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
@@ -54,41 +55,17 @@ static int save_dev(blkid_dev dev, FILE *file)
return 0;
}
-int blkid_save_cache_file(blkid_cache cache, FILE *file)
-{
- struct list_head *p;
- int ret = 0;
-
- if (!cache || !file)
- return -BLKID_ERR_PARAM;
-
- if (list_empty(&cache->bic_devs) ||
- !cache->bic_flags & BLKID_BIC_FL_CHANGED)
- return 0;
-
- list_for_each(p, &cache->bic_devs) {
- blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
- if ((ret = save_dev(dev, file)) < 0)
- break;
- }
-
- if (ret >= 0) {
- cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
- ret = 1;
- }
-
- return ret;
-}
-
/*
* Write out the cache struct to the cache file on disk.
*/
-int blkid_save_cache(blkid_cache cache, const char *filename)
+int blkid_flush_cache(blkid_cache cache)
{
+ struct list_head *p;
char *tmp = NULL;
const char *opened = NULL;
+ const char *filename;
FILE *file = NULL;
- int fd, ret;
+ int fd, ret = 0;
if (!cache)
return -BLKID_ERR_PARAM;
@@ -99,10 +76,9 @@ int blkid_save_cache(blkid_cache cache, const char *filename)
return 0;
}
- if (!filename || !strlen(filename))
- filename = BLKID_CACHE_FILE;
+ filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE;
- if (!strcmp(filename, "-") || !strcmp(filename, "stdout"))
+ if (!strcmp(filename, "-"))
file = stdout;
else {
struct stat st;
@@ -142,14 +118,23 @@ int blkid_save_cache(blkid_cache cache, const char *filename)
DBG(printf("cache file %s (really %s)\n", filename, opened));
if (!file) {
- perror(opened);
- if (tmp)
- free(tmp);
- return errno;
+ ret = errno;
+ goto errout;
}
}
- ret = blkid_save_cache_file(cache, file);
+ list_for_each(p, &cache->bic_devs) {
+ blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
+ if (!dev->bid_type)
+ continue;
+ if ((ret = save_dev(dev, file)) < 0)
+ break;
+ }
+
+ if (ret >= 0) {
+ cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
+ ret = 1;
+ }
if (file != stdout) {
fclose(file);
@@ -173,6 +158,7 @@ int blkid_save_cache(blkid_cache cache, const char *filename)
}
}
+errout:
if (tmp)
free(tmp);
return ret;
@@ -189,13 +175,23 @@ int main(int argc, char **argv)
"Test loading/saving a cache (filename)\n", argv[0]);
exit(1);
}
- if ((ret = blkid_probe_all(&cache) < 0))
- fprintf(stderr, "error probing devices\n");
- else if ((ret = blkid_save_cache(cache, argv[1])) < 0)
- fprintf(stderr, "error %d saving cache to %s\n", ret,
- argv[1] ? argv[1] : BLKID_CACHE_FILE);
- blkid_free_cache(cache);
+ if ((cache = blkid_new_cache()) == NULL) {
+ fprintf(stderr, "%s: error creating cache\n", argv[0]);
+ exit(1);
+ }
+ if ((ret = blkid_probe_all(cache)) < 0) {
+ fprintf(stderr, "error (%d) probing devices\n", ret);
+ exit(1);
+ }
+ cache->bic_filename = blkid_strdup(argv[1]);
+
+ if ((ret = blkid_flush_cache(cache)) < 0) {
+ fprintf(stderr, "error (%d) saving cache\n", ret);
+ exit(1);
+ }
+
+ blkid_put_cache(cache);
return ret;
}
diff --git a/lib/blkid/tag.c b/lib/blkid/tag.c
index d0e1b0a0..9bb99e14 100644
--- a/lib/blkid/tag.c
+++ b/lib/blkid/tag.c
@@ -2,6 +2,7 @@
* tag.c - allocation/initialization/free routines for tag structs
*
* Copyright (C) 2001 Andreas Dilger
+ * Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
@@ -21,7 +22,7 @@
#define DBG(x)
#endif
-blkid_tag blkid_new_tag(void)
+static blkid_tag blkid_new_tag(void)
{
blkid_tag tag;
@@ -39,16 +40,17 @@ void blkid_free_tag(blkid_tag tag)
if (!tag)
return;
- DBG(printf(" freeing tag %s=%s\n", tag->bit_name, tag->bit_val));
+ DBG(printf(" freeing tag %s=%s\n", tag->bit_name,
+ tag->bit_val ? tag->bit_val : "(NULL)"));
DEB_DUMP_TAG(tag);
list_del(&tag->bit_tags); /* list of tags for this device */
list_del(&tag->bit_names); /* list of tags with this type */
if (tag->bit_name)
- string_free(tag->bit_name);
+ free(tag->bit_name);
if (tag->bit_val)
- string_free(tag->bit_val);
+ free(tag->bit_val);
free(tag);
}
@@ -57,122 +59,148 @@ void blkid_free_tag(blkid_tag tag)
* Find the desired tag on a device. If value is NULL, then the
* first such tag is returned, otherwise return only exact tag if found.
*/
-blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type,
- const char *value)
+blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type)
{
- blkid_tag found = NULL;
struct list_head *p;
- if (!dev || !type || !value)
+ if (!dev || !type)
return NULL;
list_for_each(p, &dev->bid_tags) {
blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
bit_tags);
- if (!strcmp(tmp->bit_name, type) &&
- (!value || !strcmp(tmp->bit_val, value))){
- found = tmp;
- break;
- }
+ if (!strcmp(tmp->bit_name, type))
+ return tmp;
}
-
- return found;
+ return NULL;
}
/*
* Find the desired tag type in the cache.
* We return the head tag for this tag type.
*/
-blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
+static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
{
- blkid_tag head = NULL;
+ blkid_tag head = NULL, tmp;
struct list_head *p;
if (!cache || !type)
return NULL;
list_for_each(p, &cache->bic_tags) {
- blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
- bit_tags);
-
+ tmp = list_entry(p, struct blkid_struct_tag, bit_tags);
if (!strcmp(tmp->bit_name, type)) {
DBG(printf(" found cache tag head %s\n", type));
head = tmp;
break;
}
}
-
return head;
}
/*
- * Add a single tag to the given device.
- * This function is not currently exported because adding arbitrary tags to
- * a device will just get lost as soon as we verify the device (which
- * uses the dev struct returned from the device probe). At some point in
- * the future it may be desirable to allow adding arbitrary tags to a device,
- * and ensure that verify keeps all such tags (maybe lower case tag names?)
- */
-static void add_tag_to_dev(blkid_dev dev, blkid_tag tag)
-{
- if (!dev)
- return;
-
- DBG(printf("adding tag %s=%s\n", tag->bit_name, tag->bit_val));
-
- tag->bit_dev = dev;
-
- list_add_tail(&tag->bit_tags, &dev->bid_tags);
-
- /* Link common tags directly to the device struct */
- if (!strcmp(tag->bit_name, "TYPE") && !dev->bid_type)
- dev->bid_type = tag->bit_val;
- else if (!strcmp(tag->bit_name, "LABEL"))
- dev->bid_label = tag->bit_val;
- else if (!strcmp(tag->bit_name, "UUID"))
- dev->bid_uuid = tag->bit_val;
-}
-
-/*
- * Allocate and fill out a tag struct.
- * If dev is valid, the tag will be added to the tags for this device
- * if an identical tag does not already exist.
- * If tag is valid, the tag will be returned in this pointer.
+ * 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.
*/
-int blkid_create_tag(blkid_dev dev, const char *name,
- const char *value, const int vlength)
+int blkid_set_tag(blkid_dev dev, const char *name,
+ const char *value, const int vlength, int replace)
{
- blkid_tag t, found;
+ blkid_tag t = 0, head = 0;
+ char *val = 0;
- if (!dev)
+ if (!dev || !name)
return -BLKID_ERR_PARAM;
- if (!name)
- return -BLKID_ERR_PARAM;
+repeat:
+ t = blkid_find_tag_dev(dev, name);
+ val = blkid_strndup(value, vlength);
+ if (!value) {
+ if (t) {
+ blkid_free_tag(t);
+ goto repeat;
+ } else
+ goto link_tags;
+ }
+ if (!val)
+ goto errout;
+ 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)
- return -BLKID_ERR_MEM;
-
- t->bit_name = string_copy(name);
- t->bit_val = stringn_copy(value, vlength);
-
- if ((found = blkid_find_tag_dev(dev, name, t->bit_val))) {
- blkid_free_tag(t);
- return 0;
+ 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(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);
}
-
- add_tag_to_dev(dev, t);
-
+
+link_tags:
+ /* Link common tags directly to the device struct */
+ if (!strcmp(name, "TYPE") && (!val || !dev->bid_type))
+ dev->bid_type = val;
+ else if (!strcmp(name, "LABEL"))
+ dev->bid_label = val;
+ else if (!strcmp(name, "UUID"))
+ dev->bid_uuid = val;
+
+ if (dev->bid_cache)
+ dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED;
return 0;
+
+errout:
+ if (t)
+ blkid_free_tag(t);
+ else if (val)
+ free(val);
+ if (head)
+ blkid_free_tag(head);
+ return -BLKID_ERR_MEM;
}
+
/*
* Parse a "NAME=value" string. This is slightly different than
* parse_token, because that will end an unquoted value at a space, while
* this will assume that an unquoted value is the rest of the token (e.g.
- * if we are passed al alreay quoted string from the command-line we don't
+ * if we are passed an already quoted string from the command-line we don't
* have to both quote and escape quote so that the quotes make it to
* us).
*
@@ -187,7 +215,7 @@ int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
if (!token || !(cp = strchr(token, '=')))
return -1;
- name = string_copy(token);
+ name = blkid_strdup(token);
if (!name)
return -1;
value = name + (cp - token);
@@ -198,7 +226,7 @@ int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
goto errout; /* missing closing quote */
*cp = '\0';
}
- value = string_copy(value);
+ value = blkid_strdup(value);
if (!value)
goto errout;
@@ -208,7 +236,7 @@ int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
return 0;
errout:
- string_free(name);
+ free(name);
return -1;
}
@@ -291,7 +319,7 @@ extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
const char *type,
const char *value)
{
- blkid_tag head = 0, found;
+ blkid_tag head = 0, found = 0;
struct list_head *p;
if (!cache || !type || !value)
@@ -303,19 +331,20 @@ try_again:
if (!head)
head = blkid_find_head_cache(cache, type);
- found = 0;
- list_for_each(p, &head->bit_names) {
- blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
- bit_names);
+ if (head) {
+ list_for_each(p, &head->bit_names) {
+ blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
+ bit_names);
- if (!strcmp(tmp->bit_val, value)) {
- found = tmp;
- break;
+ if (!strcmp(tmp->bit_val, value)) {
+ found = tmp;
+ break;
+ }
}
}
if ((!head || !found) && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
- blkid_probe_all(&cache);
+ blkid_probe_all(cache);
goto try_again;
}
return (found ? found->bit_dev : NULL);