Subversion Repositories HelenOS

Rev

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

Rev 4555 Rev 4566
Line 52... Line 52...
52
#include <vfs/canonify.h>
52
#include <vfs/canonify.h>
53
 
53
 
54
/* Forward declarations of static functions. */
54
/* Forward declarations of static functions. */
55
static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t);
55
static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t);
56
 
56
 
57
/** Pending mount structure. */
-
 
58
typedef struct {
-
 
59
    link_t link;
-
 
60
    char *fs_name;            /**< File system name */
-
 
61
    char *mp;                 /**< Mount point */
-
 
62
    char *opts;       /**< Mount options. */
-
 
63
    ipc_callid_t callid;      /**< Call ID waiting for the mount */
-
 
64
    ipc_callid_t rid;         /**< Request ID */
-
 
65
    dev_handle_t dev_handle;  /**< Device handle */
-
 
66
} pending_req_t;
-
 
67
 
-
 
68
FIBRIL_CONDVAR_INITIALIZE(pending_cv);
-
 
69
bool pending_new_fs = false;    /**< True if a new file system was mounted. */
-
 
70
LIST_INITIALIZE(pending_req);
-
 
71
 
-
 
72
/**
57
/**
73
 * This rwlock prevents the race between a triplet-to-VFS-node resolution and a
58
 * This rwlock prevents the race between a triplet-to-VFS-node resolution and a
74
 * concurrent VFS operation which modifies the file system namespace.
59
 * concurrent VFS operation which modifies the file system namespace.
75
 */
60
 */
76
FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock);
61
FIBRIL_RWLOCK_INITIALIZE(namespace_rwlock);
Line 258... Line 243...
258
 
243
 
259
    ipc_answer_0(rid, rc);
244
    ipc_answer_0(rid, rc);
260
    fibril_rwlock_write_unlock(&namespace_rwlock);
245
    fibril_rwlock_write_unlock(&namespace_rwlock);
261
}
246
}
262
 
247
 
263
/** Process pending mount requests */
-
 
264
void vfs_process_pending_mount(void)
-
 
265
{
-
 
266
    link_t *cur;
-
 
267
   
-
 
268
    while (true) {
-
 
269
        fibril_mutex_lock(&fs_head_lock);
-
 
270
        while (!pending_new_fs)
-
 
271
            fibril_condvar_wait(&pending_cv, &fs_head_lock);
-
 
272
rescan:
-
 
273
        for (cur = pending_req.next; cur != &pending_req;
-
 
274
            cur = cur->next) {
-
 
275
            pending_req_t *pr = list_get_instance(cur,
-
 
276
                pending_req_t, link);
-
 
277
            fs_handle_t fs_handle = fs_name_to_handle(pr->fs_name,
-
 
278
                false);
-
 
279
            if (!fs_handle)
-
 
280
                continue;
-
 
281
       
-
 
282
            /* Acknowledge that we know fs_name. */
-
 
283
            ipc_answer_0(pr->callid, EOK);
-
 
284
       
-
 
285
            list_remove(cur);
-
 
286
            fibril_mutex_unlock(&fs_head_lock);
-
 
287
           
-
 
288
            /* Do the mount */
-
 
289
            vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle,
-
 
290
                pr->mp, pr->opts);
-
 
291
 
-
 
292
            free(pr->fs_name);
-
 
293
            free(pr->mp);
-
 
294
            free(pr->opts);
-
 
295
            free(pr);
-
 
296
       
-
 
297
            fibril_mutex_lock(&fs_head_lock);
-
 
298
            goto rescan;
-
 
299
        }
-
 
300
        pending_new_fs = false;
-
 
301
        fibril_mutex_unlock(&fs_head_lock);
-
 
302
    }
-
 
303
}
-
 
304
 
-
 
305
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
248
void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
306
{
249
{
307
    /*
250
    /*
308
     * We expect the library to do the device-name to device-handle
251
     * We expect the library to do the device-name to device-handle
309
     * translation for us, thus the device handle will arrive as ARG1
252
     * translation for us, thus the device handle will arrive as ARG1
Line 454... Line 397...
454
    /*
397
    /*
455
     * Check if we know a file system with the same name as is in fs_name.
398
     * Check if we know a file system with the same name as is in fs_name.
456
     * This will also give us its file system handle.
399
     * This will also give us its file system handle.
457
     */
400
     */
458
    fibril_mutex_lock(&fs_head_lock);
401
    fibril_mutex_lock(&fs_head_lock);
-
 
402
    fs_handle_t fs_handle;
-
 
403
recheck:
459
    fs_handle_t fs_handle = fs_name_to_handle(fs_name, false);
404
    fs_handle = fs_name_to_handle(fs_name, false);
460
    if (!fs_handle) {
405
    if (!fs_handle) {
461
        if (flags & IPC_FLAG_BLOCKING) {
406
        if (flags & IPC_FLAG_BLOCKING) {
462
            pending_req_t *pr;
-
 
463
 
-
 
464
            /* Blocking mount, add to pending list */
-
 
465
            pr = (pending_req_t *) malloc(sizeof(pending_req_t));
-
 
466
            if (!pr) {
-
 
467
                fibril_mutex_unlock(&fs_head_lock);
407
            fibril_condvar_wait(&fs_head_cv, &fs_head_lock);
468
                ipc_answer_0(callid, ENOMEM);
-
 
469
                ipc_answer_0(rid, ENOMEM);
-
 
470
                free(mp);
408
            goto recheck;
471
                free(fs_name);
-
 
472
                free(opts);
-
 
473
                return;
-
 
474
            }
-
 
475
           
-
 
476
            pr->fs_name = fs_name;
-
 
477
            pr->mp = mp;
-
 
478
            pr->opts = opts;
-
 
479
            pr->callid = callid;
-
 
480
            pr->rid = rid;
-
 
481
            pr->dev_handle = dev_handle;
-
 
482
            link_initialize(&pr->link);
-
 
483
            list_append(&pr->link, &pending_req);
-
 
484
            fibril_mutex_unlock(&fs_head_lock);
-
 
485
            return;
-
 
486
        }
409
        }
487
       
410
       
488
        fibril_mutex_unlock(&fs_head_lock);
411
        fibril_mutex_unlock(&fs_head_lock);
489
        ipc_answer_0(callid, ENOENT);
412
        ipc_answer_0(callid, ENOENT);
490
        ipc_answer_0(rid, ENOENT);
413
        ipc_answer_0(rid, ENOENT);