Subversion Repositories HelenOS

Rev

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

Rev 2700 Rev 2707
Line 113... Line 113...
113
        ipc_answer_0(callid, EINVAL);
113
        ipc_answer_0(callid, EINVAL);
114
        ipc_answer_0(rid, EINVAL);
114
        ipc_answer_0(rid, EINVAL);
115
        return;
115
        return;
116
    }
116
    }
117
 
117
 
118
    /*
-
 
119
     * Deliver the file system name.
118
    /* Deliver the file system name. */
120
     */
-
 
121
    char fs_name[FS_NAME_MAXLEN + 1];
119
    char fs_name[FS_NAME_MAXLEN + 1];
122
    (void) ipc_data_write_finalize(callid, fs_name, size);
120
    (void) ipc_data_write_finalize(callid, fs_name, size);
123
    fs_name[size] = '\0';
121
    fs_name[size] = '\0';
124
   
122
   
125
    /*
123
    /*
Line 130... Line 128...
130
    if (!fs_handle) {
128
    if (!fs_handle) {
131
        ipc_answer_0(rid, ENOENT);
129
        ipc_answer_0(rid, ENOENT);
132
        return;
130
        return;
133
    }
131
    }
134
 
132
 
135
    /*
-
 
136
     * Now, we want the client to send us the mount point.
133
    /* Now, we want the client to send us the mount point. */
137
     */
-
 
138
    if (!ipc_data_write_receive(&callid, &size)) {
134
    if (!ipc_data_write_receive(&callid, &size)) {
139
        ipc_answer_0(callid, EINVAL);
135
        ipc_answer_0(callid, EINVAL);
140
        ipc_answer_0(rid, EINVAL);
136
        ipc_answer_0(rid, EINVAL);
141
        return;
137
        return;
142
    }
138
    }
143
 
139
 
144
    /*
-
 
145
     * Check whether size is reasonable wrt. the mount point.
140
    /* Check whether size is reasonable wrt. the mount point. */
146
     */
-
 
147
    if (size < 1 || size > MAX_PATH_LEN) {
141
    if (size < 1 || size > MAX_PATH_LEN) {
148
        ipc_answer_0(callid, EINVAL);
142
        ipc_answer_0(callid, EINVAL);
149
        ipc_answer_0(rid, EINVAL);
143
        ipc_answer_0(rid, EINVAL);
150
        return;
144
        return;
151
    }
145
    }
152
    /*
-
 
153
     * Allocate buffer for the mount point data being received.
146
    /* Allocate buffer for the mount point data being received. */
154
     */
-
 
155
    uint8_t *buf;
147
    uint8_t *buf;
156
    buf = malloc(size);
148
    buf = malloc(size);
157
    if (!buf) {
149
    if (!buf) {
158
        ipc_answer_0(callid, ENOMEM);
150
        ipc_answer_0(callid, ENOMEM);
159
        ipc_answer_0(rid, ENOMEM);
151
        ipc_answer_0(rid, ENOMEM);
160
        return;
152
        return;
161
    }
153
    }
162
 
154
 
163
    /*
-
 
164
     * Deliver the mount point.
155
    /* Deliver the mount point. */
165
     */
-
 
166
    (void) ipc_data_write_finalize(callid, buf, size);
156
    (void) ipc_data_write_finalize(callid, buf, size);
167
 
157
 
168
    /*
158
    /*
169
     * Lookup the root node of the filesystem being mounted.
159
     * Lookup the root node of the filesystem being mounted.
170
     * In this case, we don't need to take the namespace_futex as the root
160
     * In this case, we don't need to take the namespace_futex as the root
Line 184... Line 174...
184
        free(buf);
174
        free(buf);
185
        ipc_answer_0(rid, ENOMEM);
175
        ipc_answer_0(rid, ENOMEM);
186
        return;
176
        return;
187
    }
177
    }
188
 
178
 
189
    /*
-
 
190
     * Finally, we need to resolve the path to the mountpoint.
179
    /* Finally, we need to resolve the path to the mountpoint. */
191
     */
-
 
192
    vfs_lookup_res_t mp_res;
180
    vfs_lookup_res_t mp_res;
193
    futex_down(&rootfs_futex);
181
    futex_down(&rootfs_futex);
194
    if (rootfs.fs_handle) {
182
    if (rootfs.fs_handle) {
195
        /*
-
 
196
         * We already have the root FS.
183
        /* We already have the root FS. */
197
         */
-
 
198
        rwlock_write_lock(&namespace_rwlock);
184
        rwlock_write_lock(&namespace_rwlock);
199
        rc = vfs_lookup_internal(buf, size, L_DIRECTORY, &mp_res,
185
        rc = vfs_lookup_internal(buf, size, L_DIRECTORY, &mp_res,
200
            NULL);
186
            NULL);
201
        if (rc != EOK) {
187
        if (rc != EOK) {
202
            /*
-
 
203
             * The lookup failed for some reason.
188
            /* The lookup failed for some reason. */
204
             */
-
 
205
            rwlock_write_unlock(&namespace_rwlock);
189
            rwlock_write_unlock(&namespace_rwlock);
206
            futex_up(&rootfs_futex);
190
            futex_up(&rootfs_futex);
207
            vfs_node_put(mr_node);  /* failed -> drop reference */
191
            vfs_node_put(mr_node);  /* failed -> drop reference */
208
            free(buf);
192
            free(buf);
209
            ipc_answer_0(rid, rc);
193
            ipc_answer_0(rid, rc);
Line 223... Line 207...
223
         * It will be dropped upon the corresponding VFS_UNMOUNT.
207
         * It will be dropped upon the corresponding VFS_UNMOUNT.
224
         * This prevents the mount point from being deleted.
208
         * This prevents the mount point from being deleted.
225
         */
209
         */
226
        rwlock_write_unlock(&namespace_rwlock);
210
        rwlock_write_unlock(&namespace_rwlock);
227
    } else {
211
    } else {
228
        /*
-
 
229
         * We still don't have the root file system mounted.
212
        /* We still don't have the root file system mounted. */
230
         */
-
 
231
        if ((size == 1) && (buf[0] == '/')) {
213
        if ((size == 1) && (buf[0] == '/')) {
232
            /*
-
 
233
             * For this simple, but important case, we are done.
214
            /* For this simple, but important case, we are done. */
234
             */
-
 
235
            rootfs = mr_res.triplet;
215
            rootfs = mr_res.triplet;
236
            futex_up(&rootfs_futex);
216
            futex_up(&rootfs_futex);
237
            free(buf);
217
            free(buf);
238
            ipc_answer_0(rid, EOK);
218
            ipc_answer_0(rid, EOK);
239
            return;
219
            return;
Line 345... Line 325...
345
     * find/create-and-lock the VFS node corresponding to the looked-up
325
     * find/create-and-lock the VFS node corresponding to the looked-up
346
     * triplet.
326
     * triplet.
347
     */
327
     */
348
    rwlock_read_lock(&namespace_rwlock);
328
    rwlock_read_lock(&namespace_rwlock);
349
 
329
 
350
    /*
-
 
351
     * The path is now populated and we can call vfs_lookup_internal().
330
    /* The path is now populated and we can call vfs_lookup_internal(). */
352
     */
-
 
353
    vfs_lookup_res_t lr;
331
    vfs_lookup_res_t lr;
354
    rc = vfs_lookup_internal(path, len, lflag, &lr, NULL);
332
    rc = vfs_lookup_internal(path, len, lflag, &lr, NULL);
355
    if (rc) {
333
    if (rc) {
356
        rwlock_read_unlock(&namespace_rwlock);
334
        rwlock_read_unlock(&namespace_rwlock);
357
        ipc_answer_0(rid, rc);
335
        ipc_answer_0(rid, rc);
358
        free(path);
336
        free(path);
359
        return;
337
        return;
360
    }
338
    }
361
 
339
 
362
    /*
-
 
363
     * Path is no longer needed.
340
    /** Path is no longer needed. */
364
     */
-
 
365
    free(path);
341
    free(path);
366
 
342
 
367
    vfs_node_t *node = vfs_node_get(&lr);
343
    vfs_node_t *node = vfs_node_get(&lr);
368
    rwlock_read_unlock(&namespace_rwlock);
344
    rwlock_read_unlock(&namespace_rwlock);
369
 
345
 
Line 388... Line 364...
388
     * respective VFS_CLOSE.
364
     * respective VFS_CLOSE.
389
     */
365
     */
390
    vfs_node_addref(node);
366
    vfs_node_addref(node);
391
    vfs_node_put(node);
367
    vfs_node_put(node);
392
 
368
 
393
    /*
-
 
394
     * Success! Return the new file descriptor to the client.
369
    /* Success! Return the new file descriptor to the client. */
395
     */
-
 
396
    ipc_answer_1(rid, EOK, fd);
370
    ipc_answer_1(rid, EOK, fd);
397
}
371
}
398
 
372
 
399
static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
373
static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
400
{
374
{
Line 409... Line 383...
409
     * open files supports parallel access!
383
     * open files supports parallel access!
410
     */
384
     */
411
 
385
 
412
    int fd = IPC_GET_ARG1(*request);
386
    int fd = IPC_GET_ARG1(*request);
413
 
387
 
414
    /*
-
 
415
     * Lookup the file structure corresponding to the file descriptor.
388
    /* Lookup the file structure corresponding to the file descriptor. */
416
     */
-
 
417
    vfs_file_t *file = vfs_file_get(fd);
389
    vfs_file_t *file = vfs_file_get(fd);
418
    if (!file) {
390
    if (!file) {
419
        ipc_answer_0(rid, ENOENT);
391
        ipc_answer_0(rid, ENOENT);
420
        return;
392
        return;
421
    }
393
    }
Line 451... Line 423...
451
    else
423
    else
452
        rwlock_write_lock(&file->node->contents_rwlock);
424
        rwlock_write_lock(&file->node->contents_rwlock);
453
 
425
 
454
    int fs_phone = vfs_grab_phone(file->node->fs_handle);  
426
    int fs_phone = vfs_grab_phone(file->node->fs_handle);  
455
   
427
   
456
    /*
-
 
457
     * Make a VFS_READ/VFS_WRITE request at the destination FS server.
428
    /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */
458
     */
-
 
459
    aid_t msg;
429
    aid_t msg;
460
    ipc_call_t answer;
430
    ipc_call_t answer;
461
    msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
431
    msg = async_send_3(fs_phone, IPC_GET_METHOD(*request),
462
        file->node->dev_handle, file->node->index, file->pos, &answer);
432
        file->node->dev_handle, file->node->index, file->pos, &answer);
463
   
433
   
Line 469... Line 439...
469
     */
439
     */
470
    ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
440
    ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
471
 
441
 
472
    vfs_release_phone(fs_phone);
442
    vfs_release_phone(fs_phone);
473
 
443
 
474
    /*
-
 
475
     * Wait for reply from the FS server.
444
    /* Wait for reply from the FS server. */
476
     */
-
 
477
    ipcarg_t rc;
445
    ipcarg_t rc;
478
    async_wait_for(msg, &rc);
446
    async_wait_for(msg, &rc);
479
    size_t bytes = IPC_GET_ARG1(answer);
447
    size_t bytes = IPC_GET_ARG1(answer);
480
 
448
 
481
    /*
-
 
482
     * Unlock the VFS node.
449
    /* Unlock the VFS node. */
483
     */
-
 
484
    if (read)
450
    if (read)
485
        rwlock_read_unlock(&file->node->contents_rwlock);
451
        rwlock_read_unlock(&file->node->contents_rwlock);
486
    else {
452
    else {
487
        /* Update the cached version of node's size. */
453
        /* Update the cached version of node's size. */
488
        file->node->size = IPC_GET_ARG2(answer);
454
        file->node->size = IPC_GET_ARG2(answer);
489
        rwlock_write_unlock(&file->node->contents_rwlock);
455
        rwlock_write_unlock(&file->node->contents_rwlock);
490
    }
456
    }
491
 
457
 
492
    /*
-
 
493
     * Update the position pointer and unlock the open file.
458
    /* Update the position pointer and unlock the open file. */
494
     */
-
 
495
    file->pos += bytes;
459
    file->pos += bytes;
496
    futex_up(&file->lock);
460
    futex_up(&file->lock);
497
 
461
 
498
    /*
462
    /*
499
     * FS server's reply is the final result of the whole operation we
463
     * FS server's reply is the final result of the whole operation we
Line 517... Line 481...
517
    int fd = (int) IPC_GET_ARG1(*request);
481
    int fd = (int) IPC_GET_ARG1(*request);
518
    off_t off = (off_t) IPC_GET_ARG2(*request);
482
    off_t off = (off_t) IPC_GET_ARG2(*request);
519
    int whence = (int) IPC_GET_ARG3(*request);
483
    int whence = (int) IPC_GET_ARG3(*request);
520
 
484
 
521
 
485
 
522
    /*
-
 
523
     * Lookup the file structure corresponding to the file descriptor.
486
    /* Lookup the file structure corresponding to the file descriptor. */
524
     */
-
 
525
    vfs_file_t *file = vfs_file_get(fd);
487
    vfs_file_t *file = vfs_file_get(fd);
526
    if (!file) {
488
    if (!file) {
527
        ipc_answer_0(rid, ENOENT);
489
        ipc_answer_0(rid, ENOENT);
528
        return;
490
        return;
529
    }
491
    }
Line 579... Line 541...
579
    }
541
    }
580
    futex_down(&file->lock);
542
    futex_down(&file->lock);
581
 
543
 
582
    rwlock_write_lock(&file->node->contents_rwlock);
544
    rwlock_write_lock(&file->node->contents_rwlock);
583
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
545
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
584
    rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)file->node->dev_handle,
546
    rc = async_req_3_0(fs_phone, VFS_TRUNCATE,
585
        (ipcarg_t)file->node->index, (ipcarg_t)size);
547
        (ipcarg_t)file->node->dev_handle, (ipcarg_t)file->node->index,
-
 
548
        (ipcarg_t)size);
586
    vfs_release_phone(fs_phone);
549
    vfs_release_phone(fs_phone);
587
    if (rc == EOK)
550
    if (rc == EOK)
588
        file->node->size = size;
551
        file->node->size = size;
589
    rwlock_write_unlock(&file->node->contents_rwlock);
552
    rwlock_write_unlock(&file->node->contents_rwlock);
590
 
553
 
591
    futex_up(&file->lock);
554
    futex_up(&file->lock);
592
    ipc_answer_0(rid, rc);
555
    ipc_answer_0(rid, rc);
593
}
556
}
594
 
557
 
-
 
558
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
-
 
559
{
-
 
560
    int mode = IPC_GET_ARG1(*request);
-
 
561
    size_t len;
-
 
562
 
-
 
563
    ipc_callid_t callid;
-
 
564
 
-
 
565
    if (!ipc_data_write_receive(&callid, &len)) {
-
 
566
        ipc_answer_0(callid, EINVAL);
-
 
567
        ipc_answer_0(rid, EINVAL);
-
 
568
        return;
-
 
569
    }
-
 
570
 
-
 
571
    /*
-
 
572
     * Now we are on the verge of accepting the path.
-
 
573
     *
-
 
574
     * There is one optimization we could do in the future: copy the path
-
 
575
     * directly into the PLB using some kind of a callback.
-
 
576
     */
-
 
577
    char *path = malloc(len);
-
 
578
   
-
 
579
    if (!path) {
-
 
580
        ipc_answer_0(callid, ENOMEM);
-
 
581
        ipc_answer_0(rid, ENOMEM);
-
 
582
        return;
-
 
583
    }
-
 
584
 
-
 
585
    int rc;
-
 
586
    if ((rc = ipc_data_write_finalize(callid, path, len))) {
-
 
587
        ipc_answer_0(rid, rc);
-
 
588
        free(path);
-
 
589
        return;
-
 
590
    }
-
 
591
   
-
 
592
    rwlock_write_lock(&namespace_rwlock);
-
 
593
    int lflag = L_DIRECTORY | L_CREATE | L_EXCLUSIVE;
-
 
594
    rc = vfs_lookup_internal(path, len, lflag, NULL, NULL);
-
 
595
    rwlock_write_unlock(&namespace_rwlock);
-
 
596
    free(path);
-
 
597
    ipc_answer_0(rid, rc);
-
 
598
}
-
 
599
 
595
/**
600
/**
596
 * @}
601
 * @}
597
 */
602
 */