diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index 8fdbf8214f..d0fc4ee422 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -92,10 +92,10 @@ typedef struct file_system_module_info { bool (*can_page)(fs_volume fs, fs_vnode vnode, fs_cookie cookie); status_t (*read_pages)(fs_volume fs, fs_vnode vnode, fs_cookie cookie, off_t pos, const iovec *vecs, size_t count, size_t *_numBytes, - bool reenter); + bool mayBlock, bool reenter); status_t (*write_pages)(fs_volume fs, fs_vnode vnode, fs_cookie cookie, off_t pos, const iovec *vecs, size_t count, size_t *_numBytes, - bool reenter); + bool mayBlock, bool reenter); /* cache file access */ status_t (*get_file_map)(fs_volume fs, fs_vnode vnode, off_t offset, diff --git a/headers/private/fs_shell/fssh_fs_interface.h b/headers/private/fs_shell/fssh_fs_interface.h index d2bbe466eb..dcf6f441b0 100644 --- a/headers/private/fs_shell/fssh_fs_interface.h +++ b/headers/private/fs_shell/fssh_fs_interface.h @@ -1,11 +1,12 @@ -/* File System Interface Layer Definition - * - * Copyright 2004-2006, Haiku Inc. All Rights Reserved. +/* + * Copyright 2004-2007, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _FSSH_FS_INTERFACE_H #define _FSSH_FS_INTERFACE_H +/*! File System Interface Layer Definition */ + #include "fssh_disk_device_defs.h" #include "fssh_module.h" @@ -95,10 +96,12 @@ typedef struct fssh_file_system_module_info { fssh_fs_cookie cookie); fssh_status_t (*read_pages)(fssh_fs_volume fs, fssh_fs_vnode vnode, fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs, - fssh_size_t count, fssh_size_t *_numBytes, bool reenter); + fssh_size_t count, fssh_size_t *_numBytes, bool mayBlock, + bool reenter); fssh_status_t (*write_pages)(fssh_fs_volume fs, fssh_fs_vnode vnode, fssh_fs_cookie cookie, fssh_off_t pos, const fssh_iovec *vecs, - fssh_size_t count, fssh_size_t *_numBytes, bool reenter); + fssh_size_t count, fssh_size_t *_numBytes, bool mayBlock, + bool reenter); /* cache file access */ fssh_status_t (*get_file_map)(fssh_fs_volume fs, fssh_fs_vnode vnode, diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 03f62adfbe..0266fab3dd 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -91,10 +91,13 @@ void vfs_acquire_vnode(void *vnode); status_t vfs_get_cookie_from_fd(int fd, void **_cookie); bool vfs_can_page(void *vnode, void *cookie); status_t vfs_read_pages(void *vnode, void *cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter); + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool fsReenter); status_t vfs_write_pages(void *vnode, void *cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter); -status_t vfs_get_vnode_cache(void *vnode, struct vm_cache **_cache, bool allocate); + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool fsReenter); +status_t vfs_get_vnode_cache(void *vnode, struct vm_cache **_cache, + bool allocate); status_t vfs_get_file_map( void *_vnode, off_t offset, size_t size, struct file_io_vec *vecs, size_t *_count); status_t vfs_get_fs_node_from_path(dev_t mountID, const char *path, diff --git a/headers/private/kernel/vm_types.h b/headers/private/kernel/vm_types.h index a610e7f151..d530e9fda8 100644 --- a/headers/private/kernel/vm_types.h +++ b/headers/private/kernel/vm_types.h @@ -223,9 +223,11 @@ typedef struct vm_store_ops { status_t (*commit)(struct vm_store *backing_store, off_t size); bool (*has_page)(struct vm_store *backing_store, off_t offset); status_t (*read)(struct vm_store *backing_store, off_t offset, - const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter); + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool fsReenter); status_t (*write)(struct vm_store *backing_store, off_t offset, - const iovec *vecs, size_t count, size_t *_numBytes, bool fsReenter); + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool fsReenter); status_t (*fault)(struct vm_store *backing_store, struct vm_address_space *aspace, off_t offset); void (*acquire_ref)(struct vm_store *backing_store); diff --git a/src/add-ons/kernel/file_systems/bfs/Debug.h b/src/add-ons/kernel/file_systems/bfs/Debug.h index 6b2abe2001..d25399882d 100644 --- a/src/add-ons/kernel/file_systems/bfs/Debug.h +++ b/src/add-ons/kernel/file_systems/bfs/Debug.h @@ -1,6 +1,5 @@ -/* Debug - debug stuff - * - * Copyright 2001-2006, Axel Dörfler, axeld@pinc-software.de. +/* + * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ #ifndef DEBUG_H @@ -60,7 +59,9 @@ #define FUNCTION() ; // #define FUNCTION_START(x) ; #define D(x) {x;}; - #define ASSERT(x) { if (!(x)) DEBUGGER(("bfs: assert failed: " #x "\n")); } + #ifndef ASSERT + # define ASSERT(x) { if (!(x)) DEBUGGER(("bfs: assert failed: " #x "\n")); } + #endif #else #define PRINT(x) ; #define REPORT_ERROR(status) \ @@ -72,7 +73,9 @@ #define FUNCTION() ; #define FUNCTION_START(x) ; #define D(x) ; - #define ASSERT(x) ; + #ifndef ASSERT + # define ASSERT(x) ; + #endif #endif #ifdef DEBUG diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 6c1da93bb9..96729dcf8b 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -342,7 +342,8 @@ bfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie _cookie) static status_t bfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { Inode *inode = (Inode *)_node; @@ -350,7 +351,9 @@ bfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, RETURN_ERROR(B_BAD_VALUE); if (!reenter) { - if (inode->Lock().TryLock() < B_OK) + if (mayBlock) + inode->Lock().Lock(); + else if (inode->Lock().TryLock() < B_OK) return B_BUSY; } @@ -366,7 +369,8 @@ bfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, static status_t bfs_write_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { Inode *inode = (Inode *)_node; @@ -374,7 +378,9 @@ bfs_write_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, RETURN_ERROR(B_BAD_VALUE); if (!reenter) { - if (inode->Lock().TryLock() < B_OK) + if (mayBlock) + inode->Lock().Lock(); + else if (inode->Lock().TryLock() < B_OK) return B_BUSY; } diff --git a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp index 7cc3f25968..cbb9f8d780 100644 --- a/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/cdda/kernel_interface.cpp @@ -1574,17 +1574,19 @@ cdda_can_page(fs_volume _volume, fs_vnode _v, fs_cookie cookie) static status_t cdda_read_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { - return EPERM; + return B_NOT_ALLOWED; } static status_t cdda_write_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { - return EPERM; + return B_NOT_ALLOWED; } diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index 87b8a74ec4..c6093affa7 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -362,7 +362,7 @@ pages_io(file_cache_ref *ref, off_t offset, const iovec *vecs, size_t count, size = numBytes; status = vfs_read_pages(ref->device, ref->cookie, fileVecs[0].offset, - vecs, count, &size, false); + vecs, count, &size, true, false); if (status < B_OK) return status; @@ -459,10 +459,10 @@ pages_io(file_cache_ref *ref, off_t offset, const iovec *vecs, size_t count, size_t bytes = size; if (doWrite) { status = vfs_write_pages(ref->device, ref->cookie, - fileOffset, tempVecs, tempCount, &bytes, false); + fileOffset, tempVecs, tempCount, &bytes, true, false); } else { status = vfs_read_pages(ref->device, ref->cookie, - fileOffset, tempVecs, tempCount, &bytes, false); + fileOffset, tempVecs, tempCount, &bytes, true, false); } if (status < B_OK) return status; diff --git a/src/system/kernel/cache/vnode_store.cpp b/src/system/kernel/cache/vnode_store.cpp index 8a563cbfe9..0c49d65fbc 100644 --- a/src/system/kernel/cache/vnode_store.cpp +++ b/src/system/kernel/cache/vnode_store.cpp @@ -6,12 +6,12 @@ #include "vnode_store.h" -#include -#include - #include #include +#include +#include + static void store_destroy(struct vm_store *store) @@ -41,18 +41,19 @@ store_has_page(struct vm_store *_store, off_t offset) static status_t -store_read(struct vm_store *_store, off_t offset, const iovec *vecs, size_t count, - size_t *_numBytes, bool fsReenter) +store_read(struct vm_store *_store, off_t offset, const iovec *vecs, + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { vnode_store *store = (vnode_store *)_store; size_t bytesUntouched = *_numBytes; status_t status = vfs_read_pages(store->vnode, NULL, offset, vecs, count, - _numBytes, fsReenter); + _numBytes, mayBlock, fsReenter); bytesUntouched -= *_numBytes; - // if the request could be filled completely, or an error occured, we're done here + // If the request could be filled completely, or an error occured, + // we're done here if (status < B_OK || bytesUntouched == 0) return status; @@ -63,7 +64,8 @@ store_read(struct vm_store *_store, off_t offset, const iovec *vecs, size_t coun size_t length = min_c(bytesUntouched, vecs[i].iov_len); // ToDo: will have to map the pages in later (when we switch to physical pages) - memset((void *)((addr_t)vecs[i].iov_base + vecs[i].iov_len - length), 0, length); + memset((void *)((addr_t)vecs[i].iov_base + vecs[i].iov_len - length), + 0, length); bytesUntouched -= length; } @@ -72,11 +74,12 @@ store_read(struct vm_store *_store, off_t offset, const iovec *vecs, size_t coun static status_t -store_write(struct vm_store *_store, off_t offset, const iovec *vecs, size_t count, - size_t *_numBytes, bool fsReenter) +store_write(struct vm_store *_store, off_t offset, const iovec *vecs, + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { vnode_store *store = (vnode_store *)_store; - return vfs_write_pages(store->vnode, NULL, offset, vecs, count, _numBytes, fsReenter); + return vfs_write_pages(store->vnode, NULL, offset, vecs, count, _numBytes, + mayBlock, fsReenter); } diff --git a/src/system/kernel/fs/devfs.cpp b/src/system/kernel/fs/devfs.cpp index 649fe920c0..33c97a0571 100644 --- a/src/system/kernel/fs/devfs.cpp +++ b/src/system/kernel/fs/devfs.cpp @@ -1884,7 +1884,8 @@ devfs_can_page(fs_volume _fs, fs_vnode _vnode, fs_cookie cookie) static status_t devfs_read_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { struct devfs_vnode *vnode = (devfs_vnode *)_vnode; struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie; @@ -1943,7 +1944,8 @@ devfs_read_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos, static status_t devfs_write_pages(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { struct devfs_vnode *vnode = (devfs_vnode *)_vnode; struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie; diff --git a/src/system/kernel/fs/pipefs.cpp b/src/system/kernel/fs/pipefs.cpp index 4a0d8ee95f..b94abc1d39 100644 --- a/src/system/kernel/fs/pipefs.cpp +++ b/src/system/kernel/fs/pipefs.cpp @@ -1596,17 +1596,19 @@ pipefs_can_page(fs_volume _volume, fs_vnode _v, fs_cookie cookie) static status_t pipefs_read_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { - return EPERM; + return B_NOT_ALLOWED; } static status_t pipefs_write_pages(fs_volume _volume, fs_vnode _v, fs_cookie cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { - return EPERM; + return B_NOT_ALLOWED; } diff --git a/src/system/kernel/fs/rootfs.c b/src/system/kernel/fs/rootfs.c index 3de90ee86a..2811b04166 100644 --- a/src/system/kernel/fs/rootfs.c +++ b/src/system/kernel/fs/rootfs.c @@ -772,7 +772,8 @@ rootfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie cookie) static status_t rootfs_read_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { return B_NOT_ALLOWED; } @@ -780,7 +781,8 @@ rootfs_read_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos, static status_t rootfs_write_pages(fs_volume _fs, fs_vnode _v, fs_cookie cookie, off_t pos, - const iovec *vecs, size_t count, size_t *_numBytes, bool reenter) + const iovec *vecs, size_t count, size_t *_numBytes, bool mayBlock, + bool reenter) { return B_NOT_ALLOWED; } diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 291e612816..6c4596887e 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -3094,28 +3094,28 @@ vfs_can_page(void *_vnode, void *cookie) extern "C" status_t -vfs_read_pages(void *_vnode, void *cookie, off_t pos, const iovec *vecs, size_t count, - size_t *_numBytes, bool fsReenter) +vfs_read_pages(void *_vnode, void *cookie, off_t pos, const iovec *vecs, + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { struct vnode *vnode = (struct vnode *)_vnode; FUNCTION(("vfs_read_pages: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos)); return FS_CALL(vnode, read_pages)(vnode->mount->cookie, vnode->private_node, - cookie, pos, vecs, count, _numBytes, fsReenter); + cookie, pos, vecs, count, _numBytes, mayBlock, fsReenter); } extern "C" status_t -vfs_write_pages(void *_vnode, void *cookie, off_t pos, const iovec *vecs, size_t count, - size_t *_numBytes, bool fsReenter) +vfs_write_pages(void *_vnode, void *cookie, off_t pos, const iovec *vecs, + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { struct vnode *vnode = (struct vnode *)_vnode; FUNCTION(("vfs_write_pages: vnode %p, vecs %p, pos %Ld\n", vnode, vecs, pos)); return FS_CALL(vnode, write_pages)(vnode->mount->cookie, vnode->private_node, - cookie, pos, vecs, count, _numBytes, fsReenter); + cookie, pos, vecs, count, _numBytes, mayBlock, fsReenter); } diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp index fdfa4814b4..4bdd502a2e 100644 --- a/src/system/kernel/vm/vm.cpp +++ b/src/system/kernel/vm/vm.cpp @@ -3809,7 +3809,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache, // read it in status_t status = store->ops->read(store, cacheOffset, &vec, 1, - &bytesRead, false); + &bytesRead, true, false); map->ops->put_physical_page((addr_t)vec.iov_base); diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index e488e9f7ab..6b6c901762 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -640,7 +640,7 @@ page_scrubber(void *unused) static status_t -write_page(vm_page *page, bool fsReenter) +write_page(vm_page *page, bool mayBlock, bool fsReenter) { vm_store *store = page->cache->store; size_t length = B_PAGE_SIZE; @@ -656,7 +656,7 @@ write_page(vm_page *page, bool fsReenter) vecs->iov_len = B_PAGE_SIZE; status = store->ops->write(store, (off_t)page->cache_offset << PAGE_SHIFT, - vecs, 1, &length, fsReenter); + vecs, 1, &length, mayBlock, fsReenter); vm_put_physical_page((addr_t)vecs[0].iov_base); @@ -728,7 +728,7 @@ page_writer(void* /*unused*/) // TODO: put this as requests into the I/O scheduler status_t writeStatus[kNumPages]; for (uint32 i = 0; i < numPages; i++) { - writeStatus[i] = write_page(pages[i], false); + writeStatus[i] = write_page(pages[i], false, false); } // mark pages depending on whether they could be written or not @@ -927,7 +927,7 @@ vm_page_write_modified_pages(vm_cache *cache, bool fsReenter) vm_clear_map_flags(page, PAGE_MODIFIED); mutex_unlock(&cache->lock); - status_t status = write_page(page, fsReenter); + status_t status = write_page(page, true, fsReenter); mutex_lock(&cache->lock); InterruptsSpinLocker locker(&sPageLock); diff --git a/src/system/kernel/vm/vm_store_anonymous_noswap.cpp b/src/system/kernel/vm/vm_store_anonymous_noswap.cpp index ef7fe64006..6b8e8ef2fd 100644 --- a/src/system/kernel/vm/vm_store_anonymous_noswap.cpp +++ b/src/system/kernel/vm/vm_store_anonymous_noswap.cpp @@ -90,7 +90,7 @@ anonymous_has_page(struct vm_store *store, off_t offset) static status_t anonymous_read(struct vm_store *store, off_t offset, const iovec *vecs, - size_t count, size_t *_numBytes, bool fsReenter) + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { panic("anonymous_store: read called. Invalid!\n"); return B_ERROR; @@ -99,7 +99,7 @@ anonymous_read(struct vm_store *store, off_t offset, const iovec *vecs, static status_t anonymous_write(struct vm_store *store, off_t offset, const iovec *vecs, - size_t count, size_t *_numBytes, bool fsReenter) + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { // no place to write, this will cause the page daemon to skip this store return B_ERROR; diff --git a/src/system/kernel/vm/vm_store_device.c b/src/system/kernel/vm/vm_store_device.c index ca1946cbb7..44502cb1c8 100644 --- a/src/system/kernel/vm/vm_store_device.c +++ b/src/system/kernel/vm/vm_store_device.c @@ -45,8 +45,8 @@ device_has_page(struct vm_store *store, off_t offset) static status_t -device_read(struct vm_store *store, off_t offset, const iovec *vecs, size_t count, - size_t *_numBytes, bool fsReenter) +device_read(struct vm_store *store, off_t offset, const iovec *vecs, + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { panic("device_store: read called. Invalid!\n"); return B_ERROR; @@ -54,8 +54,8 @@ device_read(struct vm_store *store, off_t offset, const iovec *vecs, size_t coun static status_t -device_write(struct vm_store *store, off_t offset, const iovec *vecs, size_t count, - size_t *_numBytes, bool fsReenter) +device_write(struct vm_store *store, off_t offset, const iovec *vecs, + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { // no place to write, this will cause the page daemon to skip this store return B_OK; diff --git a/src/system/kernel/vm/vm_store_null.c b/src/system/kernel/vm/vm_store_null.c index 3f001f4607..1013c45dce 100644 --- a/src/system/kernel/vm/vm_store_null.c +++ b/src/system/kernel/vm/vm_store_null.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -36,17 +36,17 @@ null_has_page(struct vm_store *store, off_t offset) static status_t null_read(struct vm_store *store, off_t offset, const iovec *vecs, - size_t count, size_t *_numBytes, bool fsReenter) + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { - return -1; + return B_ERROR; } static status_t null_write(struct vm_store *store, off_t offset, const iovec *vecs, - size_t count, size_t *_numBytes, bool fsReenter) + size_t count, size_t *_numBytes, bool mayBlock, bool fsReenter) { - return -1; + return B_ERROR; }