Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2545 → Rev 2546

/trunk/uspace/srv/fs/fat/fat.c
42,7 → 42,7
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <as.h>>
#include <as.h>
#include "../../vfs/vfs.h"
 
#define dprintf(...) printf(__VA_ARGS__)
65,6 → 65,8
 
uint8_t *plb_ro = NULL;
 
int fs_handle = 0;
 
/**
* This connection fibril processes VFS requests from VFS.
*
155,8 → 157,8
/*
* Request sharing the Path Lookup Buffer with VFS.
*/
rc = ipc_call_sync_3(vfs_phone, IPC_M_AS_AREA_RECV, plb_ro, PLB_SIZE, 0,
NULL, NULL, NULL);
rc = ipc_call_sync_3(vfs_phone, IPC_M_AS_AREA_RECV, (ipcarg_t) plb_ro,
PLB_SIZE, 0, NULL, NULL, NULL);
if (rc) {
async_wait_for(req, NULL);
return rc;
163,6 → 165,13
}
/*
* Pick up the answer for the request to the VFS_REQUEST call.
*/
async_wait_for(req, NULL);
fs_handle = (int) IPC_GET_ARG1(answer);
dprintf("FAT filesystem registered, fs_handle=%d.\n", fs_handle);
 
/*
* Create a connection fibril to handle the callback connection.
*/
async_new_connection(phonehash, 0, NULL, fat_connection);
173,12 → 182,6
*/
async_set_client_connection(fat_connection);
 
/*
* Pick up the answer for the request to the VFS_REQUEST call.
*/
async_wait_for(req, NULL);
dprintf("FAT filesystem registered.\n");
 
async_create_manager();
 
/*
/trunk/uspace/srv/vfs/vfs_register.c
47,11 → 47,16
#include <futex.h>
#include <as.h>
#include <libadt/list.h>
#include <assert.h>
#include "vfs.h"
 
atomic_t fs_head_futex = FUTEX_INITIALIZER;
link_t fs_head;
 
atomic_t fs_handle_next = {
.count = 1
};
 
/** Verify the VFS info structure.
*
* @param info Info structure to be verified.
305,13 → 310,80
 
/*
* That was it. The FS has been registered.
* In reply to the VFS_REGISTER request, we assign the client file
* system a global file system handle.
*/
ipc_answer_fast(rid, EOK, 0, 0);
dprintf("\"%s\" filesystem successfully registered.\n",
fs_info->vfs_info.name);
fs_info->fs_handle = (int) atomic_postinc(&fs_handle_next);
ipc_answer_fast(rid, EOK, (ipcarg_t) fs_info->fs_handle, 0);
dprintf("\"%s\" filesystem successfully registered, handle=%d.\n",
fs_info->vfs_info.name, fs_info->fs_handle);
 
}
 
/** For a given file system handle, implement policy for allocating a phone.
*
* @param handle File system handle.
*
* @return Phone over which a multi-call request can be safely
* sent. Return 0 if no phone was found.
*/
int vfs_grab_phone(int handle)
{
/*
* For now, we don't try to be very clever and very fast.
* We simply lookup the phone in the fs_head list. We currently don't
* open any additional phones (even though that itself would be pretty
* straightforward; housekeeping multiple open phones to a FS task would
* be more demanding). Instead, we simply take the respective
* phone_futex and keep it until vfs_release_phone().
*/
futex_down(&fs_head_futex);
link_t *cur;
fs_info_t *fs;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs = list_get_instance(cur, fs_info_t, fs_link);
if (fs->fs_handle == handle) {
futex_up(&fs_head_futex);
/*
* For now, take the futex unconditionally.
* Oh yeah, serialization rocks.
* It will be up'ed in vfs_release_phone().
*/
futex_down(&fs->phone_futex);
return fs->phone;
}
}
futex_up(&fs_head_futex);
return 0;
}
 
/** Tell VFS that the phone is in use for any request.
*
* @param phone Phone to FS task.
*/
void vfs_release_phone(int phone)
{
bool found = false;
 
futex_down(&fs_head_futex);
link_t *cur;
for (cur = fs_head.next; cur != &fs_head; cur = cur->next) {
fs_info_t *fs = list_get_instance(cur, fs_info_t, fs_link);
if (fs->phone == phone) {
found = true;
futex_up(&fs_head_futex);
futex_up(&fs->phone_futex);
return;
}
}
futex_up(&fs_head_futex);
 
/*
* Not good to get here.
*/
assert(found == true);
}
 
/**
* @}
*/
/trunk/uspace/srv/vfs/vfs.h
92,6 → 92,8
typedef struct {
link_t fs_link;
vfs_info_t vfs_info;
int fs_handle;
atomic_t phone_futex; /**< Phone serializing futex. */
ipcarg_t phone;
} fs_info_t;
 
142,6 → 144,9
extern uint8_t *plb; /**< Path Lookup Buffer */
extern link_t plb_head; /**< List of active PLB entries. */
 
extern int vfs_grab_phone(int);
extern void vfs_release_phone(int);
 
extern int vfs_lookup_internal(char *path, size_t len, vfs_node_t *result);
 
extern void vfs_register(ipc_callid_t, ipc_call_t *);
/trunk/uspace/srv/vfs/vfs_lookup.c
125,9 → 125,10
memcpy(plb, &path[cnt1], cnt2);
 
ipc_call_t answer;
int phone = 0; /* TODO */
aid_t req = async_send_2(phone, VFS_LOOKUP, (ipcarg_t) first,
(ipcarg_t) last, &answer);
int phone = vfs_grab_phone(rootfs->fs_handle);
aid_t req = async_send_3(phone, VFS_LOOKUP, (ipcarg_t) first,
(ipcarg_t) last, (ipcarg_t) rootfs->dev_handle, &answer);
vfs_release_phone(phone);
 
ipcarg_t rc;
async_wait_for(req, &rc);