mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-01 06:43:53 -06:00
Merge remote-tracking branch 'kwolf/for-anthony' into staging
This commit is contained in:
commit
2a22e6eb1b
12 changed files with 285 additions and 635 deletions
|
@ -296,273 +296,6 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
|
|||
#endif
|
||||
*/
|
||||
|
||||
/*
|
||||
* offset and count are in bytes, but must be multiples of 512 for files
|
||||
* opened with O_DIRECT. buf must be aligned to 512 bytes then.
|
||||
*
|
||||
* This function may be called without alignment if the caller ensures
|
||||
* that O_DIRECT is not in effect.
|
||||
*/
|
||||
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
|
||||
uint8_t *buf, int count)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret;
|
||||
|
||||
ret = fd_open(bs);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = pread(s->fd, buf, count, offset);
|
||||
if (ret == count)
|
||||
return ret;
|
||||
|
||||
/* Allow reads beyond the end (needed for pwrite) */
|
||||
if ((ret == 0) && bs->growable) {
|
||||
int64_t size = raw_getlength(bs);
|
||||
if (offset >= size) {
|
||||
memset(buf, 0, count);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
|
||||
"] read failed %d : %d = %s\n",
|
||||
s->fd, bs->filename, offset, buf, count,
|
||||
bs->total_sectors, ret, errno, strerror(errno));
|
||||
|
||||
/* Try harder for CDrom. */
|
||||
if (s->type != FTYPE_FILE) {
|
||||
ret = pread(s->fd, buf, count, offset);
|
||||
if (ret == count)
|
||||
return ret;
|
||||
ret = pread(s->fd, buf, count, offset);
|
||||
if (ret == count)
|
||||
return ret;
|
||||
|
||||
DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
|
||||
"] retry read failed %d : %d = %s\n",
|
||||
s->fd, bs->filename, offset, buf, count,
|
||||
bs->total_sectors, ret, errno, strerror(errno));
|
||||
}
|
||||
|
||||
return (ret < 0) ? -errno : ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* offset and count are in bytes, but must be multiples of the sector size
|
||||
* for files opened with O_DIRECT. buf must be aligned to sector size bytes
|
||||
* then.
|
||||
*
|
||||
* This function may be called without alignment if the caller ensures
|
||||
* that O_DIRECT is not in effect.
|
||||
*/
|
||||
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
|
||||
const uint8_t *buf, int count)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
int ret;
|
||||
|
||||
ret = fd_open(bs);
|
||||
if (ret < 0)
|
||||
return -errno;
|
||||
|
||||
ret = pwrite(s->fd, buf, count, offset);
|
||||
if (ret == count)
|
||||
return ret;
|
||||
|
||||
DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
|
||||
"] write failed %d : %d = %s\n",
|
||||
s->fd, bs->filename, offset, buf, count,
|
||||
bs->total_sectors, ret, errno, strerror(errno));
|
||||
|
||||
return (ret < 0) ? -errno : ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* offset and count are in bytes and possibly not aligned. For files opened
|
||||
* with O_DIRECT, necessary alignments are ensured before calling
|
||||
* raw_pread_aligned to do the actual read.
|
||||
*/
|
||||
static int raw_pread(BlockDriverState *bs, int64_t offset,
|
||||
uint8_t *buf, int count)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
unsigned sector_mask = bs->buffer_alignment - 1;
|
||||
int size, ret, shift, sum;
|
||||
|
||||
sum = 0;
|
||||
|
||||
if (s->aligned_buf != NULL) {
|
||||
|
||||
if (offset & sector_mask) {
|
||||
/* align offset on a sector size bytes boundary */
|
||||
|
||||
shift = offset & sector_mask;
|
||||
size = (shift + count + sector_mask) & ~sector_mask;
|
||||
if (size > s->aligned_buf_size)
|
||||
size = s->aligned_buf_size;
|
||||
ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
size = bs->buffer_alignment - shift;
|
||||
if (size > count)
|
||||
size = count;
|
||||
memcpy(buf, s->aligned_buf + shift, size);
|
||||
|
||||
buf += size;
|
||||
offset += size;
|
||||
count -= size;
|
||||
sum += size;
|
||||
|
||||
if (count == 0)
|
||||
return sum;
|
||||
}
|
||||
if (count & sector_mask || (uintptr_t) buf & sector_mask) {
|
||||
|
||||
/* read on aligned buffer */
|
||||
|
||||
while (count) {
|
||||
|
||||
size = (count + sector_mask) & ~sector_mask;
|
||||
if (size > s->aligned_buf_size)
|
||||
size = s->aligned_buf_size;
|
||||
|
||||
ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
} else if (ret == 0) {
|
||||
fprintf(stderr, "raw_pread: read beyond end of file\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
size = ret;
|
||||
if (size > count)
|
||||
size = count;
|
||||
|
||||
memcpy(buf, s->aligned_buf, size);
|
||||
|
||||
buf += size;
|
||||
offset += size;
|
||||
count -= size;
|
||||
sum += size;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
return raw_pread_aligned(bs, offset, buf, count) + sum;
|
||||
}
|
||||
|
||||
static int raw_read(BlockDriverState *bs, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf,
|
||||
nb_sectors * BDRV_SECTOR_SIZE);
|
||||
if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* offset and count are in bytes and possibly not aligned. For files opened
|
||||
* with O_DIRECT, necessary alignments are ensured before calling
|
||||
* raw_pwrite_aligned to do the actual write.
|
||||
*/
|
||||
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
|
||||
const uint8_t *buf, int count)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
unsigned sector_mask = bs->buffer_alignment - 1;
|
||||
int size, ret, shift, sum;
|
||||
|
||||
sum = 0;
|
||||
|
||||
if (s->aligned_buf != NULL) {
|
||||
|
||||
if (offset & sector_mask) {
|
||||
/* align offset on a sector size bytes boundary */
|
||||
shift = offset & sector_mask;
|
||||
ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf,
|
||||
bs->buffer_alignment);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
size = bs->buffer_alignment - shift;
|
||||
if (size > count)
|
||||
size = count;
|
||||
memcpy(s->aligned_buf + shift, buf, size);
|
||||
|
||||
ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf,
|
||||
bs->buffer_alignment);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf += size;
|
||||
offset += size;
|
||||
count -= size;
|
||||
sum += size;
|
||||
|
||||
if (count == 0)
|
||||
return sum;
|
||||
}
|
||||
if (count & sector_mask || (uintptr_t) buf & sector_mask) {
|
||||
|
||||
while ((size = (count & ~sector_mask)) != 0) {
|
||||
|
||||
if (size > s->aligned_buf_size)
|
||||
size = s->aligned_buf_size;
|
||||
|
||||
memcpy(s->aligned_buf, buf, size);
|
||||
|
||||
ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf += ret;
|
||||
offset += ret;
|
||||
count -= ret;
|
||||
sum += ret;
|
||||
}
|
||||
/* here, count < sector_size because (count & ~sector_mask) == 0 */
|
||||
if (count) {
|
||||
ret = raw_pread_aligned(bs, offset, s->aligned_buf,
|
||||
bs->buffer_alignment);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
memcpy(s->aligned_buf, buf, count);
|
||||
|
||||
ret = raw_pwrite_aligned(bs, offset, s->aligned_buf,
|
||||
bs->buffer_alignment);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (count < ret)
|
||||
ret = count;
|
||||
|
||||
sum += ret;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
return raw_pwrite_aligned(bs, offset, buf, count) + sum;
|
||||
}
|
||||
|
||||
static int raw_write(BlockDriverState *bs, int64_t sector_num,
|
||||
const uint8_t *buf, int nb_sectors)
|
||||
{
|
||||
int ret;
|
||||
ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf,
|
||||
nb_sectors * BDRV_SECTOR_SIZE);
|
||||
if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if all memory in this vector is sector aligned.
|
||||
*/
|
||||
|
@ -649,10 +382,24 @@ static void raw_close(BlockDriverState *bs)
|
|||
static int raw_truncate(BlockDriverState *bs, int64_t offset)
|
||||
{
|
||||
BDRVRawState *s = bs->opaque;
|
||||
if (s->type != FTYPE_FILE)
|
||||
return -ENOTSUP;
|
||||
if (ftruncate(s->fd, offset) < 0)
|
||||
struct stat st;
|
||||
|
||||
if (fstat(s->fd, &st)) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (ftruncate(s->fd, offset) < 0) {
|
||||
return -errno;
|
||||
}
|
||||
} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
|
||||
if (offset > raw_getlength(bs)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -896,8 +643,6 @@ static BlockDriver bdrv_file = {
|
|||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_probe = NULL, /* no probe for protocols */
|
||||
.bdrv_file_open = raw_open,
|
||||
.bdrv_read = raw_read,
|
||||
.bdrv_write = raw_write,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_create = raw_create,
|
||||
.bdrv_flush = raw_flush,
|
||||
|
@ -1176,8 +921,7 @@ static BlockDriver bdrv_host_device = {
|
|||
.bdrv_aio_writev = raw_aio_writev,
|
||||
.bdrv_aio_flush = raw_aio_flush,
|
||||
|
||||
.bdrv_read = raw_read,
|
||||
.bdrv_write = raw_write,
|
||||
.bdrv_truncate = raw_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
|
@ -1297,8 +1041,7 @@ static BlockDriver bdrv_host_floppy = {
|
|||
.bdrv_aio_writev = raw_aio_writev,
|
||||
.bdrv_aio_flush = raw_aio_flush,
|
||||
|
||||
.bdrv_read = raw_read,
|
||||
.bdrv_write = raw_write,
|
||||
.bdrv_truncate = raw_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
|
@ -1398,8 +1141,7 @@ static BlockDriver bdrv_host_cdrom = {
|
|||
.bdrv_aio_writev = raw_aio_writev,
|
||||
.bdrv_aio_flush = raw_aio_flush,
|
||||
|
||||
.bdrv_read = raw_read,
|
||||
.bdrv_write = raw_write,
|
||||
.bdrv_truncate = raw_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
|
@ -1519,8 +1261,7 @@ static BlockDriver bdrv_host_cdrom = {
|
|||
.bdrv_aio_writev = raw_aio_writev,
|
||||
.bdrv_aio_flush = raw_aio_flush,
|
||||
|
||||
.bdrv_read = raw_read,
|
||||
.bdrv_write = raw_write,
|
||||
.bdrv_truncate = raw_truncate,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_get_allocated_file_size
|
||||
= raw_get_allocated_file_size,
|
||||
|
|
32
block/raw.c
32
block/raw.c
|
@ -9,30 +9,16 @@ static int raw_open(BlockDriverState *bs, int flags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int raw_read(BlockDriverState *bs, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors)
|
||||
static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
|
||||
int nb_sectors, QEMUIOVector *qiov)
|
||||
{
|
||||
return bdrv_read(bs->file, sector_num, buf, nb_sectors);
|
||||
return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov);
|
||||
}
|
||||
|
||||
static int raw_write(BlockDriverState *bs, int64_t sector_num,
|
||||
const uint8_t *buf, int nb_sectors)
|
||||
static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
|
||||
int nb_sectors, QEMUIOVector *qiov)
|
||||
{
|
||||
return bdrv_write(bs->file, sector_num, buf, nb_sectors);
|
||||
}
|
||||
|
||||
static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
|
||||
}
|
||||
|
||||
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
|
||||
return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
|
||||
}
|
||||
|
||||
static void raw_close(BlockDriverState *bs)
|
||||
|
@ -129,15 +115,13 @@ static BlockDriver bdrv_raw = {
|
|||
|
||||
.bdrv_open = raw_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_read = raw_read,
|
||||
.bdrv_write = raw_write,
|
||||
.bdrv_co_readv = raw_co_readv,
|
||||
.bdrv_co_writev = raw_co_writev,
|
||||
.bdrv_flush = raw_flush,
|
||||
.bdrv_probe = raw_probe,
|
||||
.bdrv_getlength = raw_getlength,
|
||||
.bdrv_truncate = raw_truncate,
|
||||
|
||||
.bdrv_aio_readv = raw_aio_readv,
|
||||
.bdrv_aio_writev = raw_aio_writev,
|
||||
.bdrv_aio_flush = raw_aio_flush,
|
||||
.bdrv_discard = raw_discard,
|
||||
|
||||
|
|
109
block/vvfat.c
109
block/vvfat.c
|
@ -86,8 +86,7 @@ static inline void array_init(array_t* array,unsigned int item_size)
|
|||
|
||||
static inline void array_free(array_t* array)
|
||||
{
|
||||
if(array->pointer)
|
||||
free(array->pointer);
|
||||
g_free(array->pointer);
|
||||
array->size=array->next=0;
|
||||
}
|
||||
|
||||
|
@ -169,7 +168,7 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
|
|||
|
||||
memcpy(to,buf,is*count);
|
||||
|
||||
free(buf);
|
||||
g_free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -732,7 +731,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
|||
snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
|
||||
|
||||
if(stat(buffer,&st)<0) {
|
||||
free(buffer);
|
||||
g_free(buffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -755,7 +754,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
|
|||
direntry->begin=0; /* do that later */
|
||||
if (st.st_size > 0x7fffffff) {
|
||||
fprintf(stderr, "File %s is larger than 2GB\n", buffer);
|
||||
free(buffer);
|
||||
g_free(buffer);
|
||||
closedir(dir);
|
||||
return -2;
|
||||
}
|
||||
|
@ -825,20 +824,6 @@ static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
|
|||
return s->faked_sectors + s->sectors_per_cluster * cluster_num;
|
||||
}
|
||||
|
||||
static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
|
||||
{
|
||||
return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
|
||||
}
|
||||
|
||||
#ifdef DBG
|
||||
static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
|
||||
{
|
||||
if(mapping->mode==MODE_UNDEFINED)
|
||||
return 0;
|
||||
return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int init_directories(BDRVVVFATState* s,
|
||||
const char* dirname)
|
||||
{
|
||||
|
@ -1138,25 +1123,6 @@ static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_
|
|||
return mapping;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function simply compares path == mapping->path. Since the mappings
|
||||
* are sorted by cluster, this is expensive: O(n).
|
||||
*/
|
||||
static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
|
||||
const char* path)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->mapping.next; i++) {
|
||||
mapping_t* mapping = array_get(&(s->mapping), i);
|
||||
if (mapping->first_mapping_index < 0 &&
|
||||
!strcmp(path, mapping->path))
|
||||
return mapping;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int open_file(BDRVVVFATState* s,mapping_t* mapping)
|
||||
{
|
||||
if(!mapping)
|
||||
|
@ -1223,23 +1189,6 @@ read_cluster_directory:
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void hexdump(const void* address, uint32_t len)
|
||||
{
|
||||
const unsigned char* p = address;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < len; i += 16) {
|
||||
for (j = 0; j < 16 && i + j < len; j++)
|
||||
fprintf(stderr, "%02x ", p[i + j]);
|
||||
for (; j < 16; j++)
|
||||
fprintf(stderr, " ");
|
||||
fprintf(stderr, " ");
|
||||
for (j = 0; j < 16 && i + j < len; j++)
|
||||
fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void print_direntry(const direntry_t* direntry)
|
||||
{
|
||||
int j = 0;
|
||||
|
@ -1375,7 +1324,7 @@ DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
|
|||
assert(commit->path || commit->action == ACTION_WRITEOUT);
|
||||
if (commit->action != ACTION_WRITEOUT) {
|
||||
assert(commit->path);
|
||||
free(commit->path);
|
||||
g_free(commit->path);
|
||||
} else
|
||||
assert(commit->path == NULL);
|
||||
}
|
||||
|
@ -1741,7 +1690,7 @@ static int check_directory_consistency(BDRVVVFATState *s,
|
|||
|
||||
long_file_name lfn;
|
||||
int path_len = strlen(path);
|
||||
char path2[PATH_MAX];
|
||||
char path2[PATH_MAX + 1];
|
||||
|
||||
assert(path_len < PATH_MAX); /* len was tested before! */
|
||||
pstrcpy(path2, sizeof(path2), path);
|
||||
|
@ -1782,7 +1731,7 @@ DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)clu
|
|||
if (subret) {
|
||||
fprintf(stderr, "Error fetching direntries\n");
|
||||
fail:
|
||||
free(cluster);
|
||||
g_free(cluster);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1850,7 +1799,7 @@ DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i))
|
|||
cluster_num = modified_fat_get(s, cluster_num);
|
||||
} while(!fat_eof(s, cluster_num));
|
||||
|
||||
free(cluster);
|
||||
g_free(cluster);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1995,8 +1944,9 @@ static int remove_mapping(BDRVVVFATState* s, int mapping_index)
|
|||
mapping_t* first_mapping = array_get(&(s->mapping), 0);
|
||||
|
||||
/* free mapping */
|
||||
if (mapping->first_mapping_index < 0)
|
||||
free(mapping->path);
|
||||
if (mapping->first_mapping_index < 0) {
|
||||
g_free(mapping->path);
|
||||
}
|
||||
|
||||
/* remove from s->mapping */
|
||||
array_remove(&(s->mapping), mapping_index);
|
||||
|
@ -2232,11 +2182,15 @@ static int commit_one_file(BDRVVVFATState* s,
|
|||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
|
||||
strerror(errno), errno);
|
||||
g_free(cluster);
|
||||
return fd;
|
||||
}
|
||||
if (offset > 0)
|
||||
if (lseek(fd, offset, SEEK_SET) != offset)
|
||||
return -3;
|
||||
if (offset > 0) {
|
||||
if (lseek(fd, offset, SEEK_SET) != offset) {
|
||||
g_free(cluster);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
while (offset < size) {
|
||||
uint32_t c1;
|
||||
|
@ -2252,11 +2206,15 @@ static int commit_one_file(BDRVVVFATState* s,
|
|||
ret = vvfat_read(s->bs, cluster2sector(s, c),
|
||||
(uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < 0) {
|
||||
g_free(cluster);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (write(fd, cluster, rest_size) < 0)
|
||||
return -2;
|
||||
if (write(fd, cluster, rest_size) < 0) {
|
||||
g_free(cluster);
|
||||
return -2;
|
||||
}
|
||||
|
||||
offset += rest_size;
|
||||
c = c1;
|
||||
|
@ -2265,9 +2223,11 @@ static int commit_one_file(BDRVVVFATState* s,
|
|||
if (ftruncate(fd, size)) {
|
||||
perror("ftruncate()");
|
||||
close(fd);
|
||||
g_free(cluster);
|
||||
return -4;
|
||||
}
|
||||
close(fd);
|
||||
g_free(cluster);
|
||||
|
||||
return commit_mappings(s, first_cluster, dir_index);
|
||||
}
|
||||
|
@ -2399,7 +2359,7 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
|
|||
}
|
||||
}
|
||||
|
||||
free(old_path);
|
||||
g_free(old_path);
|
||||
array_remove(&(s->commits), i);
|
||||
continue;
|
||||
} else if (commit->action == ACTION_MKDIR) {
|
||||
|
@ -2775,7 +2735,7 @@ static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
|
|||
static void write_target_close(BlockDriverState *bs) {
|
||||
BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
|
||||
bdrv_delete(s->qcow);
|
||||
free(s->qcow_filename);
|
||||
g_free(s->qcow_filename);
|
||||
}
|
||||
|
||||
static BlockDriver vvfat_write_target = {
|
||||
|
@ -2836,8 +2796,7 @@ static void vvfat_close(BlockDriverState *bs)
|
|||
array_free(&(s->fat));
|
||||
array_free(&(s->directory));
|
||||
array_free(&(s->mapping));
|
||||
if(s->cluster_buffer)
|
||||
free(s->cluster_buffer);
|
||||
g_free(s->cluster_buffer);
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_vvfat = {
|
||||
|
@ -2878,11 +2837,5 @@ static void checkpoint(void) {
|
|||
direntry = array_get(&(vvv->directory), mapping->dir_index);
|
||||
assert(!memcmp(direntry->name, "USB H ", 11) || direntry->name[0]==0);
|
||||
#endif
|
||||
return;
|
||||
/* avoid compiler warnings: */
|
||||
hexdump(NULL, 100);
|
||||
remove_mapping(vvv, 0);
|
||||
print_mapping(NULL);
|
||||
print_direntry(NULL);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue