Use the same patch format in patch_io_manager and e2patch like in patchbd
parent
435a466e20
commit
ceeb9c6cdc
4
Makefile
4
Makefile
|
@ -1,8 +1,8 @@
|
||||||
all: realloc-inodes e2patch
|
all: realloc-inodes e2patch
|
||||||
realloc-inodes: realloc-inodes.c bmove.c bmove.h check_uninit.c check_uninit.h Makefile patch_io.c patch_io.h patch.c patch.h
|
realloc-inodes: realloc-inodes.c bmove.c bmove.h check_uninit.c check_uninit.h Makefile patch_io.c patch_io.h patch.c patch.h
|
||||||
gcc -g -Wsign-compare -Wall -o realloc-inodes -lcom_err -lext2fs realloc-inodes.c bmove.c patch_io.c patch.c check_uninit.c
|
gcc -D_FILE_OFFSET_BITS=64 -g -Wsign-compare -Wall -o realloc-inodes -lcom_err -lext2fs realloc-inodes.c bmove.c patch_io.c patch.c check_uninit.c
|
||||||
e2patch: e2patch.c patch.c patch.h
|
e2patch: e2patch.c patch.c patch.h
|
||||||
gcc -g -Wsign-compare -Wall -o e2patch -lcom_err -lext2fs e2patch.c patch.c
|
gcc -D_FILE_OFFSET_BITS=64 -g -Wsign-compare -Wall -o e2patch -lcom_err -lext2fs e2patch.c patch.c
|
||||||
test-ext2.img:
|
test-ext2.img:
|
||||||
sudo sh test-mkimages.sh
|
sudo sh test-mkimages.sh
|
||||||
sudo chown $(shell id -u) *.img
|
sudo chown $(shell id -u) *.img
|
||||||
|
|
|
@ -45,7 +45,7 @@ errcode_t make_backup_patch(char *device, char *io_options, char *patch_file, ch
|
||||||
blk64_t blk, start, buf_blocks;
|
blk64_t blk, start, buf_blocks;
|
||||||
int eq;
|
int eq;
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
struct ext2fs_patch_file patch, backup;
|
struct ext2fs_patch_file patch = { 0 }, backup = { 0 };
|
||||||
retval = mgr->open(device, IO_FLAG_EXCLUSIVE, &io);
|
retval = mgr->open(device, IO_FLAG_EXCLUSIVE, &io);
|
||||||
if (retval) goto out;
|
if (retval) goto out;
|
||||||
if (io_options &&
|
if (io_options &&
|
||||||
|
@ -93,7 +93,7 @@ errcode_t apply_patch(char *device, char *io_options, char *patch_file)
|
||||||
blk64_t blk, start, buf_blocks;
|
blk64_t blk, start, buf_blocks;
|
||||||
int eq;
|
int eq;
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
struct ext2fs_patch_file patch;
|
struct ext2fs_patch_file patch = { 0 };
|
||||||
retval = mgr->open(device, IO_FLAG_EXCLUSIVE|IO_FLAG_RW, &io);
|
retval = mgr->open(device, IO_FLAG_EXCLUSIVE|IO_FLAG_RW, &io);
|
||||||
if (retval) goto out;
|
if (retval) goto out;
|
||||||
if (io_options &&
|
if (io_options &&
|
||||||
|
@ -111,7 +111,7 @@ errcode_t apply_patch(char *device, char *io_options, char *patch_file)
|
||||||
{
|
{
|
||||||
if (start != blk)
|
if (start != blk)
|
||||||
{
|
{
|
||||||
retval = retry_read_at(patch.patch_fd, start*patch.block_size, (blk-start)*patch.block_size, buf);
|
retval = retry_read_at(patch.patch_fd, patch.offset + start*patch.block_size, (blk-start)*patch.block_size, buf);
|
||||||
if (retval) goto out;
|
if (retval) goto out;
|
||||||
retval = io_channel_write_blk64(io, start, blk-start, buf);
|
retval = io_channel_write_blk64(io, start, blk-start, buf);
|
||||||
if (retval) goto out;
|
if (retval) goto out;
|
||||||
|
|
35
patch.c
35
patch.c
|
@ -32,7 +32,7 @@ errcode_t retry_read(int fd, ssize_t size, void *buf)
|
||||||
while (done < size)
|
while (done < size)
|
||||||
{
|
{
|
||||||
r = read(fd, buf+done, size-done);
|
r = read(fd, buf+done, size-done);
|
||||||
if (r < 0 && errno != EAGAIN)
|
if (!r || (r < 0 && errno != EAGAIN))
|
||||||
break;
|
break;
|
||||||
done += r;
|
done += r;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ errcode_t retry_write(int fd, ssize_t size, const void *buf)
|
||||||
while (done < size)
|
while (done < size)
|
||||||
{
|
{
|
||||||
r = write(fd, buf+done, size-done);
|
r = write(fd, buf+done, size-done);
|
||||||
if (r < 0 && errno != EAGAIN)
|
if (r <= 0 && errno != EAGAIN)
|
||||||
break;
|
break;
|
||||||
done += r;
|
done += r;
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ errcode_t ext2fs_patch_read_bmap(struct ext2fs_patch_file *data)
|
||||||
void *buf = malloc(bufsize);
|
void *buf = malloc(bufsize);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
ext2fs_llseek(data->patch_fd, data->size*data->block_size, SEEK_SET);
|
ext2fs_llseek(data->patch_fd, data->block_size, SEEK_SET);
|
||||||
for (i = 0; i < data->size/8; )
|
for (i = 0; i < data->size/8; )
|
||||||
{
|
{
|
||||||
r = bufsize;
|
r = bufsize;
|
||||||
|
@ -100,10 +100,11 @@ errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data)
|
||||||
errcode_t retval = 0;
|
errcode_t retval = 0;
|
||||||
int bufsize = 65536;
|
int bufsize = 65536;
|
||||||
blk64_t i, r;
|
blk64_t i, r;
|
||||||
|
struct patchbd_super s;
|
||||||
void *buf = malloc(bufsize);
|
void *buf = malloc(bufsize);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
ext2fs_llseek(data->patch_fd, data->size*data->block_size, SEEK_SET);
|
ext2fs_llseek(data->patch_fd, data->block_size, SEEK_SET);
|
||||||
for (i = 0; i < data->size/8; )
|
for (i = 0; i < data->size/8; )
|
||||||
{
|
{
|
||||||
r = bufsize;
|
r = bufsize;
|
||||||
|
@ -115,8 +116,11 @@ errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data)
|
||||||
goto out;
|
goto out;
|
||||||
i += r;
|
i += r;
|
||||||
}
|
}
|
||||||
write(data->patch_fd, &data->block_size, sizeof(__u32));
|
ext2fs_llseek(data->patch_fd, 0, SEEK_SET);
|
||||||
write(data->patch_fd, &data->size, sizeof(blk64_t));
|
s.magic = PATCHBD_MAGIC;
|
||||||
|
s.patch_block = data->block_size;
|
||||||
|
s.patch_size = data->size;
|
||||||
|
write(data->patch_fd, &s, sizeof(struct patchbd_super));
|
||||||
out:
|
out:
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -126,8 +130,10 @@ errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file, in
|
||||||
{
|
{
|
||||||
errcode_t retval = 0;
|
errcode_t retval = 0;
|
||||||
ext2_loff_t size;
|
ext2_loff_t size;
|
||||||
|
struct patchbd_super s;
|
||||||
data->block_size = 0;
|
data->block_size = 0;
|
||||||
data->size = 0;
|
data->size = 0;
|
||||||
|
data->offset = 0;
|
||||||
data->bmap = NULL;
|
data->bmap = NULL;
|
||||||
data->patch_file = strdup(patch_file);
|
data->patch_file = strdup(patch_file);
|
||||||
data->patch_fd = open(data->patch_file, flags|O_RDWR, 0666);
|
data->patch_fd = open(data->patch_file, flags|O_RDWR, 0666);
|
||||||
|
@ -138,9 +144,14 @@ errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file, in
|
||||||
return errno;
|
return errno;
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
size = ext2fs_llseek(data->patch_fd, size-sizeof(__u32)-sizeof(blk64_t), SEEK_SET);
|
size = ext2fs_llseek(data->patch_fd, 0, SEEK_SET);
|
||||||
read(data->patch_fd, &data->block_size, sizeof(__u32));
|
read(data->patch_fd, &s, sizeof(struct patchbd_super));
|
||||||
read(data->patch_fd, &data->size, sizeof(blk64_t));
|
if (s.magic != PATCHBD_MAGIC)
|
||||||
|
return 0;
|
||||||
|
data->block_size = s.patch_block;
|
||||||
|
// if (data->block_size != 4096)
|
||||||
|
// return EINVAL;
|
||||||
|
data->size = s.patch_size;
|
||||||
retval = ext2fs_patch_init_bmap(data, NULL);
|
retval = ext2fs_patch_init_bmap(data, NULL);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -181,7 +192,10 @@ errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel chan
|
||||||
{
|
{
|
||||||
if (channel)
|
if (channel)
|
||||||
{
|
{
|
||||||
|
// channel is optional parameter, if passed, means 'take size from channel'
|
||||||
data->block_size = channel->block_size;
|
data->block_size = channel->block_size;
|
||||||
|
// if (data->block_size != 4096)
|
||||||
|
// return EINVAL;
|
||||||
retval = ext2fs_get_device_size2(channel->name, data->block_size, &data->size);
|
retval = ext2fs_get_device_size2(channel->name, data->block_size, &data->size);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -190,6 +204,7 @@ errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel chan
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
||||||
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
||||||
|
data->offset = data->block_size + ((((data->size+7)>>3)+(data->block_size-1))&~(data->block_size-1));
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -209,5 +224,5 @@ errcode_t ext2fs_patch_write_blk64(struct ext2fs_patch_file *data, unsigned long
|
||||||
else
|
else
|
||||||
size = count*data->block_size;
|
size = count*data->block_size;
|
||||||
ext2fs_mark_block_bitmap_range2(data->bmap, block, count);
|
ext2fs_mark_block_bitmap_range2(data->bmap, block, count);
|
||||||
return retry_write_at(data->patch_fd, block*data->block_size, size, buf);
|
return retry_write_at(data->patch_fd, data->offset + block*data->block_size, size, buf);
|
||||||
}
|
}
|
||||||
|
|
10
patch.h
10
patch.h
|
@ -31,15 +31,25 @@
|
||||||
#include <ext2fs/ext2_fs.h>
|
#include <ext2fs/ext2_fs.h>
|
||||||
#include <ext2fs/ext2fs.h>
|
#include <ext2fs/ext2fs.h>
|
||||||
|
|
||||||
|
#define PATCHBD_MAGIC 0x44623950 // P9bD
|
||||||
|
|
||||||
struct ext2fs_patch_file
|
struct ext2fs_patch_file
|
||||||
{
|
{
|
||||||
char *patch_file;
|
char *patch_file;
|
||||||
int patch_fd;
|
int patch_fd;
|
||||||
__u32 block_size;
|
__u32 block_size;
|
||||||
blk64_t size;
|
blk64_t size;
|
||||||
|
ext2_loff_t offset;
|
||||||
ext2fs_generic_bitmap bmap;
|
ext2fs_generic_bitmap bmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct patchbd_super
|
||||||
|
{
|
||||||
|
__u32 magic;
|
||||||
|
__u32 patch_block;
|
||||||
|
__u64 patch_size;
|
||||||
|
};
|
||||||
|
|
||||||
errcode_t retry_read(int fd, ssize_t size, void *buf);
|
errcode_t retry_read(int fd, ssize_t size, void *buf);
|
||||||
errcode_t retry_write(int fd, ssize_t size, const void *buf);
|
errcode_t retry_write(int fd, ssize_t size, const void *buf);
|
||||||
errcode_t retry_read_at(int fd, unsigned long long offset, ssize_t size, void *buf);
|
errcode_t retry_read_at(int fd, unsigned long long offset, ssize_t size, void *buf);
|
||||||
|
|
|
@ -222,7 +222,7 @@ static errcode_t patch_read_blk64(io_channel channel, unsigned long long block,
|
||||||
if (-count <= channel->block_size)
|
if (-count <= channel->block_size)
|
||||||
{
|
{
|
||||||
if (data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block))
|
if (data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block))
|
||||||
retval = retry_read_at(data->patch.patch_fd, block*channel->block_size, -count, buf);
|
retval = retry_read_at(data->patch.patch_fd, data->patch.offset + block*channel->block_size, -count, buf);
|
||||||
else
|
else
|
||||||
retval = io_channel_read_blk64(data->real, block, count, buf);
|
retval = io_channel_read_blk64(data->real, block, count, buf);
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -235,7 +235,7 @@ static errcode_t patch_read_blk64(io_channel channel, unsigned long long block,
|
||||||
for (n = 0; (b+n < count) && data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block+b+n); n++) {}
|
for (n = 0; (b+n < count) && data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block+b+n); n++) {}
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
retval = retry_read_at(data->patch.patch_fd, (block+b)*channel->block_size, n*channel->block_size, buf+b*channel->block_size);
|
retval = retry_read_at(data->patch.patch_fd, data->patch.offset + (block+b)*channel->block_size, n*channel->block_size, buf+b*channel->block_size);
|
||||||
if (retval)
|
if (retval)
|
||||||
break;
|
break;
|
||||||
b += n;
|
b += n;
|
||||||
|
|
Loading…
Reference in New Issue