⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -