/trunk/uspace/srv/vfs/vfs.c |
---|
43,9 → 43,7 |
#include <bool.h> |
#include <string.h> |
#include <as.h> |
#include <adt/list.h> |
#include <atomic.h> |
#include <assert.h> |
#include "vfs.h" |
#define NAME "vfs" |
141,11 → 139,6 |
printf(NAME ": HelenOS VFS server\n"); |
/* |
* Initialize the list of registered file systems. |
*/ |
list_initialize(&fs_head); |
/* |
* Initialize VFS node hash table. |
*/ |
if (!vfs_nodes_init()) { |
156,7 → 149,6 |
/* |
* Allocate and initialize the Path Lookup Buffer. |
*/ |
list_initialize(&plb_head); |
plb = as_get_mappable_page(PLB_SIZE); |
if (!plb) { |
printf(NAME ": Cannot allocate a mappable piece of address space\n"); |
176,13 → 168,6 |
async_set_client_connection(vfs_connection); |
/* |
* Add a fibril for handling pending mounts. |
*/ |
fid_t fid = fibril_create(vfs_process_pending_mount, NULL); |
assert(fid); |
fibril_add_ready(fid); |
/* |
* Register at the naming service. |
*/ |
ipcarg_t phonead; |
/trunk/uspace/srv/vfs/vfs_ops.c |
---|
54,21 → 54,6 |
/* Forward declarations of static functions. */ |
static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t); |
/** Pending mount structure. */ |
typedef struct { |
link_t link; |
char *fs_name; /**< File system name */ |
char *mp; /**< Mount point */ |
char *opts; /**< Mount options. */ |
ipc_callid_t callid; /**< Call ID waiting for the mount */ |
ipc_callid_t rid; /**< Request ID */ |
dev_handle_t dev_handle; /**< Device handle */ |
} pending_req_t; |
FIBRIL_CONDVAR_INITIALIZE(pending_cv); |
bool pending_new_fs = false; /**< True if a new file system was mounted. */ |
LIST_INITIALIZE(pending_req); |
/** |
* This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
* concurrent VFS operation which modifies the file system namespace. |
260,48 → 245,6 |
fibril_rwlock_write_unlock(&namespace_rwlock); |
} |
/** Process pending mount requests */ |
void vfs_process_pending_mount(void) |
{ |
link_t *cur; |
while (true) { |
fibril_mutex_lock(&fs_head_lock); |
while (!pending_new_fs) |
fibril_condvar_wait(&pending_cv, &fs_head_lock); |
rescan: |
for (cur = pending_req.next; cur != &pending_req; |
cur = cur->next) { |
pending_req_t *pr = list_get_instance(cur, |
pending_req_t, link); |
fs_handle_t fs_handle = fs_name_to_handle(pr->fs_name, |
false); |
if (!fs_handle) |
continue; |
/* Acknowledge that we know fs_name. */ |
ipc_answer_0(pr->callid, EOK); |
list_remove(cur); |
fibril_mutex_unlock(&fs_head_lock); |
/* Do the mount */ |
vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, |
pr->mp, pr->opts); |
free(pr->fs_name); |
free(pr->mp); |
free(pr->opts); |
free(pr); |
fibril_mutex_lock(&fs_head_lock); |
goto rescan; |
} |
pending_new_fs = false; |
fibril_mutex_unlock(&fs_head_lock); |
} |
} |
void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
/* |
456,33 → 399,13 |
* This will also give us its file system handle. |
*/ |
fibril_mutex_lock(&fs_head_lock); |
fs_handle_t fs_handle = fs_name_to_handle(fs_name, false); |
fs_handle_t fs_handle; |
recheck: |
fs_handle = fs_name_to_handle(fs_name, false); |
if (!fs_handle) { |
if (flags & IPC_FLAG_BLOCKING) { |
pending_req_t *pr; |
/* Blocking mount, add to pending list */ |
pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
if (!pr) { |
fibril_mutex_unlock(&fs_head_lock); |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, ENOMEM); |
free(mp); |
free(fs_name); |
free(opts); |
return; |
} |
pr->fs_name = fs_name; |
pr->mp = mp; |
pr->opts = opts; |
pr->callid = callid; |
pr->rid = rid; |
pr->dev_handle = dev_handle; |
link_initialize(&pr->link); |
list_append(&pr->link, &pending_req); |
fibril_mutex_unlock(&fs_head_lock); |
return; |
fibril_condvar_wait(&fs_head_cv, &fs_head_lock); |
goto recheck; |
} |
fibril_mutex_unlock(&fs_head_lock); |
/trunk/uspace/srv/vfs/vfs_register.c |
---|
52,8 → 52,9 |
#include <atomic.h> |
#include "vfs.h" |
FIBRIL_CONDVAR_INITIALIZE(fs_head_cv); |
FIBRIL_MUTEX_INITIALIZE(fs_head_lock); |
link_t fs_head; |
LIST_INITIALIZE(fs_head); |
atomic_t fs_handle_next = { |
.count = 1 |
268,8 → 269,7 |
fs_info->fs_handle = (fs_handle_t) atomic_postinc(&fs_handle_next); |
ipc_answer_1(rid, EOK, (ipcarg_t) fs_info->fs_handle); |
pending_new_fs = true; |
fibril_condvar_signal(&pending_cv); |
fibril_condvar_signal(&fs_head_cv); |
fibril_mutex_unlock(&fs_head_lock); |
dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", |
/trunk/uspace/srv/vfs/vfs.h |
---|
146,6 → 146,8 |
extern fibril_mutex_t nodes_mutex; |
extern fibril_condvar_t fs_head_cv; |
extern fibril_mutex_t fs_head_lock; |
extern link_t fs_head; /**< List of registered file systems. */ |
extern vfs_pair_t rootfs; /**< Root file system. */ |
169,10 → 171,6 |
extern int vfs_grab_phone(fs_handle_t); |
extern void vfs_release_phone(int); |
extern fibril_mutex_t fs_head_lock; |
extern bool pending_new_fs; |
extern fibril_condvar_t pending_cv; |
extern fs_handle_t fs_name_to_handle(char *, bool); |
extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, |
196,7 → 194,6 |
extern void vfs_node_addref(vfs_node_t *); |
extern void vfs_node_delref(vfs_node_t *); |
extern void vfs_process_pending_mount(void); |
extern void vfs_register(ipc_callid_t, ipc_call_t *); |
extern void vfs_mount(ipc_callid_t, ipc_call_t *); |
extern void vfs_open(ipc_callid_t, ipc_call_t *); |
/trunk/uspace/srv/vfs/vfs_lookup.c |
---|
49,7 → 49,7 |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
FIBRIL_MUTEX_INITIALIZE(plb_mutex); |
link_t plb_head; /**< PLB entry ring buffer. */ |
LIST_INITIALIZE(plb_head); /**< PLB entry ring buffer. */ |
uint8_t *plb = NULL; |
/** Perform a path lookup. |