| [1] | 1 | /* | 
|---|
| [610] | 2 |  * sys_unlink.c - unlink a file or directorya from VFS | 
|---|
| [305] | 3 |  * | 
|---|
| [637] | 4 |  * Author     Alain Greiner (2016,2017,2018,2019) | 
|---|
| [1] | 5 |  * | 
|---|
| [604] | 6 |  * Copyright (c)  UPMC Sorbonne Universites | 
|---|
 | 7 |  * | 
|---|
| [1] | 8 |  * This file is part of ALMOS-kernel. | 
|---|
 | 9 |  * | 
|---|
| [604] | 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 |  * | 
|---|
| [604] | 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 | 
|---|
| [604] | 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 |  | 
|---|
| [604] | 24 | #include <kernel_config.h> | 
|---|
| [457] | 25 | #include <hal_kernel_types.h> | 
|---|
| [23] | 26 | #include <hal_uspace.h> | 
|---|
| [604] | 27 | #include <errno.h> | 
|---|
| [1] | 28 | #include <vfs.h> | 
|---|
| [23] | 29 | #include <process.h> | 
|---|
| [1] | 30 | #include <thread.h> | 
|---|
| [23] | 31 | #include <printk.h> | 
|---|
| [1] | 32 |  | 
|---|
| [506] | 33 | #include <syscalls.h> | 
|---|
 | 34 |  | 
|---|
| [23] | 35 | ////////////////////////////////// | 
|---|
| [566] | 36 | int sys_unlink ( char * pathname ) | 
|---|
| [1] | 37 | { | 
|---|
| [305] | 38 |     error_t   error; | 
|---|
| [610] | 39 |     xptr_t    root_inode_xp;           // extended pointer on path root inode | 
|---|
 | 40 |  | 
|---|
| [23] | 41 |     char      kbuf[CONFIG_VFS_MAX_PATH_LENGTH]; | 
|---|
| [1] | 42 |  | 
|---|
| [305] | 43 |     thread_t     * this     = CURRENT_THREAD; | 
|---|
 | 44 |     process_t    * process  = this->process; | 
|---|
| [23] | 45 |  | 
|---|
| [604] | 46 | #if (DEBUG_SYS_UNLINK || CONFIG_INSTRUMENTATION_SYSCALLS) | 
|---|
 | 47 | uint64_t     tm_start = hal_get_cycles(); | 
|---|
 | 48 | #endif | 
|---|
 | 49 |  | 
|---|
| [407] | 50 |     // check pathname length | 
|---|
 | 51 |     if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) | 
|---|
| [23] | 52 |     { | 
|---|
| [604] | 53 |  | 
|---|
 | 54 | #if DEBUG_SYSCALLS_ERROR | 
|---|
 | 55 | printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); | 
|---|
 | 56 | #endif | 
|---|
| [305] | 57 |         this->errno = ENFILE; | 
|---|
| [23] | 58 |         return -1; | 
|---|
 | 59 |     } | 
|---|
 | 60 |  | 
|---|
| [407] | 61 |     // copy pathname in kernel space | 
|---|
| [637] | 62 |     hal_strcpy_from_uspace( XPTR( local_cxy , kbuf ), | 
|---|
 | 63 |                             pathname, | 
|---|
 | 64 |                             CONFIG_VFS_MAX_PATH_LENGTH ); | 
|---|
| [407] | 65 |  | 
|---|
| [604] | 66 | #if DEBUG_SYS_UNLINK | 
|---|
 | 67 | if( DEBUG_SYS_UNLINK < tm_start ) | 
|---|
 | 68 | printk("\n[%s] thread[%x,%x] enter for <%s> / cycle %d\n", | 
|---|
 | 69 | __FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_start ); | 
|---|
 | 70 | #endif | 
|---|
 | 71 |   | 
|---|
| [610] | 72 |     // compute root inode for path  | 
|---|
 | 73 |     if( kbuf[0] == '/' )                        // absolute path | 
|---|
 | 74 |     { | 
|---|
 | 75 |         // use extended pointer on VFS root inode | 
|---|
 | 76 |         root_inode_xp = process->vfs_root_xp; | 
|---|
 | 77 |     } | 
|---|
 | 78 |     else                                        // relative path | 
|---|
 | 79 |     { | 
|---|
 | 80 |         // get cluster and local pointer on reference process | 
|---|
 | 81 |         xptr_t      ref_xp  = process->ref_xp; | 
|---|
 | 82 |         process_t * ref_ptr = (process_t *)GET_PTR( ref_xp ); | 
|---|
 | 83 |         cxy_t       ref_cxy = GET_CXY( ref_xp ); | 
|---|
| [23] | 84 |  | 
|---|
| [610] | 85 |         // use extended pointer on CWD inode | 
|---|
 | 86 |         root_inode_xp = hal_remote_l64( XPTR( ref_cxy , &ref_ptr->cwd_xp ) ); | 
|---|
 | 87 |     } | 
|---|
| [23] | 88 |  | 
|---|
| [610] | 89 |     // call the relevant VFS function | 
|---|
 | 90 |     error  = vfs_unlink( root_inode_xp , kbuf ); | 
|---|
| [23] | 91 |  | 
|---|
| [305] | 92 |     if( error ) | 
|---|
 | 93 |     { | 
|---|
| [604] | 94 |  | 
|---|
 | 95 | #if DEBUG_SYSCALLS_ERROR | 
|---|
 | 96 | printk("\n[ERROR] in %s : cannot unlink file/dir %s\n", __FUNCTION__, kbuf ); | 
|---|
 | 97 | #endif | 
|---|
| [305] | 98 |         this->errno = ENFILE; | 
|---|
 | 99 |         return -1; | 
|---|
 | 100 |     } | 
|---|
| [23] | 101 |  | 
|---|
| [604] | 102 | #if (DEBUG_SYS_UNLINK || CONFIG_INSTRUMENTATION_SYSCALLS) | 
|---|
 | 103 | uint64_t     tm_end = hal_get_cycles(); | 
|---|
 | 104 | #endif | 
|---|
 | 105 |  | 
|---|
 | 106 | #if DEBUG_SYS_UNLINK | 
|---|
 | 107 | if( DEBUG_SYS_UNLINK < tm_end ) | 
|---|
 | 108 | printk("\n[%s] thread[%x,%x] exit for <%s> / cycle %d\n", | 
|---|
 | 109 | __FUNCTION__, process->pid, this->trdid, kbuf, (uint32_t)tm_end ); | 
|---|
 | 110 | #endif | 
|---|
 | 111 |   | 
|---|
 | 112 | #if CONFIG_INSTRUMENTATION_SYSCALLS | 
|---|
 | 113 | hal_atomic_add( &syscalls_cumul_cost[SYS_UNLINK] , tm_end - tm_start ); | 
|---|
 | 114 | hal_atomic_add( &syscalls_occurences[SYS_UNLINK] , 1 ); | 
|---|
 | 115 | #endif | 
|---|
 | 116 |  | 
|---|
| [305] | 117 |     return 0; | 
|---|
| [23] | 118 |  | 
|---|
 | 119 | } // end sys_unlink() | 
|---|