~jsvoboda/helenos/dnsr

« back to all changes in this revision

Viewing changes to uspace/srv/fs/tmpfs/tmpfs.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006 Martin Decky
 
3
 * Copyright (c) 2008 Jakub Jermar
 
4
 * All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 *
 
10
 * - Redistributions of source code must retain the above copyright
 
11
 *   notice, this list of conditions and the following disclaimer.
 
12
 * - Redistributions in binary form must reproduce the above copyright
 
13
 *   notice, this list of conditions and the following disclaimer in the
 
14
 *   documentation and/or other materials provided with the distribution.
 
15
 * - The name of the author may not be used to endorse or promote products
 
16
 *   derived from this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 */
 
29
 
 
30
/** @addtogroup fs
 
31
 * @{
 
32
 */ 
 
33
 
 
34
/**
 
35
 * @file        tmpfs.c
 
36
 * @brief       File system driver for in-memory file system.
 
37
 *
 
38
 * Every instance of tmpfs exists purely in memory and has neither a disk layout
 
39
 * nor any permanent storage (e.g. disk blocks). With each system reboot, data
 
40
 * stored in a tmpfs file system is lost.
 
41
 */
 
42
 
 
43
#include "tmpfs.h"
 
44
#include <ipc/ipc.h>
 
45
#include <ipc/services.h>
 
46
#include <async.h>
 
47
#include <errno.h>
 
48
#include <unistd.h>
 
49
#include <stdio.h>
 
50
#include <libfs.h>
 
51
#include "../../vfs/vfs.h"
 
52
 
 
53
#define NAME "tmpfs"
 
54
 
 
55
 
 
56
vfs_info_t tmpfs_vfs_info = {
 
57
        .name = "tmpfs",
 
58
};
 
59
 
 
60
fs_reg_t tmpfs_reg;
 
61
 
 
62
/**
 
63
 * This connection fibril processes VFS requests from VFS.
 
64
 *
 
65
 * In order to support simultaneous VFS requests, our design is as follows.
 
66
 * The connection fibril accepts VFS requests from VFS. If there is only one
 
67
 * instance of the fibril, VFS will need to serialize all VFS requests it sends
 
68
 * to FAT. To overcome this bottleneck, VFS can send TMPFS the
 
69
 * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be
 
70
 * created, which in turn will accept the call. Thus, a new phone will be
 
71
 * opened for VFS.
 
72
 *
 
73
 * There are few issues with this arrangement. First, VFS can run out of
 
74
 * available phones. In that case, VFS can close some other phones or use one
 
75
 * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate
 
76
 * the connection. VFS should then just make use of already existing phones and
 
77
 * route its requests through them. To avoid paying the fibril creation price 
 
78
 * upon each request, TMPFS might want to keep the connections open after the
 
79
 * request has been completed.
 
80
 */
 
81
static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall)
 
82
{
 
83
        if (iid) {
 
84
                /*
 
85
                 * This only happens for connections opened by
 
86
                 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
 
87
                 * created by IPC_M_CONNECT_TO_ME.
 
88
                 */
 
89
                ipc_answer_0(iid, EOK);
 
90
        }
 
91
        
 
92
        dprintf("VFS-TMPFS connection established.\n");
 
93
        while (1) {
 
94
                ipc_callid_t callid;
 
95
                ipc_call_t call;
 
96
        
 
97
                callid = async_get_call(&call);
 
98
                switch  (IPC_GET_METHOD(call)) {
 
99
                case IPC_M_PHONE_HUNGUP:
 
100
                        return;
 
101
                case VFS_OUT_MOUNTED:
 
102
                        tmpfs_mounted(callid, &call);
 
103
                        break;
 
104
                case VFS_OUT_MOUNT:
 
105
                        tmpfs_mount(callid, &call);
 
106
                        break;
 
107
                case VFS_OUT_LOOKUP:
 
108
                        tmpfs_lookup(callid, &call);
 
109
                        break;
 
110
                case VFS_OUT_READ:
 
111
                        tmpfs_read(callid, &call);
 
112
                        break;
 
113
                case VFS_OUT_WRITE:
 
114
                        tmpfs_write(callid, &call);
 
115
                        break;
 
116
                case VFS_OUT_TRUNCATE:
 
117
                        tmpfs_truncate(callid, &call);
 
118
                        break;
 
119
                case VFS_OUT_CLOSE:
 
120
                        tmpfs_close(callid, &call);
 
121
                        break;
 
122
                case VFS_OUT_DESTROY:
 
123
                        tmpfs_destroy(callid, &call);
 
124
                        break;
 
125
                case VFS_OUT_OPEN_NODE:
 
126
                        tmpfs_open_node(callid, &call);
 
127
                        break;
 
128
                case VFS_OUT_STAT:
 
129
                        tmpfs_stat(callid, &call);
 
130
                        break;
 
131
                case VFS_OUT_SYNC:
 
132
                        tmpfs_sync(callid, &call);
 
133
                        break;
 
134
                default:
 
135
                        ipc_answer_0(callid, ENOTSUP);
 
136
                        break;
 
137
                }
 
138
        }
 
139
}
 
140
 
 
141
int main(int argc, char **argv)
 
142
{
 
143
        printf(NAME ": HelenOS TMPFS file system server\n");
 
144
 
 
145
        if (!tmpfs_init()) {
 
146
                printf(NAME ": failed to initialize TMPFS\n");
 
147
                return -1;
 
148
        }
 
149
 
 
150
        int vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
 
151
        if (vfs_phone < EOK) {
 
152
                printf(NAME ": Unable to connect to VFS\n");
 
153
                return -1;
 
154
        }
 
155
 
 
156
        int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info,
 
157
            tmpfs_connection);
 
158
        if (rc != EOK) {
 
159
                printf(NAME ": Failed to register file system (%d)\n", rc);
 
160
                return rc;
 
161
        }
 
162
 
 
163
        printf(NAME ": Accepting connections\n");
 
164
        async_manager();
 
165
        /* not reached */
 
166
        return 0;
 
167
}
 
168
 
 
169
/**
 
170
 * @}
 
171
 */