📄 fat.c
字号:
vol->info_sec = FAT_BR_FAT32_FS_INFO_SECTOR(boot_rec); if( vol->info_sec == 0 ) { rtems_disk_release(vol->dd); set_errno_and_return_minus_one( EINVAL ); } else { ret = _fat_block_read(mt_entry, vol->info_sec , 0, FAT_FSI_LEADSIG_SIZE, fs_info_sector); if ( ret < 0 ) { rtems_disk_release(vol->dd); return -1; } if (FAT_FSINFO_LEAD_SIGNATURE(fs_info_sector) != FAT_FSINFO_LEAD_SIGNATURE_VALUE) { rtems_disk_release(vol->dd); set_errno_and_return_minus_one( EINVAL ); } else { ret = _fat_block_read(mt_entry, vol->info_sec , FAT_FSI_INFO, FAT_USEFUL_INFO_SIZE, fs_info_sector); if ( ret < 0 ) { rtems_disk_release(vol->dd); return -1; } vol->free_cls = FAT_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector); vol->next_cl = FAT_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector); rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF, 0xFFFFFFFF); if ( rc != RC_OK ) { rtems_disk_release(vol->dd); return rc; } } } } else { vol->rdir_cl = 0; vol->mirror = 0; vol->afat = 0; vol->free_cls = 0xFFFFFFFF; vol->next_cl = 0xFFFFFFFF; } vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat; /* set up collection of fat-files fd */ fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control)); if ( fs_info->vhash == NULL ) { rtems_disk_release(vol->dd); set_errno_and_return_minus_one( ENOMEM ); } for (i = 0; i < FAT_HASH_SIZE; i++) _Chain_Initialize_empty(fs_info->vhash + i); fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control)); if ( fs_info->rhash == NULL ) { rtems_disk_release(vol->dd); free(fs_info->vhash); set_errno_and_return_minus_one( ENOMEM ); } for (i = 0; i < FAT_HASH_SIZE; i++) _Chain_Initialize_empty(fs_info->rhash + i); fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE; fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4; fs_info->index = 0; fs_info->uino = (char *)calloc(fs_info->uino_pool_size, sizeof(char)); if ( fs_info->uino == NULL ) { rtems_disk_release(vol->dd); free(fs_info->vhash); free(fs_info->rhash); set_errno_and_return_minus_one( ENOMEM ); } fs_info->sec_buf = (char *)calloc(vol->bps, sizeof(char)); if (fs_info->sec_buf == NULL) { rtems_disk_release(vol->dd); free(fs_info->vhash); free(fs_info->rhash); free(fs_info->uino); set_errno_and_return_minus_one( ENOMEM ); } return RC_OK; }/* fat_shutdown_drive -- * Free all allocated resources and synchronize all necessary data * * PARAMETERS: * mt_entry - mount table entry * * RETURNS: * RC_OK on success, or -1 if error occured * and errno set appropriately */intfat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry){ int rc = RC_OK; fat_fs_info_t *fs_info = mt_entry->fs_info; int i = 0; if (fs_info->vol.type & FAT_FAT32) { rc = fat_fat32_update_fsinfo_sector(mt_entry, fs_info->vol.free_cls, fs_info->vol.next_cl); if ( rc != RC_OK ) rc = -1; } fat_buf_release(fs_info); if (rtems_bdbuf_syncdev(fs_info->vol.dev) != RTEMS_SUCCESSFUL) rc = -1; for (i = 0; i < FAT_HASH_SIZE; i++) { Chain_Node *node = NULL; Chain_Control *the_chain = fs_info->vhash + i; while ( (node = _Chain_Get(the_chain)) != NULL ) free(node); } for (i = 0; i < FAT_HASH_SIZE; i++) { Chain_Node *node = NULL; Chain_Control *the_chain = fs_info->rhash + i; while ( (node = _Chain_Get(the_chain)) != NULL ) free(node); } free(fs_info->vhash); free(fs_info->rhash); free(fs_info->uino); free(fs_info->sec_buf); rtems_disk_release(fs_info->vol.dd); if (rc) errno = EIO; return rc;}/* fat_init_clusters_chain -- * Zeroing contents of all clusters in the chain * * PARAMETERS: * mt_entry - mount table entry * start_cluster_num - num of first cluster in the chain * * RETURNS: * RC_OK on success, or -1 if error occured * and errno set appropriately */intfat_init_clusters_chain( rtems_filesystem_mount_table_entry_t *mt_entry, unsigned32 start_cln ){ int rc = RC_OK; ssize_t ret = 0; register fat_fs_info_t *fs_info = mt_entry->fs_info; unsigned32 cur_cln = start_cln; char *buf; buf = calloc(fs_info->vol.bpc, sizeof(char)); if ( buf == NULL ) set_errno_and_return_minus_one( EIO ); while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val) { ret = fat_cluster_write(mt_entry, cur_cln, buf); if ( ret == -1 ) { free(buf); return -1; } rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln); if ( rc != RC_OK ) { free(buf); return rc; } } free(buf); return rc;} #define FAT_UNIQ_INO_BASE 0x0FFFFF00 #define FAT_UNIQ_INO_IS_BUSY(index, arr) \ (((arr)[((index)>>3)]>>((index) & (8-1))) & 0x01)#define FAT_SET_UNIQ_INO_BUSY(index, arr) \ ((arr)[((index)>>3)] |= (0x01<<((index) & (8-1))))#define FAT_SET_UNIQ_INO_FREE(index, arr) \ ((arr)[((index)>>3)] &= (~(0x01<<((index) & (8-1)))))/* fat_get_unique_ino -- * Allocate unique ino from unique ino pool * * PARAMETERS: * mt_entry - mount table entry * * RETURNS: * unique inode number on success, or 0 if there is no free unique inode * number in the pool * * ATTENTION: * 0 means FAILED !!! * */unsigned32fat_get_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry){ register fat_fs_info_t *fs_info = mt_entry->fs_info; unsigned32 j = 0; rtems_boolean resrc_unsuff = FALSE; while (!resrc_unsuff) { for (j = 0; j < fs_info->uino_pool_size; j++) { if (!FAT_UNIQ_INO_IS_BUSY(fs_info->index, fs_info->uino)) { FAT_SET_UNIQ_INO_BUSY(fs_info->index, fs_info->uino); return (fs_info->uino_base + fs_info->index); } fs_info->index++; if (fs_info->index >= fs_info->uino_pool_size) fs_info->index = 0; } if ((fs_info->uino_pool_size << 1) < (0x0FFFFFFF - fs_info->uino_base)) { fs_info->uino_pool_size <<= 1; fs_info->uino = realloc(fs_info->uino, fs_info->uino_pool_size); if (fs_info->uino != NULL) fs_info->index = fs_info->uino_pool_size; else resrc_unsuff = TRUE; } else resrc_unsuff = TRUE; } return 0;}/* fat_free_unique_ino -- * Return unique ino to unique ino pool * * PARAMETERS: * mt_entry - mount table entry * ino - inode number to free * * RETURNS: * None */voidfat_free_unique_ino( rtems_filesystem_mount_table_entry_t *mt_entry, unsigned32 ino ){ fat_fs_info_t *fs_info = mt_entry->fs_info; FAT_SET_UNIQ_INO_FREE((ino - fs_info->uino_base), fs_info->uino);}/* fat_ino_is_unique -- * Test whether ino is from unique ino pool * * PARAMETERS: * mt_entry - mount table entry * ino - ino to be tested * * RETURNS: * TRUE if ino is allocated from unique ino pool, FALSE otherwise */inline rtems_booleanfat_ino_is_unique( rtems_filesystem_mount_table_entry_t *mt_entry, unsigned32 ino ){ fat_fs_info_t *fs_info = mt_entry->fs_info; return (ino >= fs_info->uino_base);}/* fat_fat32_update_fsinfo_sector -- * Synchronize fsinfo sector for FAT32 volumes * * PARAMETERS: * mt_entry - mount table entry * free_count - count of free clusters * next_free - the next free cluster num * * RETURNS: * RC_OK on success, or -1 if error occured (errno set appropriately) */intfat_fat32_update_fsinfo_sector( rtems_filesystem_mount_table_entry_t *mt_entry, unsigned32 free_count, unsigned32 next_free ){ ssize_t ret1 = 0, ret2 = 0; register fat_fs_info_t *fs_info = mt_entry->fs_info; unsigned32 le_free_count = 0; unsigned32 le_next_free = 0; le_free_count = CT_LE_L(free_count); le_next_free = CT_LE_L(next_free); ret1 = _fat_block_write(mt_entry, fs_info->vol.info_sec, FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET, 4, (char *)(&le_free_count)); ret2 = _fat_block_write(mt_entry, fs_info->vol.info_sec, FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET, 4, (char *)(&le_next_free)); if ( (ret1 < 0) || (ret2 < 0) ) return -1; return RC_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -