diff options
| author | Theodore Ts'o <tytso@mit.edu> | 2008-02-27 18:53:34 -0500 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2008-02-27 18:53:34 -0500 |
| commit | a49670e64e28ac3b15e36cb6bd0a8135d3ecdbbb (patch) | |
| tree | 30f0ecd00942e15e097ca2c253131f4d3abce3a9 /lib | |
| parent | e6bbc002c5a3d30df156d4f23bc93a7f2dbde3a1 (diff) | |
| parent | 4f9abdcb306ff515a8009a1e0fd35041688133c9 (diff) | |
| download | android_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.c | 93 | ||||
| -rw-r--r-- | lib/blkid/probe.c | 82 | ||||
| -rw-r--r-- | lib/blkid/probe.h | 14 | ||||
| -rw-r--r-- | lib/e2p/e2p.h | 5 | ||||
| -rw-r--r-- | lib/e2p/feature.c | 47 | ||||
| -rw-r--r-- | lib/e2p/ls.c | 4 | ||||
| -rw-r--r-- | lib/ext2fs/alloc.c | 1 | ||||
| -rw-r--r-- | lib/ext2fs/ext2fs.h | 1 | ||||
| -rw-r--r-- | lib/ext2fs/openfs.c | 6 |
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; } |
