#endif
#include <pwd.h>
#include <stdio.h>
+#ifdef HAVE_STDLIB_H
#include <stdlib.h>
+#endif
#include <string.h>
#include <time.h>
#include <unistd.h>
static void usage(void)
{
- fprintf(stderr, _("Usage: %s [-rsI] device image_file\n"),
+ fprintf(stderr, _("Usage: %s [-rsI] device image_file\n"),
program_name);
exit (1);
}
exit(1);
}
memset(header_buf, 0, blocksize);
-
+
if (hdr)
memcpy(header_buf, hdr, sizeof(struct ext2_image_hdr));
-
+
actual = write(fd, header_buf, blocksize);
if (actual < 0) {
perror("write header");
com_err(program_name, retval, _("while writing superblock"));
exit(1);
}
-
+
hdr.offset_inode = lseek(fd, 0, SEEK_CUR);
retval = ext2fs_image_inode_write(fs, fd,
(fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
com_err(program_name, retval, _("while writing inode table"));
exit(1);
}
-
+
hdr.offset_blockmap = lseek(fd, 0, SEEK_CUR);
retval = ext2fs_image_bitmap_write(fs, fd, 0);
if (retval) {
hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE;
strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
- strncat(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name));
+ strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
hdr.fs_blocksize = fs->blocksize;
-
+
if (stat(device_name, &st) == 0)
hdr.fs_device = st.st_rdev;
static ino_t stashed_ino = 0;
static struct ext2_inode *stashed_inode;
-static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
+static errcode_t meta_get_blocks(ext2_filsys fs EXT2FS_ATTR((unused)),
ext2_ino_t ino,
blk_t *blocks)
{
int i;
-
+
if ((ino != stashed_ino) || !stashed_inode)
return EXT2_ET_CALLBACK_NOTHANDLED;
return 0;
}
-static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
+static errcode_t meta_check_directory(ext2_filsys fs EXT2FS_ATTR((unused)),
ext2_ino_t ino)
{
if ((ino != stashed_ino) || !stashed_inode)
return 0;
}
-static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
+static errcode_t meta_read_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
ext2_ino_t ino,
struct ext2_inode *inode)
{
}
}
-static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
+static int process_dir_block(ext2_filsys fs EXT2FS_ATTR((unused)),
blk_t *block_nr,
- e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
+ e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
blk_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
+ int ref_offset EXT2FS_ATTR((unused)),
void *priv_data EXT2FS_ATTR((unused)))
{
struct process_block_struct *p;
p = (struct process_block_struct *) priv_data;
- ext2fs_mark_block_bitmap(meta_block_map, *block_nr);
- if (scramble_block_map && p->is_dir && blockcnt >= 0)
- ext2fs_mark_block_bitmap(scramble_block_map, *block_nr);
+ ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
+ if (scramble_block_map && p->is_dir && blockcnt >= 0)
+ ext2fs_mark_block_bitmap2(scramble_block_map, *block_nr);
return 0;
}
-static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
+static int process_file_block(ext2_filsys fs EXT2FS_ATTR((unused)),
blk_t *block_nr,
- e2_blkcnt_t blockcnt,
+ e2_blkcnt_t blockcnt,
blk_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
+ int ref_offset EXT2FS_ATTR((unused)),
void *priv_data EXT2FS_ATTR((unused)))
{
if (blockcnt < 0) {
- ext2fs_mark_block_bitmap(meta_block_map, *block_nr);
+ ext2fs_mark_block_bitmap2(meta_block_map, *block_nr);
}
return 0;
}
{
blk_t first_block, b;
unsigned int i,j;
-
+
first_block = fs->super->s_first_data_block;
/*
* Mark primary superblock
*/
- ext2fs_mark_block_bitmap(meta_block_map, first_block);
-
+ ext2fs_mark_block_bitmap2(meta_block_map, first_block);
+
/*
* Mark the primary superblock descriptors
*/
for (j = 0; j < fs->desc_blocks; j++) {
- ext2fs_mark_block_bitmap(meta_block_map,
+ ext2fs_mark_block_bitmap2(meta_block_map,
ext2fs_descriptor_block_loc(fs, first_block, j));
}
/*
* Mark the blocks used for the inode table
*/
- if (fs->group_desc[i].bg_inode_table) {
- for (j = 0, b = fs->group_desc[i].bg_inode_table;
+ if (ext2fs_inode_table_loc(fs, i)) {
+ for (j = 0, b = ext2fs_inode_table_loc(fs, i);
j < (unsigned) fs->inode_blocks_per_group;
j++, b++)
- ext2fs_mark_block_bitmap(meta_block_map, b);
+ ext2fs_mark_block_bitmap2(meta_block_map, b);
}
-
+
/*
- * Mark block used for the block bitmap
+ * Mark block used for the block bitmap
*/
- if (fs->group_desc[i].bg_block_bitmap) {
- ext2fs_mark_block_bitmap(meta_block_map,
- fs->group_desc[i].bg_block_bitmap);
+ if (ext2fs_block_bitmap_loc(fs, i)) {
+ ext2fs_mark_block_bitmap2(meta_block_map,
+ ext2fs_block_bitmap_loc(fs, i));
}
-
+
/*
- * Mark block used for the inode bitmap
+ * Mark block used for the inode bitmap
*/
- if (fs->group_desc[i].bg_inode_bitmap) {
- ext2fs_mark_block_bitmap(meta_block_map,
- fs->group_desc[i].bg_inode_bitmap);
+ if (ext2fs_inode_bitmap_loc(fs, i)) {
+ ext2fs_mark_block_bitmap2(meta_block_map,
+ ext2fs_inode_bitmap_loc(fs, i));
}
}
}
err = 0;
com_err(program_name, err, "error writing block %u",
block);
+ exit(1);
}
}
}
int name_id[256];
+#define EXT4_MAX_REC_LEN ((1<<16)-1)
+
static void scramble_dir_block(ext2_filsys fs, blk_t blk, char *buf)
{
char *p, *end, *cp;
struct ext2_dir_entry_2 *dirent;
- int rec_len, id, len;
+ unsigned int rec_len;
+ int id, len;
end = buf + fs->blocksize;
for (p = buf; p < end-8; p += rec_len) {
#ifdef WORDS_BIGENDIAN
rec_len = ext2fs_swab16(rec_len);
#endif
+ if (rec_len == EXT4_MAX_REC_LEN || rec_len == 0)
+ rec_len = fs->blocksize;
+ else
+ rec_len = (rec_len & 65532) | ((rec_len & 3) << 16);
#if 0
printf("rec_len = %d, name_len = %d\n", rec_len, dirent->name_len);
#endif
if (rec_len < 8 || (rec_len % 4) ||
(p+rec_len > end)) {
printf("Corrupt directory block %lu: "
- "bad rec_len (%d)\n", (unsigned long) blk,
+ "bad rec_len (%d)\n", (unsigned long) blk,
rec_len);
rec_len = end - p;
+ (void) ext2fs_set_rec_len(fs, rec_len,
+ (struct ext2_dir_entry *) dirent);
#ifdef WORDS_BIGENDIAN
- dirent->rec_len = ext2fs_swab16(rec_len);
+ dirent->rec_len = ext2fs_swab16(dirent->rec_len);
#endif
continue;
}
if (dirent->name_len + 8 > rec_len) {
printf("Corrupt directory block %lu: "
- "bad name_len (%d)\n", (unsigned long) blk,
+ "bad name_len (%d)\n", (unsigned long) blk,
dirent->name_len);
dirent->name_len = rec_len - 8;
continue;
exit(1);
}
memset(zero_buf, 0, fs->blocksize);
- for (blk = 0; blk < fs->super->s_blocks_count; blk++) {
+ for (blk = 0; blk < ext2fs_blocks_count(fs->super); blk++) {
if ((blk >= fs->super->s_first_data_block) &&
- ext2fs_test_block_bitmap(meta_block_map, blk)) {
- retval = io_channel_read_blk(fs->io, blk, 1, buf);
+ ext2fs_test_block_bitmap2(meta_block_map, blk)) {
+ retval = io_channel_read_blk64(fs->io, blk, 1, buf);
if (retval) {
com_err(program_name, retval,
"error reading block %u", blk);
}
- if (scramble_block_map &&
- ext2fs_test_block_bitmap(scramble_block_map, blk))
+ if (scramble_block_map &&
+ ext2fs_test_block_bitmap2(scramble_block_map, blk))
scramble_dir_block(fs, blk, buf);
if ((fd != 1) && check_zero_block(buf, fs->blocksize))
goto sparse_write;
}
}
}
- write_block(fd, zero_buf, sparse, 1, -1);
+ if (sparse)
+ write_block(fd, zero_buf, sparse-1, 1, -1);
free(zero_buf);
free(buf);
}
ext2_ino_t ino;
errcode_t retval;
char * block_buf;
-
+
retval = ext2fs_allocate_block_bitmap(fs, "in-use block map",
&meta_block_map);
if (retval) {
retval = ext2fs_allocate_block_bitmap(fs, "scramble block map",
&scramble_block_map);
if (retval) {
- com_err(program_name, retval,
+ com_err(program_name, retval,
"while allocating scramble block bitmap");
exit(1);
}
}
-
+
mark_table_blocks(fs);
retval = ext2fs_open_inode_scan(fs, 0, &scan);
com_err(program_name, 0, "Can't allocate block buffer");
exit(1);
}
-
+
use_inode_shortcuts(fs, 1);
stashed_inode = &inode;
while (1) {
break;
if (!inode.i_links_count)
continue;
- if (inode.i_file_acl) {
- ext2fs_mark_block_bitmap(meta_block_map,
- inode.i_file_acl);
+ if (ext2fs_file_acl_block(&inode)) {
+ ext2fs_mark_block_bitmap2(meta_block_map,
+ ext2fs_file_acl_block(&inode));
}
if (!ext2fs_inode_has_valid_blocks(&inode))
continue;
-
+
stashed_ino = ino;
pb.ino = ino;
pb.is_dir = LINUX_S_ISDIR(inode.i_mode);
(LINUX_S_ISLNK(inode.i_mode) &&
ext2fs_inode_has_valid_blocks(&inode)) ||
ino == fs->super->s_journal_inum) {
- retval = ext2fs_block_iterate2(fs, ino, 0,
- block_buf, process_dir_block, &pb);
+ retval = ext2fs_block_iterate2(fs, ino,
+ BLOCK_FLAG_READ_ONLY, block_buf,
+ process_dir_block, &pb);
if (retval) {
com_err(program_name, retval,
"while iterating over inode %u",
exit(1);
}
} else {
- if (inode.i_block[EXT2_IND_BLOCK] ||
+ if ((inode.i_flags & EXT4_EXTENTS_FL) ||
+ inode.i_block[EXT2_IND_BLOCK] ||
inode.i_block[EXT2_DIND_BLOCK] ||
inode.i_block[EXT2_TIND_BLOCK]) {
retval = ext2fs_block_iterate2(fs,
- ino, 0, block_buf,
+ ino, BLOCK_FLAG_READ_ONLY, block_buf,
process_file_block, &pb);
if (retval) {
com_err(program_name, retval,
com_err(program_name, 0, "Raw images cannot be installed");
exit(1);
}
-
+
#ifdef CONFIG_TESTIO_DEBUG
- io_ptr = test_io_manager;
- test_io_backing_manager = unix_io_manager;
-#else
- io_ptr = unix_io_manager;
+ if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
+ io_ptr = test_io_manager;
+ test_io_backing_manager = unix_io_manager;
+ } else
#endif
+ io_ptr = unix_io_manager;
retval = ext2fs_open (image_fn, open_flag, 0, 0,
io_ptr, &fs);
exit(1);
}
-
+#ifdef HAVE_OPEN64
+ fd = open64(image_fn, O_RDONLY);
+#else
fd = open(image_fn, O_RDONLY);
+#endif
if (fd < 0) {
perror(image_fn);
exit(1);
}
- retval = io_ptr->open(device, IO_FLAG_RW, &io);
+ retval = io_ptr->open(device, IO_FLAG_RW, &io);
if (retval) {
com_err(device, 0, "while opening device file");
exit(1);