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
|
||||
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
|
||||
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:
|
||||
sudo sh test-mkimages.sh
|
||||
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;
|
||||
int eq;
|
||||
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);
|
||||
if (retval) goto out;
|
||||
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;
|
||||
int eq;
|
||||
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);
|
||||
if (retval) goto out;
|
||||
if (io_options &&
|
||||
|
@ -111,7 +111,7 @@ errcode_t apply_patch(char *device, char *io_options, char *patch_file)
|
|||
{
|
||||
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;
|
||||
retval = io_channel_write_blk64(io, start, blk-start, buf);
|
||||
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)
|
||||
{
|
||||
r = read(fd, buf+done, size-done);
|
||||
if (r < 0 && errno != EAGAIN)
|
||||
if (!r || (r < 0 && errno != EAGAIN))
|
||||
break;
|
||||
done += r;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ errcode_t retry_write(int fd, ssize_t size, const void *buf)
|
|||
while (done < size)
|
||||
{
|
||||
r = write(fd, buf+done, size-done);
|
||||
if (r < 0 && errno != EAGAIN)
|
||||
if (r <= 0 && errno != EAGAIN)
|
||||
break;
|
||||
done += r;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ errcode_t ext2fs_patch_read_bmap(struct ext2fs_patch_file *data)
|
|||
void *buf = malloc(bufsize);
|
||||
if (!buf)
|
||||
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; )
|
||||
{
|
||||
r = bufsize;
|
||||
|
@ -100,10 +100,11 @@ errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data)
|
|||
errcode_t retval = 0;
|
||||
int bufsize = 65536;
|
||||
blk64_t i, r;
|
||||
struct patchbd_super s;
|
||||
void *buf = malloc(bufsize);
|
||||
if (!buf)
|
||||
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; )
|
||||
{
|
||||
r = bufsize;
|
||||
|
@ -115,8 +116,11 @@ errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data)
|
|||
goto out;
|
||||
i += r;
|
||||
}
|
||||
write(data->patch_fd, &data->block_size, sizeof(__u32));
|
||||
write(data->patch_fd, &data->size, sizeof(blk64_t));
|
||||
ext2fs_llseek(data->patch_fd, 0, SEEK_SET);
|
||||
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:
|
||||
free(buf);
|
||||
return 0;
|
||||
|
@ -126,8 +130,10 @@ errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file, in
|
|||
{
|
||||
errcode_t retval = 0;
|
||||
ext2_loff_t size;
|
||||
struct patchbd_super s;
|
||||
data->block_size = 0;
|
||||
data->size = 0;
|
||||
data->offset = 0;
|
||||
data->bmap = NULL;
|
||||
data->patch_file = strdup(patch_file);
|
||||
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;
|
||||
if (size > 0)
|
||||
{
|
||||
size = ext2fs_llseek(data->patch_fd, size-sizeof(__u32)-sizeof(blk64_t), SEEK_SET);
|
||||
read(data->patch_fd, &data->block_size, sizeof(__u32));
|
||||
read(data->patch_fd, &data->size, sizeof(blk64_t));
|
||||
size = ext2fs_llseek(data->patch_fd, 0, SEEK_SET);
|
||||
read(data->patch_fd, &s, sizeof(struct patchbd_super));
|
||||
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);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -181,7 +192,10 @@ errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel chan
|
|||
{
|
||||
if (channel)
|
||||
{
|
||||
// channel is optional parameter, if passed, means 'take size from channel'
|
||||
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);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -190,6 +204,7 @@ errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel chan
|
|||
return EINVAL;
|
||||
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
||||
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;
|
||||
}
|
||||
|
@ -209,5 +224,5 @@ errcode_t ext2fs_patch_write_blk64(struct ext2fs_patch_file *data, unsigned long
|
|||
else
|
||||
size = count*data->block_size;
|
||||
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/ext2fs.h>
|
||||
|
||||
#define PATCHBD_MAGIC 0x44623950 // P9bD
|
||||
|
||||
struct ext2fs_patch_file
|
||||
{
|
||||
char *patch_file;
|
||||
int patch_fd;
|
||||
__u32 block_size;
|
||||
blk64_t size;
|
||||
ext2_loff_t offset;
|
||||
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_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);
|
||||
|
|
|
@ -222,7 +222,7 @@ static errcode_t patch_read_blk64(io_channel channel, unsigned long long block,
|
|||
if (-count <= channel->block_size)
|
||||
{
|
||||
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
|
||||
retval = io_channel_read_blk64(data->real, block, count, buf);
|
||||
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++) {}
|
||||
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)
|
||||
break;
|
||||
b += n;
|
||||
|
|
Loading…
Reference in New Issue