* Added parameter "size_t align" to file_map_translate(). If > 1, the
vector at the end of the file will be aligned to the given value. * BFS uses an alignment of 512 bytes (should be block size of the underlying device or BFS block size, whatever is less), which should be fine, since file data are only stored in BFS blocks. This totally avoids any partial operations at the I/O scheduler level, thus saving disk operations. Not that I could measure any performance difference. Theoretically it should help a lot though, particularly when dealing with lots of small files, since we avoid using bounce buffers, which are (a) limited in number and (b) require copying of the data. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27246 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
fd49e6b35a
commit
4612433715
|
@ -97,7 +97,7 @@ extern void file_map_set_size(void *_map, off_t size);
|
||||||
extern void file_map_invalidate(void *_map, off_t offset, off_t size);
|
extern void file_map_invalidate(void *_map, off_t offset, off_t size);
|
||||||
extern status_t file_map_set_mode(void *_map, uint32 mode);
|
extern status_t file_map_set_mode(void *_map, uint32 mode);
|
||||||
extern status_t file_map_translate(void *_map, off_t offset, size_t size,
|
extern status_t file_map_translate(void *_map, off_t offset, size_t size,
|
||||||
struct file_io_vec *vecs, size_t *_count);
|
struct file_io_vec *vecs, size_t *_count, size_t align);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ extern void fssh_file_map_invalidate(void *_map, fssh_off_t offset,
|
||||||
extern fssh_status_t fssh_file_map_set_mode(void *_map, uint32_t mode);
|
extern fssh_status_t fssh_file_map_set_mode(void *_map, uint32_t mode);
|
||||||
extern fssh_status_t fssh_file_map_translate(void *_map, fssh_off_t offset,
|
extern fssh_status_t fssh_file_map_translate(void *_map, fssh_off_t offset,
|
||||||
fssh_size_t size, struct fssh_file_io_vec *vecs,
|
fssh_size_t size, struct fssh_file_io_vec *vecs,
|
||||||
fssh_size_t *_count);
|
fssh_size_t *_count, fssh_size_t align);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,9 @@ iterative_io_get_vecs_hook(void* cookie, io_request* request, off_t offset,
|
||||||
size_t size, struct file_io_vec* vecs, size_t* _count)
|
size_t size, struct file_io_vec* vecs, size_t* _count)
|
||||||
{
|
{
|
||||||
Inode* inode = (Inode*)cookie;
|
Inode* inode = (Inode*)cookie;
|
||||||
return file_map_translate(inode->Map(), offset, size, vecs, _count);
|
return file_map_translate(inode->Map(), offset, size, vecs, _count, 512);
|
||||||
|
// TODO: Use the actual block size of the underlying device for the
|
||||||
|
// alignment!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -382,7 +384,7 @@ bfs_read_pages(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
||||||
uint32 fileVecCount = 8;
|
uint32 fileVecCount = 8;
|
||||||
|
|
||||||
status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs,
|
status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs,
|
||||||
&fileVecCount);
|
&fileVecCount, 0);
|
||||||
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -427,7 +429,7 @@ bfs_write_pages(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
||||||
uint32 fileVecCount = 8;
|
uint32 fileVecCount = 8;
|
||||||
|
|
||||||
status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs,
|
status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs,
|
||||||
&fileVecCount);
|
&fileVecCount, 0);
|
||||||
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ ext2_read_pages(fs_volume* _volume, fs_vnode* _node, void* _cookie,
|
||||||
uint32 fileVecCount = 8;
|
uint32 fileVecCount = 8;
|
||||||
|
|
||||||
status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs,
|
status = file_map_translate(inode->Map(), pos, bytesLeft, fileVecs,
|
||||||
&fileVecCount);
|
&fileVecCount, 0);
|
||||||
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -1533,7 +1533,7 @@ dosfs_read_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie,
|
||||||
size_t bytes = bytesLeft;
|
size_t bytes = bytesLeft;
|
||||||
|
|
||||||
status = file_map_translate(node->file_map, pos, bytesLeft, fileVecs,
|
status = file_map_translate(node->file_map, pos, bytesLeft, fileVecs,
|
||||||
&fileVecCount);
|
&fileVecCount, 0);
|
||||||
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1586,7 +1586,7 @@ dosfs_write_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie,
|
||||||
size_t bytes = bytesLeft;
|
size_t bytes = bytesLeft;
|
||||||
|
|
||||||
status = file_map_translate(node->file_map, pos, bytesLeft, fileVecs,
|
status = file_map_translate(node->file_map, pos, bytesLeft, fileVecs,
|
||||||
&fileVecCount);
|
&fileVecCount, 0);
|
||||||
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
if (status != B_OK && status != B_BUFFER_OVERFLOW)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,8 @@ public:
|
||||||
void SetSize(off_t size);
|
void SetSize(off_t size);
|
||||||
|
|
||||||
status_t Translate(off_t offset, size_t size,
|
status_t Translate(off_t offset, size_t size,
|
||||||
file_io_vec* vecs, size_t* _count);
|
file_io_vec* vecs, size_t* _count,
|
||||||
|
size_t align);
|
||||||
|
|
||||||
file_extent* ExtentAt(uint32 index);
|
file_extent* ExtentAt(uint32 index);
|
||||||
|
|
||||||
|
@ -383,18 +384,26 @@ FileMap::SetMode(uint32 mode)
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count)
|
FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count,
|
||||||
|
size_t align)
|
||||||
{
|
{
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
|
||||||
size_t maxVecs = *_count;
|
size_t maxVecs = *_count;
|
||||||
|
size_t padLastVec = 0;
|
||||||
|
|
||||||
if (offset >= Size()) {
|
if (offset >= Size()) {
|
||||||
*_count = 0;
|
*_count = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
if (offset + size > fSize)
|
if (offset + size > fSize) {
|
||||||
|
if (align > 1) {
|
||||||
|
off_t alignedSize = (fSize + align - 1) & ~(off_t)(align - 1);
|
||||||
|
if (offset + size >= alignedSize)
|
||||||
|
padLastVec = alignedSize - fSize;
|
||||||
|
}
|
||||||
size = fSize - offset;
|
size = fSize - offset;
|
||||||
|
}
|
||||||
|
|
||||||
// First, we need to make sure that we have already cached all file
|
// First, we need to make sure that we have already cached all file
|
||||||
// extents needed for this request.
|
// extents needed for this request.
|
||||||
|
@ -414,8 +423,7 @@ FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count)
|
||||||
vecs[0].length = fileExtent->disk.length - offset;
|
vecs[0].length = fileExtent->disk.length - offset;
|
||||||
|
|
||||||
if (vecs[0].length >= size) {
|
if (vecs[0].length >= size) {
|
||||||
if (vecs[0].length > size)
|
vecs[0].length = size + padLastVec;
|
||||||
vecs[0].length = size;
|
|
||||||
*_count = 1;
|
*_count = 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -431,8 +439,7 @@ FileMap::Translate(off_t offset, size_t size, file_io_vec* vecs, size_t* _count)
|
||||||
vecs[vecIndex++] = fileExtent->disk;
|
vecs[vecIndex++] = fileExtent->disk;
|
||||||
|
|
||||||
if (size <= fileExtent->disk.length) {
|
if (size <= fileExtent->disk.length) {
|
||||||
if (size < fileExtent->disk.length)
|
vecs[vecIndex - 1].length = size + padLastVec;
|
||||||
vecs[vecIndex - 1].length = size;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,7 +634,7 @@ file_map_set_mode(void* _map, uint32 mode)
|
||||||
|
|
||||||
extern "C" status_t
|
extern "C" status_t
|
||||||
file_map_translate(void* _map, off_t offset, size_t size, file_io_vec* vecs,
|
file_map_translate(void* _map, off_t offset, size_t size, file_io_vec* vecs,
|
||||||
size_t* _count)
|
size_t* _count, size_t align)
|
||||||
{
|
{
|
||||||
TRACE(("file_map_translate(map %p, offset %Ld, size %ld)\n",
|
TRACE(("file_map_translate(map %p, offset %Ld, size %ld)\n",
|
||||||
_map, offset, size));
|
_map, offset, size));
|
||||||
|
@ -636,6 +643,6 @@ file_map_translate(void* _map, off_t offset, size_t size, file_io_vec* vecs,
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return map->Translate(offset, size, vecs, _count);
|
return map->Translate(offset, size, vecs, _count, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@ public:
|
||||||
void SetSize(fssh_off_t size);
|
void SetSize(fssh_off_t size);
|
||||||
|
|
||||||
fssh_status_t Translate(fssh_off_t offset, fssh_size_t size,
|
fssh_status_t Translate(fssh_off_t offset, fssh_size_t size,
|
||||||
fssh_file_io_vec* vecs, fssh_size_t* _count);
|
fssh_file_io_vec* vecs, fssh_size_t* _count,
|
||||||
|
fssh_size_t align);
|
||||||
|
|
||||||
file_extent* ExtentAt(uint32_t index);
|
file_extent* ExtentAt(uint32_t index);
|
||||||
|
|
||||||
|
@ -354,18 +355,25 @@ FileMap::SetMode(uint32_t mode)
|
||||||
|
|
||||||
fssh_status_t
|
fssh_status_t
|
||||||
FileMap::Translate(fssh_off_t offset, fssh_size_t size, fssh_file_io_vec* vecs,
|
FileMap::Translate(fssh_off_t offset, fssh_size_t size, fssh_file_io_vec* vecs,
|
||||||
fssh_size_t* _count)
|
fssh_size_t* _count, fssh_size_t align)
|
||||||
{
|
{
|
||||||
MutexLocker _(fLock);
|
MutexLocker _(fLock);
|
||||||
|
|
||||||
fssh_size_t maxVecs = *_count;
|
fssh_size_t maxVecs = *_count;
|
||||||
|
fssh_size_t padLastVec = 0;
|
||||||
|
|
||||||
if (offset >= Size()) {
|
if (offset >= Size()) {
|
||||||
*_count = 0;
|
*_count = 0;
|
||||||
return FSSH_B_OK;
|
return FSSH_B_OK;
|
||||||
}
|
}
|
||||||
if (offset + size > fSize)
|
if (offset + size > fSize) {
|
||||||
|
if (align > 1) {
|
||||||
|
fssh_off_t alignedSize = (fSize + align - 1) & ~(off_t)(align - 1);
|
||||||
|
if (offset + size >= alignedSize)
|
||||||
|
padLastVec = alignedSize - fSize;
|
||||||
|
}
|
||||||
size = fSize - offset;
|
size = fSize - offset;
|
||||||
|
}
|
||||||
|
|
||||||
// First, we need to make sure that we have already cached all file
|
// First, we need to make sure that we have already cached all file
|
||||||
// extents needed for this request.
|
// extents needed for this request.
|
||||||
|
@ -385,8 +393,7 @@ FileMap::Translate(fssh_off_t offset, fssh_size_t size, fssh_file_io_vec* vecs,
|
||||||
vecs[0].length = fileExtent->disk.length - offset;
|
vecs[0].length = fileExtent->disk.length - offset;
|
||||||
|
|
||||||
if (vecs[0].length >= size) {
|
if (vecs[0].length >= size) {
|
||||||
if (vecs[0].length > size)
|
vecs[0].length = size + padLastVec;
|
||||||
vecs[0].length = size;
|
|
||||||
*_count = 1;
|
*_count = 1;
|
||||||
return FSSH_B_OK;
|
return FSSH_B_OK;
|
||||||
}
|
}
|
||||||
|
@ -402,8 +409,7 @@ FileMap::Translate(fssh_off_t offset, fssh_size_t size, fssh_file_io_vec* vecs,
|
||||||
vecs[vecIndex++] = fileExtent->disk;
|
vecs[vecIndex++] = fileExtent->disk;
|
||||||
|
|
||||||
if (size <= fileExtent->disk.length) {
|
if (size <= fileExtent->disk.length) {
|
||||||
if (size < fileExtent->disk.length)
|
vecs[vecIndex - 1].length = size + padLastVec;
|
||||||
vecs[vecIndex - 1].length = size;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,7 +496,7 @@ fssh_file_map_set_mode(void* _map, uint32_t mode)
|
||||||
|
|
||||||
extern "C" fssh_status_t
|
extern "C" fssh_status_t
|
||||||
fssh_file_map_translate(void* _map, fssh_off_t offset, fssh_size_t size,
|
fssh_file_map_translate(void* _map, fssh_off_t offset, fssh_size_t size,
|
||||||
fssh_file_io_vec* vecs, fssh_size_t* _count)
|
fssh_file_io_vec* vecs, fssh_size_t* _count, fssh_size_t align)
|
||||||
{
|
{
|
||||||
TRACE(("file_map_translate(map %p, offset %Ld, size %ld)\n",
|
TRACE(("file_map_translate(map %p, offset %Ld, size %ld)\n",
|
||||||
_map, offset, size));
|
_map, offset, size));
|
||||||
|
@ -499,6 +505,6 @@ fssh_file_map_translate(void* _map, fssh_off_t offset, fssh_size_t size,
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
return FSSH_B_BAD_VALUE;
|
return FSSH_B_BAD_VALUE;
|
||||||
|
|
||||||
return map->Translate(offset, size, vecs, _count);
|
return map->Translate(offset, size, vecs, _count, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue