* fs_{write|read}_pages() now has an additional argument "mayBlock".

* the page writer don't allow to block, while all other writers do. This fixes
  bug #1509. The reason the page writer needs this is because it marks several
  pages from different caches as busy.
* Fixed a warning about ASSERT being defined already in BFS, since
  util/DoublyLinkedList.h now includes debug.h.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22434 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-10-04 12:45:15 +00:00
parent 94b9294f48
commit 3e9513aa4a
18 changed files with 97 additions and 69 deletions
+2 -2
View File
@@ -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,
+8 -5
View File
@@ -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,
+6 -3
View File
@@ -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,
+4 -2
View File
@@ -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);
+8 -5
View File
@@ -1,6 +1,5 @@
/* Debug - debug stuff
*
* Copyright 2001-2006, Axel Dörfler, [email protected].
/*
* Copyright 2001-2007, Axel Dörfler, [email protected].
* 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
@@ -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;
}
@@ -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;
}
+3 -3
View File
@@ -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;
+14 -11
View File
@@ -6,12 +6,12 @@
#include "vnode_store.h"
#include <file_cache.h>
#include <vfs.h>
#include <stdlib.h>
#include <string.h>
#include <file_cache.h>
#include <vfs.h>
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);
}
+4 -2
View File
@@ -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;
+6 -4
View File
@@ -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;
}
+4 -2
View File
@@ -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;
}
+6 -6
View File
@@ -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);
}
+1 -1
View File
@@ -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);
+4 -4
View File
@@ -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);
@@ -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;
+4 -4
View File
@@ -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;
+5 -5
View File
@@ -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;
}