~vojtech-horky/helenos/numa

« back to all changes in this revision

Viewing changes to uspace/srv/fs/fat/fat.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        fat.c
 
36
 * @brief       FAT file system driver for HelenOS.
 
37
 */
 
38
 
 
39
#include "fat.h"
 
40
#include <ipc/ipc.h>
 
41
#include <ipc/services.h>
 
42
#include <async.h>
 
43
#include <errno.h>
 
44
#include <unistd.h>
 
45
#include <stdio.h>
 
46
#include <libfs.h>
 
47
#include "../../vfs/vfs.h"
 
48
 
 
49
 
 
50
vfs_info_t fat_vfs_info = {
 
51
        .name = "fat",
 
52
};
 
53
 
 
54
fs_reg_t fat_reg;
 
55
 
 
56
/**
 
57
 * This connection fibril processes VFS requests from VFS.
 
58
 *
 
59
 * In order to support simultaneous VFS requests, our design is as follows.
 
60
 * The connection fibril accepts VFS requests from VFS. If there is only one
 
61
 * instance of the fibril, VFS will need to serialize all VFS requests it sends
 
62
 * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO
 
63
 * call. In that case, a new connection fibril will be created, which in turn
 
64
 * will accept the call. Thus, a new phone will be opened for VFS.
 
65
 *
 
66
 * There are few issues with this arrangement. First, VFS can run out of
 
67
 * available phones. In that case, VFS can close some other phones or use one
 
68
 * phone for more serialized requests. Similarily, FAT can refuse to duplicate
 
69
 * the connection. VFS should then just make use of already existing phones and
 
70
 * route its requests through them. To avoid paying the fibril creation price 
 
71
 * upon each request, FAT might want to keep the connections open after the
 
72
 * request has been completed.
 
73
 */
 
74
static void fat_connection(ipc_callid_t iid, ipc_call_t *icall)
 
75
{
 
76
        if (iid) {
 
77
                /*
 
78
                 * This only happens for connections opened by
 
79
                 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
 
80
                 * created by IPC_M_CONNECT_TO_ME.
 
81
                 */
 
82
                ipc_answer_0(iid, EOK);
 
83
        }
 
84
        
 
85
        dprintf("VFS-FAT connection established.\n");
 
86
        while (1) {
 
87
                ipc_callid_t callid;
 
88
                ipc_call_t call;
 
89
        
 
90
                callid = async_get_call(&call);
 
91
                switch  (IPC_GET_METHOD(call)) {
 
92
                case IPC_M_PHONE_HUNGUP:
 
93
                        return;
 
94
                case VFS_OUT_MOUNTED:
 
95
                        fat_mounted(callid, &call);
 
96
                        break;
 
97
                case VFS_OUT_MOUNT:
 
98
                        fat_mount(callid, &call);
 
99
                        break;
 
100
                case VFS_OUT_LOOKUP:
 
101
                        fat_lookup(callid, &call);
 
102
                        break;
 
103
                case VFS_OUT_READ:
 
104
                        fat_read(callid, &call);
 
105
                        break;
 
106
                case VFS_OUT_WRITE:
 
107
                        fat_write(callid, &call);
 
108
                        break;
 
109
                case VFS_OUT_TRUNCATE:
 
110
                        fat_truncate(callid, &call);
 
111
                        break;
 
112
                case VFS_OUT_STAT:
 
113
                        fat_stat(callid, &call);
 
114
                        break;
 
115
                case VFS_OUT_CLOSE:
 
116
                        fat_close(callid, &call);
 
117
                        break;
 
118
                case VFS_OUT_DESTROY:
 
119
                        fat_destroy(callid, &call);
 
120
                        break;
 
121
                case VFS_OUT_OPEN_NODE:
 
122
                        fat_open_node(callid, &call);
 
123
                        break;
 
124
                case VFS_OUT_SYNC:
 
125
                        fat_sync(callid, &call);
 
126
                        break;
 
127
                default:
 
128
                        ipc_answer_0(callid, ENOTSUP);
 
129
                        break;
 
130
                }
 
131
        }
 
132
}
 
133
 
 
134
int main(int argc, char **argv)
 
135
{
 
136
        int vfs_phone;
 
137
        int rc;
 
138
 
 
139
        printf("fat: HelenOS FAT file system server.\n");
 
140
 
 
141
        rc = fat_idx_init();
 
142
        if (rc != EOK)
 
143
                goto err;
 
144
 
 
145
        vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
 
146
        if (vfs_phone < EOK) {
 
147
                printf("fat: failed to connect to VFS\n");
 
148
                return -1;
 
149
        }
 
150
        
 
151
        rc = fs_register(vfs_phone, &fat_reg, &fat_vfs_info, fat_connection);
 
152
        if (rc != EOK) {
 
153
                fat_idx_fini();
 
154
                goto err;
 
155
        }
 
156
        
 
157
        dprintf("FAT filesystem registered, fs_handle=%d.\n",
 
158
            fat_reg.fs_handle);
 
159
 
 
160
        async_manager();
 
161
        /* not reached */
 
162
        return 0;
 
163
 
 
164
err:
 
165
        printf("Failed to register the FAT file system (%d)\n", rc);
 
166
        return rc;
 
167
}
 
168
 
 
169
/**
 
170
 * @}
 
171
 */