aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2008-02-27 18:53:34 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-02-27 18:53:34 -0500
commita49670e64e28ac3b15e36cb6bd0a8135d3ecdbbb (patch)
tree30f0ecd00942e15e097ca2c253131f4d3abce3a9 /lib
parente6bbc002c5a3d30df156d4f23bc93a7f2dbde3a1 (diff)
parent4f9abdcb306ff515a8009a1e0fd35041688133c9 (diff)
downloadandroid_external_e2fsprogs-a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbb.tar.gz
android_external_e2fsprogs-a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbb.tar.bz2
android_external_e2fsprogs-a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbb.zip
Merge branch 'maint'
Conflicts: lib/blkid/devname.c lib/blkid/probe.c misc/mke2fs.c misc/tune2fs.c
Diffstat (limited to 'lib')
-rw-r--r--lib/blkid/devname.c93
-rw-r--r--lib/blkid/probe.c82
-rw-r--r--lib/blkid/probe.h14
-rw-r--r--lib/e2p/e2p.h5
-rw-r--r--lib/e2p/feature.c47
-rw-r--r--lib/e2p/ls.c4
-rw-r--r--lib/ext2fs/alloc.c1
-rw-r--r--lib/ext2fs/ext2fs.h1
-rw-r--r--lib/ext2fs/openfs.c6
9 files changed, 197 insertions, 56 deletions
diff --git a/lib/blkid/devname.c b/lib/blkid/devname.c
index 0bcba448..29cde8e7 100644
--- a/lib/blkid/devname.c
+++ b/lib/blkid/devname.c
@@ -171,37 +171,42 @@ static int dm_device_has_dep(const dev_t dev, const char *name)
struct dm_deps *deps;
struct dm_info info;
unsigned int i;
+ int ret = 0;
task = dm_task_create(DM_DEVICE_DEPS);
if (!task)
- return 0;
+ goto out;
- dm_task_set_name(task, name);
- dm_task_run(task);
- dm_task_get_info(task, &info);
+ if (!dm_task_set_name(task, name))
+ goto out;
- if (!info.exists) {
- dm_task_destroy(task);
- return 0;
- }
+ if (!dm_task_run(task))
+ goto out;
+ if (!dm_task_get_info(task, &info))
+ goto out;
+
+ if (!info.exists)
+ goto out;
+
deps = dm_task_get_deps(task);
- if (!deps || deps->count == 0) {
- dm_task_destroy(task);
- return 0;
- }
+ if (!deps || deps->count == 0)
+ goto out;
for (i = 0; i < deps->count; i++) {
dev_t dep_dev = deps->device[i];
if (dev == dep_dev) {
- dm_task_destroy(task);
- return 1;
+ ret = 1;
+ goto out;
}
}
- dm_task_destroy(task);
- return 0;
+out:
+ if (task)
+ dm_task_destroy(task);
+
+ return ret;
}
static int dm_device_is_leaf(const dev_t dev)
@@ -214,15 +219,16 @@ static int dm_device_is_leaf(const dev_t dev)
dm_log_init(dm_quiet_log);
task = dm_task_create(DM_DEVICE_LIST);
if (!task)
- return 1;
+ goto out;
+
dm_log_init(0);
- dm_task_run(task);
+ if (!dm_task_run(task))
+ goto out;
+
names = dm_task_get_names(task);
- if (!names || !names->dev) {
- dm_task_destroy(task);
- return 1;
- }
+ if (!names || !names->dev)
+ goto out;
n = 0;
do {
@@ -234,7 +240,9 @@ static int dm_device_is_leaf(const dev_t dev)
next = names->next;
} while (next);
- dm_task_destroy(task);
+out:
+ if (task)
+ dm_task_destroy(task);
return ret;
}
@@ -247,20 +255,25 @@ static dev_t dm_get_devno(const char *name)
task = dm_task_create(DM_DEVICE_INFO);
if (!task)
- return ret;
+ goto out;
- dm_task_set_name(task, name);
- dm_task_run(task);
- dm_task_get_info(task, &info);
+ if (!dm_task_set_name(task, name))
+ goto out;
- if (!info.exists) {
- dm_task_destroy(task);
- return ret;
- }
+ if (!dm_task_run(task))
+ goto out;
+
+ if (!dm_task_get_info(task, &info))
+ goto out;
+
+ if (!info.exists)
+ goto out;
ret = makedev(info.major, info.minor);
- dm_task_destroy(task);
+out:
+ if (task)
+ dm_task_destroy(task);
return ret;
}
@@ -275,15 +288,15 @@ static void dm_probe_all(blkid_cache cache, int only_if_new)
dm_log_init(dm_quiet_log);
task = dm_task_create(DM_DEVICE_LIST);
if (!task)
- return;
+ goto out;
dm_log_init(0);
- dm_task_run(task);
+ if (!dm_task_run(task))
+ goto out;
+
names = dm_task_get_names(task);
- if (!names || !names->dev) {
- dm_task_destroy(task);
- return;
- }
+ if (!names || !names->dev)
+ goto out;
n = 0;
do {
@@ -311,7 +324,9 @@ try_next:
next = names->next;
} while (next);
- dm_task_destroy(task);
+out:
+ if (task)
+ dm_task_destroy(task);
}
#endif /* HAVE_DEVMAPPER */
diff --git a/lib/blkid/probe.c b/lib/blkid/probe.c
index 04527eaf..10e018a9 100644
--- a/lib/blkid/probe.c
+++ b/lib/blkid/probe.c
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
+#include <ctype.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -163,7 +164,7 @@ static void get_ext2_info(blkid_dev dev, struct blkid_magic *id,
* Check to see if a filesystem is in /proc/filesystems.
* Returns 1 if found, 0 if not
*/
-int fs_proc_check(const char *fs_name)
+static int fs_proc_check(const char *fs_name)
{
FILE *f;
char buf[80], *cp, *t;
@@ -200,7 +201,7 @@ int fs_proc_check(const char *fs_name)
* Check to see if a filesystem is available as a module
* Returns 1 if found, 0 if not
*/
-int check_for_modules(const char *fs_name)
+static int check_for_modules(const char *fs_name)
{
struct utsname uts;
FILE *f;
@@ -236,7 +237,7 @@ int check_for_modules(const char *fs_name)
return (0);
}
-static int system_supports_ext4()
+static int system_supports_ext4(void)
{
static time_t last_check = 0;
static int ret = -1;
@@ -249,7 +250,7 @@ static int system_supports_ext4()
return ret;
}
-static int system_supports_ext4dev()
+static int system_supports_ext4dev(void)
{
static time_t last_check = 0;
static int ret = -1;
@@ -1008,7 +1009,7 @@ static int probe_gfs2(struct blkid_probe *probe,
return 1;
}
-static int probe_hfsplus(struct blkid_probe *probe,
+static int probe_hfsplus(struct blkid_probe *probe __BLKID_ATTR((unused)),
struct blkid_magic *id __BLKID_ATTR((unused)),
unsigned char *buf)
{
@@ -1021,6 +1022,73 @@ static int probe_hfsplus(struct blkid_probe *probe,
return 1;
}
+#define LVM2_LABEL_SIZE 512
+static unsigned int lvm2_calc_crc(const void *buf, uint size)
+{
+ static const uint crctab[] = {
+ 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
+ 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
+ 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
+ };
+ uint i, crc = 0xf597a6cf;
+ const __u8 *data = (const __u8 *) buf;
+
+ for (i = 0; i < size; i++) {
+ crc ^= *data++;
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ crc = (crc >> 4) ^ crctab[crc & 0xf];
+ }
+ return crc;
+}
+
+static int probe_lvm2(struct blkid_probe *probe,
+ struct blkid_magic *id __BLKID_ATTR((unused)),
+ unsigned char *buf)
+{
+ int sector = (id->bim_kboff) << 1;;
+ struct lvm2_pv_label_header *label;
+ label = (struct lvm2_pv_label_header *)buf;
+ char *p, *q, uuid[40];
+ unsigned int i, b;
+
+ /* buf is at 0k or 1k offset; find label inside */
+ if (memcmp(buf, "LABELONE", 8) == 0) {
+ label = (struct lvm2_pv_label_header *)buf;
+ } else if (memcmp(buf + 512, "LABELONE", 8) == 0) {
+ label = (struct lvm2_pv_label_header *)(buf + 512);
+ sector++;
+ } else {
+ return 1;
+ }
+
+ if (blkid_le64(label->sector_xl) != (unsigned) sector) {
+ DBG(DEBUG_PROBE,
+ printf("LVM2: label for sector %llu found at sector %d\n",
+ blkid_le64(label->sector_xl), sector));
+ return 1;
+ }
+
+ if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE -
+ ((char *)&label->offset_xl - (char *)label)) !=
+ blkid_le32(label->crc_xl)) {
+ DBG(DEBUG_PROBE,
+ printf("LVM2: label checksum incorrect at sector %d\n",
+ sector));
+ return 1;
+ }
+
+ for (i=0, b=1, p=uuid, q= (char *) label->pv_uuid; i <= 32;
+ i++, b <<= 1) {
+ if (b & 0x4444440)
+ *p++ = '-';
+ *p++ = *q++;
+ }
+
+ blkid_set_tag(probe->dev, "UUID", uuid, LVM2_ID_LEN+6);
+
+ return 0;
+}
/*
* BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
* in the type_array table below + bim_kbalign.
@@ -1114,6 +1182,10 @@ static struct blkid_magic type_array[] = {
{ "crypt_LUKS", 0, 0, 6, "LUKS\xba\xbe", probe_luks },
{ "squashfs", 0, 0, 4, "sqsh", 0 },
{ "squashfs", 0, 0, 4, "hsqs", 0 },
+ { "lvm2pv", 0, 0x218, 8, "LVM2 001", probe_lvm2 },
+ { "lvm2pv", 0, 0x018, 8, "LVM2 001", probe_lvm2 },
+ { "lvm2pv", 1, 0x018, 8, "LVM2 001", probe_lvm2 },
+ { "lvm2pv", 1, 0x218, 8, "LVM2 001", probe_lvm2 },
{ NULL, 0, 0, 0, NULL, NULL }
};
diff --git a/lib/blkid/probe.h b/lib/blkid/probe.h
index acfe1195..b3cc26b9 100644
--- a/lib/blkid/probe.h
+++ b/lib/blkid/probe.h
@@ -531,6 +531,20 @@ struct hfs_mdb {
__u16 embed_blockcount;
} __attribute__((packed));
+/* this is lvm's label_header & pv_header combined. */
+
+#define LVM2_ID_LEN 32
+
+struct lvm2_pv_label_header {
+ /* label_header */
+ __u8 id[8]; /* LABELONE */
+ __u64 sector_xl; /* Sector number of this label */
+ __u32 crc_xl; /* From next field to end of sector */
+ __u32 offset_xl; /* Offset from start of struct to contents */
+ __u8 type[8]; /* LVM2 001 */
+ /* pv_header */
+ __u8 pv_uuid[LVM2_ID_LEN];
+} __attribute__ ((packed));
/*
* Byte swap functions
diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h
index 5d9131fd..06e2120d 100644
--- a/lib/e2p/e2p.h
+++ b/lib/e2p/e2p.h
@@ -7,7 +7,9 @@
#define E2P_FEATURE_COMPAT 0
#define E2P_FEATURE_INCOMPAT 1
#define E2P_FEATURE_RO_INCOMPAT 2
+#define E2P_FEATURE_TYPE_MASK 0x03
+#define E2P_FEATURE_NEGATE_FLAG 0x80
/* `options' for print_flags() */
@@ -34,6 +36,9 @@ int setversion (int fd, unsigned long version);
const char *e2p_feature2string(int compat, unsigned int mask);
int e2p_string2feature(char *string, int *compat, unsigned int *mask);
int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array);
+int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
+ __u32 *clear_ok_array, int *type_err,
+ unsigned int *mask_err);
int e2p_is_null_uuid(void *uu);
void e2p_uuid_to_str(void *uu, char *out);
diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c
index 4bf56301..fc6052c1 100644
--- a/lib/e2p/feature.c
+++ b/lib/e2p/feature.c
@@ -163,9 +163,12 @@ static char *skip_over_word(char *cp)
/*
* Edit a feature set array as requested by the user. The ok_array,
* if set, allows the application to limit what features the user is
- * allowed to set or clear using this function.
+ * allowed to set or clear using this function. If clear_ok_array is set,
+ * then use it tell whether or not it is OK to clear a filesystem feature.
*/
-int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
+int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
+ __u32 *clear_ok_array, int *type_err,
+ unsigned int *mask_err)
{
char *cp, *buf, *next;
int neg;
@@ -173,6 +176,14 @@ int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
int compat_type;
int rc = 0;
+ if (!clear_ok_array)
+ clear_ok_array = ok_array;
+
+ if (type_err)
+ *type_err = 0;
+ if (mask_err)
+ *mask_err = 0;
+
buf = malloc(strlen(str)+1);
if (!buf)
return 1;
@@ -207,15 +218,35 @@ int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
rc = 1;
break;
}
- if (ok_array && !(ok_array[compat_type] & mask)) {
- rc = 1;
- break;
- }
- if (neg)
+ if (neg) {
+ if (clear_ok_array &&
+ !(clear_ok_array[compat_type] & mask)) {
+ rc = 1;
+ if (type_err)
+ *type_err = (compat_type |
+ E2P_FEATURE_NEGATE_FLAG);
+ if (mask_err)
+ *mask_err = mask;
+ break;
+ }
compat_array[compat_type] &= ~mask;
- else
+ } else {
+ if (ok_array && !(ok_array[compat_type] & mask)) {
+ rc = 1;
+ if (type_err)
+ *type_err = compat_type;
+ if (mask_err)
+ *mask_err = mask;
+ break;
+ }
compat_array[compat_type] |= mask;
+ }
}
free(buf);
return rc;
}
+
+int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
+{
+ return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
+}
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 23c33a58..d249f88b 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -234,10 +234,10 @@ void list_super2(struct ext2_super_block * sb, FILE *f)
fprintf(f, "Inodes per group: %u\n", sb->s_inodes_per_group);
fprintf(f, "Inode blocks per group: %u\n", inode_blocks_per_group);
if (sb->s_raid_stride)
- fprintf(f, "Raid stride: %u\n",
+ fprintf(f, "RAID stride: %u\n",
sb->s_raid_stride);
if (sb->s_raid_stripe_width)
- fprintf(f, "Raid stripe width: %u\n",
+ fprintf(f, "RAID stripe width: %u\n",
sb->s_raid_stripe_width);
if (sb->s_first_meta_bg)
fprintf(f, "First meta block group: %u\n",
diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
index 7385123b..65f3ea1c 100644
--- a/lib/ext2fs/alloc.c
+++ b/lib/ext2fs/alloc.c
@@ -134,7 +134,6 @@ errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
ext2fs_block_alloc_stats(fs, block, +1);
*ret = block;
- return 0;
fail:
if (buf)
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 4fea613b..b7de2301 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -171,6 +171,7 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_IMAGE_FILE 0x2000
#define EXT2_FLAG_EXCLUSIVE 0x4000
#define EXT2_FLAG_SOFTSUPP_FEATURES 0x8000
+#define EXT2_FLAG_NOFREE_ON_ERROR 0x10000
/*
* Special flag in the ext2 inode i_flag field that means that this is
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index cb683eea..a6a82174 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -303,10 +303,14 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
fs->stride = fs->super->s_raid_stride;
+ fs->flags &= ~EXT2_FLAG_NOFREE_ON_ERROR;
*ret_fs = fs;
return 0;
cleanup:
- ext2fs_free(fs);
+ if (flags & EXT2_FLAG_NOFREE_ON_ERROR)
+ *ret_fs = fs;
+ else
+ ext2fs_free(fs);
return retval;
}