Ignore:
Timestamp:
Jan 9, 2019, 3:02:51 PM (5 years ago)
Author:
alain
Message:

Introduce sigificant modifs in VFS to support the <ls> command,
and the . and .. directories entries.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/syscalls/sys_readdir.c

    r473 r611  
    11/*
    2  * sys_readdir.c - Read one entry from an open directory.
     2 * sys_readdir.c - Copy one entry from an open VFS directory to an user buffer.
    33 *
    4  * Author    Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017,2018)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    3030#include <vfs.h>
    3131#include <process.h>
     32#include <remote_dir.h>
    3233#include <syscalls.h>
    3334#include <shared_syscalls.h>
     
    3536///////////////////////////////////////
    3637int sys_readdir( DIR            * dirp,
    37                  struct dirent ** dentp )
     38                 struct dirent ** buffer )
    3839{
    39     printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__, dirp, dentp );
    40     return -1;
     40    error_t         error;
     41    vseg_t        * vseg;               // for user space checking of buffer
     42    xptr_t          dir_xp;             // extended pointer on remote_dir_t structure
     43    remote_dir_t  * dir_ptr;            // local pointer on remote_dir_t structure
     44    cxy_t           dir_cxy;            // remote_dir_t stucture cluster identifier
     45    struct dirent * direntp;            // dirent pointer in user space 
     46    uint32_t        entries;            // total number of dirent entries
     47    uint32_t        current;            // current dirent index
     48
     49        thread_t  * this    = CURRENT_THREAD;  // client thread
     50        process_t * process = this->process;   // client process
     51
     52#if (DEBUG_SYS_READDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     53uint64_t     tm_start = hal_get_cycles();
     54#endif
     55
     56#if DEBUG_SYS_READDIR
     57if( DEBUG_SYS_READDIR < tm_start )
     58printk("\n[%s] thread[%x,%x] enter / dirp %x / cycle %d\n",
     59__FUNCTION__, process->pid, this->trdid, dirp, (uint32_t)tm_start );
     60#endif
     61 
     62    // check buffer in user space
     63    error = vmm_get_vseg( process , (intptr_t)buffer, &vseg );
     64
     65        if( error )
     66        {
     67
     68#if DEBUG_SYSCALLS_ERROR
     69printk("\n[ERROR] in %s / thread[%x,%x] : user buffer %x unmapped\n",
     70__FUNCTION__ , process->pid , this->trdid, buffer );
     71vmm_display( process , false );
     72#endif
     73                this->errno = EINVAL;
     74                return -1;
     75        }       
     76
     77    // get pointers on remote_dir_t structure from dirp
     78    dir_xp  = remote_dir_from_ident( (intptr_t)dirp );
     79    dir_ptr = GET_PTR( dir_xp );
     80    dir_cxy = GET_CXY( dir_xp );
     81
     82    if( dir_xp == XPTR_NULL )
     83        {
     84
     85#if DEBUG_SYSCALLS_ERROR
     86printk("\n[ERROR] in %s / thread[%x,%x] : dirp %x not registered\n",
     87__FUNCTION__ , process->pid , this->trdid, dirp );
     88#endif
     89                this->errno = EBADF;
     90                return -1;
     91        }       
     92
     93    // get "current" and "entries_nr" values from remote_dir_t structure
     94    current = hal_remote_l32( XPTR( dir_cxy , &dir_ptr->current ) );
     95    entries = hal_remote_l32( XPTR( dir_cxy , &dir_ptr->entries ) );
     96
     97    // check "current" index
     98    if( current >= entries )
     99    {
     100        this->errno = 0;
     101        return -1;
     102    }
     103
     104    // compute dirent pointer in user space
     105    direntp = (struct dirent *)dirp + current;
     106
     107#if (DEBUG_SYS_READDIR & 1)
     108if( DEBUG_SYS_READDIR < tm_start )
     109printk("\n[%s] entries = %d / current = %d / direntp = %x\n",
     110__FUNCTION__, entries, current, direntp );
     111#endif
     112
     113    // copy dirent pointer to user buffer
     114    hal_copy_to_uspace( buffer, &direntp , sizeof(void *) );
     115
     116    // update current index in "remote_dir_t" structure
     117    hal_remote_atomic_add( XPTR( dir_cxy , &dir_ptr->current ) , 1 );
     118
     119    hal_fence();
     120
     121#if (DEBUG_SYS_READDIR || CONFIG_INSTRUMENTATION_SYSCALLS)
     122uint64_t     tm_end = hal_get_cycles();
     123#endif
     124
     125#if DEBUG_SYS_READDIR
     126if( DEBUG_SYS_READDIR < tm_end )
     127printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
     128__FUNCTION__, process->pid, this->trdid, (uint32_t)tm_end );
     129#endif
     130 
     131#if CONFIG_INSTRUMENTATION_SYSCALLS
     132hal_atomic_add( &syscalls_cumul_cost[SYS_READDIR] , tm_end - tm_start );
     133hal_atomic_add( &syscalls_occurences[SYS_READDIR] , 1 );
     134#endif
     135
     136        return 0;
     137
    41138}  // end sys_readdir()
Note: See TracChangeset for help on using the changeset viewer.