* Made the private kernel locking primitives available to file systems as well.

* Applied Korli's mutex_unlock() fix to block_cache.cpp.
* Removed block_cache_priv.h, as it's no longer needed (moved its definitions
  into block_cache.cpp, as in the kernel file).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26296 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-07-07 15:19:19 +00:00
parent 36bf05cac9
commit 589f1a9133
13 changed files with 470 additions and 541 deletions
@@ -33,6 +33,7 @@
#include "fssh_fs_query.h"
#include "fssh_fs_volume.h"
#include "fssh_kernel_export.h"
#include "fssh_lock.h"
#include "fssh_module.h"
#include "fssh_node_monitor.h"
#include "fssh_os.h"
@@ -953,6 +954,46 @@
#define remove_debugger_command fssh_remove_debugger_command
////////////////////////////////////////////////////////////////////////////////
// #pragma mark - fssh_lock.h
#define mutex fssh_mutex
#define rw_lock fssh_rw_lock
#define recursive_lock fssh_recursive_lock
#define MUTEX_FLAG_CLONE_NAME FSSH_MUTEX_FLAG_CLONE_NAME
#define RW_LOCK_FLAG_CLONE_NAME FSSH_RW_LOCK_FLAG_CLONE_NAME
#define ASSERT_LOCKED_RECURSIVE(r) FSSH_ASSERT_LOCKED_RECURSIVE(r)
#define ASSERT_LOCKED_MUTEX(m) FSSH_ASSERT_LOCKED_MUTEX(m)
#define MUTEX_INITIALIZER(name) FSSH_MUTEX_INITIALIZER(name)
#define RECURSIVE_LOCK_INITIALIZER(name) FSSH_RECURSIVE_LOCK_INITIALIZER(name)
#define RW_LOCK_INITIALIZER(name) FSSH_RW_LOCK_INITIALIZER(name)
#define recursive_lock_init fssh_recursive_lock_init
#define recursive_lock_init_etc fssh_recursive_lock_init_etc
#define recursive_lock_destroy fssh_recursive_lock_destroy
#define recursive_lock_lock fssh_recursive_lock_lock
#define recursive_lock_unlock fssh_recursive_lock_unlock
#define recursive_lock_get_recursion fssh_recursive_lock_get_recursion
#define rw_lock_init fssh_rw_lock_init
#define rw_lock_init_etc fssh_rw_lock_init_etc
#define rw_lock_destroy fssh_rw_lock_destroy
#define rw_lock_read_lock fssh_rw_lock_read_lock
#define rw_lock_read_unlock fssh_rw_lock_read_unlock
#define rw_lock_write_lock fssh_rw_lock_write_lock
#define rw_lock_write_unlock fssh_rw_lock_write_unlock
#define mutex_init fssh_mutex_init
#define mutex_init_etc fssh_mutex_init_etc
#define mutex_destroy fssh_mutex_destroy
#define mutex_lock fssh_mutex_lock
#define mutex_trylock fssh_mutex_trylock
#define mutex_unlock fssh_mutex_unlock
////////////////////////////////////////////////////////////////////////////////
// #pragma mark - fssh_module.h
+125
View File
@@ -0,0 +1,125 @@
/*
* Copyright 2008, Ingo Weinhold, [email protected].
* Copyright 2002-2008, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _FSSH_KERNEL_LOCK_H
#define _FSSH_KERNEL_LOCK_H
#include <fssh_auto_locker.h>
#include <fssh_errors.h>
#include <fssh_os.h>
typedef struct fssh_mutex {
fssh_sem_id sem;
fssh_thread_id holder;
} fssh_mutex;
#define FSSH_MUTEX_FLAG_CLONE_NAME 0x1
typedef struct fssh_recursive_lock {
fssh_sem_id sem;
fssh_thread_id holder;
int recursion;
} fssh_recursive_lock;
typedef struct fssh_rw_lock {
fssh_sem_id sem;
int32_t count;
} fssh_rw_lock;
#define FSSH_RW_LOCK_FLAG_CLONE_NAME 0x1
#define FSSH_ASSERT_LOCKED_RECURSIVE(r)
#define FSSH_ASSERT_LOCKED_MUTEX(m)
// static initializers
#define FSSH_MUTEX_INITIALIZER(name) { name, NULL, 0, 0 }
#define FSSH_RECURSIVE_LOCK_INITIALIZER(name) { FSSH_MUTEX_INITIALIZER(name), -1, 0 }
#define FSSH_RW_LOCK_INITIALIZER(name) { name, NULL, -1, 0, 0, 0 }
#ifdef __cplusplus
extern "C" {
#endif
extern void fssh_recursive_lock_init(fssh_recursive_lock *lock, const char *name);
// name is *not* cloned nor freed in recursive_lock_destroy()
extern void fssh_recursive_lock_init_etc(fssh_recursive_lock *lock, const char *name,
uint32_t flags);
extern void fssh_recursive_lock_destroy(fssh_recursive_lock *lock);
extern fssh_status_t fssh_recursive_lock_lock(fssh_recursive_lock *lock);
extern void fssh_recursive_lock_unlock(fssh_recursive_lock *lock);
extern int32_t fssh_recursive_lock_get_recursion(fssh_recursive_lock *lock);
extern void fssh_rw_lock_init(fssh_rw_lock* lock, const char* name);
// name is *not* cloned nor freed in rw_lock_destroy()
extern void fssh_rw_lock_init_etc(fssh_rw_lock* lock, const char* name, uint32_t flags);
extern void fssh_rw_lock_destroy(fssh_rw_lock* lock);
extern fssh_status_t fssh_rw_lock_read_lock(fssh_rw_lock* lock);
extern fssh_status_t fssh_rw_lock_read_unlock(fssh_rw_lock* lock);
extern fssh_status_t fssh_rw_lock_write_lock(fssh_rw_lock* lock);
extern fssh_status_t fssh_rw_lock_write_unlock(fssh_rw_lock* lock);
extern void fssh_mutex_init(fssh_mutex* lock, const char* name);
// name is *not* cloned nor freed in mutex_destroy()
extern void fssh_mutex_init_etc(fssh_mutex* lock, const char* name, uint32_t flags);
extern void fssh_mutex_destroy(fssh_mutex* lock);
extern fssh_status_t fssh_mutex_lock(fssh_mutex* lock);
extern fssh_status_t fssh_mutex_trylock(fssh_mutex* lock);
extern void fssh_mutex_unlock(fssh_mutex* lock);
#ifdef __cplusplus
}
namespace FSShell {
// MutexLocking
class MutexLocking {
public:
inline bool Lock(fssh_mutex *lockable)
{
return fssh_mutex_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(fssh_mutex *lockable)
{
fssh_mutex_unlock(lockable);
}
};
// MutexLocker
typedef AutoLocker<fssh_mutex, MutexLocking> MutexLocker;
// RecursiveLockLocking
class RecursiveLockLocking {
public:
inline bool Lock(fssh_recursive_lock *lockable)
{
return fssh_recursive_lock_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(fssh_recursive_lock *lockable)
{
fssh_recursive_lock_unlock(lockable);
}
};
// RecursiveLocker
typedef AutoLocker<fssh_recursive_lock, RecursiveLockLocking> RecursiveLocker;
} // namespace FSShell
using FSShell::AutoLocker;
using FSShell::MutexLocker;
using FSShell::RecursiveLocker;
#endif // __cplusplus
#endif /* _FSSH_KERNEL_LOCK_H */
-1
View File
@@ -12,7 +12,6 @@
# include "hash.h"
# include "list.h"
# include "lock.h"
#else
# include <KernelExport.h>
# include <vfs.h>
+97 -27
View File
@@ -3,16 +3,15 @@
* Distributed under the terms of the MIT License.
*/
#include "block_cache_priv.h"
#include <new>
#include <stdlib.h>
#include "DoublyLinkedList.h"
#include "fssh_atomic.h"
#include "fssh_errno.h"
#include "fssh_fs_cache.h"
#include "fssh_kernel_export.h"
#include "fssh_lock.h"
#include "fssh_string.h"
#include "fssh_unistd.h"
#include "hash.h"
@@ -43,6 +42,78 @@ using std::nothrow;
namespace FSShell {
struct hash_table;
struct vm_page;
//#define DEBUG_CHANGED
#undef DEBUG_CHANGED
struct cache_transaction;
struct cached_block;
struct block_cache;
typedef DoublyLinkedListLink<cached_block> block_link;
struct cached_block {
cached_block *next; // next in hash
cached_block *transaction_next;
block_link link;
fssh_off_t block_number;
void *current_data;
void *original_data;
void *parent_data;
#ifdef DEBUG_CHANGED
void *compare;
#endif
int32_t ref_count;
int32_t accessed;
bool busy : 1;
bool is_writing : 1;
bool is_dirty : 1;
bool unused : 1;
bool unmapped : 1;
cache_transaction *transaction;
cache_transaction *previous_transaction;
static int Compare(void *_cacheEntry, const void *_block);
static uint32_t Hash(void *_cacheEntry, const void *_block, uint32_t range);
};
typedef DoublyLinkedList<cached_block,
DoublyLinkedListMemberGetLink<cached_block,
&cached_block::link> > block_list;
struct block_cache {
hash_table *hash;
fssh_mutex lock;
int fd;
fssh_off_t max_blocks;
fssh_size_t block_size;
int32_t allocated_block_count;
int32_t next_transaction_id;
cache_transaction *last_transaction;
hash_table *transaction_hash;
block_list unused_blocks;
bool read_only;
block_cache(int fd, fssh_off_t numBlocks, fssh_size_t blockSize, bool readOnly);
~block_cache();
fssh_status_t InitCheck();
void RemoveUnusedBlocks(int32_t maxAccessed = LONG_MAX, int32_t count = LONG_MAX);
void FreeBlock(cached_block *block);
cached_block *NewBlock(fssh_off_t blockNumber);
void Free(void *address);
void *Allocate();
static void LowMemoryHandler(void *data, int32_t level);
};
static const int32_t kMaxBlockCount = 1024;
struct cache_hook : DoublyLinkedListLinkImpl<cache_hook> {
@@ -200,14 +271,13 @@ block_cache::block_cache(int _fd, fssh_off_t numBlocks, fssh_size_t blockSize,
if (transaction_hash == NULL)
return;
if (benaphore_init(&lock, "block cache") < FSSH_B_OK)
return;
fssh_mutex_init(&lock, "block cache");
}
block_cache::~block_cache()
{
benaphore_destroy(&lock);
fssh_mutex_destroy(&lock);
hash_uninit(transaction_hash);
hash_uninit(hash);
@@ -627,7 +697,7 @@ int32_t
fssh_cache_start_transaction(void *_cache)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
if (cache->last_transaction && cache->last_transaction->open) {
fssh_panic("last transaction (%d) still open!\n",
@@ -653,7 +723,7 @@ fssh_status_t
fssh_cache_sync_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
fssh_status_t status = FSSH_B_ENTRY_NOT_FOUND;
TRACE(("cache_sync_transaction(id %d)\n", id));
@@ -690,7 +760,7 @@ fssh_cache_end_transaction(void *_cache, int32_t id,
fssh_transaction_notification_hook hook, void *data)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("cache_end_transaction(id = %d)\n", id));
@@ -744,7 +814,7 @@ fssh_status_t
fssh_cache_abort_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("cache_abort_transaction(id = %ld)\n", id));
@@ -794,7 +864,7 @@ fssh_cache_detach_sub_transaction(void *_cache, int32_t id,
fssh_transaction_notification_hook hook, void *data)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("cache_detach_sub_transaction(id = %d)\n", id));
@@ -878,7 +948,7 @@ fssh_status_t
fssh_cache_abort_sub_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("cache_abort_sub_transaction(id = %ld)\n", id));
@@ -929,7 +999,7 @@ fssh_status_t
fssh_cache_start_sub_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("cache_start_sub_transaction(id = %d)\n", id));
@@ -985,7 +1055,7 @@ fssh_cache_add_transaction_listener(void *_cache, int32_t id, int32_t events,
if (hook == NULL)
return FSSH_B_NO_MEMORY;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL) {
@@ -1008,7 +1078,7 @@ fssh_cache_remove_transaction_listener(void *_cache, int32_t id,
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL)
@@ -1036,7 +1106,7 @@ fssh_cache_next_block_in_transaction(void *_cache, int32_t id, bool mainOnly,
cached_block *block = (cached_block *)*_cookie;
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL || !transaction->open)
@@ -1072,7 +1142,7 @@ int32_t
fssh_cache_blocks_in_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL)
@@ -1086,7 +1156,7 @@ int32_t
fssh_cache_blocks_in_main_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL)
@@ -1100,7 +1170,7 @@ int32_t
fssh_cache_blocks_in_sub_transaction(void *_cache, int32_t id)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
cache_transaction *transaction = lookup_transaction(cache, id);
if (transaction == NULL)
@@ -1122,7 +1192,7 @@ fssh_block_cache_delete(void *_cache, bool allowWrites)
if (allowWrites)
fssh_block_cache_sync(cache);
BenaphoreLocker locker(&cache->lock);
fssh_mutex_lock(&cache->lock);
// free all blocks
@@ -1171,7 +1241,7 @@ fssh_block_cache_sync(void *_cache)
// we will sync all dirty blocks to disk that have a completed
// transaction or no transaction only
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
hash_iterator iterator;
hash_open(cache->hash, &iterator);
@@ -1205,7 +1275,7 @@ fssh_block_cache_sync_etc(void *_cache, fssh_off_t blockNumber,
return FSSH_B_BAD_VALUE;
}
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
for (; numBlocks > 0; numBlocks--, blockNumber++) {
cached_block *block = (cached_block *)hash_lookup(cache->hash,
@@ -1228,7 +1298,7 @@ fssh_status_t
fssh_block_cache_make_writable(void *_cache, fssh_off_t blockNumber, int32_t transaction)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
if (cache->read_only)
fssh_panic("tried to make block writable on a read-only cache!");
@@ -1250,7 +1320,7 @@ fssh_block_cache_get_writable_etc(void *_cache, fssh_off_t blockNumber, fssh_off
fssh_off_t length, int32_t transaction)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("block_cache_get_writable_etc(block = %Ld, transaction = %ld)\n",
blockNumber, transaction));
@@ -1276,7 +1346,7 @@ fssh_block_cache_get_empty(void *_cache, fssh_off_t blockNumber,
int32_t transaction)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
TRACE(("block_cache_get_empty(block = %Ld, transaction = %ld)\n",
blockNumber, transaction));
@@ -1293,7 +1363,7 @@ fssh_block_cache_get_etc(void *_cache, fssh_off_t blockNumber, fssh_off_t base,
fssh_off_t length)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
bool allocated;
cached_block *block = get_cached_block(cache, blockNumber, &allocated);
@@ -1341,7 +1411,7 @@ void
fssh_block_cache_put(void *_cache, fssh_off_t blockNumber)
{
block_cache *cache = (block_cache *)_cache;
BenaphoreLocker locker(&cache->lock);
MutexLocker locker(&cache->lock);
put_cached_block(cache, blockNumber);
}
-90
View File
@@ -1,90 +0,0 @@
/*
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FSSH_BLOCK_CACHE_PRIVATE_H
#define _FSSH_BLOCK_CACHE_PRIVATE_H
#include "DoublyLinkedList.h"
#include "lock.h"
namespace FSShell {
struct hash_table;
struct vm_page;
//#define DEBUG_CHANGED
#undef DEBUG_CHANGED
struct cache_transaction;
struct cached_block;
struct block_cache;
typedef DoublyLinkedListLink<cached_block> block_link;
struct cached_block {
cached_block *next; // next in hash
cached_block *transaction_next;
block_link link;
fssh_off_t block_number;
void *current_data;
void *original_data;
void *parent_data;
#ifdef DEBUG_CHANGED
void *compare;
#endif
int32_t ref_count;
int32_t accessed;
bool busy : 1;
bool is_writing : 1;
bool is_dirty : 1;
bool unused : 1;
bool unmapped : 1;
cache_transaction *transaction;
cache_transaction *previous_transaction;
static int Compare(void *_cacheEntry, const void *_block);
static uint32_t Hash(void *_cacheEntry, const void *_block, uint32_t range);
};
typedef DoublyLinkedList<cached_block,
DoublyLinkedListMemberGetLink<cached_block,
&cached_block::link> > block_list;
struct block_cache {
hash_table *hash;
benaphore lock;
int fd;
fssh_off_t max_blocks;
fssh_size_t block_size;
int32_t allocated_block_count;
int32_t next_transaction_id;
cache_transaction *last_transaction;
hash_table *transaction_hash;
block_list unused_blocks;
bool read_only;
block_cache(int fd, fssh_off_t numBlocks, fssh_size_t blockSize, bool readOnly);
~block_cache();
fssh_status_t InitCheck();
void RemoveUnusedBlocks(int32_t maxAccessed = LONG_MAX, int32_t count = LONG_MAX);
void FreeBlock(cached_block *block);
cached_block *NewBlock(fssh_off_t blockNumber);
void Free(void *address);
void *Allocate();
static void LowMemoryHandler(void *data, int32_t level);
};
} // namespace FSShell
#endif /* _FSSH_BLOCK_CACHE_PRIVATE_H */
+12 -14
View File
@@ -28,20 +28,17 @@
#include <stdlib.h>
#include "fssh_fcntl.h"
#include "fssh_lock.h"
#include "fssh_os.h"
#include "fssh_stat.h"
#include "fssh_string.h"
#include "fssh_unistd.h"
#include "list.h"
#include "lock.h"
using namespace FSShell;
#define ASSERT_LOCKED_MUTEX(lock)
#define SETTINGS_DIRECTORY "/kernel/drivers/"
#define SETTINGS_MAGIC 'DrvS'
@@ -72,7 +69,7 @@ enum assignment_mode {
static struct list sHandles;
static mutex sLock;
static fssh_mutex sLock;
// #pragma mark - private functions
@@ -587,7 +584,7 @@ find_driver_settings(const char *name)
{
settings_handle *handle = NULL;
ASSERT_LOCKED_MUTEX(&sLock);
FSSH_ASSERT_LOCKED_MUTEX(&sLock);
while ((handle = (settings_handle*)list_get_next_item(&sHandles, handle)) != NULL) {
if (!fssh_strcmp(handle->name, name))
@@ -603,10 +600,11 @@ namespace FSShell {
fssh_status_t
driver_settings_init()
{
return mutex_init(&sLock, "driver settings");
fssh_mutex_init(&sLock, "driver settings");
return FSSH_B_OK;
}
}
} // namespace FSShell
// #pragma mark - public API
@@ -619,13 +617,13 @@ fssh_unload_driver_settings(void *handle)
return FSSH_B_BAD_VALUE;
#if 0
mutex_lock(&sLock);
fssh_mutex_lock(&sLock);
// ToDo: as soon as "/boot" is accessible, we should start throwing away settings
if (--handle->ref_count == 0) {
list_remove_link(&handle->link);
} else
handle = NULL;
mutex_unlock(&sLock);
fssh_mutex_unlock(&sLock);
#endif
if (handle != NULL)
@@ -645,7 +643,7 @@ fssh_load_driver_settings(const char *driverName)
return NULL;
// see if we already have these settings loaded
mutex_lock(&sLock);
fssh_mutex_lock(&sLock);
handle = find_driver_settings(driverName);
if (handle != NULL) {
handle->ref_count++;
@@ -661,7 +659,7 @@ fssh_load_driver_settings(const char *driverName)
handle = NULL;
}
}
mutex_unlock(&sLock);
fssh_mutex_unlock(&sLock);
return handle;
}
@@ -683,7 +681,7 @@ fssh_load_driver_settings(const char *driverName)
file = fssh_open(driverName, FSSH_O_RDONLY);
if (file < FSSH_B_OK) {
mutex_unlock(&sLock);
fssh_mutex_unlock(&sLock);
return NULL;
}
@@ -691,7 +689,7 @@ fssh_load_driver_settings(const char *driverName)
if (handle != NULL)
list_add_item(&sHandles, handle);
mutex_unlock(&sLock);
fssh_mutex_unlock(&sLock);
fssh_close(file);
return (void *)handle;
+16 -14
View File
@@ -1,13 +1,15 @@
/* Operations on file descriptors
*
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de.
/*
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
//! Operations on file descriptors
#include "fd.h"
#include <stdlib.h>
#include "fssh_atomic.h"
#include "fssh_fcntl.h"
#include "fssh_kernel_export.h"
#include "fssh_kernel_priv.h"
@@ -96,7 +98,7 @@ new_fd_etc(struct io_context *context, struct file_descriptor *descriptor,
int fd = -1;
uint32_t i;
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
for (i = firstIndex; i < context->table_size; i++) {
if (!context->fds[i]) {
@@ -114,7 +116,7 @@ new_fd_etc(struct io_context *context, struct file_descriptor *descriptor,
fssh_atomic_add(&descriptor->open_count, 1);
err:
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
return fd;
}
@@ -215,7 +217,7 @@ get_fd(struct io_context *context, int fd)
if (fd < 0)
return NULL;
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
if ((uint32_t)fd < context->table_size)
descriptor = context->fds[fd];
@@ -228,7 +230,7 @@ get_fd(struct io_context *context, int fd)
inc_fd_ref_count(descriptor);
}
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
return descriptor;
}
@@ -245,7 +247,7 @@ remove_fd(struct io_context *context, int fd)
if (fd < 0)
return NULL;
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
if ((uint32_t)fd < context->table_size)
descriptor = context->fds[fd];
@@ -260,7 +262,7 @@ remove_fd(struct io_context *context, int fd)
descriptor = NULL;
}
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
return descriptor;
}
@@ -285,9 +287,9 @@ dup_fd(int fd, bool kernel)
if (status < 0)
put_fd(descriptor);
else {
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
fd_set_close_on_exec(context, status, false);
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
}
return status;
@@ -315,14 +317,14 @@ dup2_fd(int oldfd, int newfd, bool kernel)
// Get current I/O context and lock it
context = get_current_io_context(kernel);
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
// Check if the fds are valid (mutex must be locked because
// the table size could be changed)
if ((uint32_t)oldfd >= context->table_size
|| (uint32_t)newfd >= context->table_size
|| context->fds[oldfd] == NULL) {
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
return FSSH_B_FILE_ERROR;
}
@@ -342,7 +344,7 @@ dup2_fd(int oldfd, int newfd, bool kernel)
fd_set_close_on_exec(context, newfd, false);
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
// Say bye bye to the evicted fd
if (evicted) {
+12 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2007, Haiku Inc. All rights reserved.
* Copyright 2004-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@@ -15,12 +15,12 @@
#include "DoublyLinkedList.h"
#include "fssh_kernel_export.h"
#include "fssh_lock.h"
#include "fssh_stdio.h"
#include "fssh_string.h"
#include "fssh_uio.h"
#include "fssh_unistd.h"
#include "hash.h"
#include "lock.h"
#include "vfs.h"
@@ -61,7 +61,7 @@ typedef fssh_status_t (*cache_func)(file_cache_ref *ref, void *cookie,
fssh_size_t bufferSize);
struct file_cache_ref {
mutex lock;
fssh_mutex lock;
fssh_mount_id mountID;
fssh_vnode_id nodeID;
void* node;
@@ -87,12 +87,12 @@ read_from_file(file_cache_ref *ref, void *cookie, fssh_off_t offset,
vec.iov_base = (void *)buffer;
vec.iov_len = bufferSize;
mutex_unlock(&ref->lock);
fssh_mutex_unlock(&ref->lock);
fssh_status_t status = vfs_read_pages(ref->node, cookie,
offset + pageOffset, &vec, 1, &bufferSize, false);
mutex_lock(&ref->lock);
fssh_mutex_lock(&ref->lock);
return status;
}
@@ -106,12 +106,12 @@ write_to_file(file_cache_ref *ref, void *cookie, fssh_off_t offset,
vec.iov_base = (void *)buffer;
vec.iov_len = bufferSize;
mutex_unlock(&ref->lock);
fssh_mutex_unlock(&ref->lock);
fssh_status_t status = vfs_write_pages(ref->node, cookie,
offset + pageOffset, &vec, 1, &bufferSize, false);
mutex_lock(&ref->lock);
fssh_mutex_lock(&ref->lock);
return status;
}
@@ -258,13 +258,7 @@ fssh_file_cache_create(fssh_mount_id mountID, fssh_vnode_id vnodeID,
// create lock
char buffer[32];
fssh_snprintf(buffer, sizeof(buffer), "file cache %d:%lld", (int)mountID, vnodeID);
error = mutex_init(&ref->lock, buffer);
if (error != FSSH_B_OK) {
fssh_dprintf("file_cache_create(): Failed to init mutex: %s\n",
fssh_strerror(error));
delete ref;
return NULL;
}
fssh_mutex_init(&ref->lock, buffer);
return ref;
}
@@ -280,8 +274,8 @@ fssh_file_cache_delete(void *_cacheRef)
TRACE(("file_cache_delete(ref = %p)\n", ref));
mutex_lock(&ref->lock);
mutex_destroy(&ref->lock);
fssh_mutex_lock(&ref->lock);
fssh_mutex_destroy(&ref->lock);
delete ref;
}
@@ -297,9 +291,9 @@ fssh_file_cache_set_size(void *_cacheRef, fssh_off_t size)
if (ref == NULL)
return FSSH_B_OK;
mutex_lock(&ref->lock);
fssh_mutex_lock(&ref->lock);
ref->virtual_size = size;
mutex_unlock(&ref->lock);
fssh_mutex_unlock(&ref->lock);
return FSSH_B_OK;
}
+42 -77
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@@ -8,16 +8,16 @@
/* Mutex and recursive_lock code */
#include "lock.h"
#include "fssh_lock.h"
#include "fssh_kernel_export.h"
namespace FSShell {
#define FSSH_RW_MAX_READERS 100000
int32_t
recursive_lock_get_recursion(recursive_lock *lock)
extern "C" int32_t
fssh_recursive_lock_get_recursion(fssh_recursive_lock *lock)
{
if (lock->holder == fssh_find_thread(NULL))
return lock->recursion;
@@ -26,11 +26,11 @@ recursive_lock_get_recursion(recursive_lock *lock)
}
fssh_status_t
recursive_lock_init(recursive_lock *lock, const char *name)
extern "C" void
fssh_recursive_lock_init(fssh_recursive_lock *lock, const char *name)
{
if (lock == NULL)
return FSSH_B_BAD_VALUE;
return;
if (name == NULL)
name = "recursive lock";
@@ -38,16 +38,13 @@ recursive_lock_init(recursive_lock *lock, const char *name)
lock->holder = -1;
lock->recursion = 0;
lock->sem = fssh_create_sem(1, name);
if (lock->sem >= FSSH_B_OK)
return FSSH_B_OK;
return lock->sem;
if (lock->sem < FSSH_B_OK)
fssh_panic("could not create recursive lock");
}
void
recursive_lock_destroy(recursive_lock *lock)
extern "C" void
fssh_recursive_lock_destroy(fssh_recursive_lock *lock)
{
if (lock == NULL)
return;
@@ -57,8 +54,8 @@ recursive_lock_destroy(recursive_lock *lock)
}
fssh_status_t
recursive_lock_lock(recursive_lock *lock)
extern "C" fssh_status_t
fssh_recursive_lock_lock(fssh_recursive_lock *lock)
{
fssh_thread_id thread = fssh_find_thread(NULL);
@@ -74,8 +71,8 @@ recursive_lock_lock(recursive_lock *lock)
}
void
recursive_lock_unlock(recursive_lock *lock)
extern "C" void
fssh_recursive_lock_unlock(fssh_recursive_lock *lock)
{
if (fssh_find_thread(NULL) != lock->holder)
fssh_panic("recursive_lock %p unlocked by non-holder thread!\n", lock);
@@ -90,11 +87,11 @@ recursive_lock_unlock(recursive_lock *lock)
// #pragma mark -
fssh_status_t
mutex_init(mutex *m, const char *name)
extern "C" void
fssh_mutex_init(fssh_mutex *m, const char *name)
{
if (m == NULL)
return FSSH_EINVAL;
return;
if (name == NULL)
name = "mutex_sem";
@@ -102,15 +99,13 @@ mutex_init(mutex *m, const char *name)
m->holder = -1;
m->sem = fssh_create_sem(1, name);
if (m->sem >= FSSH_B_OK)
return FSSH_B_OK;
return m->sem;
if (m->sem < FSSH_B_OK)
fssh_panic("could not create mutex");
}
void
mutex_destroy(mutex *mutex)
extern "C" void
fssh_mutex_destroy(fssh_mutex *mutex)
{
if (mutex == NULL)
return;
@@ -123,8 +118,8 @@ mutex_destroy(mutex *mutex)
}
fssh_status_t
mutex_lock(mutex *mutex)
extern "C" fssh_status_t
fssh_mutex_lock(fssh_mutex *mutex)
{
fssh_thread_id me = fssh_find_thread(NULL);
fssh_status_t status;
@@ -141,8 +136,8 @@ mutex_lock(mutex *mutex)
}
void
mutex_unlock(mutex *mutex)
extern "C" void
fssh_mutex_unlock(fssh_mutex *mutex)
{
fssh_thread_id me = fssh_find_thread(NULL);
@@ -159,51 +154,23 @@ mutex_unlock(mutex *mutex)
// #pragma mark -
fssh_status_t
benaphore_init(benaphore *ben, const char *name)
{
if (ben == NULL || name == NULL)
return FSSH_B_BAD_VALUE;
ben->count = 1;
ben->sem = fssh_create_sem(0, name);
if (ben->sem >= FSSH_B_OK)
return FSSH_B_OK;
return ben->sem;
}
void
benaphore_destroy(benaphore *ben)
{
fssh_delete_sem(ben->sem);
ben->sem = -1;
}
// #pragma mark -
fssh_status_t
rw_lock_init(rw_lock *lock, const char *name)
extern "C" void
fssh_rw_lock_init(fssh_rw_lock *lock, const char *name)
{
if (lock == NULL)
return FSSH_B_BAD_VALUE;
return;
if (name == NULL)
name = "r/w lock";
lock->sem = fssh_create_sem(FSSH_RW_MAX_READERS, name);
if (lock->sem >= FSSH_B_OK)
return FSSH_B_OK;
return lock->sem;
if (lock->sem < FSSH_B_OK)
fssh_panic("could not create r/w lock");
}
void
rw_lock_destroy(rw_lock *lock)
extern "C" void
fssh_rw_lock_destroy(fssh_rw_lock *lock)
{
if (lock == NULL)
return;
@@ -212,32 +179,30 @@ rw_lock_destroy(rw_lock *lock)
}
fssh_status_t
rw_lock_read_lock(rw_lock *lock)
extern "C" fssh_status_t
fssh_rw_lock_read_lock(fssh_rw_lock *lock)
{
return fssh_acquire_sem(lock->sem);
}
fssh_status_t
rw_lock_read_unlock(rw_lock *lock)
extern "C" fssh_status_t
fssh_rw_lock_read_unlock(fssh_rw_lock *lock)
{
return fssh_release_sem(lock->sem);
}
fssh_status_t
rw_lock_write_lock(rw_lock *lock)
extern "C" fssh_status_t
fssh_rw_lock_write_lock(fssh_rw_lock *lock)
{
return fssh_acquire_sem_etc(lock->sem, FSSH_RW_MAX_READERS, 0, 0);
}
fssh_status_t
rw_lock_write_unlock(rw_lock *lock)
extern "C" fssh_status_t
fssh_rw_lock_write_unlock(fssh_rw_lock *lock)
{
return fssh_release_sem_etc(lock->sem, FSSH_RW_MAX_READERS, 0);
}
} // namespace FSShell
-160
View File
@@ -1,160 +0,0 @@
/*
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#ifndef _FSSH_LOCK_H
#define _FSSH_LOCK_H
#include "fssh_atomic.h"
#include "fssh_auto_locker.h"
#include "fssh_errors.h"
#include "fssh_os.h"
namespace FSShell {
typedef struct recursive_lock {
fssh_sem_id sem;
fssh_thread_id holder;
int recursion;
} recursive_lock;
typedef struct mutex {
fssh_sem_id sem;
fssh_thread_id holder;
} mutex;
typedef struct benaphore {
fssh_sem_id sem;
int32_t count;
} benaphore;
// Note: this is currently a trivial r/w lock implementation
// it will be replaced with something better later - this
// or a similar API will be made publically available at this point.
typedef struct rw_lock {
fssh_sem_id sem;
int32_t count;
benaphore writeLock;
} rw_lock;
#define FSSH_RW_MAX_READERS 1000000
extern fssh_status_t recursive_lock_init(recursive_lock *lock,
const char *name);
extern void recursive_lock_destroy(recursive_lock *lock);
extern fssh_status_t recursive_lock_lock(recursive_lock *lock);
extern void recursive_lock_unlock(recursive_lock *lock);
extern int32_t recursive_lock_get_recursion(recursive_lock *lock);
extern fssh_status_t mutex_init(mutex *m, const char *name);
extern void mutex_destroy(mutex *m);
extern fssh_status_t mutex_lock(mutex *m);
extern void mutex_unlock(mutex *m);
extern fssh_status_t benaphore_init(benaphore *ben,
const char *name);
extern void benaphore_destroy(benaphore *ben);
static inline fssh_status_t
benaphore_lock_etc(benaphore *ben, uint32_t flags, fssh_bigtime_t timeout)
{
if (fssh_atomic_add(&ben->count, -1) <= 0)
return fssh_acquire_sem_etc(ben->sem, 1, flags, timeout);
return FSSH_B_OK;
}
static inline fssh_status_t
benaphore_lock(benaphore *ben)
{
if (fssh_atomic_add(&ben->count, -1) <= 0)
return fssh_acquire_sem(ben->sem);
return FSSH_B_OK;
}
static inline fssh_status_t
benaphore_unlock(benaphore *ben)
{
if (fssh_atomic_add(&ben->count, 1) < 0)
return fssh_release_sem(ben->sem);
return FSSH_B_OK;
}
extern fssh_status_t rw_lock_init(rw_lock *lock, const char *name);
extern void rw_lock_destroy(rw_lock *lock);
extern fssh_status_t rw_lock_read_lock(rw_lock *lock);
extern fssh_status_t rw_lock_read_unlock(rw_lock *lock);
extern fssh_status_t rw_lock_write_lock(rw_lock *lock);
extern fssh_status_t rw_lock_write_unlock(rw_lock *lock);
/* C++ Auto Locking */
// MutexLocking
class MutexLocking {
public:
inline bool Lock(mutex *lockable)
{
return mutex_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(mutex *lockable)
{
mutex_unlock(lockable);
}
};
// MutexLocker
typedef AutoLocker<mutex, MutexLocking> MutexLocker;
// RecursiveLockLocking
class RecursiveLockLocking {
public:
inline bool Lock(recursive_lock *lockable)
{
return recursive_lock_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(recursive_lock *lockable)
{
recursive_lock_unlock(lockable);
}
};
// RecursiveLocker
typedef AutoLocker<recursive_lock, RecursiveLockLocking> RecursiveLocker;
// BenaphoreLocking
class BenaphoreLocking {
public:
inline bool Lock(benaphore *lockable)
{
return benaphore_lock(lockable) == FSSH_B_OK;
}
inline void Unlock(benaphore *lockable)
{
benaphore_unlock(lockable);
}
};
// BenaphoreLocker
typedef AutoLocker<benaphore, BenaphoreLocking> BenaphoreLocker;
} // namespace FSShell
using FSShell::MutexLocker;
using FSShell::RecursiveLocker;
using FSShell::BenaphoreLocker;
#endif /* _FSSH_LOCK_H */
+12 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007, Haiku Inc. All rights reserved.
* Copyright 2002-2008, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001, Thomas Kurschel. All rights reserved.
@@ -14,10 +14,10 @@
#include "fssh_errors.h"
#include "fssh_kernel_export.h"
#include "fssh_lock.h"
#include "fssh_module.h"
#include "fssh_string.h"
#include "hash.h"
#include "lock.h"
//#define TRACE_MODULE
@@ -67,7 +67,7 @@ struct module {
* they have to wait for each other, i.e. we need one lock per module;
* also we must detect circular references during init and not dead-lock
*/
static recursive_lock sModulesLock;
static fssh_recursive_lock sModulesLock;
/* we store the loaded modules by directory path, and all known modules by module name
* in a hash table for quick access
@@ -167,9 +167,9 @@ create_module(fssh_module_info *info, const char *file, int offset, module **_mo
module->ref_count = 0;
module->flags = info->flags;
recursive_lock_lock(&sModulesLock);
fssh_recursive_lock_lock(&sModulesLock);
hash_insert(sModulesHash, module);
recursive_lock_unlock(&sModulesLock);
fssh_recursive_lock_unlock(&sModulesLock);
if (_module)
*_module = module;
@@ -317,8 +317,7 @@ dump_modules(int argc, char **argv)
fssh_status_t
module_init(kernel_args *args)
{
if (recursive_lock_init(&sModulesLock, "modules rlock") < FSSH_B_OK)
return FSSH_B_ERROR;
fssh_recursive_lock_init(&sModulesLock, "modules rlock");
sModulesHash = hash_init(MODULE_HASH_SIZE, 0, module_compare, module_hash);
if (sModulesHash == NULL)
@@ -351,7 +350,7 @@ fssh_get_module(const char *path, fssh_module_info **_info)
if (path == NULL)
return FSSH_B_BAD_VALUE;
recursive_lock_lock(&sModulesLock);
fssh_recursive_lock_lock(&sModulesLock);
module = (struct module *)hash_lookup(sModulesHash, path);
if (module == NULL)
@@ -369,11 +368,11 @@ fssh_get_module(const char *path, fssh_module_info **_info)
*_info = module->info;
}
recursive_lock_unlock(&sModulesLock);
fssh_recursive_lock_unlock(&sModulesLock);
return status;
err:
recursive_lock_unlock(&sModulesLock);
fssh_recursive_lock_unlock(&sModulesLock);
return FSSH_B_ENTRY_NOT_FOUND;
}
@@ -385,12 +384,12 @@ fssh_put_module(const char *path)
TRACE(("put_module(path = %s)\n", path));
recursive_lock_lock(&sModulesLock);
fssh_recursive_lock_lock(&sModulesLock);
module = (struct module *)hash_lookup(sModulesHash, path);
if (module == NULL) {
FATAL(("module: We don't seem to have a reference to module %s\n", path));
recursive_lock_unlock(&sModulesLock);
fssh_recursive_lock_unlock(&sModulesLock);
return FSSH_B_BAD_VALUE;
}
@@ -401,6 +400,6 @@ fssh_put_module(const char *path)
uninit_module(module);
}
recursive_lock_unlock(&sModulesLock);
fssh_recursive_lock_unlock(&sModulesLock);
return FSSH_B_OK;
}
+110 -124
View File
@@ -114,7 +114,7 @@ struct fs_mount {
void *cookie;
char *device_name;
char *fs_name;
recursive_lock rlock; // guards the vnodes list
fssh_recursive_lock rlock; // guards the vnodes list
struct vnode *root_vnode;
struct vnode *covers_vnode;
struct list vnodes;
@@ -122,7 +122,7 @@ struct fs_mount {
bool owns_file_device;
};
static mutex sFileSystemsMutex;
static fssh_mutex sFileSystemsMutex;
/** \brief Guards sMountsTable.
*
@@ -130,7 +130,7 @@ static mutex sFileSystemsMutex;
* Manipulation of the fs_mount structures themselves
* (and their destruction) requires different locks though.
*/
static mutex sMountMutex;
static fssh_mutex sMountMutex;
/** \brief Guards mount/unmount operations.
*
@@ -145,7 +145,7 @@ static mutex sMountMutex;
* The thread trying to lock the lock must not hold sVnodeMutex or
* sMountMutex.
*/
static recursive_lock sMountOpLock;
static fssh_recursive_lock sMountOpLock;
/** \brief Guards the vnode::covered_by field of any vnode
*
@@ -154,7 +154,7 @@ static recursive_lock sMountOpLock;
*
* The thread trying to lock the must not hold sVnodeMutex.
*/
static mutex sVnodeCoveredByMutex;
static fssh_mutex sVnodeCoveredByMutex;
/** \brief Guards sVnodeTable.
*
@@ -168,7 +168,7 @@ static mutex sVnodeCoveredByMutex;
* You must not have this mutex held when calling create_sem(), as this
* might call vfs_free_unused_vnodes().
*/
static mutex sVnodeMutex;
static fssh_mutex sVnodeMutex;
#define VNODE_HASH_TABLE_SIZE 1024
static hash_table *sVnodeTable;
@@ -443,7 +443,7 @@ get_mount(fssh_mount_id id, struct fs_mount **_mount)
struct fs_mount *mount;
fssh_status_t status;
mutex_lock(&sMountMutex);
fssh_mutex_lock(&sMountMutex);
mount = find_mount(id);
if (mount) {
@@ -459,7 +459,7 @@ get_mount(fssh_mount_id id, struct fs_mount **_mount)
} else
status = FSSH_B_BAD_VALUE;
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
if (mount == NULL)
return FSSH_B_BUSY;
@@ -577,23 +577,23 @@ vnode_hash(void *_vnode, const void *_key, uint32_t range)
static void
add_vnode_to_mount_list(struct vnode *vnode, struct fs_mount *mount)
{
recursive_lock_lock(&mount->rlock);
fssh_recursive_lock_lock(&mount->rlock);
list_add_link_to_head(&mount->vnodes, &vnode->mount_link);
recursive_lock_unlock(&mount->rlock);
fssh_recursive_lock_unlock(&mount->rlock);
}
static void
remove_vnode_from_mount_list(struct vnode *vnode, struct fs_mount *mount)
{
recursive_lock_lock(&mount->rlock);
fssh_recursive_lock_lock(&mount->rlock);
list_remove_link(&vnode->mount_link);
vnode->mount_link.next = vnode->mount_link.prev = NULL;
recursive_lock_unlock(&mount->rlock);
fssh_recursive_lock_unlock(&mount->rlock);
}
@@ -612,10 +612,10 @@ create_new_vnode(struct vnode **_vnode, fssh_mount_id mountID, fssh_vnode_id vno
vnode->id = vnodeID;
// add the vnode to the mount structure
mutex_lock(&sMountMutex);
fssh_mutex_lock(&sMountMutex);
vnode->mount = find_mount(mountID);
if (!vnode->mount || vnode->mount->unmounting) {
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
free(vnode);
return FSSH_B_ENTRY_NOT_FOUND;
}
@@ -623,7 +623,7 @@ create_new_vnode(struct vnode **_vnode, fssh_mount_id mountID, fssh_vnode_id vno
hash_insert(sVnodeTable, vnode);
add_vnode_to_mount_list(vnode, vnode->mount);
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
vnode->ref_count = 1;
*_vnode = vnode;
@@ -658,9 +658,9 @@ free_vnode(struct vnode *vnode, bool reenter)
// The file system has removed the resources of the vnode now, so we can
// make it available again (and remove the busy vnode from the hash)
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
hash_remove(sVnodeTable, vnode);
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
remove_vnode_from_mount_list(vnode, vnode->mount);
@@ -684,7 +684,7 @@ free_vnode(struct vnode *vnode, bool reenter)
static fssh_status_t
dec_vnode_ref_count(struct vnode *vnode, bool reenter)
{
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
int32_t oldRefCount = fssh_atomic_add(&vnode->ref_count, -1);
@@ -713,12 +713,12 @@ dec_vnode_ref_count(struct vnode *vnode, bool reenter)
}
}
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (freeNode)
free_vnode(vnode, reenter);
} else
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_OK;
}
@@ -783,21 +783,21 @@ get_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID, struct vnode **_vnode, i
{
FUNCTION(("get_vnode: mountid %ld vnid 0x%Lx %p\n", mountID, vnodeID, _vnode));
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
int32_t tries = 300;
// try for 3 secs
restart:
struct vnode *vnode = lookup_vnode(mountID, vnodeID);
if (vnode && vnode->busy) {
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (--tries < 0) {
// vnode doesn't seem to become unbusy
fssh_panic("vnode %d:%lld is not becoming unbusy!\n", (int)mountID, vnodeID);
return FSSH_B_BUSY;
}
fssh_snooze(10000); // 10 ms
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
goto restart;
}
@@ -819,7 +819,7 @@ restart:
goto err;
vnode->busy = true;
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
int type;
uint32_t flags;
@@ -828,7 +828,7 @@ restart:
if (status == FSSH_B_OK && vnode->private_node == NULL)
status = FSSH_B_BAD_VALUE;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
if (status < FSSH_B_OK)
goto err1;
@@ -837,7 +837,7 @@ restart:
vnode->busy = false;
}
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
TRACE(("get_vnode: returning %p\n", vnode));
@@ -848,7 +848,7 @@ err1:
hash_remove(sVnodeTable, vnode);
remove_vnode_from_mount_list(vnode, vnode->mount);
err:
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (vnode)
free(vnode);
@@ -912,12 +912,12 @@ resolve_mount_point_to_volume_root(struct vnode *vnode)
struct vnode *volumeRoot = NULL;
mutex_lock(&sVnodeCoveredByMutex);
fssh_mutex_lock(&sVnodeCoveredByMutex);
if (vnode->covered_by) {
volumeRoot = vnode->covered_by;
inc_vnode_ref_count(volumeRoot);
}
mutex_unlock(&sVnodeCoveredByMutex);
fssh_mutex_unlock(&sVnodeCoveredByMutex);
return volumeRoot;
}
@@ -1075,9 +1075,9 @@ lookup_dir_entry(struct vnode* dir, const char* name, struct vnode** _vnode)
if (status < FSSH_B_OK)
return status;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
*_vnode = lookup_vnode(dir->device, id);
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (*_vnode == NULL) {
fssh_panic("lookup_dir_entry(): could not lookup vnode (mountid 0x%x vnid "
@@ -1272,11 +1272,11 @@ path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode,
} else {
struct io_context *context = get_current_io_context(kernel);
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
start = context->cwd;
if (start != NULL)
inc_vnode_ref_count(start);
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
if (start == NULL)
return FSSH_B_ERROR;
@@ -1896,7 +1896,7 @@ fssh_new_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID,
if (privateNode == NULL)
return FSSH_B_BAD_VALUE;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
// file system integrity check:
// test if the vnode already exists and bail out if this is the case!
@@ -1920,7 +1920,7 @@ fssh_new_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID,
TRACE(("returns: %s\n", strerror(status)));
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
return status;
}
@@ -2022,9 +2022,9 @@ fssh_put_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID)
{
struct vnode *vnode;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
vnode = lookup_vnode(volume->id, vnodeID);
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (vnode)
dec_vnode_ref_count(vnode, true);
@@ -2047,7 +2047,7 @@ fssh_remove_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID)
if (vnode->covered_by != NULL) {
// this vnode is in use
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_BUSY;
}
@@ -2075,13 +2075,13 @@ fssh_unremove_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID)
{
struct vnode *vnode;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
vnode = lookup_vnode(volume->id, vnodeID);
if (vnode)
vnode->remove = false;
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_OK;
}
@@ -2089,7 +2089,7 @@ fssh_unremove_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID)
extern "C" fssh_status_t
fssh_get_vnode_removed(fssh_fs_volume *volume, fssh_vnode_id vnodeID, bool* removed)
{
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
fssh_status_t result;
@@ -2100,7 +2100,7 @@ fssh_get_vnode_removed(fssh_fs_volume *volume, fssh_vnode_id vnodeID, bool* remo
} else
result = FSSH_B_BAD_VALUE;
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
return result;
}
@@ -2347,9 +2347,9 @@ vfs_fs_vnode_to_node_ref(void *_vnode, fssh_mount_id *_mountID,
fssh_status_t
vfs_lookup_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID, void **_vnode)
{
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
struct vnode *vnode = lookup_vnode(mountID, vnodeID);
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (vnode == NULL)
return FSSH_B_ERROR;
@@ -2591,7 +2591,7 @@ vfs_get_cwd(fssh_mount_id *_mountID, fssh_vnode_id *_vnodeID)
struct io_context *context = get_current_io_context(false);
fssh_status_t status = FSSH_B_OK;
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
if (context->cwd != NULL) {
*_mountID = context->cwd->device;
@@ -2599,7 +2599,7 @@ vfs_get_cwd(fssh_mount_id *_mountID, fssh_vnode_id *_vnodeID)
} else
status = FSSH_B_ERROR;
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
return status;
}
@@ -2707,7 +2707,7 @@ vfs_exec_io_context(void *_context)
uint32_t i;
for (i = 0; i < context->table_size; i++) {
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
struct file_descriptor *descriptor = context->fds[i];
bool remove = false;
@@ -2719,7 +2719,7 @@ vfs_exec_io_context(void *_context)
remove = true;
}
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
if (remove) {
close_fd(descriptor);
@@ -2764,18 +2764,14 @@ vfs_new_io_context(void *_parentContext)
+ (tableSize + 7) / 8);
context->fds_close_on_exec = (uint8_t *)(context->fds + tableSize);
if (mutex_init(&context->io_mutex, "I/O context") < 0) {
free(context->fds);
free(context);
return NULL;
}
fssh_mutex_init(&context->io_mutex, "I/O context");
// Copy all parent files which don't have the FSSH_O_CLOEXEC flag set
if (parentContext) {
fssh_size_t i;
mutex_lock(&parentContext->io_mutex);
fssh_mutex_lock(&parentContext->io_mutex);
context->cwd = parentContext->cwd;
if (context->cwd)
@@ -2792,7 +2788,7 @@ vfs_new_io_context(void *_parentContext)
}
}
mutex_unlock(&parentContext->io_mutex);
fssh_mutex_unlock(&parentContext->io_mutex);
} else {
context->cwd = sRoot;
@@ -2815,7 +2811,7 @@ vfs_free_io_context(void *_ioContext)
if (context->cwd)
dec_vnode_ref_count(context->cwd, false);
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
for (i = 0; i < context->table_size; i++) {
if (struct file_descriptor *descriptor = context->fds[i]) {
@@ -2824,7 +2820,7 @@ vfs_free_io_context(void *_ioContext)
}
}
mutex_destroy(&context->io_mutex);
fssh_mutex_destroy(&context->io_mutex);
free(context->fds);
free(context);
@@ -2850,20 +2846,11 @@ vfs_init(kernel_args *args)
sRoot = NULL;
if (mutex_init(&sFileSystemsMutex, "vfs_lock") < 0)
fssh_panic("vfs_init: error allocating file systems lock\n");
if (recursive_lock_init(&sMountOpLock, "vfs_mount_op_lock") < 0)
fssh_panic("vfs_init: error allocating mount op lock\n");
if (mutex_init(&sMountMutex, "vfs_mount_lock") < 0)
fssh_panic("vfs_init: error allocating mount lock\n");
if (mutex_init(&sVnodeCoveredByMutex, "vfs_vnode_covered_by_lock") < 0)
fssh_panic("vfs_init: error allocating vnode::covered_by lock\n");
if (mutex_init(&sVnodeMutex, "vfs_vnode_lock") < 0)
fssh_panic("vfs_init: error allocating vnode lock\n");
fssh_mutex_init(&sFileSystemsMutex, "vfs_lock");
fssh_recursive_lock_init(&sMountOpLock, "vfs_mount_op_lock");
fssh_mutex_init(&sMountMutex, "vfs_mount_lock");
fssh_mutex_init(&sVnodeCoveredByMutex, "vfs_vnode_covered_by_lock");
fssh_mutex_init(&sVnodeMutex, "vfs_vnode_lock");
if (block_cache_init() != FSSH_B_OK)
return FSSH_B_ERROR;
@@ -2895,9 +2882,9 @@ create_vnode(struct vnode *directory, const char *name, int openMode, int perms,
if (status < FSSH_B_OK)
return status;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
vnode = lookup_vnode(directory->device, newID);
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
if (vnode == NULL) {
fssh_dprintf("vfs: fs_create() returned success but there is no vnode!");
@@ -3349,12 +3336,12 @@ fix_dirent(struct vnode *parent, struct fssh_dirent *entry)
if (status != FSSH_B_OK)
return;
mutex_lock(&sVnodeCoveredByMutex);
fssh_mutex_lock(&sVnodeCoveredByMutex);
if (vnode->covered_by) {
entry->d_dev = vnode->covered_by->device;
entry->d_ino = vnode->covered_by->id;
}
mutex_unlock(&sVnodeCoveredByMutex);
fssh_mutex_unlock(&sVnodeCoveredByMutex);
put_vnode(vnode);
}
@@ -3473,9 +3460,9 @@ common_fcntl(int fd, int op, uint32_t argument, bool kernel)
// Set file descriptor flags
// FSSH_O_CLOEXEC is the only flag available at this time
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
fd_set_close_on_exec(context, fd, argument == FSSH_FD_CLOEXEC);
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
status = FSSH_B_OK;
break;
@@ -3486,9 +3473,9 @@ common_fcntl(int fd, int op, uint32_t argument, bool kernel)
struct io_context *context = get_current_io_context(kernel);
// Get file descriptor flags
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
status = fd_close_on_exec(context, fd) ? FSSH_FD_CLOEXEC : 0;
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
break;
}
@@ -3519,9 +3506,9 @@ common_fcntl(int fd, int op, uint32_t argument, bool kernel)
status = new_fd_etc(context, descriptor, (int)argument);
if (status >= 0) {
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
fd_set_close_on_exec(context, fd, false);
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
fssh_atomic_add(&descriptor->ref_count, 1);
}
@@ -4538,9 +4525,7 @@ fs_mount(char *path, const char *device, const char *fsName, uint32_t flags,
goto err3;
}
status = recursive_lock_init(&mount->rlock, "mount rlock");
if (status < FSSH_B_OK)
goto err4;
fssh_recursive_lock_init(&mount->rlock, "mount rlock");
// initialize structure
mount->id = sNextMountID++;
@@ -4558,9 +4543,9 @@ fs_mount(char *path, const char *device, const char *fsName, uint32_t flags,
// insert mount struct into list before we call FS's mount() function
// so that vnodes can be created for this mount
mutex_lock(&sMountMutex);
fssh_mutex_lock(&sMountMutex);
hash_insert(sMountsTable, mount);
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
fssh_vnode_id rootID;
@@ -4568,36 +4553,36 @@ fs_mount(char *path, const char *device, const char *fsName, uint32_t flags,
// we haven't mounted anything yet
if (fssh_strcmp(path, "/") != 0) {
status = FSSH_B_ERROR;
goto err5;
goto err4;
}
status = mount->fs->mount(mount->volume, device, flags, args, &rootID);
if (status < 0) {
// ToDo: why should we hide the error code from the file system here?
//status = ERR_VFS_GENERAL;
goto err5;
goto err4;
}
} else {
struct vnode *coveredVnode;
status = path_to_vnode(path, true, &coveredVnode, NULL, kernel);
if (status < FSSH_B_OK)
goto err5;
goto err4;
// make sure covered_vnode is a DIR
struct fssh_stat coveredNodeStat;
status = FS_CALL(coveredVnode, read_stat, &coveredNodeStat);
if (status < FSSH_B_OK)
goto err5;
goto err4;
if (!FSSH_S_ISDIR(coveredNodeStat.fssh_st_mode)) {
status = FSSH_B_NOT_A_DIRECTORY;
goto err5;
goto err4;
}
if (coveredVnode->mount->root_vnode == coveredVnode) {
// this is already a mount point
status = FSSH_B_BUSY;
goto err5;
goto err4;
}
mount->covers_vnode = coveredVnode;
@@ -4605,7 +4590,7 @@ fs_mount(char *path, const char *device, const char *fsName, uint32_t flags,
// mount it
status = mount->fs->mount(mount->volume, device, flags, args, &rootID);
if (status < FSSH_B_OK)
goto err6;
goto err5;
}
// the root node is supposed to be owned by the file system - it must
@@ -4614,33 +4599,34 @@ fs_mount(char *path, const char *device, const char *fsName, uint32_t flags,
if (mount->root_vnode == NULL || mount->root_vnode->ref_count != 1) {
fssh_panic("fs_mount: file system does not own its root node!\n");
status = FSSH_B_ERROR;
goto err7;
goto err6;
}
// No race here, since fs_mount() is the only function changing
// covers_vnode (and holds sMountOpLock at that time).
mutex_lock(&sVnodeCoveredByMutex);
fssh_mutex_lock(&sVnodeCoveredByMutex);
if (mount->covers_vnode)
mount->covers_vnode->covered_by = mount->root_vnode;
mutex_unlock(&sVnodeCoveredByMutex);
fssh_mutex_unlock(&sVnodeCoveredByMutex);
if (!sRoot)
sRoot = mount->root_vnode;
return mount->id;
err7:
FS_MOUNT_CALL_NO_PARAMS(mount, unmount);
err6:
FS_MOUNT_CALL_NO_PARAMS(mount, unmount);
err5:
if (mount->covers_vnode)
put_vnode(mount->covers_vnode);
err5:
mutex_lock(&sMountMutex);
hash_remove(sMountsTable, mount);
mutex_unlock(&sMountMutex);
recursive_lock_destroy(&mount->rlock);
err4:
fssh_mutex_lock(&sMountMutex);
hash_remove(sMountsTable, mount);
fssh_mutex_unlock(&sMountMutex);
fssh_recursive_lock_destroy(&mount->rlock);
put_file_system(mount->fs);
free(mount->device_name);
err3:
@@ -4680,7 +4666,7 @@ fs_unmount(char *path, uint32_t flags, bool kernel)
// grab the vnode master mutex to keep someone from creating
// a vnode while we're figuring out if we can continue
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
bool disconnectedDescriptors = false;
@@ -4707,7 +4693,7 @@ fs_unmount(char *path, uint32_t flags, bool kernel)
break;
if ((flags & FSSH_B_FORCE_UNMOUNT) == 0) {
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
put_vnode(mount->root_vnode);
return FSSH_B_BUSY;
@@ -4715,11 +4701,11 @@ fs_unmount(char *path, uint32_t flags, bool kernel)
if (disconnectedDescriptors) {
// wait a bit until the last access is finished, and then try again
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
fssh_snooze(100000);
// TODO: if there is some kind of bug that prevents the ref counts
// from getting back to zero, this will fall into an endless loop...
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
continue;
}
@@ -4729,12 +4715,12 @@ fs_unmount(char *path, uint32_t flags, bool kernel)
mount->unmounting = true;
// prevent new vnodes from being created
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
disconnect_mount_or_vnode_fds(mount, NULL);
disconnectedDescriptors = true;
mutex_lock(&sVnodeMutex);
fssh_mutex_lock(&sVnodeMutex);
}
// we can safely continue, mark all of the vnodes busy and this mount
@@ -4754,11 +4740,11 @@ fs_unmount(char *path, uint32_t flags, bool kernel)
// The ref_count of the root node is 2 at this point, see above why this is
mount->root_vnode->ref_count -= 2;
mutex_unlock(&sVnodeMutex);
fssh_mutex_unlock(&sVnodeMutex);
mutex_lock(&sVnodeCoveredByMutex);
fssh_mutex_lock(&sVnodeCoveredByMutex);
mount->covers_vnode->covered_by = NULL;
mutex_unlock(&sVnodeCoveredByMutex);
fssh_mutex_unlock(&sVnodeCoveredByMutex);
put_vnode(mount->covers_vnode);
// Free all vnodes associated with this mount.
@@ -4769,9 +4755,9 @@ fs_unmount(char *path, uint32_t flags, bool kernel)
}
// remove the mount structure from the hash table
mutex_lock(&sMountMutex);
fssh_mutex_lock(&sMountMutex);
hash_remove(sMountsTable, mount);
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
mountOpLocker.Unlock();
@@ -4796,17 +4782,17 @@ fs_sync(fssh_dev_t device)
if (status < FSSH_B_OK)
return status;
mutex_lock(&sMountMutex);
fssh_mutex_lock(&sMountMutex);
if (HAS_FS_MOUNT_CALL(mount, sync))
status = FS_MOUNT_CALL_NO_PARAMS(mount, sync);
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
struct vnode *previousVnode = NULL;
while (true) {
// synchronize access to vnode list
recursive_lock_lock(&mount->rlock);
fssh_recursive_lock_lock(&mount->rlock);
struct vnode *vnode = (struct vnode *)list_get_next_item(&mount->vnodes,
previousVnode);
@@ -4815,7 +4801,7 @@ fs_sync(fssh_dev_t device)
if (vnode != NULL)
id = vnode->id;
recursive_lock_unlock(&mount->rlock);
fssh_recursive_lock_unlock(&mount->rlock);
if (vnode == NULL)
break;
@@ -4902,7 +4888,7 @@ fs_next_device(int32_t *_cookie)
struct fs_mount *mount = NULL;
fssh_dev_t device = *_cookie;
mutex_lock(&sMountMutex);
fssh_mutex_lock(&sMountMutex);
// Since device IDs are assigned sequentially, this algorithm
// does work good enough. It makes sure that the device list
@@ -4922,7 +4908,7 @@ fs_next_device(int32_t *_cookie)
else
device = FSSH_B_BAD_VALUE;
mutex_unlock(&sMountMutex);
fssh_mutex_unlock(&sMountMutex);
return device;
}
@@ -4937,14 +4923,14 @@ get_cwd(char *buffer, fssh_size_t size, bool kernel)
FUNCTION(("vfs_get_cwd: buf %p, size %ld\n", buffer, size));
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
if (context->cwd)
status = dir_vnode_to_path(context->cwd, buffer, size);
else
status = FSSH_B_ERROR;
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
return status;
}
@@ -4977,13 +4963,13 @@ set_cwd(int fd, char *path, bool kernel)
// Get current io context and lock
context = get_current_io_context(kernel);
mutex_lock(&context->io_mutex);
fssh_mutex_lock(&context->io_mutex);
// save the old current working directory first
oldDirectory = context->cwd;
context->cwd = vnode;
mutex_unlock(&context->io_mutex);
fssh_mutex_unlock(&context->io_mutex);
if (oldDirectory)
put_vnode(oldDirectory);
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@@ -10,8 +10,8 @@
#include "fssh_fs_interface.h"
#include "fssh_lock.h"
#include "list.h"
#include "lock.h"
namespace FSShell {
@@ -31,7 +31,7 @@ struct file_descriptor;
/** The I/O context of a process/team, holds the fd array among others */
typedef struct io_context {
struct vnode *cwd;
mutex io_mutex;
fssh_mutex io_mutex;
uint32_t table_size;
uint32_t num_used_fds;
struct file_descriptor **fds;