* 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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user