hrev48220 adds 1 changeset to branch 'master' old head: b7ff6340ae200ac60c43e97efdbc2ce190fb165f new head: 76b8f002e1aef2f3b7311178b810f3ed6f505b1c overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=76b8f00+%5Eb7ff634 ---------------------------------------------------------------------------- 76b8f00: Implement lseek(SEEK_END) on devices While the partitioning system does publish partitions as block devices and report their size in stat(), the old BeOS-style drivers have no means of reporting it this way. So we fall back to ioctl(B_GET_GEOMETRY) to find out the size. [ François Revol <revol@xxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev48220 Commit: 76b8f002e1aef2f3b7311178b810f3ed6f505b1c URL: http://cgit.haiku-os.org/haiku/commit/?id=76b8f00 Author: François Revol <revol@xxxxxxx> Date: Tue Nov 4 19:47:04 2014 UTC ---------------------------------------------------------------------------- 1 file changed, 22 insertions(+), 2 deletions(-) src/system/kernel/fs/vfs.cpp | 24 ++++++++++++++++++++++-- ---------------------------------------------------------------------------- diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 22571c2..845912c 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -5582,6 +5582,7 @@ file_seek(struct file_descriptor* descriptor, off_t pos, int seekType) { struct vnode* vnode = descriptor->u.vnode; off_t offset; + bool isDevice = false; FUNCTION(("file_seek(pos = %" B_PRIdOFF ", seekType = %d)\n", pos, seekType)); @@ -5592,13 +5593,16 @@ file_seek(struct file_descriptor* descriptor, off_t pos, int seekType) case S_IFSOCK: return ESPIPE; + // drivers publish block devices as chr, so pick both + case S_IFBLK: + case S_IFCHR: + isDevice = true; + break; // The Open Group Base Specs don't mention any file types besides pipes, // fifos, and sockets specially, so we allow seeking them. case S_IFREG: - case S_IFBLK: case S_IFDIR: case S_IFLNK: - case S_IFCHR: break; } @@ -5621,6 +5625,22 @@ file_seek(struct file_descriptor* descriptor, off_t pos, int seekType) return status; offset = stat.st_size; + + if (offset == 0 && isDevice) { + // stat() on regular drivers doesn't report size + device_geometry geometry; + + if (HAS_FS_CALL(vnode, ioctl)) { + status = FS_CALL(vnode, ioctl, descriptor->cookie, + B_GET_GEOMETRY, &geometry, sizeof(geometry)); + if (status == B_OK) + offset = (off_t)geometry.bytes_per_sector + * geometry.sectors_per_track + * geometry.cylinder_count + * geometry.head_count; + } + } + break; } default: