rem: dprintf("warning: device driver %p doesn't respect total length in read_pages() call!\n", ref->device);
context: pages_io(file_cache_ref *ref, off_t offset, const iovec *vecs, size_t count,	size_t *_numBytes, bool doWrite){	TRACE(("pages_io: ref = %p, offset = %Ld, size = %lu, %s\n", ref, offset,		*_numBytes, doWrite ? "write" : "read"));	// translate the iovecs into direct device accesses	file_io_vec fileVecs[MAX_FILE_IO_VECS];	size_t fileVecCount = MAX_FILE_IO_VECS;	size_t numBytes = *_numBytes;	status_t status = get_file_map(ref, offset, numBytes, fileVecs, &fileVecCount);	if (status < B_OK)		return status;	// ToDo: handle array overflow gracefully!#ifdef TRACE_FILE_CACHE	dprintf("got %lu file vecs for %Ld:%lu:\n", fileVecCount, offset, numBytes);	for (size_t i = 0; i < fileVecCount; i++)		dprintf("[%lu] offset = %Ld, size = %Ld\n", i, fileVecs[i].offset, fileVecs[i].length);#endif	uint32 fileVecIndex;	size_t size;	if (!doWrite) {		// now directly read the data from the device		// the first file_io_vec can be read directly		size = fileVecs[0].length;		if (size > numBytes)			size = numBytes;		status = vfs_read_pages(ref->device, ref->cookie, fileVecs[0].offset, vecs, count, &size);		if (status < B_OK)			return status;		// ToDo: this is a work-around for buggy device drivers!		//	When our own drivers honour the length, we can:		//	a) also use this direct I/O for writes (otherwise, it would overwrite precious data)		//	b) panic if the term below is true (at least for writes)		if (size > fileVecs[0].length) {			dprintf("warning: device driver %p doesn't respect total length in read_pages() call!\n", ref->device);			size = fileVecs[0].length;		}		ASSERT(size <= fileVecs[0].length);		// If the file portion was contiguous, we're already done now		if (size == numBytes)			return B_OK;		// if we reached the end of the file, we can return as well		if (size != fileVecs[0].length) {			*_numBytes = size;			return B_OK;		}				fileVecIndex = 1;	} else {		fileVecIndex = 0;		size = 0;	}	// Too bad, let's process the rest of the file_io_vecs	size_t totalSize = size;	// first, find out where we have to continue in our iovecs	uint32 i = 0;	for (; i < count; i++) {		if (size <= vecs[i].iov_len)			break;		size -= vecs[i].iov_len;	}	size_t vecOffset = size;	for (; fileVecIndex < fileVecCount; fileVecIndex++) {		file_io_vec &fileVec = fileVecs[fileVecIndex];		iovec tempVecs[8];		uint32 tempCount = 1;		tempVecs[0].iov_base = (void *)((addr_t)vecs[i].iov_base + vecOffset);		size = min_c(vecs[i].iov_len - vecOffset, fileVec.length);		tempVecs[0].iov_len = size;		TRACE(("fill vec %ld, offset = %lu, size = %lu\n", i, vecOffset, size));		if (size >= fileVec.length)			vecOffset += size;		else			vecOffset = 0;		while (size < fileVec.length && ++i < count) {			tempVecs[tempCount].iov_base = vecs[i].iov_base;			tempCount++;			// is this iovec larger than the file_io_vec?			if (vecs[i].iov_len + size > fileVec.length) {				size += tempVecs[tempCount].iov_len = vecOffset = fileVec.length - size;				break;			}			size += tempVecs[tempCount].iov_len = vecs[i].iov_len;		}		size_t bytes = size;		if (doWrite)			status = vfs_write_pages(ref->device, ref->cookie, fileVec.offset, tempVecs, tempCount, &bytes);		else			status = vfs_read_pages(ref->device, ref->cookie, fileVec.offset, tempVecs, tempCount, &bytes);		if (status < B_OK)			return status;		totalSize += size;		if (size != bytes) {			// there are no more bytes, let's bail out			*_numBytes = totalSize;			return B_OK;		}	}	return B_OK;}