Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3108 → Rev 3109

/trunk/uspace/srv/fs/tmpfs/tmpfs.h
40,7 → 40,9
#include <bool.h>
#include <libadt/hash_table.h>
 
#ifndef dprintf
#define dprintf(...) printf(__VA_ARGS__)
#endif
 
typedef struct tmpfs_dentry {
fs_index_t index; /**< TMPFS node index. */
62,6 → 64,7
 
extern libfs_ops_t tmpfs_libfs_ops;
 
extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
/trunk/uspace/srv/fs/tmpfs/tmpfs.c
61,6 → 61,7
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_MOUNTED)] = VFS_OP_DEFINED,
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL,
[IPC_METHOD_TO_VFS_OP(VFS_DESTROY)] = VFS_OP_DEFINED,
}
105,6 → 106,9
callid = async_get_call(&call);
switch (IPC_GET_METHOD(call)) {
case VFS_MOUNTED:
tmpfs_mounted(callid, &call);
break;
case VFS_MOUNT:
tmpfs_mount(callid, &call);
break;
/trunk/uspace/srv/fs/tmpfs/tmpfs_ops.c
393,36 → 393,38
return EOK;
}
 
void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
 
/* Initialize TMPFS. */
if (!root && !tmpfs_init()) {
ipc_answer_0(rid, ENOMEM);
return;
}
 
if (dev_handle >= 0) {
if (tmpfs_restore(dev_handle))
ipc_answer_0(rid, EOK);
else
ipc_answer_0(rid, ELIMIT);
} else {
ipc_answer_0(rid, EOK);
}
}
 
void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t mr_index = (fs_index_t) IPC_GET_ARG2(*request);
fs_handle_t mp_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request);
fs_index_t mp_index = (fs_index_t) IPC_GET_ARG5(*request);
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
fs_index_t mp_index = (fs_index_t) IPC_GET_ARG2(*request);
fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request);
if ((mr_index == root->index) &&
(mp_fs_handle == tmpfs_reg.fs_handle) &&
(mp_index == mr_index)) {
if (mr_dev_handle >= 0) {
if (tmpfs_restore(mr_dev_handle))
ipc_answer_0(rid, EOK);
else
ipc_answer_0(rid, ELIMIT);
} else
ipc_answer_0(rid, EOK);
} else
ipc_answer_0(rid, ENOTSUP);
ipc_answer_0(rid, ENOTSUP);
}
 
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
{
/* Initialize TMPFS. */
if (!root && !tmpfs_init()) {
ipc_answer_0(rid, ENOMEM);
return;
}
libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
}
 
/trunk/uspace/srv/vfs/vfs_ops.c
62,24 → 62,11
RWLOCK_INITIALIZE(namespace_rwlock);
 
futex_t rootfs_futex = FUTEX_INITIALIZER;
vfs_triplet_t rootfs = {
vfs_pair_t rootfs = {
.fs_handle = 0,
.dev_handle = 0,
.index = 0,
.dev_handle = 0
};
 
static int
lookup_root(fs_handle_t fs_handle, dev_handle_t dev_handle,
vfs_lookup_res_t *result)
{
vfs_pair_t altroot = {
.fs_handle = fs_handle,
.dev_handle = dev_handle,
};
 
return vfs_lookup_internal("/", L_DIRECTORY, result, &altroot);
}
 
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
{
dev_handle_t dev_handle;
163,27 → 150,7
(void) ipc_data_write_finalize(callid, buf, size);
buf[size] = '\0';
 
/*
* Lookup the root node of the filesystem being mounted.
* In this case, we don't need to take the namespace_futex as the root
* node cannot be removed. However, we do take a reference to it so
* that we can track how many times it has been mounted.
*/
vfs_lookup_res_t mr_res;
rc = lookup_root(fs_handle, dev_handle, &mr_res);
if (rc != EOK) {
free(buf);
ipc_answer_0(rid, rc);
return;
}
vfs_node_t *mr_node = vfs_node_get(&mr_res);
if (!mr_node) {
free(buf);
ipc_answer_0(rid, ENOMEM);
return;
}
 
/* Finally, we need to resolve the path to the mountpoint. */
/* Resolve the path to the mountpoint. */
vfs_lookup_res_t mp_res;
futex_down(&rootfs_futex);
if (rootfs.fs_handle) {
193,7 → 160,6
/* Trying to mount root FS over root FS */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
vfs_node_put(mr_node);
free(buf);
ipc_answer_0(rid, EBUSY);
return;
203,7 → 169,6
/* The lookup failed for some reason. */
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
vfs_node_put(mr_node); /* failed -> drop reference */
free(buf);
ipc_answer_0(rid, rc);
return;
212,7 → 177,6
if (!mp_node) {
rwlock_write_unlock(&namespace_rwlock);
futex_up(&rootfs_futex);
vfs_node_put(mr_node); /* failed -> drop reference */
free(buf);
ipc_answer_0(rid, ENOMEM);
return;
232,20 → 196,16
*/
free(buf);
/* Inform the mount point about the root mount. */
phone = vfs_grab_phone(mr_res.triplet.fs_handle);
rc = async_req_5_0(phone, VFS_MOUNT,
(ipcarg_t) mr_res.triplet.dev_handle,
(ipcarg_t) mr_res.triplet.index,
(ipcarg_t) mr_res.triplet.fs_handle,
(ipcarg_t) mr_res.triplet.dev_handle,
(ipcarg_t) mr_res.triplet.index);
/* Tell the mountee that it is being mounted. */
phone = vfs_grab_phone(fs_handle);
rc = async_req_1_0(phone, VFS_MOUNTED,
(ipcarg_t) dev_handle);
vfs_release_phone(phone);
 
if (rc == EOK)
rootfs = mr_res.triplet;
else
vfs_node_put(mr_node);
if (rc == EOK) {
rootfs.fs_handle = fs_handle;
rootfs.dev_handle = dev_handle;
}
 
futex_up(&rootfs_futex);
ipc_answer_0(rid, rc);
257,7 → 217,6
*/
futex_up(&rootfs_futex);
free(buf);
vfs_node_put(mr_node); /* failed -> drop reference */
ipc_answer_0(rid, ENOENT);
return;
}
268,26 → 227,19
/*
* At this point, we have all necessary pieces: file system and device
* handles, and we know the mount point VFS node and also the root node
* of the file system being mounted.
* handles, and we know the mount point VFS node.
*/
 
/**
* @todo
* Add more IPC parameters so that we can send mount mode/flags.
*/
phone = vfs_grab_phone(mp_res.triplet.fs_handle);
rc = async_req_5_0(phone, VFS_MOUNT,
rc = async_req_4_0(phone, VFS_MOUNT,
(ipcarg_t) mp_res.triplet.dev_handle,
(ipcarg_t) mp_res.triplet.index,
(ipcarg_t) mr_res.triplet.fs_handle,
(ipcarg_t) mr_res.triplet.dev_handle,
(ipcarg_t) mr_res.triplet.index);
(ipcarg_t) fs_handle,
(ipcarg_t) dev_handle);
vfs_release_phone(phone);
 
if (rc != EOK) {
/* Mount failed, drop references to mr_node and mp_node. */
vfs_node_put(mr_node);
/* Mount failed, drop reference to mp_node. */
if (mp_node)
vfs_node_put(mp_node);
}
/trunk/uspace/srv/vfs/vfs.h
65,6 → 65,7
 
typedef enum {
VFS_LOOKUP = VFS_LAST_CMN,
VFS_MOUNTED,
VFS_DESTROY,
VFS_LAST_CLNT, /* keep this the last member of this enum */
} vfs_request_clnt_t;
244,7 → 245,7
 
extern link_t fs_head; /**< List of registered file systems. */
 
extern vfs_triplet_t rootfs; /**< Root node of the root file system. */
extern vfs_pair_t rootfs; /**< Root file system. */
 
#define MAX_PATH_LEN (64 * 1024)
 
/trunk/uspace/srv/vfs/vfs_lookup.c
72,7 → 72,7
if (altroot)
root = altroot;
else
root = (vfs_pair_t *) &rootfs;
root = &rootfs;
 
if (!root->fs_handle)
return ENOENT;