Subversion Repositories HelenOS

Rev

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

Rev 2742 Rev 2748
Line 50... Line 50...
50
#include <fcntl.h>
50
#include <fcntl.h>
51
#include <assert.h>
51
#include <assert.h>
52
#include <atomic.h>
52
#include <atomic.h>
53
#include "vfs.h"
53
#include "vfs.h"
54
 
54
 
-
 
55
/* Forward declarations of static functions. */
-
 
56
static int vfs_truncate_internal(int, int, unsigned long, size_t);
-
 
57
 
55
/**
58
/**
56
 * This rwlock prevents the race between a triplet-to-VFS-node resolution and a
59
 * This rwlock prevents the race between a triplet-to-VFS-node resolution and a
57
 * concurrent VFS operation which modifies the file system namespace.
60
 * concurrent VFS operation which modifies the file system namespace.
58
 */
61
 */
59
RWLOCK_INITIALIZE(namespace_rwlock);
62
RWLOCK_INITIALIZE(namespace_rwlock);
Line 347... Line 350...
347
        ipc_answer_0(rid, rc);
350
        ipc_answer_0(rid, rc);
348
        free(path);
351
        free(path);
349
        return;
352
        return;
350
    }
353
    }
351
 
354
 
352
    /** Path is no longer needed. */
355
    /* Path is no longer needed. */
353
    free(path);
356
    free(path);
354
 
357
 
355
    vfs_node_t *node = vfs_node_get(&lr);
358
    vfs_node_t *node = vfs_node_get(&lr);
356
    if (lflag & L_CREATE)
359
    if (lflag & L_CREATE)
357
        rwlock_write_unlock(&namespace_rwlock);
360
        rwlock_write_unlock(&namespace_rwlock);
358
    else
361
    else
359
        rwlock_read_unlock(&namespace_rwlock);
362
        rwlock_read_unlock(&namespace_rwlock);
360
 
363
 
-
 
364
    /* Truncate the file if requested and if necessary. */
-
 
365
    if (oflag & O_TRUNC) {
-
 
366
        futex_down(&node->contents_rwlock);
-
 
367
        if (node->size) {
-
 
368
            rc = vfs_truncate_internal(node->fs_handle,
-
 
369
                node->dev_handle, node->index, 0);
-
 
370
            if (rc) {
-
 
371
                futex_up(&node->contents_rwlock);
-
 
372
                vfs_node_put(node);
-
 
373
                ipc_answer_0(rid, rc);
-
 
374
                return;
-
 
375
            }
-
 
376
            node->size = 0;
-
 
377
        }
-
 
378
        futex_up(&node->contents_rwlock);
-
 
379
    }
-
 
380
 
361
    /*
381
    /*
362
     * Get ourselves a file descriptor and the corresponding vfs_file_t
382
     * Get ourselves a file descriptor and the corresponding vfs_file_t
363
     * structure.
383
     * structure.
364
     */
384
     */
365
    int fd = vfs_fd_alloc();
385
    int fd = vfs_fd_alloc();
Line 558... Line 578...
558
    }
578
    }
559
    futex_up(&file->lock);
579
    futex_up(&file->lock);
560
    ipc_answer_0(rid, EINVAL);
580
    ipc_answer_0(rid, EINVAL);
561
}
581
}
562
 
582
 
-
 
583
int vfs_truncate_internal(int fs_handle, int dev_handle, unsigned long index,
-
 
584
    size_t size)
-
 
585
{
-
 
586
    ipcarg_t rc;
-
 
587
    int fs_phone;
-
 
588
   
-
 
589
    fs_phone = vfs_grab_phone(fs_handle);
-
 
590
    rc = async_req_3_0(fs_phone, VFS_TRUNCATE, (ipcarg_t)dev_handle,
-
 
591
        (ipcarg_t)index, (ipcarg_t)size);
-
 
592
    vfs_release_phone(fs_phone);
-
 
593
    return (int)rc;
-
 
594
}
-
 
595
 
563
void vfs_truncate(ipc_callid_t rid, ipc_call_t *request)
596
void vfs_truncate(ipc_callid_t rid, ipc_call_t *request)
564
{
597
{
565
    int fd = IPC_GET_ARG1(*request);
598
    int fd = IPC_GET_ARG1(*request);
566
    size_t size = IPC_GET_ARG2(*request);
599
    size_t size = IPC_GET_ARG2(*request);
567
    ipcarg_t rc;
600
    int rc;
568
 
601
 
569
    vfs_file_t *file = vfs_file_get(fd);
602
    vfs_file_t *file = vfs_file_get(fd);
570
    if (!file) {
603
    if (!file) {
571
        ipc_answer_0(rid, ENOENT);
604
        ipc_answer_0(rid, ENOENT);
572
        return;
605
        return;
573
    }
606
    }
574
    futex_down(&file->lock);
607
    futex_down(&file->lock);
575
 
608
 
576
    rwlock_write_lock(&file->node->contents_rwlock);
609
    rwlock_write_lock(&file->node->contents_rwlock);
577
    int fs_phone = vfs_grab_phone(file->node->fs_handle);
610
    rc = vfs_truncate_internal(file->node->fs_handle,
578
    rc = async_req_3_0(fs_phone, VFS_TRUNCATE,
-
 
579
        (ipcarg_t)file->node->dev_handle, (ipcarg_t)file->node->index,
611
        file->node->dev_handle, file->node->index, size);
580
        (ipcarg_t)size);
-
 
581
    vfs_release_phone(fs_phone);
-
 
582
    if (rc == EOK)
612
    if (rc == EOK)
583
        file->node->size = size;
613
        file->node->size = size;
584
    rwlock_write_unlock(&file->node->contents_rwlock);
614
    rwlock_write_unlock(&file->node->contents_rwlock);
585
 
615
 
586
    futex_up(&file->lock);
616
    futex_up(&file->lock);
587
    ipc_answer_0(rid, rc);
617
    ipc_answer_0(rid, (ipcarg_t)rc);
588
}
618
}
589
 
619
 
590
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
620
void vfs_mkdir(ipc_callid_t rid, ipc_call_t *request)
591
{
621
{
592
    int mode = IPC_GET_ARG1(*request);
622
    int mode = IPC_GET_ARG1(*request);