1 /* 2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 #include "vnode_store.h" 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <file_cache.h> 13 #include <vfs.h> 14 15 16 status_t 17 VMVnodeCache::Init(struct vnode *vnode) 18 { 19 status_t error = VMCache::Init(CACHE_TYPE_VNODE); 20 if (error != B_OK) 21 return error; 22 23 fVnode = vnode; 24 fFileCacheRef = NULL; 25 26 vfs_vnode_to_node_ref(fVnode, &fDevice, &fInode); 27 28 return B_OK; 29 } 30 31 32 bool 33 VMVnodeCache::HasPage(off_t offset) 34 { 35 // We always pretend to have the page - even if it's beyond the size of 36 // the file. The read function will only cut down the size of the read, 37 // it won't fail because of that. 38 return true; 39 } 40 41 42 status_t 43 VMVnodeCache::Read(off_t offset, const iovec *vecs, size_t count, 44 size_t *_numBytes) 45 { 46 size_t bytesUntouched = *_numBytes; 47 48 status_t status = vfs_read_pages(fVnode, NULL, offset, vecs, count, 49 0, _numBytes); 50 51 bytesUntouched -= *_numBytes; 52 53 // If the request could be filled completely, or an error occured, 54 // we're done here 55 if (status < B_OK || bytesUntouched == 0) 56 return status; 57 58 // Clear out any leftovers that were not touched by the above read - we're 59 // doing this here so that not every file system/device has to implement 60 // this 61 for (int32 i = count; i-- > 0 && bytesUntouched != 0;) { 62 size_t length = min_c(bytesUntouched, vecs[i].iov_len); 63 64 // ToDo: will have to map the pages in later (when we switch to physical pages) 65 memset((void *)((addr_t)vecs[i].iov_base + vecs[i].iov_len - length), 66 0, length); 67 bytesUntouched -= length; 68 } 69 70 return B_OK; 71 } 72 73 74 status_t 75 VMVnodeCache::Write(off_t offset, const iovec *vecs, size_t count, 76 size_t *_numBytes) 77 { 78 return vfs_write_pages(fVnode, NULL, offset, vecs, count, 0, _numBytes); 79 } 80 81 82 status_t 83 VMVnodeCache::Fault(struct vm_address_space *aspace, off_t offset) 84 { 85 return B_BAD_HANDLER; 86 } 87 88 89 status_t 90 VMVnodeCache::AcquireUnreferencedStoreRef() 91 { 92 struct vnode *vnode; 93 status_t status = vfs_get_vnode(fDevice, fInode, false, &vnode); 94 95 // If successful, update the store's vnode pointer, so that release_ref() 96 // won't use a stale pointer. 97 if (status == B_OK) 98 fVnode = vnode; 99 100 return status; 101 } 102 103 104 void 105 VMVnodeCache::AcquireStoreRef() 106 { 107 vfs_acquire_vnode(fVnode); 108 } 109 110 111 void 112 VMVnodeCache::ReleaseStoreRef() 113 { 114 vfs_put_vnode(fVnode); 115 } 116 117