Changeset 623 for trunk/kernel/fs/fatfs.c
- Timestamp:
- Mar 6, 2019, 4:37:15 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/fatfs.c
r614 r623 793 793 #if (DEBUG_FATFS_CTX_INIT & 0x1) 794 794 if( DEBUG_FATFS_CTX_INIT < cycle ) 795 { 796 uint32_t line; 797 uint32_t byte = 0; 798 printk("\n***** %s : FAT boot record\n", __FUNCTION__ ); 799 for ( line = 0 ; line < 32 ; line++ ) 800 { 801 printk(" %X | %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x |\n", 802 byte, 803 buffer[byte+ 0],buffer[byte+ 1],buffer[byte+ 2],buffer[byte+ 3], 804 buffer[byte+ 4],buffer[byte+ 5],buffer[byte+ 6],buffer[byte+ 7], 805 buffer[byte+ 8],buffer[byte+ 9],buffer[byte+10],buffer[byte+11], 806 buffer[byte+12],buffer[byte+13],buffer[byte+14],buffer[byte+15] ); 807 808 byte += 16; 809 } 810 } 795 putb( "boot record", buffer , 256 ); 811 796 #endif 812 797 … … 960 945 assert( (inode != NULL) , "inode pointer is NULL\n" ); 961 946 assert( (dentry != NULL) , "dentry pointer is NULL\n" ); 962 assert( (inode->type == INODE_TYPE_DIR) , "inode is not a directory\n" );963 947 assert( (inode->mapper != NULL ) , "mapper pointer is NULL\n" ); 964 948 … … 1359 1343 } // end fatfs_remove_dentry 1360 1344 1361 ///////////////////////////////////////////////////// 1362 error_t fatfs_get_dentry( vfs_inode_t * parent_inode, 1363 char * name, 1364 xptr_t child_inode_xp ) 1345 1346 ////////////////////////////////////////////////////////////////////////////////////////////// 1347 // This static function scan the pages of a mapper containing a FAT32 directory, identified 1348 // by the <mapper> argument, to find the directory entry identified by the <name> argument, 1349 // and return a pointer on the directory entry, described as and array of 32 bytes, and the 1350 // incex of this entry in the FAT32 mapper, seen as an array of 32 bytes entries. 1351 // It is called by the fatfs_new_dentry() and fatfs_update_dentry() functions. 1352 // It must be called by a thread running in the cluster containing the mapper. 1353 ////////////////////////////////////////////////////////////////////////////////////////////// 1354 // @ mapper : [in] local pointer on directory mapper. 1355 // @ name : [in] searched directory entry name. 1356 // @ entry : [out] buffer for the pointer on the 32 bytes directory entry (when found). 1357 // @ index : [out] buffer for the directory entry index in mapper. 1358 // @ return 0 if found / return 1 if not found / return -1 if mapper access error. 1359 ////////////////////////////////////////////////////////////////////////////////////////////// 1360 error_t fatfs_scan_directory( mapper_t * mapper, 1361 char * name, 1362 uint8_t ** entry, 1363 uint32_t * index ) 1365 1364 { 1366 1365 // Two embedded loops to scan the directory mapper: … … 1368 1367 // - scan the directory entries in each 4 Kbytes page 1369 1368 1370 #if DEBUG_FATFS_GET_DENTRY 1369 // check parent_inode and child_inode 1370 assert( (mapper != NULL) , "mapper pointer is NULL\n" ); 1371 assert( (name != NULL ), "child name is undefined\n" ); 1372 assert( (entry != NULL ), "entry buffer undefined\n" ); 1373 1374 #if DEBUG_FATFS_SCAN_DIRECTORY 1371 1375 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1372 1376 uint32_t cycle = (uint32_t)hal_get_cycles(); 1373 1377 thread_t * this = CURRENT_THREAD; 1374 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name );1375 if( DEBUG_FATFS_ GET_DENTRY < cycle )1376 printk("\n[%s] thread[%x,%x] enter forchild <%s> in parent <%s> / cycle %d\n",1378 vfs_inode_get_name( XPTR( local_cxy , mapper->inode ) , parent_name ); 1379 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1380 printk("\n[%s] thread[%x,%x] enter to search child <%s> in parent <%s> / cycle %d\n", 1377 1381 __FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle ); 1378 1382 #endif 1379 1383 1380 // check parent_inode and child_inode 1381 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1382 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is XPTR_NULL\n" ); 1383 1384 mapper_t * mapper = parent_inode->mapper; 1385 xptr_t mapper_xp = XPTR( local_cxy , mapper ); 1386 1387 // check parent mapper 1388 assert( (mapper != NULL) , "parent mapper is NULL\n"); 1389 1390 char cname[CONFIG_VFS_MAX_NAME_LENGTH]; // name extracter from each directory entry 1384 char cname[CONFIG_VFS_MAX_NAME_LENGTH]; // name extracted from each directory entry 1391 1385 1392 1386 char lfn1[16]; // buffer for one partial cname 1393 1387 char lfn2[16]; // buffer for one partial cname 1394 1388 char lfn3[16]; // buffer for one partial cname 1389 xptr_t mapper_xp; // extended pointer on mapper descriptor 1395 1390 xptr_t page_xp; // extended pointer on page descriptor 1396 1391 xptr_t base_xp; // extended pointer on page base … … 1400 1395 uint32_t seq; // sequence index 1401 1396 uint32_t lfn = 0; // LFN entries number 1402 uint32_t size = 0; // searched file/dir size (bytes) 1403 uint32_t cluster = 0; // searched file/dir cluster index 1404 uint32_t is_dir = 0; // searched file/dir type 1405 int32_t found = 0; // not found (0) / name found (1) / end of dir (-1) 1397 int32_t found = 0; // not yet = 0 / success = 1 / not found = 2 / error = -1 1406 1398 uint32_t page_id = 0; // page index in mapper 1407 uint32_t dentry_id = 0; // directory entry index1408 1399 uint32_t offset = 0; // byte offset in page 1409 1400 1410 // scan the parent directory mapper 1401 mapper_xp = XPTR( local_cxy , mapper ); 1402 1403 // scan the mapper pages 1411 1404 while ( found == 0 ) 1412 1405 { … … 1414 1407 page_xp = mapper_remote_get_page( mapper_xp , page_id ); 1415 1408 1416 if( page_xp == XPTR_NULL) return EIO; 1409 if( page_xp == XPTR_NULL) 1410 { 1411 found = -1; 1412 } 1417 1413 1418 1414 // get page base … … 1420 1416 base = (uint8_t *)GET_PTR( base_xp ); 1421 1417 1422 #if (DEBUG_FATFS_ GET_DENTRY & 0x1)1423 if( DEBUG_FATFS_ GET_DENTRY < cycle )1418 #if (DEBUG_FATFS_SCAN_DIRECTORY & 0x1) 1419 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1424 1420 mapper_display_page( mapper_xp , page_id , 256 ); 1425 1421 #endif … … 1432 1428 if (ord == NO_MORE_ENTRY) // no more entry => break 1433 1429 { 1434 found = -1;1430 found = 2; 1435 1431 } 1436 1432 else if ( ord == FREE_ENTRY ) // free entry => skip … … 1477 1473 if ( strcmp( name , cname ) == 0 ) 1478 1474 { 1479 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , base + offset , 1 ) << 16) | 1480 (fatfs_get_record( DIR_FST_CLUS_LO , base + offset , 1 ) ) ; 1481 dentry_id = ((page_id<<12) + offset)>>5; 1482 is_dir = ((attr & ATTR_DIRECTORY) == ATTR_DIRECTORY); 1483 size = fatfs_get_record( DIR_FILE_SIZE , base + offset , 1 ); 1475 *entry = base + offset; 1476 *index = ((page_id<<12) + offset)>>5; 1484 1477 found = 1; 1485 1478 } … … 1494 1487 } // end loop on pages 1495 1488 1496 // analyse the result of scan 1497 1498 if ( found == -1 ) // found end of directory => failure 1499 { 1489 if( found == 1 ) 1490 { 1491 1492 #if DEBUG_FATFS_SCAN_DIRECTORY 1493 cycle = (uint32_t)hal_get_cycles(); 1494 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1495 printk("\n[%s] thread[%x,%x] exit / found child <%s> in <%s>\n", 1496 __FUNCTION__, this->process->pid, this->trdid, name, parent_name ); 1497 #endif 1498 return 0; 1499 } 1500 else if( found == 2 ) 1501 { 1502 1503 #if DEBUG_FATFS_SCAN_DIRECTORY 1504 cycle = (uint32_t)hal_get_cycles(); 1505 if( DEBUG_FATFS_SCAN_DIRECTORY < cycle ) 1506 printk("\n[%s] thread[%x,%x] exit / child <%s> in <%s> not found\n", 1507 __FUNCTION__, this->process->pid, this->trdid, name, parent_name ); 1508 #endif 1509 return 1; 1510 } 1511 else 1512 { 1513 printk("\n[ERROR] in %s : cannot get page %d from mapper\n", 1514 __FUNCTION__, page_id ); 1515 1516 return -1; 1517 } 1518 } // end fatfs_scan_directory() 1519 1520 1521 1522 ///////////////////////////////////////////////////// 1523 error_t fatfs_new_dentry( vfs_inode_t * parent_inode, 1524 char * name, 1525 xptr_t child_inode_xp ) 1526 { 1527 uint8_t * entry; // pointer on FAT32 directory entry (array of 32 bytes) 1528 uint32_t index; // index of FAT32 directory entry in mapper 1529 mapper_t * mapper; // pointer on directory mapper 1530 uint32_t cluster; // directory entry cluster 1531 uint32_t size; // directory entry size 1532 bool_t is_dir; // directory entry type (file/dir) 1533 error_t error; 1534 1535 // check arguments 1536 assert( (parent_inode != NULL) , "parent_inode is NULL\n" ); 1537 assert( (name != NULL) , "name is NULL\n" ); 1538 assert( (child_inode_xp != XPTR_NULL ) , "child_inode is XPTR_NULL\n" ); 1539 1540 #if DEBUG_FATFS_GET_DENTRY 1541 char parent_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1542 uint32_t cycle = (uint32_t)hal_get_cycles(); 1543 thread_t * this = CURRENT_THREAD; 1544 vfs_inode_get_name( XPTR( local_cxy , parent_inode ) , parent_name ); 1545 if( DEBUG_FATFS_GET_DENTRY < cycle ) 1546 printk("\n[%s] thread[%x,%x] enter for child <%s> in parent <%s> / cycle %d\n", 1547 __FUNCTION__, this->process->pid, this->trdid, name , parent_name , cycle ); 1548 #endif 1549 1550 // get pointer and index of searched directory entry in mapper 1551 mapper = parent_inode->mapper; 1552 error = fatfs_scan_directory( mapper, name , &entry , &index ); 1553 1554 // update child inode and dentry descriptors if sucess 1555 if( error == 0 ) 1556 { 1500 1557 1501 1558 #if DEBUG_FATFS_GET_DENTRY 1502 1559 cycle = (uint32_t)hal_get_cycles(); 1503 1560 if( DEBUG_FATFS_GET_DENTRY < cycle ) 1504 printk("\n[%s] thread[%x,%x] exit / child <%s> not found / cycle %d\n", 1505 __FUNCTION__, this->process->pid, this->trdid, name, cycle ); 1506 #endif 1507 1508 return -1; 1509 } 1510 1511 // get child inode cluster and local pointer 1512 cxy_t inode_cxy = GET_CXY( child_inode_xp ); 1513 vfs_inode_t * inode_ptr = GET_PTR( child_inode_xp ); 1514 1515 // build extended pointer on parent dentried root 1516 xptr_t parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 1561 printk("\n[%s] thread[%x,%x] exit / intialised child <%s> in %s / cycle %d\n", 1562 __FUNCTION__, this->process->pid, this->trdid, name, parent_name, cycle ); 1563 #endif 1564 // get relevant infos from FAT32 directory entry 1565 cluster = (fatfs_get_record( DIR_FST_CLUS_HI , entry , 1 ) << 16) | 1566 (fatfs_get_record( DIR_FST_CLUS_LO , entry , 1 ) ) ; 1567 is_dir = (fatfs_get_record( DIR_ATTR , entry , 1 ) & ATTR_DIRECTORY); 1568 size = fatfs_get_record( DIR_FILE_SIZE , entry , 1 ); 1569 1570 // get child inode cluster and local pointer 1571 cxy_t inode_cxy = GET_CXY( child_inode_xp ); 1572 vfs_inode_t * inode_ptr = GET_PTR( child_inode_xp ); 1573 1574 // build extended pointer on root of list of prent dentries 1575 xptr_t parents_root_xp = XPTR( inode_cxy , &inode_ptr->parents ); 1517 1576 1518 1577 // check child inode has at least one parent 1519 1578 assert( (xlist_is_empty( parents_root_xp ) == false ), "child inode must have one parent\n"); 1520 1579 1521 // get dentry pointers and cluster1522 xptr_t dentry_xp = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents );1523 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp );1524 cxy_t dentry_cxy = GET_CXY( dentry_xp );1580 // get dentry pointers and cluster 1581 xptr_t dentry_xp = XLIST_FIRST( parents_root_xp , vfs_dentry_t , parents ); 1582 vfs_dentry_t * dentry_ptr = GET_PTR( dentry_xp ); 1583 cxy_t dentry_cxy = GET_CXY( dentry_xp ); 1525 1584 1526 1585 // check dentry descriptor in same cluster as parent inode 1527 1586 assert( (dentry_cxy == local_cxy) , "illegal dentry cluster\n" ); 1528 1587 1529 // update the child inode "type", "size", and "extend" fields 1530 vfs_inode_type_t type = (is_dir) ? INODE_TYPE_DIR : INODE_TYPE_FILE; 1531 1532 hal_remote_s32( XPTR( inode_cxy , &inode_ptr->type ) , type ); 1533 hal_remote_s32( XPTR( inode_cxy , &inode_ptr->size ) , size ); 1534 hal_remote_s32( XPTR( inode_cxy , &inode_ptr->extend ) , cluster ); 1535 1536 // update the dentry "extend" field 1537 dentry_ptr->extend = (void *)(intptr_t)dentry_id; 1538 1539 #if DEBUG_FATFS_GET_DENTRY 1588 // update the child inode "type", "size", and "extend" fields 1589 vfs_inode_type_t type = (is_dir) ? INODE_TYPE_DIR : INODE_TYPE_FILE; 1590 1591 hal_remote_s32( XPTR( inode_cxy , &inode_ptr->type ) , type ); 1592 hal_remote_s32( XPTR( inode_cxy , &inode_ptr->size ) , size ); 1593 hal_remote_s32( XPTR( inode_cxy , &inode_ptr->extend ) , cluster ); 1594 1595 // update the dentry "extend" field 1596 dentry_ptr->extend = (void *)(intptr_t)index; 1597 1598 return 0; 1599 } 1600 else 1601 { 1602 return -1; 1603 } 1604 1605 } // end fatfs_new_dentry() 1606 1607 ////////////////////////////////////////////////// 1608 error_t fatfs_update_dentry( vfs_inode_t * inode, 1609 vfs_dentry_t * dentry, 1610 uint32_t size ) 1611 { 1612 uint8_t * entry; // pointer on FAT32 directory entry (array of 32 bytes) 1613 uint32_t index; // index of FAT32 directory entry in mapper 1614 mapper_t * mapper; // pointer on directory mapper 1615 error_t error; 1616 1617 // check arguments 1618 assert( (inode != NULL) , "inode is NULL\n" ); 1619 assert( (dentry != NULL) , "dentry is NULL\n" ); 1620 assert( (size != 0 ) , "size is 0\n" ); 1621 1622 #if DEBUG_FATFS_UPDATE_DENTRY 1623 char dir_name[CONFIG_VFS_MAX_NAME_LENGTH]; 1624 uint32_t cycle = (uint32_t)hal_get_cycles(); 1625 thread_t * this = CURRENT_THREAD; 1626 vfs_inode_get_name( XPTR( local_cxy , inode ) , dir_name ); 1627 if( DEBUG_FATFS_UPDATE_DENTRY < cycle ) 1628 printk("\n[%s] thread[%x,%x] enter for entry <%s> in dir <%s> / cycle %d\n", 1629 __FUNCTION__, this->process->pid, this->trdid, dentry->name , dir_name , cycle ); 1630 #endif 1631 1632 // get pointer and index of searched directory entry in mapper 1633 mapper = inode->mapper; 1634 error = fatfs_scan_directory( mapper, dentry->name , &entry , &index ); 1635 1636 // update size in mapper if found 1637 if( error == 0 ) 1638 { 1639 1640 #if DEBUG_FATFS_UPDATE_DENTRY 1540 1641 cycle = (uint32_t)hal_get_cycles(); 1541 if( DEBUG_FATFS_GET_DENTRY < cycle ) 1542 printk("\n[%s] thread[%x,%x] exit / child <%s> loaded in <%s> / cycle %d\n", 1543 __FUNCTION__, this->process->pid, this->trdid, name, parent_name, cycle ); 1544 #endif 1545 1546 return 0; 1547 1548 } // end fatfs_get_dentry() 1642 if( DEBUG_FATFS_UPDATE_DENTRY < cycle ) 1643 printk("\n[%s] thread[%x,%x] exit / found entry <%s> in <%s> / cycle %d\n", 1644 __FUNCTION__, this->process->pid, this->trdid, dentry->name, dir_name, cycle ); 1645 #endif 1646 // set size in FAT32 directory entry 1647 fatfs_set_record( DIR_FILE_SIZE , entry , 1 , size ); 1648 1649 // get local pointer on modified page base 1650 void * base = (void *)((intptr_t)entry & (~CONFIG_PPM_PAGE_MASK)); 1651 1652 // get extended pointer on modified page descriptor 1653 xptr_t page_xp = ppm_base2page( XPTR( local_cxy , base ) ); 1654 1655 // mark page as dirty 1656 ppm_page_do_dirty( page_xp ); 1657 1658 return 0; 1659 } 1660 else 1661 { 1662 return -1; 1663 } 1664 1665 } // end fatfs_update_dentry() 1549 1666 1550 1667 /////////////////////////////////////////////////////// … … 2056 2173 assert( (inode_xp != XPTR_NULL) , "inode pointer is NULL\n" ); 2057 2174 2058 // get first_cluster from inode extension2175 // get inode cluster and local pointer 2059 2176 inode_ptr = GET_PTR( inode_xp ); 2060 2177 inode_cxy = GET_CXY( inode_xp ); 2178 2179 // get first_cluster from inode extension 2061 2180 first_xp = XPTR( inode_cxy , &inode_ptr->extend ); 2062 2181 first_cluster = (uint32_t)(intptr_t)hal_remote_lpt( first_xp ); … … 2073 2192 printk("\n[%s] thread[%x,%x] enter for <%s> / first_cluster %x / cycle %d\n", 2074 2193 __FUNCTION__ , this->process->pid, this->trdid, name, first_cluster, cycle ); 2194 #endif 2195 2196 #if (DEBUG_FATFS_RELEASE_INODE & 1) 2197 fatfs_display_fat( 0 , 512 ); 2075 2198 #endif 2076 2199
Note: See TracChangeset
for help on using the changeset viewer.