simplification: only VFS allocates output buffer
This was SVN commit r1051.
This commit is contained in:
parent
13e5f5dc11
commit
df5ba1f690
@ -835,7 +835,7 @@ skip_issue:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ssize_t file_io(File* const f, const off_t data_ofs, size_t data_size, void** const p,
|
ssize_t file_io(File* const f, const off_t data_ofs, size_t data_size, void* const data_buf,
|
||||||
const FileIOCB cb, const uintptr_t ctx) // optional
|
const FileIOCB cb, const uintptr_t ctx) // optional
|
||||||
{
|
{
|
||||||
#ifdef PARANOIA
|
#ifdef PARANOIA
|
||||||
@ -847,9 +847,6 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
|
|||||||
const bool is_write = !!(f->flags & FILE_WRITE);
|
const bool is_write = !!(f->flags & FILE_WRITE);
|
||||||
const bool no_aio = !!(f->flags & FILE_NO_AIO);
|
const bool no_aio = !!(f->flags & FILE_NO_AIO);
|
||||||
|
|
||||||
void* data_buf = 0; // I/O source or sink buffer
|
|
||||||
|
|
||||||
|
|
||||||
// when reading:
|
// when reading:
|
||||||
if(!is_write)
|
if(!is_write)
|
||||||
{
|
{
|
||||||
@ -861,46 +858,21 @@ debug_out("file_io fd=%d size=%d ofs=%d\n", f->fd, data_size, data_ofs);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
bool temp = (data_buf == 0);
|
||||||
// set buffer options
|
|
||||||
//
|
|
||||||
|
|
||||||
enum { TEMP, USER, ALLOC } buf_type;
|
|
||||||
|
|
||||||
// .. temp buffer
|
|
||||||
if(!p)
|
|
||||||
buf_type = TEMP;
|
|
||||||
// .. user-specified buffer (=> no align)
|
|
||||||
else if(*p)
|
|
||||||
{
|
|
||||||
buf_type = USER;
|
|
||||||
data_buf = *p;
|
|
||||||
}
|
|
||||||
// .. we allocate the buffer
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf_type = ALLOC;
|
|
||||||
// data_buf will be set from actual_buf
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// sanity checks:
|
// sanity checks:
|
||||||
// .. temp blocks requested AND
|
// .. temp blocks requested AND
|
||||||
// (not reading OR using lowio OR no callback)
|
// (not reading OR using lowio OR no callback)
|
||||||
if(buf_type == TEMP && (is_write || no_aio || !cb))
|
if(temp && (is_write || no_aio || !cb))
|
||||||
{
|
{
|
||||||
invalid:
|
|
||||||
debug_warn("file_io: invalid parameter");
|
debug_warn("file_io: invalid parameter");
|
||||||
return ERR_INVALID_PARAM;
|
return ERR_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
// .. write, but no buffer passed in.
|
|
||||||
if(is_write && buf_type != USER)
|
|
||||||
goto invalid;
|
|
||||||
|
|
||||||
|
|
||||||
// only align if we allocate the buffer and in AIO mode
|
// only align if we allocate the buffer and in AIO mode
|
||||||
const bool do_align = buf_type != USER && !no_aio;
|
const bool do_align = temp;
|
||||||
const bool cache = buf_type == TEMP;
|
const bool cache = temp;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -927,14 +899,6 @@ invalid:
|
|||||||
actual_size = round_up(ofs_misalign + data_size, BLOCK_SIZE);
|
actual_size = round_up(ofs_misalign + data_size, BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buf_type == ALLOC)
|
|
||||||
{
|
|
||||||
actual_buf = mem_alloc(actual_size, BLOCK_SIZE);
|
|
||||||
if(!actual_buf)
|
|
||||||
return ERR_NO_MEM;
|
|
||||||
data_buf = (char*)actual_buf + lead_padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
// warn in debug build if buffer and offset don't match
|
// warn in debug build if buffer and offset don't match
|
||||||
// (=> aio would have to realign every block).
|
// (=> aio would have to realign every block).
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -989,7 +953,7 @@ invalid:
|
|||||||
|
|
||||||
off_t issue_ofs = (off_t)(actual_ofs + issue_cnt);
|
off_t issue_ofs = (off_t)(actual_ofs + issue_cnt);
|
||||||
|
|
||||||
void* buf = (buf_type == TEMP)? 0 : (char*)actual_buf + issue_cnt;
|
void* buf = (temp)? 0 : (char*)actual_buf + issue_cnt;
|
||||||
ssize_t issued = block_issue(f, slot, issue_ofs, buf);
|
ssize_t issued = block_issue(f, slot, issue_ofs, buf);
|
||||||
if(issued < 0)
|
if(issued < 0)
|
||||||
err = issued;
|
err = issued;
|
||||||
@ -1039,7 +1003,7 @@ invalid:
|
|||||||
|
|
||||||
// we have useable data from a previous temp buffer,
|
// we have useable data from a previous temp buffer,
|
||||||
// but it needs to be copied into the user's buffer
|
// but it needs to be copied into the user's buffer
|
||||||
if(from_cache && buf_type != TEMP)
|
if(from_cache && !temp)
|
||||||
memcpy((char*)data_buf+raw_transferred_cnt, data, size);
|
memcpy((char*)data_buf+raw_transferred_cnt, data, size);
|
||||||
|
|
||||||
|
|
||||||
@ -1067,7 +1031,7 @@ if(from_cache && buf_type != TEMP)
|
|||||||
if(!from_cache)
|
if(!from_cache)
|
||||||
file_discard_io(slot->io);
|
file_discard_io(slot->io);
|
||||||
|
|
||||||
if(buf_type == TEMP)
|
if(temp)
|
||||||
{
|
{
|
||||||
// adding is allowed and we didn't take this from the cache already: add
|
// adding is allowed and we didn't take this from the cache already: add
|
||||||
if(!slot->cached_block)
|
if(!slot->cached_block)
|
||||||
@ -1081,20 +1045,7 @@ if(from_cache && buf_type != TEMP)
|
|||||||
|
|
||||||
// failed (0 means callback reports it's finished)
|
// failed (0 means callback reports it's finished)
|
||||||
if(err < 0)
|
if(err < 0)
|
||||||
{
|
|
||||||
// user didn't specify output buffer - free what we allocated,
|
|
||||||
// and clear p (value-return param)
|
|
||||||
if(buf_type == ALLOC)
|
|
||||||
{
|
|
||||||
mem_free(actual_buf);
|
|
||||||
*p = 0;
|
|
||||||
// alloc_buf => p != 0
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
|
|
||||||
if(p)
|
|
||||||
*p = data_buf;
|
|
||||||
|
|
||||||
assert(issue_cnt >= raw_transferred_cnt && raw_transferred_cnt >= data_size);
|
assert(issue_cnt >= raw_transferred_cnt && raw_transferred_cnt >= data_size);
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ extern int file_discard_io(FileIO io);
|
|||||||
// >= 0: bytes output; continue.
|
// >= 0: bytes output; continue.
|
||||||
typedef ssize_t(*FileIOCB)(uintptr_t ctx, void* p, size_t size);
|
typedef ssize_t(*FileIOCB)(uintptr_t ctx, void* p, size_t size);
|
||||||
|
|
||||||
extern ssize_t file_io(File* f, off_t ofs, size_t size, void** p, FileIOCB cb = 0, uintptr_t ctx = 0);
|
extern ssize_t file_io(File* f, off_t ofs, size_t size, void* buf, FileIOCB cb = 0, uintptr_t ctx = 0);
|
||||||
|
|
||||||
|
|
||||||
#endif // #ifndef FILE_H
|
#endif // #ifndef FILE_H
|
||||||
|
@ -1343,14 +1343,28 @@ debug_out("vfs_io size=%d\n", size);
|
|||||||
off_t ofs = vf->ofs;
|
off_t ofs = vf->ofs;
|
||||||
vf->ofs += (off_t)size;
|
vf->ofs += (off_t)size;
|
||||||
|
|
||||||
|
void* buf = 0; // assume temp buffer (p == 0)
|
||||||
|
if(p)
|
||||||
|
// user-specified buffer
|
||||||
|
if(*p)
|
||||||
|
buf = *p;
|
||||||
|
// we allocate
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = mem_alloc(round_up(size, 4096), 4096);
|
||||||
|
if(!buf)
|
||||||
|
return ERR_NO_MEM;
|
||||||
|
*p = buf;
|
||||||
|
}
|
||||||
|
|
||||||
// (vfs_open makes sure it's not opened for writing if zip)
|
// (vfs_open makes sure it's not opened for writing if zip)
|
||||||
if(vf_flags(vf) & VF_ZIP)
|
if(vf_flags(vf) & VF_ZIP)
|
||||||
return zip_read(&vf->zf, ofs, size, p, cb, ctx);
|
return zip_read(&vf->zf, ofs, size, buf, cb, ctx);
|
||||||
|
|
||||||
// normal file:
|
// normal file:
|
||||||
// let file_io alloc the buffer if the caller didn't (i.e. p = 0),
|
// let file_io alloc the buffer if the caller didn't (i.e. p = 0),
|
||||||
// because it knows about alignment / padding requirements
|
// because it knows about alignment / padding requirements
|
||||||
return file_io(&vf->f, ofs, size, p, cb, ctx);
|
return file_io(&vf->f, ofs, size, buf, cb, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user