Subversion Repositories HelenOS

Rev

Rev 3079 | Rev 3215 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3079 Rev 3109
Line 60... Line 60...
60
 * concurrent VFS operation which modifies the file system namespace.
60
 * concurrent VFS operation which modifies the file system namespace.
61
 */
61
 */
62
RWLOCK_INITIALIZE(namespace_rwlock);
62
RWLOCK_INITIALIZE(namespace_rwlock);
63
 
63
 
64
futex_t rootfs_futex = FUTEX_INITIALIZER;
64
futex_t rootfs_futex = FUTEX_INITIALIZER;
65
vfs_triplet_t rootfs = {
65
vfs_pair_t rootfs = {
66
    .fs_handle = 0,
66
    .fs_handle = 0,
67
    .dev_handle = 0,
67
    .dev_handle = 0
68
    .index = 0,
-
 
69
};
68
};
70
 
69
 
71
static int
-
 
72
lookup_root(fs_handle_t fs_handle, dev_handle_t dev_handle,
-
 
73
    vfs_lookup_res_t *result)
-
 
74
{
-
 
75
    vfs_pair_t altroot = {
-
 
76
        .fs_handle = fs_handle,
-
 
77
        .dev_handle = dev_handle,
-
 
78
    };
-
 
79
 
-
 
80
    return vfs_lookup_internal("/", L_DIRECTORY, result, &altroot);
-
 
81
}
-
 
82
 
-
 
83
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
70
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
84
{
71
{
85
    dev_handle_t dev_handle;
72
    dev_handle_t dev_handle;
86
    vfs_node_t *mp_node = NULL;
73
    vfs_node_t *mp_node = NULL;
87
    int rc;
74
    int rc;
Line 161... Line 148...
161
 
148
 
162
    /* Deliver the mount point. */
149
    /* Deliver the mount point. */
163
    (void) ipc_data_write_finalize(callid, buf, size);
150
    (void) ipc_data_write_finalize(callid, buf, size);
164
    buf[size] = '\0';
151
    buf[size] = '\0';
165
 
152
 
166
    /*
-
 
167
     * Lookup the root node of the filesystem being mounted.
-
 
168
     * In this case, we don't need to take the namespace_futex as the root
-
 
169
     * node cannot be removed. However, we do take a reference to it so
-
 
170
     * that we can track how many times it has been mounted.
-
 
171
     */
-
 
172
    vfs_lookup_res_t mr_res;
-
 
173
    rc = lookup_root(fs_handle, dev_handle, &mr_res);
-
 
174
    if (rc != EOK) {
-
 
175
        free(buf);
-
 
176
        ipc_answer_0(rid, rc);
-
 
177
        return;
-
 
178
    }
-
 
179
    vfs_node_t *mr_node = vfs_node_get(&mr_res);
-
 
180
    if (!mr_node) {
-
 
181
        free(buf);
-
 
182
        ipc_answer_0(rid, ENOMEM);
-
 
183
        return;
-
 
184
    }
-
 
185
 
-
 
186
    /* Finally, we need to resolve the path to the mountpoint. */
153
    /* Resolve the path to the mountpoint. */
187
    vfs_lookup_res_t mp_res;
154
    vfs_lookup_res_t mp_res;
188
    futex_down(&rootfs_futex);
155
    futex_down(&rootfs_futex);
189
    if (rootfs.fs_handle) {
156
    if (rootfs.fs_handle) {
190
        /* We already have the root FS. */
157
        /* We already have the root FS. */
191
        rwlock_write_lock(&namespace_rwlock);
158
        rwlock_write_lock(&namespace_rwlock);
192
        if ((size == 1) && (buf[0] == '/')) {
159
        if ((size == 1) && (buf[0] == '/')) {
193
            /* Trying to mount root FS over root FS */
160
            /* Trying to mount root FS over root FS */
194
            rwlock_write_unlock(&namespace_rwlock);
161
            rwlock_write_unlock(&namespace_rwlock);
195
            futex_up(&rootfs_futex);
162
            futex_up(&rootfs_futex);
196
            vfs_node_put(mr_node);
-
 
197
            free(buf);
163
            free(buf);
198
            ipc_answer_0(rid, EBUSY);
164
            ipc_answer_0(rid, EBUSY);
199
            return;
165
            return;
200
        }
166
        }
201
        rc = vfs_lookup_internal(buf, L_DIRECTORY, &mp_res, NULL);
167
        rc = vfs_lookup_internal(buf, L_DIRECTORY, &mp_res, NULL);
202
        if (rc != EOK) {
168
        if (rc != EOK) {
203
            /* The lookup failed for some reason. */
169
            /* The lookup failed for some reason. */
204
            rwlock_write_unlock(&namespace_rwlock);
170
            rwlock_write_unlock(&namespace_rwlock);
205
            futex_up(&rootfs_futex);
171
            futex_up(&rootfs_futex);
206
            vfs_node_put(mr_node);  /* failed -> drop reference */
-
 
207
            free(buf);
172
            free(buf);
208
            ipc_answer_0(rid, rc);
173
            ipc_answer_0(rid, rc);
209
            return;
174
            return;
210
        }
175
        }
211
        mp_node = vfs_node_get(&mp_res);
176
        mp_node = vfs_node_get(&mp_res);
212
        if (!mp_node) {
177
        if (!mp_node) {
213
            rwlock_write_unlock(&namespace_rwlock);
178
            rwlock_write_unlock(&namespace_rwlock);
214
            futex_up(&rootfs_futex);
179
            futex_up(&rootfs_futex);
215
            vfs_node_put(mr_node);  /* failed -> drop reference */
-
 
216
            free(buf);
180
            free(buf);
217
            ipc_answer_0(rid, ENOMEM);
181
            ipc_answer_0(rid, ENOMEM);
218
            return;
182
            return;
219
        }
183
        }
220
        /*
184
        /*
Line 230... Line 194...
230
             * For this simple, but important case,
194
             * For this simple, but important case,
231
             * we are almost done.
195
             * we are almost done.
232
             */
196
             */
233
            free(buf);
197
            free(buf);
234
           
198
           
235
            /* Inform the mount point about the root mount. */
199
            /* Tell the mountee that it is being mounted. */
236
            phone = vfs_grab_phone(mr_res.triplet.fs_handle);
200
            phone = vfs_grab_phone(fs_handle);
237
            rc = async_req_5_0(phone, VFS_MOUNT,
201
            rc = async_req_1_0(phone, VFS_MOUNTED,
238
                (ipcarg_t) mr_res.triplet.dev_handle,
-
 
239
                (ipcarg_t) mr_res.triplet.index,
-
 
240
                (ipcarg_t) mr_res.triplet.fs_handle,
-
 
241
                (ipcarg_t) mr_res.triplet.dev_handle,
202
                (ipcarg_t) dev_handle);
242
                (ipcarg_t) mr_res.triplet.index);
-
 
243
            vfs_release_phone(phone);
203
            vfs_release_phone(phone);
244
 
204
 
245
            if (rc == EOK)
205
            if (rc == EOK) {
246
                rootfs = mr_res.triplet;
206
                rootfs.fs_handle = fs_handle;
-
 
207
                rootfs.dev_handle = dev_handle;
247
            else
208
            }
248
                vfs_node_put(mr_node);
-
 
249
 
209
 
250
            futex_up(&rootfs_futex);
210
            futex_up(&rootfs_futex);
251
            ipc_answer_0(rid, rc);
211
            ipc_answer_0(rid, rc);
252
            return;
212
            return;
253
        } else {
213
        } else {
Line 255... Line 215...
255
             * We can't resolve this without the root filesystem
215
             * We can't resolve this without the root filesystem
256
             * being mounted first.
216
             * being mounted first.
257
             */
217
             */
258
            futex_up(&rootfs_futex);
218
            futex_up(&rootfs_futex);
259
            free(buf);
219
            free(buf);
260
            vfs_node_put(mr_node);  /* failed -> drop reference */
-
 
261
            ipc_answer_0(rid, ENOENT);
220
            ipc_answer_0(rid, ENOENT);
262
            return;
221
            return;
263
        }
222
        }
264
    }
223
    }
265
    futex_up(&rootfs_futex);
224
    futex_up(&rootfs_futex);
266
   
225
   
267
    free(buf);  /* The buffer is not needed anymore. */
226
    free(buf);  /* The buffer is not needed anymore. */
268
   
227
   
269
    /*
228
    /*
270
     * At this point, we have all necessary pieces: file system and device
229
     * At this point, we have all necessary pieces: file system and device
271
     * handles, and we know the mount point VFS node and also the root node
230
     * handles, and we know the mount point VFS node.
272
     * of the file system being mounted.
-
 
273
     */
231
     */
274
 
232
 
275
    /**
-
 
276
     * @todo
-
 
277
     * Add more IPC parameters so that we can send mount mode/flags.
-
 
278
     */
-
 
279
    phone = vfs_grab_phone(mp_res.triplet.fs_handle);
233
    phone = vfs_grab_phone(mp_res.triplet.fs_handle);
280
    rc = async_req_5_0(phone, VFS_MOUNT,
234
    rc = async_req_4_0(phone, VFS_MOUNT,
281
        (ipcarg_t) mp_res.triplet.dev_handle,
235
        (ipcarg_t) mp_res.triplet.dev_handle,
282
        (ipcarg_t) mp_res.triplet.index,
236
        (ipcarg_t) mp_res.triplet.index,
283
        (ipcarg_t) mr_res.triplet.fs_handle,
237
        (ipcarg_t) fs_handle,
284
        (ipcarg_t) mr_res.triplet.dev_handle,
238
        (ipcarg_t) dev_handle);
285
        (ipcarg_t) mr_res.triplet.index);
-
 
286
    vfs_release_phone(phone);
239
    vfs_release_phone(phone);
287
 
240
 
288
    if (rc != EOK) {
241
    if (rc != EOK) {
289
        /* Mount failed, drop references to mr_node and mp_node. */
242
        /* Mount failed, drop reference to mp_node. */
290
        vfs_node_put(mr_node);
-
 
291
        if (mp_node)
243
        if (mp_node)
292
            vfs_node_put(mp_node);
244
            vfs_node_put(mp_node);
293
    }
245
    }
294
   
246
   
295
    ipc_answer_0(rid, rc);
247
    ipc_answer_0(rid, rc);