diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index 0e77164792..44b333fce0 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -1002,7 +1002,7 @@ BPlusTree::_SplitNode(bplustree_node *node, off_t nodeOffset, int32 keyIndex = *_keyIndex; // can become less than zero! if (keyIndex > node->NumKeys()) { - FATAL(("key index out of bounds: %d, num keys: %d\n", keyIndex, + FATAL(("key index out of bounds: %ld, num keys: %u\n", keyIndex, node->NumKeys())); return B_BAD_VALUE; } diff --git a/src/add-ons/kernel/file_systems/bfs/Lock.h b/src/add-ons/kernel/file_systems/bfs/Lock.h index ec5180c188..0b8730365f 100644 --- a/src/add-ons/kernel/file_systems/bfs/Lock.h +++ b/src/add-ons/kernel/file_systems/bfs/Lock.h @@ -16,7 +16,7 @@ // Configure here if and when real benaphores should be used -#define USE_BENAPHORE +//#define USE_BENAPHORE // if defined, benaphores are used for the Semaphore/RecursiveLock classes //# define FAST_LOCK // the ReadWriteLock class uses a second Semaphore to @@ -285,16 +285,16 @@ class ReadWriteLock { { if (atomic_add(&fCount, -1) <= 0) return acquire_sem(fSemaphore); - + return B_OK; } - + void Unlock() { if (atomic_add(&fCount, 1) < 0) release_sem(fSemaphore); } - + status_t LockWrite() { if (fWriteLock.Lock() < B_OK) @@ -313,7 +313,7 @@ class ReadWriteLock { return status; } - + void UnlockWrite() { int32 readers = atomic_add(&fCount, MAX_READERS); @@ -377,7 +377,18 @@ class ReadWriteLock { } return acquire_sem(fSemaphore); } - + + status_t TryLock() + { + // This allows nested locking when holding a write lock + thread_id currentThread = find_thread(NULL); + if (currentThread == fOwner) { + fOwnerCount++; + return B_OK; + } + return acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, 0); + } + void Unlock() { thread_id currentThread = find_thread(NULL); @@ -386,7 +397,7 @@ class ReadWriteLock { release_sem(fSemaphore); } - + status_t LockWrite() { thread_id currentThread = find_thread(NULL); @@ -401,7 +412,7 @@ class ReadWriteLock { } return status; } - + void UnlockWrite() { if (--fOwnerCount == 0) { 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 9efd0953ca..6c1da93bb9 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -225,11 +225,10 @@ bfs_sync(void *_ns) // #pragma mark - -/** Reads in the node from disk and creates an inode object from it. - */ - +/*! Reads in the node from disk and creates an inode object from it. +*/ static status_t -bfs_read_vnode(void *_ns, ino_t id, void **_node, bool reenter) +bfs_get_vnode(void *_ns, ino_t id, void **_node, bool reenter) { //FUNCTION_START(("ino_t = %Ld\n", id)); Volume *volume = (Volume *)_ns; @@ -271,11 +270,9 @@ bfs_read_vnode(void *_ns, ino_t id, void **_node, bool reenter) static status_t -bfs_release_vnode(void *_ns, void *_node, bool reenter) +bfs_put_vnode(void *_volume, void *_node, bool reenter) { - //FUNCTION_START(("node = %p\n", _node)); - - Volume *volume = (Volume *)_ns; + Volume *volume = (Volume *)_volume; Inode *inode = (Inode *)_node; // since a directory's size can be changed without having it opened, @@ -292,8 +289,7 @@ bfs_release_vnode(void *_ns, void *_node, bool reenter) } delete inode; - - return B_NO_ERROR; + return B_OK; } @@ -353,11 +349,13 @@ bfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, if (inode->FileCache() == NULL) RETURN_ERROR(B_BAD_VALUE); - if (!reenter) - inode->Lock().Lock(); + if (!reenter) { + if (inode->Lock().TryLock() < B_OK) + return B_BUSY; + } - status_t status = file_cache_read_pages(inode->FileCache(), pos, vecs, count, - _numBytes); + status_t status = file_cache_read_pages(inode->FileCache(), pos, vecs, + count, _numBytes); if (!reenter) inode->Lock().Unlock(); @@ -375,11 +373,13 @@ bfs_write_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, if (inode->FileCache() == NULL) RETURN_ERROR(B_BAD_VALUE); - if (!reenter) - inode->Lock().Lock(); + if (!reenter) { + if (inode->Lock().TryLock() < B_OK) + return B_BUSY; + } - status_t status = file_cache_write_pages(inode->FileCache(), pos, vecs, count, - _numBytes); + status_t status = file_cache_write_pages(inode->FileCache(), pos, vecs, + count, _numBytes); if (!reenter) inode->Lock().Unlock(); @@ -2161,8 +2161,8 @@ static file_system_module_info sBeFileSystem = { /* vnode operations */ &bfs_lookup, &bfs_get_vnode_name, - &bfs_read_vnode, - &bfs_release_vnode, + &bfs_get_vnode, + &bfs_put_vnode, &bfs_remove_vnode, /* VM file access */