source: trunk/kernel/syscalls/sys_open.c @ 628

Last change on this file since 628 was 625, checked in by alain, 6 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 4.0 KB
RevLine 
[1]1/*
[23]2 * sys_open.c - open a file.
[305]3 *
[625]4 * Author        Alain Greiner (2016,2017,2018,2019)
[1]5 *
[23]6 * Copyright (c) UPMC Sorbonne Universites
[1]7 *
[23]8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
[1]11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
[23]14 * ALMOS-MKH is distributed in the hope that it will be useful, but
[1]15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
[23]20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
[1]21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[23]24#include <kernel_config.h>
[457]25#include <hal_kernel_types.h>
[23]26#include <hal_uspace.h>
[1]27#include <errno.h>
28#include <thread.h>
[23]29#include <printk.h>
[1]30#include <vfs.h>
31#include <process.h>
[23]32#include <remote_rwlock.h>
[1]33
[506]34#include <syscalls.h>
35
[1]36///////////////////////////////////
[566]37int sys_open ( char     * pathname,
38               uint32_t   flags,
39               uint32_t   mode )
[1]40{
[305]41    error_t        error;
[610]42    xptr_t         file_xp;                 // extended pointer on vfs_file_t
43    uint32_t       file_id;                 // file descriptor index
44    xptr_t         root_inode_xp;           // extended pointer on path root inode
45
[23]46    char           kbuf[CONFIG_VFS_MAX_PATH_LENGTH];
[1]47
[305]48    thread_t     * this     = CURRENT_THREAD;
49    process_t    * process  = this->process;
[1]50
[594]51#if (DEBUG_SYS_OPEN || CONFIG_INSTRUMENTATION_SYSCALLS)
52uint64_t     tm_start = hal_get_cycles();
[459]53#endif
[594]54
[23]55    // check fd_array not full
[305]56    if( process_fd_array_full() )
57    {
[566]58
59#if DEBUG_SYSCALLS_ERROR
60printk("\n[ERROR] in %s : file descriptor array full for process %x\n",
61__FUNCTION__ , process->pid );
62#endif
[305]63        this->errno = ENFILE;
[23]64        return -1;
[305]65    }
[1]66
[407]67    // check pathname length
68    if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH )
[23]69    {
[566]70
71#if DEBUG_SYSCALLS_ERROR
72printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ );
73#endif
[305]74        this->errno = ENFILE;
[23]75        return -1;
76    }
[1]77
[407]78    // copy pathname in kernel space
79    hal_strcpy_from_uspace( kbuf , pathname , CONFIG_VFS_MAX_PATH_LENGTH );
80
[459]81#if DEBUG_SYS_OPEN
82if( DEBUG_SYS_OPEN < tm_start )
[594]83printk("\n[%s] thread[%x,%x] enter for <%s> / flags %x / cycle %d\n",
84__FUNCTION__, process->pid, this->trdid, kbuf, flags, (uint32_t)tm_start );
[459]85#endif
86 
[23]87    // get cluster and local pointer on reference process
88    xptr_t      ref_xp  = process->ref_xp;
89    process_t * ref_ptr = (process_t *)GET_PTR( ref_xp );
90    cxy_t       ref_cxy = GET_CXY( ref_xp );
91
[610]92    // compute root inode for path
93    if( kbuf[0] == '/' )                        // absolute path
94    {
95        // use extended pointer on VFS root inode
96        root_inode_xp = process->vfs_root_xp;
97    }
98    else                                        // relative path
99    {
100        // use extended pointer on CWD inode
101        root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) );
102    }
[23]103
104    // call the relevant VFS function
[610]105    error = vfs_open( root_inode_xp,
[23]106                      kbuf,
[610]107                      ref_xp,
[23]108                      flags,
109                      mode,
110                      &file_xp,
111                      &file_id );
112
[305]113    if( error )
114    {
[459]115        printk("\n[ERROR] in %s : cannot create file descriptor for %s\n",
116        __FUNCTION__ , kbuf );
[305]117        this->errno = ENFILE;
118        return -1;
119    }
[1]120
[599]121    hal_fence();
[594]122
123#if (DEBUG_SYS_OPEN || CONFIG_INSTRUMENTATION_SYSCALLS)
124uint64_t     tm_end = hal_get_cycles();
125#endif
126
[459]127#if DEBUG_SYS_OPEN
[604]128if( DEBUG_SYS_OPEN < tm_end )
[594]129printk("\n[%s] thread[%x,%x] exit for <%s> / cycle %d\n",
130__FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_end );
[459]131#endif
132 
[594]133#if CONFIG_INSTRUMENTATION_SYSCALLS
134hal_atomic_add( &syscalls_cumul_cost[SYS_OPEN] , tm_end - tm_start );
135hal_atomic_add( &syscalls_occurences[SYS_OPEN] , 1 );
136#endif
137
[305]138    return file_id;
[1]139}
Note: See TracBrowser for help on using the repository browser.