Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4565 → Rev 4566

/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.