* bfs_{read|write}_pages() now only try to lock - this fixes a possible

deadlock whenever someone without a lock (like the page_writer()) is calling
  this function.
* Added a new ReadWriteLock::TryLock() method.
* Renamed bfs_read_vnode() and bfs_release_vnode() to bfs_get_vnode() and
  bfs_put_vnode() just like those functions are called in fs_interface.h.
* Fixed a warning in BPlusTree::_SplitNode().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22372 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2007-09-29 14:06:04 +00:00
parent 5b06c4ae51
commit ab88b095f2
3 changed files with 40 additions and 29 deletions
@@ -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;
}
+19 -8
View File
@@ -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) {
@@ -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 */