rem: addr_t lastPageOffset = (pageOffset + bufferSize) & ~(B_PAGE_SIZE - 1);
add: addr_t lastPageOffset = (pageOffset + bufferSize) & (B_PAGE_SIZE - 1);
context: write_chunk_to_cache(file_cache_ref *ref, off_t offset, size_t size,	int32 pageOffset, addr_t buffer, size_t bufferSize){	iovec vecs[MAX_IO_VECS];	int32 vecCount = 0;	vm_page *pages[MAX_IO_VECS];	int32 pageIndex = 0;	status_t status = B_OK;	// ToDo: this should be settable somewhere	bool writeThrough = false;	// allocate pages for the cache and mark them busy	for (size_t pos = 0; pos < size; pos += B_PAGE_SIZE) {		// ToDo: if space is becoming tight, and this cache is already grown		//	big - shouldn't we better steal the pages directly in that case?		//	(a working set like approach for the file cache)		vm_page *page = pages[pageIndex++] = vm_page_allocate_page(PAGE_STATE_FREE);		page->state = PAGE_STATE_BUSY;		vm_cache_insert_page(ref->cache, page, offset + pos);		addr_t virtualAddress;		vm_get_physical_page(page->ppn * B_PAGE_SIZE, &virtualAddress,			PHYSICAL_PAGE_CAN_WAIT);		add_to_iovec(vecs, vecCount, MAX_IO_VECS, virtualAddress, B_PAGE_SIZE);		// ToDo: check if the array is large enough!	}	mutex_unlock(&ref->cache->lock);	// copy contents (and read in partially written pages first)	if (pageOffset != 0) {		// This is only a partial write, so we have to read the rest of the page		// from the file to have consistent data in the cache		iovec readVec = { vecs[0].iov_base, B_PAGE_SIZE };		size_t bytesRead = B_PAGE_SIZE;		status = pages_io(ref, offset, &readVec, 1, &bytesRead, false);		// ToDo: handle errors for real!		if (status < B_OK)			panic("pages_io() failed!\n");	}	addr_t lastPageOffset = (pageOffset + bufferSize) & ~(B_PAGE_SIZE - 1);	if (lastPageOffset != 0) {		// get the last page in the I/O vectors		addr_t last = (addr_t)vecs[vecCount - 1].iov_base			+ vecs[vecCount - 1].iov_len - B_PAGE_SIZE;		if (offset + pageOffset + bufferSize == ref->cache->cache->virtual_size) {			// the space in the page after this write action needs to be cleaned			memset((void *)(last + lastPageOffset), 0, B_PAGE_SIZE - lastPageOffset);		} else if (vecCount > 1) {			// the end of this write does not happen on a page boundary, so we			// need to fetch the last page before we can update it			iovec readVec = { (void *)last, B_PAGE_SIZE };			size_t bytesRead = B_PAGE_SIZE;			status = pages_io(ref, offset + size - B_PAGE_SIZE, &readVec, 1,				&bytesRead, false);			// ToDo: handle errors for real!			if (status < B_OK)				panic("pages_io() failed!\n");		}	}	for (int32 i = 0; i < vecCount; i++) {		addr_t base = (addr_t)vecs[i].iov_base;		size_t bytes = min_c(bufferSize, size_t(vecs[i].iov_len - pageOffset));		// copy data from user buffer		user_memcpy((void *)(base + pageOffset), (void *)buffer, bytes);		bufferSize -= bytes;		if (bufferSize == 0)			break;		buffer += bytes;		pageOffset = 0;	}	if (writeThrough) {		// write cached pages back to the file if we were asked to do that		status_t status = pages_io(ref, offset, vecs, vecCount, &size, true);		if (status < B_OK) {			// ToDo: remove allocated pages, ...?			panic("file_cache: remove allocated pages! write pages failed: %s\n",				strerror(status));		}	}	mutex_lock(&ref->cache->lock);	// unmap the pages again	for (int32 i = 0; i < vecCount; i++) {		addr_t base = (addr_t)vecs[i].iov_base;		size_t size = vecs[i].iov_len;		for (size_t pos = 0; pos < size; pos += B_PAGE_SIZE, base += B_PAGE_SIZE)			vm_put_physical_page(base);	}	// make the pages accessible in the cache	for (int32 i = pageIndex; i-- > 0;) {		if (writeThrough)			pages[i]->state = PAGE_STATE_ACTIVE;		else			vm_page_set_state(pages[i], PAGE_STATE_MODIFIED);	}	return status;}