* 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! int32 keyIndex = *_keyIndex; // can become less than zero!
if (keyIndex > node->NumKeys()) { 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())); node->NumKeys()));
return B_BAD_VALUE; return B_BAD_VALUE;
} }
+19 -8
View File
@@ -16,7 +16,7 @@
// Configure here if and when real benaphores should be used // 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 // if defined, benaphores are used for the Semaphore/RecursiveLock classes
//# define FAST_LOCK //# define FAST_LOCK
// the ReadWriteLock class uses a second Semaphore to // the ReadWriteLock class uses a second Semaphore to
@@ -285,16 +285,16 @@ class ReadWriteLock {
{ {
if (atomic_add(&fCount, -1) <= 0) if (atomic_add(&fCount, -1) <= 0)
return acquire_sem(fSemaphore); return acquire_sem(fSemaphore);
return B_OK; return B_OK;
} }
void Unlock() void Unlock()
{ {
if (atomic_add(&fCount, 1) < 0) if (atomic_add(&fCount, 1) < 0)
release_sem(fSemaphore); release_sem(fSemaphore);
} }
status_t LockWrite() status_t LockWrite()
{ {
if (fWriteLock.Lock() < B_OK) if (fWriteLock.Lock() < B_OK)
@@ -313,7 +313,7 @@ class ReadWriteLock {
return status; return status;
} }
void UnlockWrite() void UnlockWrite()
{ {
int32 readers = atomic_add(&fCount, MAX_READERS); int32 readers = atomic_add(&fCount, MAX_READERS);
@@ -377,7 +377,18 @@ class ReadWriteLock {
} }
return acquire_sem(fSemaphore); 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() void Unlock()
{ {
thread_id currentThread = find_thread(NULL); thread_id currentThread = find_thread(NULL);
@@ -386,7 +397,7 @@ class ReadWriteLock {
release_sem(fSemaphore); release_sem(fSemaphore);
} }
status_t LockWrite() status_t LockWrite()
{ {
thread_id currentThread = find_thread(NULL); thread_id currentThread = find_thread(NULL);
@@ -401,7 +412,7 @@ class ReadWriteLock {
} }
return status; return status;
} }
void UnlockWrite() void UnlockWrite()
{ {
if (--fOwnerCount == 0) { if (--fOwnerCount == 0) {
@@ -225,11 +225,10 @@ bfs_sync(void *_ns)
// #pragma mark - // #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 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)); //FUNCTION_START(("ino_t = %Ld\n", id));
Volume *volume = (Volume *)_ns; Volume *volume = (Volume *)_ns;
@@ -271,11 +270,9 @@ bfs_read_vnode(void *_ns, ino_t id, void **_node, bool reenter)
static status_t 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 *)_volume;
Volume *volume = (Volume *)_ns;
Inode *inode = (Inode *)_node; Inode *inode = (Inode *)_node;
// since a directory's size can be changed without having it opened, // 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; delete inode;
return B_OK;
return B_NO_ERROR;
} }
@@ -353,11 +349,13 @@ bfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos,
if (inode->FileCache() == NULL) if (inode->FileCache() == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
if (!reenter) if (!reenter) {
inode->Lock().Lock(); if (inode->Lock().TryLock() < B_OK)
return B_BUSY;
}
status_t status = file_cache_read_pages(inode->FileCache(), pos, vecs, count, status_t status = file_cache_read_pages(inode->FileCache(), pos, vecs,
_numBytes); count, _numBytes);
if (!reenter) if (!reenter)
inode->Lock().Unlock(); 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) if (inode->FileCache() == NULL)
RETURN_ERROR(B_BAD_VALUE); RETURN_ERROR(B_BAD_VALUE);
if (!reenter) if (!reenter) {
inode->Lock().Lock(); if (inode->Lock().TryLock() < B_OK)
return B_BUSY;
}
status_t status = file_cache_write_pages(inode->FileCache(), pos, vecs, count, status_t status = file_cache_write_pages(inode->FileCache(), pos, vecs,
_numBytes); count, _numBytes);
if (!reenter) if (!reenter)
inode->Lock().Unlock(); inode->Lock().Unlock();
@@ -2161,8 +2161,8 @@ static file_system_module_info sBeFileSystem = {
/* vnode operations */ /* vnode operations */
&bfs_lookup, &bfs_lookup,
&bfs_get_vnode_name, &bfs_get_vnode_name,
&bfs_read_vnode, &bfs_get_vnode,
&bfs_release_vnode, &bfs_put_vnode,
&bfs_remove_vnode, &bfs_remove_vnode,
/* VM file access */ /* VM file access */