Move common patch file functions to separate source
parent
a7bf43764f
commit
f94c155aab
8
Makefile
8
Makefile
|
@ -1,5 +1,5 @@
|
||||||
all: realloc-inodes e2patch
|
all: realloc-inodes e2patch
|
||||||
realloc-inodes: realloc-inodes.c bmove.c ext2fsP.h Makefile patch_io.c patch_io.h
|
realloc-inodes: realloc-inodes.c bmove.c ext2fsP.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
|
gcc -g -Wsign-compare -Wall -o realloc-inodes -lcom_err -lext2fs realloc-inodes.c bmove.c patch_io.c patch.c
|
||||||
e2patch: e2patch.c
|
e2patch: e2patch.c patch.c patch.h
|
||||||
gcc -g -Wsign-compare -Wall -o e2patch -lcom_err -lext2fs e2patch.c
|
gcc -g -Wsign-compare -Wall -o e2patch -lcom_err -lext2fs e2patch.c patch.c
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
#define _LARGEFILE_SOURCE
|
||||||
|
#define _LARGEFILE64_SOURCE
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "patch.h"
|
||||||
|
|
||||||
|
errcode_t retry_read(int fd, ssize_t size, void *buf)
|
||||||
|
{
|
||||||
|
ssize_t r, done = 0;
|
||||||
|
while (done < size)
|
||||||
|
{
|
||||||
|
r = read(fd, buf+done, size-done);
|
||||||
|
if (r < 0 && errno != EAGAIN)
|
||||||
|
break;
|
||||||
|
done += r;
|
||||||
|
}
|
||||||
|
if (done < size)
|
||||||
|
return errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t retry_write(int fd, ssize_t size, void *buf)
|
||||||
|
{
|
||||||
|
ssize_t r, done = 0;
|
||||||
|
while (done < size)
|
||||||
|
{
|
||||||
|
r = write(fd, buf+done, size-done);
|
||||||
|
if (r < 0 && errno != EAGAIN)
|
||||||
|
break;
|
||||||
|
done += r;
|
||||||
|
}
|
||||||
|
if (done < size)
|
||||||
|
return errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t retry_read_at(int fd, unsigned long long offset, ssize_t size, void *buf)
|
||||||
|
{
|
||||||
|
if ((unsigned)ext2fs_llseek(fd, offset, SEEK_SET) != offset)
|
||||||
|
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
||||||
|
return retry_read(fd, size, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t retry_write_at(int fd, unsigned long long offset, ssize_t size, void *buf)
|
||||||
|
{
|
||||||
|
if ((unsigned)ext2fs_llseek(fd, offset, SEEK_SET) != offset)
|
||||||
|
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
||||||
|
return retry_write(fd, size, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t ext2fs_patch_read_bmap(struct ext2fs_patch_file *data)
|
||||||
|
{
|
||||||
|
errcode_t retval = 0;
|
||||||
|
int bufsize = 65536;
|
||||||
|
blk64_t i, r;
|
||||||
|
void *buf = malloc(bufsize);
|
||||||
|
if (!buf)
|
||||||
|
return ENOMEM;
|
||||||
|
ext2fs_llseek(data->patch_fd, data->size*data->block_size, SEEK_SET);
|
||||||
|
for (i = 0; i < data->size/8; )
|
||||||
|
{
|
||||||
|
r = bufsize;
|
||||||
|
if (data->size/8 - i < r)
|
||||||
|
r = data->size/8 - i;
|
||||||
|
retval = retry_read(data->patch_fd, r, buf);
|
||||||
|
if (retval)
|
||||||
|
goto out;
|
||||||
|
ext2fs_set_generic_bmap_range(data->bmap, i*8, r*8, buf);
|
||||||
|
i += r;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(buf);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data)
|
||||||
|
{
|
||||||
|
errcode_t retval = 0;
|
||||||
|
int bufsize = 65536;
|
||||||
|
blk64_t i, r;
|
||||||
|
void *buf = malloc(bufsize);
|
||||||
|
if (!buf)
|
||||||
|
return ENOMEM;
|
||||||
|
ext2fs_llseek(data->patch_fd, data->size*data->block_size, SEEK_SET);
|
||||||
|
for (i = 0; i < data->size/8; )
|
||||||
|
{
|
||||||
|
r = bufsize;
|
||||||
|
if (data->size/8 - i < r)
|
||||||
|
r = data->size/8 - i;
|
||||||
|
ext2fs_get_generic_bmap_range(data->bmap, i*8, r*8, buf);
|
||||||
|
retval = retry_write(data->patch_fd, r, buf);
|
||||||
|
if (retval)
|
||||||
|
goto out;
|
||||||
|
i += r;
|
||||||
|
}
|
||||||
|
write(data->patch_fd, &data->block_size, sizeof(__u32));
|
||||||
|
write(data->patch_fd, &data->size, sizeof(blk64_t));
|
||||||
|
out:
|
||||||
|
free(buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file)
|
||||||
|
{
|
||||||
|
errcode_t retval = 0;
|
||||||
|
ext2_loff_t size;
|
||||||
|
data->block_size = 0;
|
||||||
|
data->size = 0;
|
||||||
|
data->bmap = NULL;
|
||||||
|
data->patch_file = strdup(patch_file);
|
||||||
|
data->patch_fd = open(data->patch_file, O_CREAT|O_RDWR, 0666);
|
||||||
|
if (data->patch_fd < 0)
|
||||||
|
return errno;
|
||||||
|
size = ext2fs_llseek(data->patch_fd, 0, SEEK_END);
|
||||||
|
if (size < 0)
|
||||||
|
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));
|
||||||
|
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
||||||
|
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
retval = ext2fs_patch_read_bmap(data);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t ext2fs_patch_close(struct ext2fs_patch_file *data)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
if (data->bmap)
|
||||||
|
{
|
||||||
|
if (data->patch_fd >= 0)
|
||||||
|
ext2fs_patch_write_bmap(data);
|
||||||
|
ext2fs_free_generic_bmap(data->bmap);
|
||||||
|
data->bmap = NULL;
|
||||||
|
}
|
||||||
|
if (data->patch_fd >= 0)
|
||||||
|
{
|
||||||
|
close(data->patch_fd);
|
||||||
|
data->patch_fd = -1;
|
||||||
|
}
|
||||||
|
if (data->patch_file)
|
||||||
|
{
|
||||||
|
free(data->patch_file);
|
||||||
|
data->patch_file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel channel)
|
||||||
|
{
|
||||||
|
errcode_t retval = 0;
|
||||||
|
if (!data->bmap)
|
||||||
|
{
|
||||||
|
if (channel)
|
||||||
|
{
|
||||||
|
data->block_size = channel->block_size;
|
||||||
|
retval = ext2fs_get_device_size2(channel->name, data->block_size, &data->size);
|
||||||
|
if (retval)
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
else if (!data->block_size || !data->size)
|
||||||
|
return EINVAL;
|
||||||
|
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
||||||
|
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef E2_PATCH_H
|
||||||
|
#define E2_PATCH_H
|
||||||
|
|
||||||
|
#include <ext2fs/ext2_fs.h>
|
||||||
|
#include <ext2fs/ext2fs.h>
|
||||||
|
|
||||||
|
struct ext2fs_patch_file
|
||||||
|
{
|
||||||
|
char *patch_file;
|
||||||
|
int patch_fd;
|
||||||
|
__u32 block_size;
|
||||||
|
blk64_t size;
|
||||||
|
ext2fs_generic_bitmap bmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
errcode_t retry_read(int fd, ssize_t size, void *buf);
|
||||||
|
errcode_t retry_write(int fd, ssize_t size, void *buf);
|
||||||
|
errcode_t retry_read_at(int fd, unsigned long long offset, ssize_t size, void *buf);
|
||||||
|
errcode_t retry_write_at(int fd, unsigned long long offset, ssize_t size, void *buf);
|
||||||
|
errcode_t ext2fs_patch_read_bmap(struct ext2fs_patch_file *data);
|
||||||
|
errcode_t ext2fs_patch_write_bmap(struct ext2fs_patch_file *data);
|
||||||
|
errcode_t ext2fs_patch_open(struct ext2fs_patch_file *data, char *patch_file);
|
||||||
|
errcode_t ext2fs_patch_close(struct ext2fs_patch_file *data);
|
||||||
|
errcode_t ext2fs_patch_init_bmap(struct ext2fs_patch_file *data, io_channel channel);
|
||||||
|
|
||||||
|
#endif
|
165
patch_io.c
165
patch_io.c
|
@ -28,6 +28,8 @@
|
||||||
#include <ext2fs/ext2_fs.h>
|
#include <ext2fs/ext2_fs.h>
|
||||||
#include <ext2fs/ext2fs.h>
|
#include <ext2fs/ext2fs.h>
|
||||||
|
|
||||||
|
#include "patch.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define ATTR(x) __attribute__(x)
|
#define ATTR(x) __attribute__(x)
|
||||||
#else
|
#else
|
||||||
|
@ -36,13 +38,10 @@
|
||||||
|
|
||||||
#define EXT2_CHECK_MAGIC(struct, code) if ((struct)->magic != (code)) return (code)
|
#define EXT2_CHECK_MAGIC(struct, code) if ((struct)->magic != (code)) return (code)
|
||||||
|
|
||||||
struct patch_private_data {
|
struct patch_private_data
|
||||||
int magic;
|
{
|
||||||
char *patch_file;
|
int magic;
|
||||||
int patch_fd;
|
struct ext2fs_patch_file patch;
|
||||||
int block_size;
|
|
||||||
blk64_t size;
|
|
||||||
ext2fs_generic_bitmap bmap;
|
|
||||||
/* The backing io channel */
|
/* The backing io channel */
|
||||||
io_channel real;
|
io_channel real;
|
||||||
/* to support offset in unix I/O manager */
|
/* to support offset in unix I/O manager */
|
||||||
|
@ -93,56 +92,6 @@ errcode_t set_patch_io_patch_file(char *file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_read_bmap(struct patch_private_data *data, int fd)
|
|
||||||
{
|
|
||||||
int bufsize = 65536;
|
|
||||||
blk64_t i, r;
|
|
||||||
void *buf = malloc(bufsize);
|
|
||||||
ext2fs_llseek(fd, data->size*data->block_size, SEEK_SET);
|
|
||||||
for (i = 0; i < data->size/8; )
|
|
||||||
{
|
|
||||||
r = bufsize;
|
|
||||||
if (data->size/8 - i < r)
|
|
||||||
r = data->size/8 - i;
|
|
||||||
r = read(fd, buf, r);
|
|
||||||
if (r < 0)
|
|
||||||
{
|
|
||||||
r = 0;
|
|
||||||
if (errno != EAGAIN)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ext2fs_set_generic_bmap_range(data->bmap, i*8, r*8, buf);
|
|
||||||
i += r;
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void patch_write_bmap(struct patch_private_data *data, int fd)
|
|
||||||
{
|
|
||||||
int bufsize = 65536;
|
|
||||||
blk64_t i, r;
|
|
||||||
void *buf = malloc(bufsize);
|
|
||||||
ext2fs_llseek(fd, data->size*data->block_size, SEEK_SET);
|
|
||||||
for (i = 0; i < data->size/8; )
|
|
||||||
{
|
|
||||||
r = bufsize;
|
|
||||||
if (data->size/8 - i < r)
|
|
||||||
r = data->size/8 - i;
|
|
||||||
ext2fs_get_generic_bmap_range(data->bmap, i*8, r*8, buf);
|
|
||||||
r = write(fd, buf, r);
|
|
||||||
if (r < 0)
|
|
||||||
{
|
|
||||||
r = 0;
|
|
||||||
if (errno != EAGAIN)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i += r;
|
|
||||||
}
|
|
||||||
free(buf);
|
|
||||||
write(fd, &data->block_size, sizeof(int));
|
|
||||||
write(fd, &data->size, sizeof(blk64_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_open(const char *name, int flags, io_channel *channel)
|
static errcode_t patch_open(const char *name, int flags, io_channel *channel)
|
||||||
{
|
{
|
||||||
io_channel io = NULL;
|
io_channel io = NULL;
|
||||||
|
@ -184,31 +133,9 @@ static errcode_t patch_open(const char *name, int flags, io_channel *channel)
|
||||||
|
|
||||||
if (patch_file)
|
if (patch_file)
|
||||||
{
|
{
|
||||||
long long size;
|
retval = ext2fs_patch_open(&data->patch, patch_file);
|
||||||
data->patch_file = strdup(patch_file);
|
if (retval)
|
||||||
data->patch_fd = open(data->patch_file, O_CREAT|O_RDWR, 0666);
|
|
||||||
if (data->patch_fd < 0)
|
|
||||||
{
|
|
||||||
retval = errno;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
|
||||||
size = ext2fs_llseek(data->patch_fd, 0, SEEK_END);
|
|
||||||
if (size < 0)
|
|
||||||
{
|
|
||||||
retval = errno;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (size > sizeof(int)+sizeof(blk64_t))
|
|
||||||
{
|
|
||||||
ext2fs_llseek(data->patch_fd, size-sizeof(int)-sizeof(blk64_t), 0);
|
|
||||||
read(data->patch_fd, &data->block_size, sizeof(int));
|
|
||||||
read(data->patch_fd, &data->size, sizeof(blk64_t));
|
|
||||||
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
|
||||||
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
|
||||||
if (retval)
|
|
||||||
goto cleanup;
|
|
||||||
patch_read_bmap(data, data->patch_fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*channel = io;
|
*channel = io;
|
||||||
|
@ -217,12 +144,7 @@ static errcode_t patch_open(const char *name, int flags, io_channel *channel)
|
||||||
cleanup:
|
cleanup:
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
if (data->bmap)
|
ext2fs_patch_close(&data->patch);
|
||||||
ext2fs_free_generic_bmap(data->bmap);
|
|
||||||
if (data->patch_fd >= 0)
|
|
||||||
close(data->patch_fd);
|
|
||||||
if (data->patch_file)
|
|
||||||
free(data->patch_file);
|
|
||||||
if (data->real)
|
if (data->real)
|
||||||
io_channel_close(data->real);
|
io_channel_close(data->real);
|
||||||
ext2fs_free_mem(&data);
|
ext2fs_free_mem(&data);
|
||||||
|
@ -248,16 +170,7 @@ static errcode_t patch_close(io_channel channel)
|
||||||
if (--channel->refcount > 0)
|
if (--channel->refcount > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (data->bmap)
|
ext2fs_patch_close(&data->patch);
|
||||||
{
|
|
||||||
if (data->patch_fd >= 0)
|
|
||||||
patch_write_bmap(data, data->patch_fd);
|
|
||||||
ext2fs_free_generic_bmap(data->bmap);
|
|
||||||
}
|
|
||||||
if (data->patch_fd >= 0)
|
|
||||||
close(data->patch_fd);
|
|
||||||
if (data->patch_file)
|
|
||||||
free(data->patch_file);
|
|
||||||
if (data->real)
|
if (data->real)
|
||||||
retval = io_channel_close(data->real);
|
retval = io_channel_close(data->real);
|
||||||
ext2fs_free_mem(&channel->private_data);
|
ext2fs_free_mem(&channel->private_data);
|
||||||
|
@ -277,31 +190,14 @@ static errcode_t patch_set_blksize(io_channel channel, int blksize)
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
data = (struct patch_private_data *) channel->private_data;
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
||||||
|
|
||||||
if (data->block_size && data->block_size != blksize)
|
if (data->patch.block_size && data->patch.block_size != (unsigned)blksize)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
if (data->real)
|
if (data->real)
|
||||||
retval = io_channel_set_blksize(data->real, blksize);
|
retval = io_channel_set_blksize(data->real, blksize);
|
||||||
channel->block_size = blksize;
|
channel->block_size = (unsigned)blksize;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static errcode_t re_read(int fd, unsigned long long offset, ssize_t size, void *buf)
|
|
||||||
{
|
|
||||||
ssize_t r, done = 0;
|
|
||||||
if ((unsigned)ext2fs_llseek(fd, offset, SEEK_SET) != offset)
|
|
||||||
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
|
||||||
while (done < size)
|
|
||||||
{
|
|
||||||
r = read(fd, buf+done, size-done);
|
|
||||||
if (r < 0 && errno != EAGAIN)
|
|
||||||
break;
|
|
||||||
done += r;
|
|
||||||
}
|
|
||||||
if (done < size)
|
|
||||||
return errno;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_read_blk64(io_channel channel, unsigned long long block, int count, void *buf)
|
static errcode_t patch_read_blk64(io_channel channel, unsigned long long block, int count, void *buf)
|
||||||
{
|
{
|
||||||
errcode_t retval = 0;
|
errcode_t retval = 0;
|
||||||
|
@ -316,8 +212,8 @@ 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->bmap && ext2fs_test_generic_bitmap(data->bmap, block))
|
if (data->patch.bmap && ext2fs_test_generic_bitmap(data->patch.bmap, block))
|
||||||
retval = re_read(data->patch_fd, block*channel->block_size, -count, buf);
|
retval = retry_read_at(data->patch.patch_fd, 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;
|
||||||
|
@ -327,15 +223,15 @@ static errcode_t patch_read_blk64(io_channel channel, unsigned long long block,
|
||||||
}
|
}
|
||||||
for (b = 0; b < count; )
|
for (b = 0; b < count; )
|
||||||
{
|
{
|
||||||
for (n = 0; (b+n < count) && data->bmap && ext2fs_test_generic_bitmap(data->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 = re_read(data->patch_fd, (block+b)*channel->block_size, n*channel->block_size, buf+b*channel->block_size);
|
retval = retry_read_at(data->patch.patch_fd, (block+b)*channel->block_size, n*channel->block_size, buf+b*channel->block_size);
|
||||||
if (retval)
|
if (retval)
|
||||||
break;
|
break;
|
||||||
b += n;
|
b += n;
|
||||||
}
|
}
|
||||||
for (n = 0; (b+n < count) && (!data->bmap || !ext2fs_test_generic_bitmap(data->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 && data->real)
|
if (n > 0 && data->real)
|
||||||
{
|
{
|
||||||
retval = io_channel_read_blk64(data->real, block+b, n, buf+(block+b)*channel->block_size);
|
retval = io_channel_read_blk64(data->real, block+b, n, buf+(block+b)*channel->block_size);
|
||||||
|
@ -353,21 +249,6 @@ static errcode_t patch_read_blk(io_channel channel, unsigned long block, int cou
|
||||||
return patch_read_blk64(channel, block, count, buf);
|
return patch_read_blk64(channel, block, count, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static errcode_t patch_check_bmap_init(struct patch_private_data *data, io_channel channel)
|
|
||||||
{
|
|
||||||
errcode_t retval = 0;
|
|
||||||
if (!data->bmap)
|
|
||||||
{
|
|
||||||
data->block_size = channel->block_size;
|
|
||||||
retval = ext2fs_get_device_size2(channel->name, data->block_size, &data->size);
|
|
||||||
if (retval)
|
|
||||||
return retval;
|
|
||||||
retval = ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_BLOCK_BITMAP, NULL,
|
|
||||||
0, data->size, data->size, "overwritten blocks", 0, &data->bmap);
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
static errcode_t patch_write_blk64(io_channel channel, unsigned long long block, int count, const void *buf)
|
static errcode_t patch_write_blk64(io_channel channel, unsigned long long block, int count, const void *buf)
|
||||||
{
|
{
|
||||||
struct patch_private_data *data;
|
struct patch_private_data *data;
|
||||||
|
@ -378,9 +259,9 @@ static errcode_t patch_write_blk64(io_channel channel, unsigned long long block,
|
||||||
data = (struct patch_private_data *) channel->private_data;
|
data = (struct patch_private_data *) channel->private_data;
|
||||||
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
|
||||||
|
|
||||||
if ((unsigned)ext2fs_llseek(data->patch_fd, block*channel->block_size, SEEK_SET) != block*channel->block_size)
|
if ((unsigned)ext2fs_llseek(data->patch.patch_fd, block*channel->block_size, SEEK_SET) != block*channel->block_size)
|
||||||
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
return errno ? errno : EXT2_ET_LLSEEK_FAILED;
|
||||||
retval = patch_check_bmap_init(data, channel);
|
retval = ext2fs_patch_init_bmap(&data->patch, channel);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
|
@ -390,11 +271,11 @@ static errcode_t patch_write_blk64(io_channel channel, unsigned long long block,
|
||||||
left = -count;
|
left = -count;
|
||||||
count = 1;
|
count = 1;
|
||||||
}
|
}
|
||||||
ext2fs_mark_block_bitmap_range2(data->bmap, block, count);
|
ext2fs_mark_block_bitmap_range2(data->patch.bmap, block, count);
|
||||||
buf += left;
|
buf += left;
|
||||||
while (left > 0)
|
while (left > 0)
|
||||||
{
|
{
|
||||||
r = write(data->patch_fd, buf-left, left);
|
r = write(data->patch.patch_fd, buf-left, left);
|
||||||
if (r < 0 && errno != EAGAIN)
|
if (r < 0 && errno != EAGAIN)
|
||||||
break;
|
break;
|
||||||
left -= r;
|
left -= r;
|
||||||
|
@ -426,8 +307,8 @@ static errcode_t patch_flush(io_channel channel)
|
||||||
|
|
||||||
if (data->real)
|
if (data->real)
|
||||||
retval = io_channel_flush(data->real);
|
retval = io_channel_flush(data->real);
|
||||||
if (data->patch_fd)
|
if (data->patch.patch_fd)
|
||||||
fsync(data->patch_fd);
|
fsync(data->patch.patch_fd);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue