From 4accd841c7331a6674a4c5db4d9b2686d7eb8bac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 6 Jan 2008 14:04:15 +0000 Subject: [PATCH] * Fixed a big bug in common_file_io_vec_pages(): vecOffset was not correctly set when the first chunk of the file could be read in directly, causing it to read data to a wrong place in the buffer. * Reading in the first chunk directly would have also only worked if vecIndex and vecOffset was 0 when calling the function. * Applied the fs_shell changes in file_map to the kernel version as well (the constructor already worked correctly, though). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23265 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/cache/file_map.cpp | 2 +- src/system/kernel/fs/vfs.cpp | 10 ++++++---- src/tools/fs_shell/vfs.cpp | 10 ++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/system/kernel/cache/file_map.cpp b/src/system/kernel/cache/file_map.cpp index ae936a31ae..b7a90472aa 100644 --- a/src/system/kernel/cache/file_map.cpp +++ b/src/system/kernel/cache/file_map.cpp @@ -253,7 +253,7 @@ file_map_translate(void *_map, off_t offset, size_t size, file_io_vec *vecs, size_t maxVecs = *_count; status_t status = B_OK; - if (offset > map.size) { + if (offset >= map.size) { *_count = 0; return B_OK; } diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index dcc8a456a1..f21b080d6c 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -2594,7 +2594,7 @@ common_file_io_vec_pages(struct vnode *vnode, void *cookie, status_t status; size_t size; - if (!doWrite) { + if (!doWrite && vecOffset == 0) { // now directly read the data from the device // the first file_io_vec can be read directly @@ -2603,8 +2603,8 @@ common_file_io_vec_pages(struct vnode *vnode, void *cookie, size = numBytes; status = FS_CALL(vnode, read_pages)(vnode->mount->cookie, - vnode->private_node, cookie, fileVecs[0].offset, vecs, vecCount, - &size, false); + vnode->private_node, cookie, fileVecs[0].offset, &vecs[vecIndex], + vecCount - vecIndex, &size, false); if (status < B_OK) return status; @@ -2636,9 +2636,11 @@ common_file_io_vec_pages(struct vnode *vnode, void *cookie, for (; vecIndex < vecCount; vecIndex++) { if (size < vecs[vecIndex].iov_len) break; - + size -= vecs[vecIndex].iov_len; } + + vecOffset = size; } else { fileVecIndex = 0; size = 0; diff --git a/src/tools/fs_shell/vfs.cpp b/src/tools/fs_shell/vfs.cpp index b403ef2533..51d249a267 100644 --- a/src/tools/fs_shell/vfs.cpp +++ b/src/tools/fs_shell/vfs.cpp @@ -1749,7 +1749,7 @@ common_file_io_vec_pages(int fd, const fssh_file_io_vec *fileVecs, fssh_status_t status; fssh_size_t size; - if (!doWrite) { + if (!doWrite && vecOffset == 0) { // now directly read the data from the device // the first file_io_vec can be read directly @@ -1757,8 +1757,8 @@ common_file_io_vec_pages(int fd, const fssh_file_io_vec *fileVecs, if (size > numBytes) size = numBytes; - status = fssh_read_pages(fd, fileVecs[0].offset, vecs, vecCount, - &size, false); + status = fssh_read_pages(fd, fileVecs[0].offset, &vecs[vecIndex], + vecCount - vecIndex, &size, false); if (status < FSSH_B_OK) return status; @@ -1790,9 +1790,11 @@ common_file_io_vec_pages(int fd, const fssh_file_io_vec *fileVecs, for (; vecIndex < vecCount; vecIndex++) { if (size < vecs[vecIndex].iov_len) break; - + size -= vecs[vecIndex].iov_len; } + + vecOffset = size; } else { fileVecIndex = 0; size = 0;