Merge "libsparse: output_file.c, fix large data chunk issue" am: 62c9101646
am: faaeda8e12
Change-Id: I167d7d8083e8e15f89f21b5838fc5b4e97121b10
This commit is contained in:
commit
4179f2ec65
1 changed files with 30 additions and 21 deletions
|
|
@ -63,7 +63,7 @@ struct output_file_ops {
|
||||||
int (*open)(struct output_file *, int fd);
|
int (*open)(struct output_file *, int fd);
|
||||||
int (*skip)(struct output_file *, int64_t);
|
int (*skip)(struct output_file *, int64_t);
|
||||||
int (*pad)(struct output_file *, int64_t);
|
int (*pad)(struct output_file *, int64_t);
|
||||||
int (*write)(struct output_file *, void *, int);
|
int (*write)(struct output_file *, void *, size_t);
|
||||||
void (*close)(struct output_file *);
|
void (*close)(struct output_file *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -149,18 +149,23 @@ static int file_pad(struct output_file *out, int64_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int file_write(struct output_file *out, void *data, int len)
|
static int file_write(struct output_file *out, void *data, size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
ssize_t ret;
|
||||||
struct output_file_normal *outn = to_output_file_normal(out);
|
struct output_file_normal *outn = to_output_file_normal(out);
|
||||||
|
|
||||||
ret = write(outn->fd, data, len);
|
while (len > 0) {
|
||||||
if (ret < 0) {
|
ret = write(outn->fd, data, len);
|
||||||
error_errno("write");
|
if (ret < 0) {
|
||||||
return -1;
|
if (errno == EINTR) {
|
||||||
} else if (ret < len) {
|
continue;
|
||||||
error("incomplete write");
|
}
|
||||||
return -1;
|
error_errno("write");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (char *)data + ret;
|
||||||
|
len -= ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -232,18 +237,20 @@ static int gz_file_pad(struct output_file *out, int64_t len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gz_file_write(struct output_file *out, void *data, int len)
|
static int gz_file_write(struct output_file *out, void *data, size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct output_file_gz *outgz = to_output_file_gz(out);
|
struct output_file_gz *outgz = to_output_file_gz(out);
|
||||||
|
|
||||||
ret = gzwrite(outgz->gz_fd, data, len);
|
while (len > 0) {
|
||||||
if (ret < 0) {
|
ret = gzwrite(outgz->gz_fd, data,
|
||||||
error_errno("gzwrite");
|
min(len, (unsigned int)INT_MAX));
|
||||||
return -1;
|
if (ret == 0) {
|
||||||
} else if (ret < len) {
|
error("gzwrite %s", gzerror(outgz->gz_fd, NULL));
|
||||||
error("incomplete gzwrite");
|
return -1;
|
||||||
return -1;
|
}
|
||||||
|
len -= ret;
|
||||||
|
data = (char *)data + ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -293,7 +300,7 @@ static int callback_file_pad(struct output_file *out __unused, int64_t len __unu
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int callback_file_write(struct output_file *out, void *data, int len)
|
static int callback_file_write(struct output_file *out, void *data, size_t len)
|
||||||
{
|
{
|
||||||
struct output_file_callback *outc = to_output_file_callback(out);
|
struct output_file_callback *outc = to_output_file_callback(out);
|
||||||
|
|
||||||
|
|
@ -698,14 +705,16 @@ int write_fd_chunk(struct output_file *out, unsigned int len,
|
||||||
int ret;
|
int ret;
|
||||||
int64_t aligned_offset;
|
int64_t aligned_offset;
|
||||||
int aligned_diff;
|
int aligned_diff;
|
||||||
int buffer_size;
|
uint64_t buffer_size;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
aligned_offset = offset & ~(4096 - 1);
|
aligned_offset = offset & ~(4096 - 1);
|
||||||
aligned_diff = offset - aligned_offset;
|
aligned_diff = offset - aligned_offset;
|
||||||
buffer_size = len + aligned_diff;
|
buffer_size = (uint64_t)len + (uint64_t)aligned_diff;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
if (buffer_size > SIZE_MAX)
|
||||||
|
return -E2BIG;
|
||||||
char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd,
|
char *data = mmap64(NULL, buffer_size, PROT_READ, MAP_SHARED, fd,
|
||||||
aligned_offset);
|
aligned_offset);
|
||||||
if (data == MAP_FAILED) {
|
if (data == MAP_FAILED) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue