* %End-Header%
*/
+#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __linux__
struct utsname uts;
FILE *f;
- char buf[1024], *cp, *t;
- int i;
+ char buf[1024], *cp;
+ int namesz;
if (uname(&uts))
return (0);
f = fopen(buf, "r");
if (!f)
return (0);
+
+ namesz = strlen(fs_name);
+
while (!feof(f)) {
if (!fgets(buf, sizeof(buf), f))
break;
cp++;
else
cp = buf;
- i = strlen(cp);
- if (i > 3) {
- t = cp + i - 3;
- if (!strcmp(t, ".ko"))
- *t = 0;
- }
- if (!strcmp(cp, fs_name)) {
+ if (!strncmp(cp, fs_name, namesz) &&
+ (!strcmp(cp + namesz, ".ko") ||
+ !strcmp(cp + namesz, ".ko.gz"))) {
fclose(f);
return (1);
}
return (0);
}
+static int linux_version_code()
+{
+#ifdef __linux__
+ struct utsname ut;
+ static int version_code = -1;
+ int major, minor, rev;
+ char *endptr;
+ const char *cp;
+
+ if (version_code > 0)
+ return version_code;
+
+ if (uname(&ut))
+ return 0;
+ cp = ut.release;
+
+ major = strtol(cp, &endptr, 10);
+ if (cp == endptr || *endptr != '.')
+ return 0;
+ cp = endptr + 1;
+ minor = strtol(cp, &endptr, 10);
+ if (cp == endptr || *endptr != '.')
+ return 0;
+ cp = endptr + 1;
+ rev = strtol(cp, &endptr, 10);
+ if (cp == endptr)
+ return 0;
+ version_code = (((major * 256) + minor) * 256) + rev;
+ return version_code;
+#else
+ return 0;
+#endif
+}
+
+#define EXT4_SUPPORTS_EXT2 (2 * 65536 + 6*256 + 29)
+
+static int system_supports_ext2(void)
+{
+ static time_t last_check = 0;
+ static int ret = -1;
+ time_t now = time(0);
+
+ if (ret != -1 || (now - last_check) < 5)
+ return ret;
+ last_check = now;
+ ret = (fs_proc_check("ext2") || check_for_modules("ext2"));
+ return ret;
+}
+
static int system_supports_ext4(void)
{
static time_t last_check = 0;
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
return -BLKID_ERR_PARAM;
- /* ext4dev requires a journal */
+ /*
+ * If the filesystem does not have a journal and ext2 and ext4
+ * is not present, then force this to be detected as an
+ * ext4dev filesystem.
+ */
if (!(blkid_le32(es->s_feature_compat) &
- EXT3_FEATURE_COMPAT_HAS_JOURNAL))
- return -BLKID_ERR_PARAM;
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+ !system_supports_ext2() && !system_supports_ext4() &&
+ system_supports_ext4dev() &&
+ linux_version_code() >= EXT4_SUPPORTS_EXT2)
+ goto force_ext4dev;
/*
* If the filesystem is marked as OK for use by in-development
} else
return -BLKID_ERR_PARAM;
+force_ext4dev:
get_ext2_info(probe->dev, id, buf);
return 0;
}
EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
return -BLKID_ERR_PARAM;
- /* ext4 requires journal */
+ /*
+ * If the filesystem does not have a journal and ext2 is not
+ * present, then force this to be detected as an ext2
+ * filesystem.
+ */
if (!(blkid_le32(es->s_feature_compat) &
- EXT3_FEATURE_COMPAT_HAS_JOURNAL))
- return -BLKID_ERR_PARAM;
+ EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+ !system_supports_ext2() && system_supports_ext4() &&
+ linux_version_code() >= EXT4_SUPPORTS_EXT2)
+ goto force_ext4;
/* Ext4 has at least one feature which ext3 doesn't understand */
if (!(blkid_le32(es->s_feature_ro_compat) &
EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
return -BLKID_ERR_PARAM;
+force_ext4:
/*
* If the filesystem is a OK for use by in-development
* filesystem code, and ext4dev is supported or ext4 is not
EXT2_FEATURE_INCOMPAT_UNSUPPORTED))
return -BLKID_ERR_PARAM;
+ /*
+ * If ext2 is not present, but ext4 or ext4dev are, then
+ * disclaim we are ext2
+ */
+ if (!system_supports_ext2() &&
+ (system_supports_ext4() || system_supports_ext4dev()) &&
+ linux_version_code() >= EXT4_SUPPORTS_EXT2)
+ return -BLKID_ERR_PARAM;
+
get_ext2_info(probe->dev, id, buf);
return 0;
}
sprintf(uuid_str, "%016llX", uuid);
blkid_set_tag(probe->dev, "UUID", uuid_str, 0);
}
- blkid_set_tag(probe->dev, "LABEL", hfs->label, hfs->label_len);
+ blkid_set_tag(probe->dev, "LABEL", (char *)hfs->label, hfs->label_len);
return 0;
}
return 0;
label_len = blkid_be16(key->unicode_len) * 2;
- unicode_16be_to_utf8(label, sizeof(label), key->unicode, label_len);
+ unicode_16be_to_utf8((unsigned char *)label, sizeof(label),
+ key->unicode, label_len);
blkid_set_tag(probe->dev, "LABEL", label, 0);
return 0;
}
dev->bid_name, (long long)st.st_rdev, type));
}
- if (probe.sbbuf)
- free(probe.sbbuf);
- if (probe.buf)
- free(probe.buf);
+ free(probe.sbbuf);
+ free(probe.buf);
if (probe.fd >= 0)
close(probe.fd);