diff options
Diffstat (limited to 'c/src/libfs/src/dosfs/fat_fat_operations.c')
-rw-r--r-- | c/src/libfs/src/dosfs/fat_fat_operations.c | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/c/src/libfs/src/dosfs/fat_fat_operations.c b/c/src/libfs/src/dosfs/fat_fat_operations.c deleted file mode 100644 index 49b2ab70d3..0000000000 --- a/c/src/libfs/src/dosfs/fat_fat_operations.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * fat_fat_operations.c - * - * General operations on File Allocation Table - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * @(#) $Id$ - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> -#include <assert.h> - -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" - -/* fat_scan_fat_for_free_clusters -- - * Allocate chain of free clusters from Files Allocation Table - * - * PARAMETERS: - * mt_entry - mount table entry - * chain - the number of the first allocated cluster (first cluster - * in the chain) - * count - count of clusters to allocate (chain length) - * - * RETURNS: - * RC_OK on success, or error code if error occured (errno set - * appropriately) - * - * - */ -int -fat_scan_fat_for_free_clusters( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 *chain, - unsigned32 count, - unsigned32 *cls_added, - unsigned32 *last_cl - ) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cl4find = 2; - unsigned32 next_cln = 0; - unsigned32 save_cln = 0; - unsigned32 data_cls_val = fs_info->vol.data_cls + 2; - unsigned32 i = 2; - - *cls_added = 0; - - if (count == 0) - return rc; - - if ((fs_info->vol.type & FAT_FAT32) && - (fs_info->vol.next_cl != FAT_UNDEFINED_VALUE)) - cl4find = fs_info->vol.next_cl; - - /* - * fs_info->vol.data_cls is exactly the count of data clusters - * starting at cluster 2, so the maximum valid cluster number is - * (fs_info->vol.data_cls + 1) - */ - while (i < data_cls_val) - { - rc = fat_get_fat_cluster(mt_entry, cl4find, &next_cln); - if ( rc != RC_OK ) - { - if (*cls_added != 0) - fat_free_fat_clusters_chain(mt_entry, (*chain)); - return rc; - } - - if ((next_cln & fs_info->vol.mask) == FAT_GENFAT_FREE) - { - /* - * We are enforced to process allocation of the first free cluster - * by separate 'if' statement because otherwise undo function - * wouldn't work properly - */ - if (*cls_added == 0) - { - *chain = cl4find; - rc = fat_set_fat_cluster(mt_entry, cl4find, FAT_GENFAT_EOC); - if ( rc != RC_OK ) - { - /* - * this is the first cluster we tried to allocate so no - * cleanup activity needed - */ - return rc; - } - } - else - { - /* set EOC value to new allocated cluster */ - rc = fat_set_fat_cluster(mt_entry, cl4find, FAT_GENFAT_EOC); - if ( rc != RC_OK ) - { - /* cleanup activity */ - fat_free_fat_clusters_chain(mt_entry, (*chain)); - return rc; - } - - rc = fat_set_fat_cluster(mt_entry, save_cln, cl4find); - if ( rc != RC_OK ) - { - /* cleanup activity */ - fat_free_fat_clusters_chain(mt_entry, (*chain)); - /* trying to save last allocated cluster for future use */ - fat_set_fat_cluster(mt_entry, cl4find, FAT_GENFAT_FREE); - fat_buf_release(fs_info); - return rc; - } - } - - save_cln = cl4find; - (*cls_added)++; - - /* have we satisfied request ? */ - if (*cls_added == count) - { - if (fs_info->vol.type & FAT_FAT32) - { - fs_info->vol.next_cl = save_cln; - if (fs_info->vol.free_cls != 0xFFFFFFFF) - fs_info->vol.free_cls -= (*cls_added); - } - *last_cl = save_cln; - fat_buf_release(fs_info); - return rc; - } - } - i++; - cl4find++; - if (cl4find >= data_cls_val) - cl4find = 2; - } - - if (fs_info->vol.type & FAT_FAT32) - { - fs_info->vol.next_cl = save_cln; - if (fs_info->vol.free_cls != 0xFFFFFFFF) - fs_info->vol.free_cls -= (*cls_added); - } - *last_cl = save_cln; - fat_buf_release(fs_info); - return RC_OK; -} - -/* fat_free_fat_clusters_chain -- - * Free chain of clusters in Files Allocation Table. - * - * PARAMETERS: - * mt_entry - mount table entry - * chain - number of the first cluster in the chain - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -fat_free_fat_clusters_chain( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 chain - ) -{ - int rc = RC_OK, rc1 = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cur_cln = chain; - unsigned32 next_cln = 0; - unsigned32 freed_cls_cnt = 0; - - while ((cur_cln & fs_info->vol.mask) != fs_info->vol.eoc_val) - { - rc = fat_get_fat_cluster(mt_entry, cur_cln, &next_cln); - if ( rc != RC_OK ) - { - if ((fs_info->vol.type & FAT_FAT32) && - (fs_info->vol.free_cls != FAT_UNDEFINED_VALUE)) - fs_info->vol.free_cls += freed_cls_cnt; - fat_buf_release(fs_info); - return rc; - } - - rc = fat_set_fat_cluster(mt_entry, cur_cln, FAT_GENFAT_FREE); - if ( rc != RC_OK ) - rc1 = rc; - - freed_cls_cnt++; - cur_cln = next_cln; - } - - if (fs_info->vol.type & FAT_FAT32) - { - fs_info->vol.next_cl = chain; - if (fs_info->vol.free_cls != FAT_UNDEFINED_VALUE) - fs_info->vol.free_cls += freed_cls_cnt; - } - - fat_buf_release(fs_info); - if (rc1 != RC_OK) - return rc1; - - return RC_OK; -} - -/* fat_get_fat_cluster -- - * Fetches the contents of the cluster (link to next cluster in the chain) - * from Files Allocation Table. - * - * PARAMETERS: - * mt_entry - mount table entry - * cln - number of cluster to fetch the contents from - * ret_val - contents of the cluster 'cln' (link to next cluster in - * the chain) - * - * RETURNS: - * RC_OK on success, or -1 if error occured - * and errno set appropriately - */ -int -fat_get_fat_cluster( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - unsigned32 *ret_val - ) -{ - int rc = RC_OK; - register fat_fs_info_t *fs_info = mt_entry->fs_info; - bdbuf_buffer *block0 = NULL; - unsigned32 sec = 0; - unsigned32 ofs = 0; - - /* sanity check */ - if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) ) - set_errno_and_return_minus_one(EIO); - - sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) + - fs_info->vol.afat_loc; - ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1); - - rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &block0); - if (rc != RC_OK) - return rc; - - switch ( fs_info->vol.type ) - { - case FAT_FAT12: - /* - * we are enforced in complex computations for FAT12 to escape CPU - * align problems for some architectures - */ - *ret_val = (*((unsigned8 *)(block0->buffer + ofs))); - if ( ofs == (fs_info->vol.bps - 1) ) - { - rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ, - &block0); - if (rc != RC_OK) - return rc; - - *ret_val |= (*((unsigned8 *)(block0->buffer)))<<8; - } - else - { - *ret_val |= (*((unsigned8 *)(block0->buffer + ofs + 1)))<<8; - } - - if ( FAT_CLUSTER_IS_ODD(cln) ) - *ret_val = (*ret_val) >> FAT12_SHIFT; - else - *ret_val = (*ret_val) & FAT_FAT12_MASK; - - break; - - case FAT_FAT16: - *ret_val = *((unsigned16 *)(block0->buffer + ofs)); - *ret_val = CF_LE_W(*ret_val); - break; - - case FAT_FAT32: - *ret_val = *((unsigned32 *)(block0->buffer + ofs)); - *ret_val = CF_LE_L(*ret_val); - break; - - default: - set_errno_and_return_minus_one(EIO); - break; - } - - return RC_OK; -} - -/* fat_set_fat_cluster -- - * Set the contents of the cluster (link to next cluster in the chain) - * from Files Allocation Table. - * - * PARAMETERS: - * mt_entry - mount table entry - * cln - number of cluster to set contents to - * in_val - value to set - * - * RETURNS: - * RC_OK on success, or -1 if error occured - * and errno set appropriately - */ -int -fat_set_fat_cluster( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - unsigned32 in_val - ) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 sec = 0; - unsigned32 ofs = 0; - unsigned16 fat16_clv = 0; - unsigned32 fat32_clv = 0; - bdbuf_buffer *block0 = NULL; - - /* sanity check */ - if ( (cln < 2) || (cln > (fs_info->vol.data_cls + 1)) ) - set_errno_and_return_minus_one(EIO); - - sec = (FAT_FAT_OFFSET(fs_info->vol.type, cln) >> fs_info->vol.sec_log2) + - fs_info->vol.afat_loc; - ofs = FAT_FAT_OFFSET(fs_info->vol.type, cln) & (fs_info->vol.bps - 1); - - rc = fat_buf_access(fs_info, sec, FAT_OP_TYPE_READ, &block0); - if (rc != RC_OK) - return rc; - - switch ( fs_info->vol.type ) - { - case FAT_FAT12: - if ( FAT_CLUSTER_IS_ODD(cln) ) - { - fat16_clv = CT_LE_W((((unsigned16)in_val) << FAT_FAT12_SHIFT)); - - *((unsigned8 *)(block0->buffer + ofs)) = - (*((unsigned8 *)(block0->buffer + ofs))) & 0x0F; - - *((unsigned8 *)(block0->buffer + ofs)) = - (*((unsigned8 *)(block0->buffer + ofs))) | - (unsigned8)(fat16_clv & 0x00FF); - - fat_buf_mark_modified(fs_info); - - if ( ofs == (fs_info->vol.bps - 1) ) - { - rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ, - &block0); - if (rc != RC_OK) - return rc; - - *((unsigned8 *)(block0->buffer)) &= 0x00; - - *((unsigned8 *)(block0->buffer)) = - (*((unsigned8 *)(block0->buffer))) | - (unsigned8)((fat16_clv & 0xFF00)>>8); - - fat_buf_mark_modified(fs_info); - } - else - { - *((unsigned8 *)(block0->buffer + ofs + 1)) &= 0x00; - - *((unsigned8 *)(block0->buffer + ofs + 1)) = - (*((unsigned8 *)(block0->buffer + ofs + 1))) | - (unsigned8)((fat16_clv & 0xFF00)>>8); - } - } - else - { - fat16_clv = CT_LE_W((((unsigned16)in_val) & FAT_FAT12_MASK)); - - *((unsigned8 *)(block0->buffer + ofs)) &= 0x00; - - *((unsigned8 *)(block0->buffer + ofs)) = - (*((unsigned8 *)(block0->buffer + ofs))) | - (unsigned8)(fat16_clv & 0x00FF); - - fat_buf_mark_modified(fs_info); - - if ( ofs == (fs_info->vol.bps - 1) ) - { - rc = fat_buf_access(fs_info, sec + 1, FAT_OP_TYPE_READ, - &block0); - if (rc != RC_OK) - return rc; - - *((unsigned8 *)(block0->buffer)) = - (*((unsigned8 *)(block0->buffer))) & 0xF0; - - *((unsigned8 *)(block0->buffer)) = - (*((unsigned8 *)(block0->buffer))) | - (unsigned8)((fat16_clv & 0xFF00)>>8); - - fat_buf_mark_modified(fs_info); - } - else - { - *((unsigned8 *)(block0->buffer + ofs + 1)) = - (*((unsigned8 *)(block0->buffer + ofs + 1))) & 0xF0; - - *((unsigned8 *)(block0->buffer + ofs+1)) = - (*((unsigned8 *)(block0->buffer + ofs+1))) | - (unsigned8)((fat16_clv & 0xFF00)>>8); - } - } - break; - - case FAT_FAT16: - *((unsigned16 *)(block0->buffer + ofs)) = - (unsigned16)(CT_LE_W(in_val)); - fat_buf_mark_modified(fs_info); - break; - - case FAT_FAT32: - fat32_clv = CT_LE_L((in_val & FAT_FAT32_MASK)); - - *((unsigned32 *)(block0->buffer + ofs)) = - (*((unsigned32 *)(block0->buffer + ofs))) & (CT_LE_L(0xF0000000)); - - *((unsigned32 *)(block0->buffer + ofs)) = - fat32_clv | (*((unsigned32 *)(block0->buffer + ofs))); - - fat_buf_mark_modified(fs_info); - break; - - default: - set_errno_and_return_minus_one(EIO); - break; - - } - - return RC_OK; -} |