/* _fat_block_release -- * This function works around the hack that hold a bdbuf and does * not release it. * * PARAMETERS: * mt_entry - mount table entry * * RETURNS: * 0 on success, or -1 if error occured and errno set appropriately */ int _fat_block_release( rtems_filesystem_mount_table_entry_t *mt_entry) { fat_fs_info_t *fs_info = mt_entry->fs_info; return fat_buf_release(fs_info); }
/* fat_file_close -- * Close fat-file. If count of links to fat-file * descriptor is greater than 1 (i.e. somebody esle holds pointer * to this descriptor) just decrement it. Otherwise * do the following. If this descriptor corresponded to removed fat-file * then free clusters contained fat-file data, delete descriptor from * "rhash" table and free memory allocated by descriptor. If descriptor * correspondes to non-removed fat-file and 'ino' field has value from * unique inode numbers pool then set count of links to descriptor to zero * and leave it in hash, otherwise delete descriptor from "vhash" and free * memory allocated by the descriptor * * PARAMETERS: * mt_entry - mount table entry * fat_fd - fat-file descriptor * * RETURNS: * RC_OK, or -1 if error occured (errno set appropriately) */ int fat_file_close( rtems_filesystem_mount_table_entry_t *mt_entry, fat_file_fd_t *fat_fd ) { int rc = RC_OK; fat_fs_info_t *fs_info = mt_entry->fs_info; uint32_t key = 0; /* * if links_num field of fat-file descriptor is greater than 1 * decrement the count of links and return */ if (fat_fd->links_num > 1) { fat_fd->links_num--; return rc; } key = fat_construct_key(mt_entry, &fat_fd->dir_pos.sname); if (fat_fd->flags & FAT_FILE_REMOVED) { rc = fat_file_truncate(mt_entry, fat_fd, 0); if ( rc != RC_OK ) return rc; _hash_delete(fs_info->rhash, key, fat_fd->ino, fat_fd); if ( fat_ino_is_unique(mt_entry, fat_fd->ino) ) fat_free_unique_ino(mt_entry, fat_fd->ino); free(fat_fd); } else { if (fat_ino_is_unique(mt_entry, fat_fd->ino)) { fat_fd->links_num = 0; } else { _hash_delete(fs_info->vhash, key, fat_fd->ino, fat_fd); free(fat_fd); } } /* * flush any modified "cached" buffer back to disk */ rc = fat_buf_release(fs_info); return rc; }
/* 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 */ int fat_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; }