Changeset 238 for trunk/kernel
- Timestamp:
- Jul 19, 2017, 3:31:39 PM (7 years ago)
- Location:
- trunk/kernel
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_dma.c
r188 r238 40 40 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 41 41 42 ////////////////////////////////// //43 void dev_dma_init( chdev_t * chdev)42 ////////////////////////////////// 43 void dev_dma_init( chdev_t * dma ) 44 44 { 45 // get implementation & channel from DMA chdevdescriptor46 uint32_t impl = chdev->impl;47 uint32_t channel = chdev->channel;45 // get implementation & channel from DMA dma descriptor 46 uint32_t impl = dma->impl; 47 uint32_t channel = dma->channel; 48 48 49 // set chdevname50 snprintf( chdev->name , 16 , "dma_%d_%x" , channel , local_cxy );49 // set dma name 50 snprintf( dma->name , 16 , "dma_%d_%x" , channel , local_cxy ); 51 51 52 52 // set field "cmd", "isr", and call the relevant driver init function 53 53 if( impl == IMPL_DMA_SCL ) 54 54 { 55 chdev->cmd = &soclib_dma_cmd;56 chdev->isr = &soclib_dma_isr;57 soclib_dma_init( chdev);55 dma->cmd = &soclib_dma_cmd; 56 dma->isr = &soclib_dma_isr; 57 soclib_dma_init( dma ); 58 58 } 59 59 else … … 63 63 64 64 // bind IRQ to the core defined by the DMA channel 65 dev_pic_bind_irq( channel , chdev);65 dev_pic_bind_irq( channel , dma ); 66 66 67 67 // enable IRQ 68 dev_pic_enable_irq( channel, chdev);68 dev_pic_enable_irq( channel, XPTR( local_cxy , dma ) ); 69 69 70 70 // create server thread … … 75 75 THREAD_DEV, 76 76 &chdev_sequencial_server, 77 chdev,77 dma, 78 78 cluster_select_local_core() ); 79 79 if( error ) … … 83 83 84 84 // initialises server field in DMA chdev descriptor 85 chdev->server = new_thread;85 dma->server = new_thread; 86 86 87 87 // start server thread -
trunk/kernel/devices/dev_ioc.c
r216 r238 63 63 64 64 // enable IRQ 65 dev_pic_enable_irq( lid , ioc);65 dev_pic_enable_irq( lid , XPTR( local_cxy , ioc ) ); 66 66 67 67 // create server thread -
trunk/kernel/devices/dev_mmc.c
r188 r238 36 36 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 37 37 38 ////////////////////////////////// //39 void dev_mmc_init( chdev_t * chdev)38 ////////////////////////////////// 39 void dev_mmc_init( chdev_t * mmc ) 40 40 { 41 41 // get implementation from device descriptor 42 uint32_t impl = chdev->impl;43 44 // set chdevname45 snprintf( chdev->name , 16 , "mmc_%x" , local_cxy );42 uint32_t impl = mmc->impl; 43 44 // set mmc name 45 snprintf( mmc->name , 16 , "mmc_%x" , local_cxy ); 46 46 47 47 // set driver specific fields in device descriptor and call driver init function 48 48 if( impl == IMPL_MMC_TSR ) 49 49 { 50 chdev->cmd = &soclib_mmc_cmd;51 chdev->isr = &soclib_mmc_isr;52 soclib_mmc_init( chdev);50 mmc->cmd = &soclib_mmc_cmd; 51 mmc->isr = &soclib_mmc_isr; 52 soclib_mmc_init( mmc ); 53 53 } 54 54 else … … 58 58 59 59 // bind IRQ to CP0 60 dev_pic_bind_irq( 0 , chdev);60 dev_pic_bind_irq( 0 , mmc ); 61 61 62 62 // enable IRQ 63 dev_pic_enable_irq( 0 , chdev);63 dev_pic_enable_irq( 0 , XPTR( local_cxy , mmc ) ); 64 64 65 65 } // end dev_mmc_init() -
trunk/kernel/devices/dev_nic.c
r188 r238 133 133 { 134 134 // enable NIC-RX IRQ 135 dev_pic_enable_irq( core->lid , dev_ ptr);135 dev_pic_enable_irq( core->lid , dev_xp ); 136 136 137 137 // block on THREAD_BLOCKED_IO condition and deschedule … … 140 140 141 141 // disable NIC-RX IRQ 142 dev_pic_disable_irq( core->lid , dev_ ptr);142 dev_pic_disable_irq( core->lid , dev_xp ); 143 143 } 144 144 … … 203 203 { 204 204 // enable NIC-TX IRQ 205 dev_pic_enable_irq( core->lid ,dev_ ptr);205 dev_pic_enable_irq( core->lid ,dev_xp ); 206 206 207 207 // block on THREAD_BLOCKED I/O condition and deschedule … … 210 210 211 211 // disable NIC-TX IRQ 212 dev_pic_disable_irq( core->lid , dev_ ptr);212 dev_pic_disable_irq( core->lid , dev_xp ); 213 213 } 214 214 -
trunk/kernel/devices/dev_txt.c
r188 r238 77 77 78 78 // enable TXT IRQ 79 dev_pic_enable_irq( lid , txt);79 dev_pic_enable_irq( lid , XPTR( local_cxy , txt ) ); 80 80 81 81 // create server thread -
trunk/kernel/kern/rpc.c
r188 r238 66 66 &rpc_vfs_file_create_server, // 14 67 67 &rpc_vfs_file_destroy_server, // 15 68 &rpc_ fatfs_get_cluster_server,// 1669 &rpc_ undefined,// 1770 &rpc_ undefined,// 1868 &rpc_vfs_inode_load_server, // 16 69 &rpc_vfs_mapper_load_all_server, // 17 70 &rpc_fatfs_get_cluster_server, // 18 71 71 &rpc_undefined, // 19 72 72 … … 100 100 uint32_t * ppn ) // out 101 101 { 102 // any RPC must be remote 103 if( cxy == local_cxy ) 104 { 105 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 106 hal_core_sleep(); 107 } 102 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 108 103 109 104 // initialise RPC descriptor header … … 157 152 pid_t * pid ) // out 158 153 { 159 // RPC must be remote 160 if( cxy == local_cxy ) 161 { 162 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 163 hal_core_sleep(); 164 } 154 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 165 155 166 156 // initialise RPC descriptor header … … 213 203 error_t * error ) // out 214 204 { 215 // RPC must be remote 216 if( cxy == local_cxy ) 217 { 218 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 219 hal_core_sleep(); 220 } 205 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 221 206 222 207 // initialise RPC descriptor header … … 270 255 { 271 256 // only reference cluster can send this RPC 272 if( GET_CXY( process->ref_xp ) != local_cxy ) 273 { 274 printk("PANIC in %s : caller is not the reference process\n", __FUNCTION__ ); 275 hal_core_sleep(); 276 } 257 assert( (GET_CXY( process->ref_xp ) == local_cxy) , __FUNCTION__ , 258 "caller must be reference process cluster\n"); 277 259 278 260 // get local process index in reference cluster … … 344 326 error_t * error ) // out 345 327 { 346 // RPC must be remote 347 if( cxy == local_cxy ) 348 { 349 printk("\n[PANIC] in %s : target is not remote\n", __FUNCTION__ ); 350 hal_core_sleep(); 351 } 328 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 352 329 353 330 // initialise RPC descriptor header … … 427 404 error_t * error ) // out 428 405 { 429 // RPC must be remote 430 if( cxy == local_cxy ) 431 { 432 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 433 hal_core_sleep(); 434 } 406 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 435 407 436 408 // initialise RPC descriptor header … … 490 462 uint32_t sig_id ) // in 491 463 { 492 // RPC must be remote 493 if( cxy == local_cxy ) 494 { 495 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 496 hal_core_sleep(); 497 } 464 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 498 465 499 466 // initialise RPC descriptor header … … 545 512 error_t * error ) // out 546 513 { 547 // RPC must be remote 548 if( cxy == local_cxy ) 549 { 550 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 551 hal_core_sleep(); 552 } 514 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 553 515 554 516 // initialise RPC descriptor header … … 627 589 struct vfs_inode_s * inode ) 628 590 { 629 // RPC must be remote 630 if( cxy == local_cxy ) 631 { 632 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 633 hal_core_sleep(); 634 } 591 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 635 592 636 593 // initialise RPC descriptor header … … 674 631 error_t * error ) // out 675 632 { 676 // RPC must be remote 677 if( cxy == local_cxy ) 678 { 679 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 680 hal_core_sleep(); 681 } 633 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 682 634 683 635 // initialise RPC descriptor header … … 689 641 rpc.args[0] = (uint64_t)type; 690 642 rpc.args[1] = (uint64_t)(intptr_t)name; 691 rpc.args[2] = (uint64_t)strlen( name ); 692 rpc.args[3] = (uint64_t)(intptr_t)parent; 643 rpc.args[2] = (uint64_t)(intptr_t)parent; 693 644 694 645 // register RPC request in remote RPC fifo (blocking function) … … 696 647 697 648 // get output values from RPC descriptor 698 *dentry_xp = (xptr_t)rpc.args[ 4];699 *error = (error_t)rpc.args[ 5];649 *dentry_xp = (xptr_t)rpc.args[3]; 650 *error = (error_t)rpc.args[4]; 700 651 } 701 652 … … 707 658 vfs_inode_t * parent; 708 659 xptr_t dentry_xp; 660 error_t error; 661 709 662 char name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; 710 uint32_t length;711 error_t error;712 663 713 664 // get client cluster identifier and pointer on RPC descriptor … … 715 666 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 716 667 717 // get argument "name" & "length" from client RPC descriptor and makes a local copy 718 name = (char *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 719 length = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); 720 hal_remote_memcpy( XPTR( local_cxy , name_copy ), 721 XPTR( client_cxy , name ), 722 length + 1 ); // +1 for the NUL char 723 724 // get arguments "type" and "parent" from client RPC descriptor 668 // get arguments "name", "type", and "parent" from client RPC descriptor 725 669 type = (uint32_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 726 parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) ); 670 name = (char *)(intptr_t) hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 671 parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); 727 672 673 // makes a local copy of name 674 hal_remote_strcpy( XPTR( local_cxy , name_copy ), 675 XPTR( client_cxy , name ) ); 676 728 677 // call local kernel function 729 678 error = vfs_dentry_create( type, … … 733 682 734 683 // set output arguments 735 hal_remote_swd( XPTR( client_cxy , &desc->args[ 4] ) , (uint64_t)dentry_xp );736 hal_remote_swd( XPTR( client_cxy , &desc->args[ 5] ) , (uint64_t)error );684 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp ); 685 hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error ); 737 686 } 738 687 … … 745 694 vfs_dentry_t * dentry ) 746 695 { 747 // RPC must be remote 748 if( cxy == local_cxy ) 749 { 750 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 751 hal_core_sleep(); 752 } 696 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 753 697 754 698 // initialise RPC descriptor header … … 792 736 error_t * error ) // out 793 737 { 794 // RPC must be remote 795 if( cxy == local_cxy ) 796 { 797 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 798 hal_core_sleep(); 799 } 738 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 800 739 801 740 // initialise RPC descriptor header … … 850 789 vfs_file_t * file ) 851 790 { 852 // RPC must be remote 853 if( cxy == local_cxy ) 854 { 855 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 856 hal_core_sleep(); 857 } 791 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 858 792 859 793 // initialise RPC descriptor header … … 886 820 887 821 ///////////////////////////////////////////////////////////////////////////////////////// 888 // [16] Marshaling functions attached to RPC_FATFS_GET_CLUSTER 822 // [16] Marshaling functions attached to RPC_VFS_INODE_LOAD 823 ///////////////////////////////////////////////////////////////////////////////////////// 824 825 ////////////////////////////////////////////////// 826 void rpc_vfs_inode_load_client( cxy_t cxy, 827 vfs_inode_t * parent_inode, // in 828 char * name, // in 829 xptr_t child_inode_xp, // in 830 error_t * error ) // out 831 { 832 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 833 834 // initialise RPC descriptor header 835 rpc_desc_t rpc; 836 rpc.index = RPC_VFS_INODE_LOAD; 837 rpc.response = 1; 838 839 // set input arguments in RPC descriptor 840 rpc.args[0] = (uint64_t)(intptr_t)parent_inode; 841 rpc.args[1] = (uint64_t)(intptr_t)name; 842 rpc.args[2] = (uint64_t)child_inode_xp; 843 844 // register RPC request in remote RPC fifo (blocking function) 845 rpc_send_sync( cxy , &rpc ); 846 847 // get output values from RPC descriptor 848 *error = (error_t)rpc.args[3]; 849 } 850 851 /////////////////////////////////////////// 852 void rpc_vfs_inode_load_server( xptr_t xp ) 853 { 854 error_t error; 855 vfs_inode_t * parent; 856 xptr_t child_xp; 857 char * name; 858 859 char name_copy[CONFIG_VFS_MAX_NAME_LENGTH]; 860 861 // get client cluster identifier and pointer on RPC descriptor 862 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 863 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 864 865 // get arguments "parent", "name", and "child_xp" 866 parent = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0])); 867 name = (char*)(intptr_t) hal_remote_lwd(XPTR(client_cxy , &desc->args[1])); 868 child_xp = (xptr_t) hal_remote_lwd(XPTR(client_cxy , &desc->args[2])); 869 870 // get name local copy 871 hal_remote_strcpy( XPTR( local_cxy , name_copy ) , 872 XPTR( client_cxy , name ) ); 873 874 // call the kernel function 875 error = vfs_inode_load( parent , name_copy , child_xp ); 876 877 // set output argument 878 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); 879 } 880 881 ///////////////////////////////////////////////////////////////////////////////////////// 882 // [17] Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL 883 ///////////////////////////////////////////////////////////////////////////////////////// 884 885 /////////////////////////////////////////////////////// 886 void rpc_vfs_mapper_load_all_client( cxy_t cxy, 887 vfs_inode_t * inode, // in 888 error_t * error ) // out 889 { 890 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 891 892 // initialise RPC descriptor header 893 rpc_desc_t rpc; 894 rpc.index = RPC_VFS_INODE_LOAD; 895 rpc.response = 1; 896 897 // set input arguments in RPC descriptor 898 rpc.args[0] = (uint64_t)(intptr_t)inode; 899 900 // register RPC request in remote RPC fifo (blocking function) 901 rpc_send_sync( cxy , &rpc ); 902 903 // get output values from RPC descriptor 904 *error = (error_t)rpc.args[1]; 905 } 906 907 //////////////////////////////////////////////// 908 void rpc_vfs_mapper_load_all_server( xptr_t xp ) 909 { 910 error_t error; 911 vfs_inode_t * inode; 912 913 // get client cluster identifier and pointer on RPC descriptor 914 cxy_t client_cxy = (cxy_t)GET_CXY( xp ); 915 rpc_desc_t * desc = (rpc_desc_t *)GET_PTR( xp ); 916 917 // get arguments "parent", "name", and "child_xp" 918 inode = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0])); 919 920 // call the kernel function 921 error = vfs_mapper_load_all( inode ); 922 923 // set output argument 924 hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error ); 925 } 926 927 ///////////////////////////////////////////////////////////////////////////////////////// 928 // [18] Marshaling functions attached to RPC_FATFS_GET_CLUSTER 889 929 ///////////////////////////////////////////////////////////////////////////////////////// 890 930 … … 897 937 error_t * error ) // out 898 938 { 899 // RPC must be remote 900 if( cxy == local_cxy ) 901 { 902 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 903 hal_core_sleep(); 904 } 939 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 905 940 906 941 // initialise RPC descriptor header … … 958 993 xptr_t * vseg_xp ) // out 959 994 { 960 // RPC must be remote 961 if( cxy == local_cxy ) 962 { 963 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 964 hal_core_sleep(); 965 } 995 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 966 996 967 997 // initialise RPC descriptor header … … 1019 1049 error_t * error ) // out 1020 1050 { 1021 // RPC must be remote 1022 if( cxy == local_cxy ) 1023 { 1024 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 1025 hal_core_sleep(); 1026 } 1051 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1027 1052 1028 1053 // initialise RPC descriptor header … … 1079 1104 xptr_t * buf_xp ) // out 1080 1105 { 1081 // RPC must be remote 1082 if( cxy == local_cxy ) 1083 { 1084 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 1085 hal_core_sleep(); 1086 } 1106 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1087 1107 1088 1108 // initialise RPC descriptor header … … 1131 1151 uint32_t kmem_type ) // in 1132 1152 { 1133 // RPC must be remote 1134 if( cxy == local_cxy ) 1135 { 1136 printk("PANIC in %s : target is not remote\n", __FUNCTION__ ); 1137 hal_core_sleep(); 1138 } 1153 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1139 1154 1140 1155 // initialise RPC descriptor header … … 1182 1197 error_t * error ) // out 1183 1198 { 1184 // RPC must be remote 1185 if( cxy == local_cxy ) 1186 { 1187 printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ ); 1188 hal_core_sleep(); 1189 } 1199 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1190 1200 1191 1201 // initialise RPC descriptor header -
trunk/kernel/kern/rpc.h
r188 r238 71 71 RPC_VFS_FILE_CREATE = 14, 72 72 RPC_VFS_FILE_DESTROY = 15, 73 RPC_FATFS_GET_CLUSTER = 16, 73 RPC_VFS_INODE_LOAD = 16, 74 RPC_VFS_MAPPER_LOAD_ALL = 17, 75 RPC_FATFS_GET_CLUSTER = 18, 74 76 75 77 RPC_VMM_GET_REF_VSEG = 20, … … 421 423 void rpc_vfs_file_destroy_server( xptr_t xp ); 422 424 423 /*********************************************************************************** 424 * [16] The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client" 425 /*********************************************************************************** 426 * [16] The RPC_VFS_LOAD_INODE calls the vfs_inode_load() kernel function in a 427 * remote cluster containing a parent inode directory to scan the associated 428 * mapper, find a directory entry, identified by its name, and update the remote 429 * child inode. 430 *********************************************************************************** 431 * @ cxy : server cluster identifier 432 * @ parent_inode : [in] local pointer on parent inode. 433 * @ name : [in] local pointer on child name (in client cluster). 434 * @ child_inode_xp : [in] extended pointer on child inode (in another cluster). 435 * @ error : [out] error status (0 if success). 436 **********************************************************************************/ 437 void rpc_vfs_inode_load_client( cxy_t cxy, 438 struct vfs_inode_s * parent_inode, 439 char * name, 440 xptr_t child_inode_xp, 441 error_t * error ); 442 443 void rpc_vfs_inode_load_server( xptr_t xp ); 444 445 /*********************************************************************************** 446 * [17] The RPC_VFS_MAPPER_LOAD_ALL calls the vfs_mapper_load_all() kernel function 447 * in a remote cluster containing an inode, to load all pages of the associated 448 * mapper from the file system on device. 449 *********************************************************************************** 450 * @ cxy : server cluster identifier 451 * @ inode : [in] local pointer on inode in server cluster. 452 * @ error : [out] error status (0 if success). 453 **********************************************************************************/ 454 void rpc_vfs_mapper_load_all_client( cxy_t cxy, 455 struct vfs_inode_s * inode, 456 error_t * error ); 457 458 void rpc_vfs_mapper_load_all_server( xptr_t xp ); 459 460 /*********************************************************************************** 461 * [18] The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client" 425 462 * cluster to scan the FAT mapper, stored in a remote "server" cluster, and get 426 463 * from the mapper the local pointer on a given page. -
trunk/kernel/libk/string.c
r223 r238 152 152 } 153 153 154 ///////////////////////////////////// 155 inline uint8_t to_lower( uint8_t c ) 156 { 157 if (c >= 'A' && c <= 'Z') return (c | 0x20); 158 else return c; 159 } 160 161 162 ///////////////////////////////////// 163 inline uint8_t to_upper( uint8_t c ) 164 { 165 if (c >= 'a' && c <= 'z') return (c & ~(0x20)); 166 else return c; 167 } 168 169 -
trunk/kernel/libk/string.h
r23 r238 122 122 int c ); 123 123 124 /******************************************************************************************** 125 * This function returns a lower case ASCII code if input is in [A...Z] range. 126 ******************************************************************************************** 127 * @ c : character to be forced to lower case. 128 * @ return lower case ASCII code. 129 *******************************************************************************************/ 130 inline uint8_t to_lower( uint8_t c ); 131 132 /******************************************************************************************** 133 * This function returns an upper case ASCII code if input is in [a...z] range. 134 ******************************************************************************************** 135 * @ c : character to be forced to upper case. 136 * @ return upper case ASCII code. 137 *******************************************************************************************/ 138 inline uint8_t to_upper( uint8_t c ); 139 124 140 #endif /* _STRING_H_ */ -
trunk/kernel/mm/mapper.c
r204 r238 164 164 page = grdxt_lookup( &mapper->radix , index ); 165 165 166 if ( page == NULL ) // missing page => load it from file system166 if ( page == NULL ) // missing page => create it and load it from file system 167 167 { 168 168 mapper_dmsg("\n[INFO] %s : missing page => load from FS\n", __FUNCTION__ ); … … 208 208 } 209 209 210 // update the mapper and index fields in page descriptor 211 // required by the vfs_move_page_to_mapper() 212 page->mapper = mapper; 213 page->index = index; 214 210 215 // launch I/O operation to load page from file system 211 error = vfs_m ove_page_to_mapper( page );216 error = vfs_mapper_move_page( page , true ); // to mapper 212 217 213 218 if( error ) … … 223 228 } 224 229 225 // update the mapper and index fields in page descriptor226 page->mapper = mapper;227 page->index = index;228 229 230 // reset the page INLOAD flag to make the page available to all readers 230 231 page_clear_flag( page , PG_INLOAD ); … … 267 268 268 269 // lauch IO operation to update page to file system 269 error = vfs_m ove_page_from_mapper( page );270 error = vfs_mapper_move_page( page , false ); // from mapper 270 271 271 272 if( error ) -
trunk/kernel/mm/mapper.h
r204 r238 49 49 * - The mapper is protected by a blocking "rwlock", to support several simultaneous 50 50 * readers, and only one writer. This lock implement a busy waiting policy. 51 * - The two functions vfs_move_page_to_mapper() and vfs_move_page_from_mapper() define52 * the generic API used to move pages to or from the relevant file system.53 * - the mapper_move() function is used to move data to or from a , possibly distributed54 * user buffer in user space.51 * - The vfs_mapper_move_page() and vfs_mapper_load_all() functions are used to move 52 * pages to or from the file system on device. 53 * - the mapper_move() function is used to move data to or from an user buffer. 54 * This user space buffer can be physically distributed in several clusters. 55 55 * - The mapper_get_page() function that return a page descriptor pointer from a page 56 56 * index in file is in charge of handling the miss on the mapper cache. -
trunk/kernel/mm/page.c
r149 r238 147 147 148 148 // sync the page 149 vfs_m ove_page_from_mapper( page );149 vfs_mapper_move_page( page , false ); // from mapper 150 150 151 151 // unlock the page -
trunk/kernel/vfs/devfs.h
r204 r238 28 28 ////////////////////////////////////////////////////////////////////////////////////////// 29 29 // The DEVFS File System contains inodes and dentries associated to all chdev descriptors 30 // availables in the architecture. It is structured as a three levels tree structure : 30 // availables in the architecture. 31 // 32 // It is structured as a three levels tree structure : 31 33 // - The "dev" directory inode is stored in cluster_IO. It is the root of the DEVFS 32 34 // file system. The parent inode is the "/" VFS root. … … 38 40 // The parent dentry is stored in cluster_IO. 39 41 // 40 // The DEVFS file system uses the DEVFS context extension to register an extended pointer 41 // on the DEVFS "dev" inode, and and another extended pointer on the "external" inode. 42 // 43 // The DEVFS file system uses the VFS inode extension to store the pointer 44 // on the associated chdev descriptor. 42 // The DEVFS extensions to the generic VFS are the following: 43 // 1) The vfs_ctx_t "extend" field is a void* pointing on the devfs_ctx_t structure. 44 // This structure contains two extended pointers on the DEVFS "dev" directory inode, 45 // and on the "external" directory inode. 46 // 2) The vfs_inode_t "extend" field is a void*, pointing on the associated 47 // chdev descriptor. 45 48 ////////////////////////////////////////////////////////////////////////////////////////// 46 49 -
trunk/kernel/vfs/fatfs.c
r188 r238 2 2 * fatfs.c - FATFS file system API implementation. 3 3 * 4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017) 4 * Author Alain Greiner (2016,2017) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 30 29 #include <ppm.h> 31 30 #include <vfs.h> 31 #include <string.h> 32 32 #include <rpc.h> 33 33 #include <mapper.h> … … 46 46 47 47 ////////////////////////////////////////////////////////////////////////////////////////// 48 // FATFS private functions 49 ////////////////////////////////////////////////////////////////////////////////////////// 48 // FATFS private and static functions 49 ////////////////////////////////////////////////////////////////////////////////////////// 50 51 ////////////////////////////////////////////////////////////////////////////////////////// 52 // These functions return the "offset" and "length" values of an 53 // [offset,length] constant defined in the fatfs.h file. 54 ////////////////////////////////////////////////////////////////////////////////////////// 55 56 static inline int get_length( int offset , int length ) { return length; } 57 58 static inline int get_offset( int offset , int length ) { return offset; } 59 50 60 51 61 ////////////////////////////////////////////////////////////////////////////////////////// … … 63 73 } 64 74 65 ///////////////////////////////////////////// 66 error_t fatfs_get_cluster( mapper_t * mapper, 67 uint32_t first_cluster, 68 uint32_t searched_page, 69 uint32_t * cluster ) 70 { 71 page_t * current_page_desc; // pointer on current page descriptor 72 uint32_t * current_page_buffer; // pointer on current page (array of uint32_t) 73 uint32_t current_page_index; // index of current page in mapper 74 uint32_t current_page_offset; // offset of slot in current page 75 uint32_t page_count_in_file; // index of page in file (index in linked list) 76 uint32_t current_cluster; // content of current FAT slot 77 78 // compute number of FAT slots per PPM page 79 uint32_t slots_per_page = CONFIG_PPM_PAGE_SIZE >> 2; 80 81 // initialize loop variable 82 current_page_index = first_cluster / slots_per_page; 83 current_page_offset = first_cluster % slots_per_page; 84 page_count_in_file = 0; 85 86 // scan FAT (i.e. traverse FAT linked list) 87 while( page_count_in_file <= searched_page ) 88 { 89 // get pointer on current page descriptor 90 current_page_desc = mapper_get_page( mapper , current_page_index ); 91 92 if( current_page_desc == NULL ) return EIO; 93 94 // get pointer on buffer for current page 95 current_page_buffer = (uint32_t *)ppm_page2vaddr( current_page_desc ); 96 97 // get FAT slot content 98 current_cluster = current_page_buffer[current_page_offset]; 99 100 // update loop variables 101 current_page_index = current_cluster / slots_per_page; 102 current_page_offset = current_cluster % slots_per_page; 103 page_count_in_file++; 104 } 105 106 // return success 107 *cluster = current_cluster; 108 return 0; 109 110 } // end fatfs_get_cluster() 111 112 /////////////////////////////////////////////////////////////////////////////////////// 113 // This static function return an integer record value (one, two, or four bytes) 75 76 ////////////////////////////////////////////////////////////////////////////////////////// 77 // This function return an integer record value (one, two, or four bytes) 114 78 // from a memory buffer, taking into account endianness. 115 /////////////////////////////////////////////////////////////////////////////////////// 79 ////////////////////////////////////////////////////////////////////////////////////////// 116 80 // @ offset : first byte of record in buffer. 117 81 // @ size : record length in bytes (1/2/4). … … 119 83 // @ little endian : the most significant byte has the highest address when true. 120 84 // @ return the integer value in a 32 bits word. 121 /////////////////////////////////////////////////////////////////////////////////////// 122 static uint32_t get_record_from_buffer( uint32_t offset,123 124 125 85 ////////////////////////////////////////////////////////////////////////////////////////// 86 static uint32_t fatfs_get_record( uint32_t offset, 87 uint32_t size, 88 uint8_t * buffer, 89 uint32_t little_endian ) 126 90 { 127 91 uint32_t n; … … 138 102 return res; 139 103 140 } // end get_record_from_buffer() 141 142 143 144 //////////////////////////////////////////////////////////////////////////////////////// 104 } // end fatfs_get_record() 105 106 ////////////////////////////////////////////////////////////////////////////////////////// 107 // This static function retun in the <name> buffer a short name stored in 108 // a SFN FATFS directory entry. 109 /////////////////////////i//////////////////////////////////////////////////////////////// 110 // @ buffer : pointer on buffer containing the directory entry. 111 // @ name : [out] buffer allocated by the caller. 112 ////////////////////////////////////////////////////////////////////////////////////////// 113 static void fatfs_get_name_from_short( uint8_t * buffer, 114 char * name ) 115 { 116 uint32_t i; 117 uint32_t j = 0; 118 119 // get name 120 for ( i = 0; i < 8 && buffer[i] != ' '; i++ ) 121 { 122 name[j] = to_lower( buffer[i] ); 123 j++; 124 } 125 126 // get extension 127 for ( i = 8; i < 8 + 3 && buffer[i] != ' '; i++ ) 128 { 129 // we entered the loop so there is an extension. add the dot 130 if ( i == 8 ) 131 { 132 name[j] = '.'; 133 j++; 134 } 135 136 name[j] = to_lower( buffer[i] ); 137 j++; 138 } 139 140 name[j] = '\0'; 141 } 142 143 ////////////////////////////////////////////////////////////////////////////////////////// 144 // This static function retun in the <name> buffer a partial name stored in 145 // a LFN FATFS directory entry. 146 /////////////////////////i//////////////////////////////////////////////////////////////// 147 // @ buffer : pointer on buffer containing the directory entry. 148 // @ name : [out] buffer allocated by the caller. 149 ////////////////////////////////////////////////////////////////////////////////////////// 150 static void fatfs_get_name_from_long( uint8_t * buffer, 151 char * name ) 152 { 153 uint32_t name_offset = 0; 154 uint32_t buffer_offset = get_length(LDIR_ORD); 155 uint32_t l_name_1 = get_length(LDIR_NAME_1); 156 uint32_t l_name_2 = get_length(LDIR_NAME_2); 157 uint32_t l_name_3 = get_length(LDIR_NAME_3); 158 uint32_t l_attr = get_length(LDIR_ATTR); 159 uint32_t l_type = get_length(LDIR_TYPE); 160 uint32_t l_chksum = get_length(LDIR_CHKSUM); 161 uint32_t l_rsvd = get_length(LDIR_RSVD); 162 163 uint32_t j = 0; 164 uint32_t eof = 0; 165 166 while ( (buffer_offset != DIR_ENTRY_SIZE) && (!eof) ) 167 { 168 while (j != l_name_1 && !eof ) 169 { 170 if ( (buffer[buffer_offset] == 0x00) || 171 (buffer[buffer_offset] == 0xFF) ) 172 { 173 eof = 1; 174 continue; 175 } 176 name[name_offset] = buffer[buffer_offset]; 177 buffer_offset += 2; 178 j += 2; 179 name_offset++; 180 } 181 182 buffer_offset += (l_attr + l_type + l_chksum); 183 j = 0; 184 185 while (j != l_name_2 && !eof ) 186 { 187 if ( (buffer[buffer_offset] == 0x00) || 188 (buffer[buffer_offset] == 0xFF) ) 189 { 190 eof = 1; 191 continue; 192 } 193 name[name_offset] = buffer[buffer_offset]; 194 buffer_offset += 2; 195 j += 2; 196 name_offset++; 197 } 198 199 buffer_offset += l_rsvd; 200 j = 0; 201 202 while (j != l_name_3 && !eof ) 203 { 204 if ( (buffer[buffer_offset] == 0x00) || 205 (buffer[buffer_offset] == 0xFF) ) 206 { 207 eof = 1; 208 continue; 209 } 210 name[name_offset] = buffer[buffer_offset]; 211 buffer_offset += 2; 212 j += 2; 213 name_offset++; 214 } 215 } 216 name[name_offset] = 0; 217 218 } // end get_name_from_long() 219 220 ////////////////////////////////////////////////////////////////////////////////////////// 145 221 // This function returns the FATFS cluster index of a page identified by its page 146 222 // index in the file, using the FAT mapper. It scans the FAT mapper, starting from the … … 152 228 // in the cluster containing the FAT mapper, and the RPC latency is not critical 153 229 // compared to the device access latency. 154 //////////////////////////////////////////////////////////////////////////////////////// 230 ////////////////////////////////////////////////////////////////////////////////////////// 155 231 // @ ctx : pointer on local FATFS context. 156 232 // @ first_cluster : first cluster allocated to a file in FATFS. … … 158 234 // @ cluster_index : [out] pointer on buffer for FATFS cluster index. 159 235 // @ return 0 if success / return EIO if a FAT cluster miss cannot be solved. 160 //////////////////////////////////////////////////////////////////////////////////////// 236 ////////////////////////////////////////////////////////////////////////////////////////// 161 237 static error_t fatfs_cluster_from_index( fatfs_ctx_t * ctx, 162 238 uint32_t first_cluster, … … 203 279 } // end fatfs_cluster_from_index() 204 280 281 ////////////////////////////////////////////////////////////////////////////////////////// 282 // FATFS specific but public functions (used by RPC_FATFS_GET_CLUSTER) 283 ////////////////////////////////////////////////////////////////////////////////////////// 284 285 ///////////////////////////////////////////// 286 error_t fatfs_get_cluster( mapper_t * mapper, 287 uint32_t first_cluster, 288 uint32_t searched_page, 289 uint32_t * cluster ) 290 { 291 page_t * current_page_desc; // pointer on current page descriptor 292 uint32_t * current_page_buffer; // pointer on current page (array of uint32_t) 293 uint32_t current_page_index; // index of current page in mapper 294 uint32_t current_page_offset; // offset of slot in current page 295 uint32_t page_count_in_file; // index of page in file (index in linked list) 296 uint32_t current_cluster; // content of current FAT slot 297 298 // compute number of FAT slots per PPM page 299 uint32_t slots_per_page = CONFIG_PPM_PAGE_SIZE >> 2; 300 301 // initialize loop variable 302 current_page_index = first_cluster / slots_per_page; 303 current_page_offset = first_cluster % slots_per_page; 304 page_count_in_file = 0; 305 306 // scan FAT (i.e. traverse FAT linked list) 307 while( page_count_in_file <= searched_page ) 308 { 309 // get pointer on current page descriptor 310 current_page_desc = mapper_get_page( mapper , current_page_index ); 311 312 if( current_page_desc == NULL ) return EIO; 313 314 // get pointer on buffer for current page 315 current_page_buffer = (uint32_t *)ppm_page2vaddr( current_page_desc ); 316 317 // get FAT slot content 318 current_cluster = current_page_buffer[current_page_offset]; 319 320 // update loop variables 321 current_page_index = current_cluster / slots_per_page; 322 current_page_offset = current_cluster % slots_per_page; 323 page_count_in_file++; 324 } 325 326 // return success 327 *cluster = current_cluster; 328 return 0; 329 330 } // end fatfs_get_cluster() 205 331 206 332 207 333 208 334 /////////////////////////////////////////////////////////////////////////////////////// 209 // Generic API : the following functions are called by the kernel 335 // Generic API : the following functions are called by the kernel (VFS) 210 336 // and must be defined by all supported file systems. 211 337 /////////////////////////////////////////////////////////////////////////////////////// … … 275 401 276 402 // check sector size from boot record 277 uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 );403 uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer , 1 ); 278 404 279 405 nolock_assert( (sector_size == 512) , __FUNCTION__ , … … 281 407 282 408 // check cluster size from boot record 283 uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 );409 uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer , 1 ); 284 410 285 411 nolock_assert( (nb_sectors == 8) , __FUNCTION__ , … … 287 413 288 414 // check number of FAT copies from boot record 289 uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 );415 uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer , 1 ); 290 416 291 417 nolock_assert( (nb_fats == 1) , __FUNCTION__ , … … 293 419 294 420 // get & check number of sectors in FAT from boot record 295 uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 );421 uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer , 1 ); 296 422 297 423 nolock_assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ , … … 299 425 300 426 // get and check root cluster from boot record 301 uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 );427 uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer , 1 ); 302 428 303 429 nolock_assert( (root_cluster == 2) , __FUNCTION__ , … … 305 431 306 432 // get FAT lba from boot record 307 uint32_t fat_lba = get_record_from_buffer( BPB_RSVDSECCNT , buffer , 1 );433 uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer , 1 ); 308 434 309 435 // release the 512 bytes buffer … … 353 479 } 354 480 355 /////////////////////////////////////// /////////356 static error_t fatfs_access_page( page_t * page,357 bool_t is_read)481 /////////////////////////////////////// 482 error_t fatfs_move_page( page_t * page, 483 bool_t to_mapper ) 358 484 { 359 485 // get memory buffer base address … … 388 514 389 515 // access device 390 if( is_read) error = dev_ioc_read ( buffer , lba , count );391 else error = dev_ioc_write( buffer , lba , count );516 if( to_mapper ) error = dev_ioc_read ( buffer , lba , count ); 517 else error = dev_ioc_write( buffer , lba , count ); 392 518 393 519 if( error ) … … 401 527 } 402 528 403 //////////////////////////////////////////////// 404 error_t fatfs_write_page( struct page_s * page ) 405 { 406 bool_t is_read = false; 407 return fatfs_access_page( page , is_read ); 408 } 409 410 /////////////////////////////////////////////// 411 error_t fatfs_read_page( struct page_s * page ) 412 { 413 bool_t is_read = true; 414 return fatfs_access_page( page , is_read ); 415 } 416 529 ///////////////////////////////////////////////////////////////// 530 error_t fatfs_inode_load( vfs_inode_t * parent_inode, 531 char * name, 532 xptr_t child_inode_xp ) 533 { 534 // Two embedded loops: 535 // - scan the parent mapper pages 536 // - scan the directory entries in each 4 Kbytes page 537 538 fatfs_dmsg("\n[INFO] %s : enter for child <%s> in parent inode %l\n", 539 __FUNCTION__ , name , child_inode_xp ); 540 541 mapper_t * mapper = parent_inode->mapper; 542 543 assert( (mapper != NULL) , __FUNCTION__ , "parent mapper undefined\n"); 544 545 char cname[CONFIG_VFS_MAX_NAME_LENGTH]; // name extracter from each directory entry 546 547 char lfn1[16]; // buffer for one partial cname 548 char lfn2[16]; // buffer for one partial cname 549 char lfn3[16]; // buffer for one partial cname 550 page_t * page; // pointer on current page descriptor 551 uint8_t * base; // pointer on current page base 552 uint32_t offset = 0; // byte offset in page 553 uint32_t index = 0; // page index in mapper 554 uint32_t attr; // directory entry ATTR field 555 uint32_t ord; // directory entry ORD field 556 uint32_t seq; // sequence index 557 uint32_t lfn = 0; // LFN entries number 558 uint32_t size = 0; // searched file/dir size (bytes) 559 uint32_t cluster = 0; // searched file/dir cluster index 560 uint32_t is_dir = 0; // searched file/dir type 561 uint32_t dentry; // directory entry index 562 int32_t found = 0; // not found (0) / name found (1) / end of dir (-1) 563 564 // scan the parent directory mapper 565 while ( found == 0 ) 566 { 567 // get one page 568 page = mapper_get_page( mapper , index ); 569 570 assert( (page != NULL) , __FUNCTION__ , "bad parent mapper\n"); 571 572 // get page base 573 base = ppm_page2vaddr( page ); 574 575 // scan this page until end of directory, end of page, or name found 576 while( (offset < 4096) && (found == 0) ) 577 { 578 attr = fatfs_get_record( DIR_ATTR , base + offset , 0 ); 579 ord = fatfs_get_record( LDIR_ORD , base + offset , 0 ); 580 581 if (ord == NO_MORE_ENTRY) // no more entry => break 582 { 583 found = -1; 584 } 585 else if ( ord == FREE_ENTRY ) // free entry => skip 586 { 587 offset = offset + 32; 588 } 589 else if ( attr == ATTR_LONG_NAME_MASK ) // LFN entry => get partial cname 590 { 591 seq = ord & 0x3; 592 lfn = (seq > lfn) ? seq : lfn; 593 if ( seq == 1 ) fatfs_get_name_from_long( base + offset, lfn1 ); 594 else if ( seq == 2 ) fatfs_get_name_from_long( base + offset, lfn2 ); 595 else if ( seq == 3 ) fatfs_get_name_from_long( base + offset, lfn3 ); 596 offset = offset + 32; 597 } 598 else // NORMAL entry 599 { 600 // build the extracted name 601 if ( lfn == 0 ) 602 { 603 fatfs_get_name_from_short( base + offset , cname ); 604 } 605 else if ( lfn == 1 ) 606 { 607 strcpy( cname , lfn1 ); 608 } 609 else if ( lfn == 2 ) 610 { 611 strcpy( cname , lfn1 ); 612 strcpy( cname + 13 , lfn2 ); 613 } 614 else if ( lfn == 3 ) 615 { 616 strcpy( cname , lfn1 ); 617 strcpy( cname + 13 , lfn2 ); 618 strcpy( cname + 26 , lfn3 ); 619 } 620 621 // get dentry arguments if extracted cname == searched name 622 if ( strcmp( name , cname ) == 0 ) 623 { 624 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , base + offset , 1 ) << 16) | 625 (fatfs_get_record( DIR_FST_CLUS_LO , base + offset , 1 ) ) ; 626 dentry = ((index<<12) + offset)>>5; 627 is_dir = ((attr & ATTR_DIRECTORY) == ATTR_DIRECTORY); 628 size = fatfs_get_record( DIR_FILE_SIZE , base + offset , 1 ); 629 found = 1; 630 } 631 offset = offset + 32; 632 lfn = 0; 633 } 634 } // end loop on directory entries 635 index++; 636 offset = 0; 637 } // end loop on pages 638 639 // analyse the result of scan 640 641 if ( found == -1 ) // found end of directory => failure 642 { 643 fatfs_dmsg("\n[INFO] %s : child <%s> not found in parent inode %l\n", 644 __FUNCTION__ , name , parent_inode_xp ); 645 646 return ENOENT; 647 } 648 else // found searched child name 649 { 650 fatfs_dmsg("\n[INFO] %s : child <%s> found in parent inode %l\n", 651 __FUNCTION__ , name , parent_inode_xp ); 652 653 // get child inode cluster and local pointer 654 cxy_t child_cxy = GET_CXY( child_inode_xp ); 655 vfs_inode_t * child_ptr = (vfs_inode_t *)GET_PTR( child_inode_xp ); 656 657 // update the child inode "type", "size", and "extend" fields 658 vfs_inode_type_t type = (is_dir) ? INODE_TYPE_DIR : INODE_TYPE_FILE; 659 660 hal_remote_sw( XPTR( child_cxy , &child_ptr->type ) , type ); 661 hal_remote_sw( XPTR( child_cxy , &child_ptr->size ) , size ); 662 hal_remote_sw( XPTR( child_cxy , &child_ptr->extend ) , cluster ); 663 664 return 0; 665 } 666 } // end fatfs_inode_load() -
trunk/kernel/vfs/fatfs.h
r188 r238 33 33 /////////////////////////////////////////////////////////////////////////////////////////// 34 34 // The FATFS File System implements a FAT32 read/write file system. 35 // 36 // The FATFS extensions to the generic VFS are the following: 37 // 1) The vfs_ctx_t "extend" field is a void* pointing on the fatfs_ctx_t structure. 38 // This structure contains various general informations such as the total 39 // number of sectors in FAT region, the number of bytes per sector, the number 40 // of sectors per cluster, the lba of FAT region, the lba of data region, or the 41 // cluster index for the root directory. It contains also an extended pointer 42 // on the FAT mapper. 43 // 2) The vfs_inode_t "extend" field is a void*, but contains for each inode, 44 // the first FAT cluster index (after cast to intptr). 35 45 /////////////////////////////////////////////////////////////////////////////////////////// 36 46 … … 173 183 174 184 ////////////////////////////////////////////////////////////////////////////////////////// 185 // FATFS specific but public functions (used by RPC) 186 ////////////////////////////////////////////////////////////////////////////////////////// 187 188 /****************************************************************************************** 189 * This static function scan the FAT (File Allocation Table), stored in the FAT mapper, 190 * and returns the FATFS cluster index for a given page of a given file. 191 * It must be called by a thread running in the cluster containing the FAT mapper. 192 * The FAT is actually an array of uint32_t slots. Each slot in this array contains the 193 * index of another slot in this array, to form one linked list for each file stored on 194 * device in the FATFS file system. This index in the FAT array is also the index of the 195 * FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page. 196 * For a given file, the entry point in the FAT is simply the index of the FATFS cluster 197 * containing the first page of the file. The mapper being a cache, this function 198 * automatically updates the FAT mapper from informations stored on device in case of miss. 199 ****************************************************************************************** 200 * @ mapper : local pointer on the FAT mapper. 201 * @ first_cluster : index of the first FATFS cluster allocated to the file. 202 * @ searched_page : index of searched page in the file. 203 * @ cluster : [out] pointer on buffer for the found FATFS cluster index. 204 * @ return 0 if success / return EIO if FAT mapper miss cannot be solved. 205 *****************************************************************************************/ 206 error_t fatfs_get_cluster( struct mapper_s * mapper, 207 uint32_t first_cluster, 208 uint32_t searched_page, 209 uint32_t * cluster ); 210 211 212 213 214 ////////////////////////////////////////////////////////////////////////////////////////// 175 215 // Generic API: These functions are called by the kernel, 176 216 // and must be implemented by all File Systems. … … 185 225 186 226 /***************************************************************************************** 187 * This function access the external boot device, and initialises it227 * This function access the boot device, and initialises the FATFS context 188 228 * from informations contained in the boot record. 189 229 ***************************************************************************************** … … 200 240 201 241 /***************************************************************************************** 202 * This function moves a page from the mapper tothe FATFS file system on device.242 * This function moves a page from/to the mapper to/from the FATFS file system on device. 203 243 * It must be called by a thread running in cluster containing the mapper. 204 244 * The pointer on the mapper and the page index in file are registered 205 245 * in the page descriptor. 206 246 ***************************************************************************************** 207 * @ page : local pointer on page descriptor. 247 * @ page : local pointer on page descriptor. 248 * @ to_mapper : transfer direction 208 249 * @ return 0 if success / return EIO if error. 209 250 ****************************************************************************************/ 210 error_t fatfs_write_page( struct page_s * page ); 211 212 /***************************************************************************************** 213 * This function moves a page from the FATFS file system on device to the mapper. 214 * It must be called by a thread running in cluster containing the mapper. 215 * The pointer on the mapper and the page index in file are registered 216 * in the page descriptor. 217 ***************************************************************************************** 218 * @ page : local pointer on page descriptor. 219 * @ return 0 if success / return EIO if error. 220 ****************************************************************************************/ 221 error_t fatfs_read_page( struct page_s * page ); 222 223 /***************************************************************************************** 224 * This function scan the FAT (File Allocation Table), stored in the FAT mapper, 225 * and return the FATFS cluster index for a given page of a given file. 226 * It must be called by a thread running in the cluster containing the FAT mapper 227 * (can be a local thread or a RPC thread). 228 * The FAT is actually an array of uint32_t slots. Each slot in this array contains the 229 * index of another slot in this array, to form one linked list for each file stored on 230 * device in the RAMFS file system. This index in the FAT array is also the index of the 231 * FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page. 232 * For a given file, the entry point in the FAT is simply the index of the FATFS cluster 233 * containing the first page of the file. The mapper being a cache, this function 234 * automatically updates the FAT mapper from informations stored on device in case of miss. 235 ***************************************************************************************** 236 * @ mapper : local pointer on the FAT mapper. 237 * @ first_cluster : index of the first FATFS cluster allocated to the file. 238 * @ searched_page : index of searched page in the file. 239 * @ cluster : [out] pointer on buffer for the found FATFS cluster index. 240 * @ return 0 if success / return EIO if FAT mapper miss cannot be solved. 241 ****************************************************************************************/ 242 error_t fatfs_get_cluster( struct mapper_s * mapper, 243 uint32_t first_cluster, 244 uint32_t searched_page, 245 uint32_t * cluster ); 251 error_t fatfs_move_page( struct page_s * page, 252 bool_t to_mapper ); 253 254 255 /***************************************************************************************** 256 * This function scan an existing parent directory, identified by the <parent> argument, 257 * to find a directory entry identified by the <name> argument and update the remote 258 * child inode, identified by the <child_xp> argument. 259 * It set the "type", "size", and "extend" (FAT cluster index) fields in child inode. 260 * It must be called by a thread running in the cluster containing the parent inode. 261 ***************************************************************************************** 262 * @ parent_inode : local pointer on parent inode (directory). 263 * @ name : child name. 264 * @ child_inode_xp : extended pointer on remote child inode (file or directory). 265 * @ return 0 if success / return ENOENT if child not found. 266 ****************************************************************************************/ 267 error_t fatfs_inode_load( struct vfs_inode_s * parent_inode, 268 char * name, 269 xptr_t child_inode_xp ); 246 270 247 271 #endif /* _FATFS_H_ */ -
trunk/kernel/vfs/vfs.c
r222 r238 248 248 } // end vfs_inode_destroy() 249 249 250 ///////////////////////////////////////////// 251 error_t vfs_inode_load( vfs_inode_t * parent, 252 char * name, 253 xptr_t child_xp ) 254 { 255 error_t error = 0; 256 257 assert( (parent != NULL) , __FUNCTION__ , "parent pointer is NULL\n"); 258 259 assert( (child_xp != XPTR_NULL) , __FUNCTION__ , "child pointer is NULL\n"); 260 261 // get parent inode FS type 262 vfs_fs_type_t fs_type = parent->ctx->type; 263 264 // call relevant FS function 265 if( fs_type == FS_TYPE_FATFS ) 266 { 267 error = fatfs_inode_load( parent , name , child_xp ); 268 } 269 else if( fs_type == FS_TYPE_RAMFS ) 270 { 271 assert( false , __FUNCTION__ , "should not be called for RAMFS\n" ); 272 } 273 else if( fs_type == FS_TYPE_DEVFS ) 274 { 275 assert( false , __FUNCTION__ , "should not be called for DEVFS\n" ); 276 } 277 else 278 { 279 assert( false , __FUNCTION__ , "undefined file system type\n" ); 280 } 281 282 return error; 283 284 } // end vfs_load_inode() 285 250 286 //////////////////////////////////////////// 251 287 void vfs_inode_remote_up( xptr_t inode_xp ) … … 594 630 595 631 if( error ) return error; 632 633 vfs_dmsg("\n[INFO] %s exit for %s / file_id = %d / file_xp = %l / at cycle %d\n", 634 __FUNCTION__ , path , file_id , file_xp , hal_get_cycles() ); 596 635 597 636 // success … … 1161 1200 cxy_t child_cxy; // cluster for child inode 1162 1201 vfs_inode_t * child_ptr; // local pointer on child inode 1163 vfs_inode_type_t inode_type; // child inode type1202 vfs_inode_type_t child_type; // child inode type 1164 1203 vfs_fs_type_t fs_type; // File system type 1165 1204 vfs_ctx_t * ctx_ptr; // local pointer on FS context … … 1206 1245 &child_xp ); 1207 1246 1208 if( found == false ) // child inode not found in inode tree => try to load it 1247 // if a child inode is not found in the inode tree: 1248 // - we create the missing inode/dentry couple in the inode tree, 1249 // - we scan the parent mapper to complete the child inode (type and extension), 1250 // - we return an error if child not found on device. 1251 // - if the missing child is a directory, we load the child mapper from device 1252 1253 // for the last name, the behaviour depends on the "mode" argument: 1254 1255 if (found == false ) // directory node not found in inode tree 1209 1256 { 1210 1257 vfs_dmsg("\n[INFO] %s : <%s> not found, try to load it\n", … … 1214 1261 vfs_inode_unlock( parent_xp ); 1215 1262 1216 // get cluster and local pointer on parent inode1263 // get parent inode FS type 1217 1264 parent_cxy = GET_CXY( parent_xp ); 1218 1265 parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp ); 1219 1266 1220 // get local pointer on parent inode context 1221 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) ); 1222 1223 // get parent inode FS type 1224 fs_type = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) ); 1225 1226 // get child inode type 1227 if( (last == false) || (mode & VFS_LOOKUP_DIR) ) inode_type = INODE_TYPE_DIR; 1228 else inode_type = INODE_TYPE_FILE; 1229 1230 // select a cluster for child inode 1231 cxy_t child_cxy = vfs_cluster_random_select(); 1267 ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , 1268 &parent_ptr->ctx ) ); 1269 fs_type = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) ); 1270 1271 // select a cluster for missing inode 1272 child_cxy = vfs_cluster_random_select(); 1232 1273 1233 printk("\n@@@ name not found : <%s>\n", name );1234 1235 1274 // insert a new child dentry/inode in parent inode 1236 1275 error = vfs_add_child_in_parent( child_cxy, 1237 inode_type,1276 INODE_TYPE_DIR, 1238 1277 fs_type, 1239 1278 parent_xp, 1240 1279 name, 1241 NULL, 1280 NULL, // fs_type_specific inode extend 1242 1281 &child_xp ); 1243 1282 if( error ) 1283 { 1284 printk("\n[ERROR] in %s : no memory for inode %s in path %s\n", 1285 __FUNCTION__ , name , pathname ); 1286 return ENOMEM; 1287 } 1288 1289 // scan parent mapper to complete the missing inode 1290 if( parent_cxy == local_cxy ) 1291 { 1292 error = vfs_inode_load( parent_ptr, 1293 name, 1294 child_xp ); 1295 } 1296 else 1297 { 1298 rpc_vfs_inode_load_client( parent_cxy, 1299 parent_ptr, 1300 name, 1301 child_xp, 1302 &error ); 1303 } 1304 1305 if ( error ) 1244 1306 { 1245 1307 printk("\n[ERROR] in %s : node %s not found in path %s\n", … … 1248 1310 } 1249 1311 1312 // get child inode type 1313 child_ptr = (vfs_inode_t *)GET_PTR( child_xp ); 1314 child_type = hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) ); 1315 1316 // load child mapper from device if it is a directory 1317 if( child_type == INODE_TYPE_DIR ) 1318 { 1319 if( child_cxy == local_cxy ) 1320 { 1321 error = vfs_mapper_load_all( child_ptr ); 1322 } 1323 else 1324 { 1325 rpc_vfs_mapper_load_all_client( child_cxy, 1326 child_ptr, 1327 &error ); 1328 } 1329 1330 if ( error ) 1331 { 1332 printk("\n[ERROR] in %s : cannot access device for node %s in path %s\n", 1333 __FUNCTION__ , name , pathname ); 1334 return EIO; 1335 } 1336 } 1337 1338 // TODO handle lookup mode here [AG] 1339 1250 1340 // take lock on parent inode 1251 1341 vfs_inode_lock( parent_xp ); 1252 1342 } 1253 1343 1254 vfs_inode_display( child_xp );1255 1256 vfs_display( parent_xp );1257 1258 1344 vfs_dmsg("\n[INFO] %s : found <%s> / parent = %l / child = %l / last = %d\n", 1259 __FUNCTION__ , name , parent_xp , child_xp , last );1345 __FUNCTION__ , name , parent_xp , child_xp , last ); 1260 1346 1261 1347 // TODO check access rights … … 1269 1355 // } 1270 1356 1271 // TODO TODO TODO access device and load inode mapper if required... 1272 1273 // take lock on child inode if not last 1274 if( last == false ) vfs_inode_lock( child_xp ); 1275 1276 // release lock on parent inode 1357 // take lock on child inode and release lock on parent 1358 vfs_inode_lock( child_xp ); 1277 1359 vfs_inode_unlock( parent_xp ); 1278 1360 … … 1280 1362 parent_xp = child_xp; 1281 1363 current = next; 1282 1283 vfs_dmsg("\n[INFO] %s : complete node <%s> / last = %d\n",1284 __FUNCTION__ , name , last );1285 1286 1364 } 1287 1365 while( last == false ); 1288 1366 1289 vfs_dmsg("\n[INFO] in %s : searched inode found for %s\n", 1290 __FUNCTION__ , pathname ); 1291 1292 // get cluster and local pointer on child inode 1293 child_cxy = GET_CXY( child_xp ); 1294 child_ptr = (vfs_inode_t *)GET_PTR( child_xp ); 1295 1296 // return searched pointers 1367 // release lock 1368 vfs_inode_unlock( parent_xp ); 1369 1370 vfs_dmsg("\n[INFO] in %s : exit / %s found / inode = %l\n", 1371 __FUNCTION__ , pathname , child_xp ); 1372 1373 // return searched pointer 1297 1374 *inode_xp = child_xp; 1298 1375 … … 1385 1462 cxy_t parent_cxy; // parent inode cluster identifier 1386 1463 vfs_inode_t * parent_ptr; // parent inode local pointer 1387 vfs_ctx_t * parent_ctx; // parent inode context local pointer1388 1464 1389 1465 // get parent inode cluster and local pointer … … 1471 1547 } // end vfs_add_child_in_parent() 1472 1548 1473 1474 1475 1476 1549 ////////////////////////////////////////////////////////////////////////////////////////// 1477 1550 // Mapper related functions 1478 1551 ////////////////////////////////////////////////////////////////////////////////////////// 1479 1552 1480 //////////////////////////////////////////////// 1481 error_t vfs_move_page_to_mapper( page_t * page ) 1553 //////////////////////////////////////////// 1554 error_t vfs_mapper_move_page( page_t * page, 1555 bool_t to_mapper ) 1482 1556 { 1483 1557 error_t error = 0; … … 1492 1566 vfs_fs_type_t fs_type = mapper->inode->ctx->type; 1493 1567 1494 // update mapper if permitted by file system type1568 // call relevant FS function 1495 1569 if( fs_type == FS_TYPE_FATFS ) 1496 1570 { 1497 // get mapper lock in WRITE_MODE1498 1571 rwlock_wr_lock( &mapper->lock ); 1499 1500 error = fatfs_read_page( page ); 1501 1502 // release mapper lock 1572 error = fatfs_move_page( page , to_mapper ); 1503 1573 rwlock_wr_unlock( &mapper->lock ); 1504 1574 } … … 1518 1588 return error; 1519 1589 1520 } // end vfs_move_page _to_mapper()1590 } // end vfs_move_page() 1521 1591 1522 1592 ////////////////////////////////////////////////// 1523 error_t vfs_move_page_from_mapper( page_t * page ) 1524 { 1525 error_t error = 0; 1526 1527 assert( (page != NULL) , __FUNCTION__ , "page pointer is NULL\n" ); 1528 1529 mapper_t * mapper = page->mapper; 1593 error_t vfs_mapper_load_all( vfs_inode_t * inode ) 1594 { 1595 assert( (inode != NULL) , __FUNCTION__ , "page pointer is NULL\n" ); 1596 1597 uint32_t index; 1598 page_t * page; 1599 1600 mapper_t * mapper = inode->mapper; 1601 uint32_t size = inode->size; 1530 1602 1531 1603 assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" ); 1532 1604 1533 // get FS type 1534 vfs_fs_type_t fs_type = mapper->inode->ctx->type; 1535 1536 // update file system if permitted by file system type 1537 if( fs_type == FS_TYPE_FATFS ) 1538 { 1539 if( page_is_flag( page , PG_DIRTY ) ) 1540 { 1541 // get mapper lock in READ_MODE 1542 rwlock_rd_lock( &mapper->lock ); 1543 1544 error = fatfs_write_page( page ); 1545 1546 // release mapper lock from READ_MODE 1547 rwlock_rd_unlock( &mapper->lock ); 1548 1549 // clear dirty bit if success 1550 if( error == 0 ) page_undo_dirty( page ); 1551 } 1552 } 1553 else if( fs_type == FS_TYPE_RAMFS ) 1554 { 1555 assert( false , __FUNCTION__ , "should not be called for RAMFS\n" ); 1556 } 1557 else if( fs_type == FS_TYPE_DEVFS ) 1558 { 1559 assert( false , __FUNCTION__ , "should not be called for DEVFS\n" ); 1560 } 1561 else 1562 { 1563 assert( false , __FUNCTION__ , "undefined file system type\n" ); 1564 } 1565 1566 return error; 1567 1568 } // end vfs_move_page_from_mapper() 1569 1570 1605 assert( (size != 0) , __FUNCTION__ , "size cannot be 0\n"); 1606 1607 uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT; 1608 if( size & CONFIG_PPM_PAGE_MASK ) npages++; 1609 1610 // loop on all pages 1611 for( index = 0 ; index < npages ; index ++ ) 1612 { 1613 // this function allocates the missing page in mapper, 1614 // and call the vfs_mapper_move_page() to load the page from device 1615 page = mapper_get_page( mapper , index ); 1616 1617 if( page == NULL ) return EIO; 1618 } 1619 1620 return 0; 1621 1622 } // end vfs_mapper_load_all() 1623 -
trunk/kernel/vfs/vfs.h
r204 r238 399 399 void vfs_inode_destroy( vfs_inode_t * inode ); 400 400 401 /****************************************************************************************** 402 * This function scan an existing parent inode directory, identified by the <parent> 403 * argument to find a directory entry identified by the <name> argument, and update 404 * the remote child inode, identified by the <child_xp> argument. 405 * Depending on the file system type, it calls the relevant, FS specific function, 406 * to scan the directory, and set the "type", "size", and "extend" fields. 407 * It must be called by a thread running in the cluster containing the parent inode. 408 ****************************************************************************************** 409 * @ parent : local pointer on parent inode (directory). 410 * @ name : child name. 411 * @ child_xp : extended pointer on remote child inode (file or directory) 412 * @ return 0 if success / return ENOENT if not found. 413 *****************************************************************************************/ 414 error_t vfs_inode_load( vfs_inode_t * parent, 415 char * name, 416 xptr_t child_xp ); 417 401 418 /****************************************************************************************** 402 419 * This function atomically increment/decrement the inode refcount. … … 617 634 * @ pathname : path in kernel space (can be relative or absolute). 618 635 * @ lookup_mode : flags defining the working mode (defined above in this file). 619 * @ inode_xp : [out] buffer for extended pointer on inode.636 * @ inode_xp : [out] buffer for extended pointer on searched inode. 620 637 * @ return 0 if success / ENOENT if inode not found , EACCES if permissopn denied, 621 638 * EAGAIN if a new complete lookup must be made … … 635 652 * 2) The inode and its associated mapper are created in cluster identified by <child_cxy>. 636 653 * The new inode and the parent inode can have different FS types. 637 * 3) The "child_xp" field in created dentry (pointing on the created inode) is updated.654 * 3) The "child_xp" field in created dentry (pointing on the created inode) is updated. 638 655 ****************************************************************************************** 639 656 * @ child_cxy : target cluster for child inode. … … 666 683 * This recursive function diplays a complete inode/dentry sub-tree. 667 684 * Any inode can be selected as the sub-tree root. 668 * TODO this function is not p totected against a concurrent noderemoval...685 * TODO this function is not protected against a concurrent inode/dentry removal... 669 686 ****************************************************************************************** 670 687 * @ inode_xp : extended pointer on sub-tree root inode. … … 857 874 858 875 /****************************************************************************************** 859 * This function makes an I/O operation to move one page from VFS to a given mapper, 860 * in case of MISS on the mapper cache. 876 * This function makes an I/O operation to move one page to/from device from/to the mapper. 877 * It is used in case of MISS on the mapper, or when a dirty page in the mapper must 878 * be updated in the File System. 861 879 * Depending on the file system type, it calls the proper, FS specific function. 862 880 * It must be executed by a thread running in the cluster containing the mapper. … … 864 882 * It takes the mapper lock before launching the IO operation. 865 883 ****************************************************************************************** 866 * @ page : local pointer on the page descriptor. 884 * @ page : local pointer on the page descriptor. 885 * @ to_mapper : transfer direction. 867 886 * @ returns 0 if success / return EINVAL if it cannot access the external device. 868 887 *****************************************************************************************/ 869 error_t vfs_move_page_to_mapper( struct page_s * page ); 870 871 /****************************************************************************************** 872 * This function makes an I/0 operation to move one page from a given mapper to VFS, 873 * when a dirty page in the mapper cache must be updated in the File System. 888 error_t vfs_mapper_move_page( struct page_s * page, 889 bool_t to_mapper ); 890 891 /****************************************************************************************** 892 * This function makes an I/O operation to move, from device to mapper, all pages covering 893 * a given inode, identified by the <inode> argument. It can be a directory or a file, 894 * but is mainly used to load (prefetch) a complete directory in the inode mapper. 874 895 * Depending on the file system type, it calls the proper, FS specific function. 875 896 * It must be executed by a thread running in the cluster containing the mapper. 876 * The mapper pointer is obtained from the page descriptor.897 * The mapper pointer is obtained from the inode descriptor. 877 898 * It takes the mapper lock before launching the IO operation. 878 * It does nothing if the page is not dirty. If the page is dirty, it clear the page 879 * dirty bit, and remove the page from the PPM dirty list. 880 ****************************************************************************************** 881 * @ page : local pointer on the page descriptor. 882 * @ returns 0 if success / return EINVAL if it cannot access the external device. 883 *****************************************************************************************/ 884 error_t vfs_move_page_from_mapper( struct page_s * page ); 885 886 887 888 889 890 891 /////////////////////////////////////////////////////////////////////////////////////////// 892 // These typedef define the FS specific operations that must be implemented by any 893 // specific file system to be supported by the ALMOS_MKH VFS. 894 // These typedef are not actually used, and are only defined for documentation 895 /////////////////////////////////////////////////////////////////////////////////////////// 896 897 typedef error_t (fs_init_t) ( xptr_t vfs_root_xp ); 898 899 typedef error_t (fs_inode_extend_t) ( struct vfs_inode_s * inode, 900 void * extend ); 901 902 typedef void (fs_inode_release_t) ( struct vfs_inode_s * inode ); 903 904 typedef error_t (fs_write_page_t) ( struct page_s * page ); 905 906 typedef error_t (fs_read_page_t) ( struct page_s * page ); 907 908 909 910 911 899 ****************************************************************************************** 900 * @ inode : local pointer on inode. 901 * @ return 0 if success / return EIO if device access failure. 902 *****************************************************************************************/ 903 error_t vfs_mapper_load_all( vfs_inode_t * inode ); 912 904 913 905
Note: See TracChangeset
for help on using the changeset viewer.