diff options
Diffstat (limited to 'c/src/exec/libfs/src/dosfs')
23 files changed, 0 insertions, 6613 deletions
diff --git a/c/src/exec/libfs/src/dosfs/.cvsignore b/c/src/exec/libfs/src/dosfs/.cvsignore deleted file mode 100644 index 7bb609bf24..0000000000 --- a/c/src/exec/libfs/src/dosfs/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile -Makefile.in -config.h -config.h.in -stamp-h -stamp-h.in diff --git a/c/src/exec/libfs/src/dosfs/Makefile.am b/c/src/exec/libfs/src/dosfs/Makefile.am deleted file mode 100644 index 9bb265386a..0000000000 --- a/c/src/exec/libfs/src/dosfs/Makefile.am +++ /dev/null @@ -1,55 +0,0 @@ -## -## $Id$ -## - - -include $(top_srcdir)/../automake/multilib.am -include $(top_srcdir)/../automake/compile.am -include $(top_srcdir)/../automake/lib.am - -INCLUDES = -I../.. - -AM_CFLAGS += $(LIBC_DEFINES) - -FATFS_C_FILES = fat.c fat_fat_operations.c fat_file.c - -DOSFS_C_FILES = msdos_create.c msdos_dir.c msdos_eval.c msdos_file.c \ - msdos_free.c msdos_fsunmount.c msdos_handlers_dir.c \ - msdos_handlers_file.c msdos_init.c msdos_initsupp.c \ - msdos_misc.c msdos_mknod.c msdos_node_type.c - -if !UNIX -LIBNAME = libdosfs -LIB = ${ARCH}/${LIBNAME}.a - -C_FILES = $(FATFS_C_FILES) $(DOSFS_C_FILES) - -C_O_FILES = $(C_FILES:%.c=${ARCH}/%.o) - -include_HEADERS = dosfs.h - -H_FILES = $(PROJECT_INCLUDE) \ - $(include_HEADERS:%=$(PROJECT_INCLUDE)/%) - -$(PROJECT_INCLUDE): - @$(mkinstalldirs) $@ - -$(PROJECT_INCLUDE)/%.h: %.h - $(INSTALL_DATA) $< $@ - -OBJS = $(C_O_FILES) - -# -# Add local stuff here using += -# -all-local: ${ARCH} $(LIB) - -$(LIB): ${OBJS} - $(make-library) -endif - -TMPINSTALL_FILES += $(H_FILES) - -EXTRA_DIST = $(DOSFS_C_FILES) $(FATFS_C_FILES) - -include $(top_srcdir)/../automake/local.am diff --git a/c/src/exec/libfs/src/dosfs/dosfs.h b/c/src/exec/libfs/src/dosfs/dosfs.h deleted file mode 100644 index 4cea929d4c..0000000000 --- a/c/src/exec/libfs/src/dosfs/dosfs.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * dosfs.h - * - * Application interface to MSDOS filesystem. - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ -#ifndef __DOSFS_DOSFS_H__ -#define __DOSFS_DOSFS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <rtems.h> -#include <rtems/libio.h> - -extern rtems_filesystem_operations_table msdos_ops; - -#ifdef __cplusplus -} -#endif - -#endif /* __DOSFS_DOSFS_H__ */ diff --git a/c/src/exec/libfs/src/dosfs/fat.c b/c/src/exec/libfs/src/dosfs/fat.c deleted file mode 100644 index 852c104781..0000000000 --- a/c/src/exec/libfs/src/dosfs/fat.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * fat.c - * - * Low-level operations on a volume with FAT filesystem - * - * 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" - -/* _fat_block_read -- - * This function reads 'count' bytes from device filesystem is mounted on, - * starts at 'start+offset' position where 'start' computed in sectors - * and 'offset' is offset inside sector (reading may cross sectors - * boundary; in this case assumed we want to read sequential sector(s)) - * - * PARAMETERS: - * mt_entry - mount table entry - * start - sector num to start read from - * offset - offset inside sector 'start' - * count - count of bytes to read - * buff - buffer provided by user - * - * RETURNS: - * bytes read on success, or -1 if error occured - * and errno set appropriately - */ -ssize_t -_fat_block_read( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 start, - unsigned32 offset, - unsigned32 count, - void *buff - ) -{ - int rc = RC_OK; - register fat_fs_info_t *fs_info = mt_entry->fs_info; - ssize_t cmpltd = 0; - unsigned32 blk = start; - unsigned32 ofs = offset; - bdbuf_buffer *block = NULL; - unsigned32 c = 0; - - while (count > 0) - { - rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block); - if (rc != RC_OK) - return rc; - - c = MIN(count, (fs_info->vol.bps - ofs)); - memcpy((buff + cmpltd), (block->buffer + ofs), c); - - count -= c; - cmpltd += c; - blk++; - ofs = 0; - } - return cmpltd; -} - -/* _fat_block_write -- - * This function write 'count' bytes to device filesystem is mounted on, - * starts at 'start+offset' position where 'start' computed in sectors - * and 'offset' is offset inside sector (writing may cross sectors - * boundary; in this case assumed we want to write sequential sector(s)) - * - * PARAMETERS: - * mt_entry - mount table entry - * start - sector num to start read from - * offset - offset inside sector 'start' - * count - count of bytes to write - * buff - buffer provided by user - * - * RETURNS: - * bytes written on success, or -1 if error occured - * and errno set appropriately - */ -ssize_t -_fat_block_write( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 start, - unsigned32 offset, - unsigned32 count, - const void *buff) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - ssize_t cmpltd = 0; - unsigned32 blk = start; - unsigned32 ofs = offset; - bdbuf_buffer *block = NULL; - unsigned32 c = 0; - - while(count > 0) - { - c = MIN(count, (fs_info->vol.bps - ofs)); - - if (c == fs_info->vol.bps) - rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_GET, &block); - else - rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block); - if (rc != RC_OK) - return rc; - - memcpy((block->buffer + ofs), (buff + cmpltd), c); - - fat_buf_mark_modified(fs_info); - - count -= c; - cmpltd +=c; - blk++; - ofs = 0; - } - return cmpltd; -} - - - - -/* fat_cluster_read -- - * wrapper for reading a whole cluster at once - * - * PARAMETERS: - * mt_entry - mount table entry - * cln - number of cluster to read - * buff - buffer provided by user - * - * RETURNS: - * bytes read on success, or -1 if error occured - * and errno set appropriately - */ -ssize_t -fat_cluster_read( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - void *buff - ) -{ - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 fsec = 0; - - fsec = fat_cluster_num_to_sector_num(mt_entry, cln); - - return _fat_block_read(mt_entry, fsec, 0, - fs_info->vol.spc << fs_info->vol.sec_log2, buff); -} - -/* fat_cluster_write -- - * wrapper for writting a whole cluster at once - * - * PARAMETERS: - * mt_entry - mount table entry - * cln - number of cluster to write - * buff - buffer provided by user - * - * RETURNS: - * bytes written on success, or -1 if error occured - * and errno set appropriately - */ -ssize_t -fat_cluster_write( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - const void *buff - ) -{ - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 fsec = 0; - - fsec = fat_cluster_num_to_sector_num(mt_entry, cln); - - return _fat_block_write(mt_entry, fsec, 0, - fs_info->vol.spc << fs_info->vol.sec_log2, buff); -} - -/* fat_init_volume_info -- - * Get inforamtion about volume on which filesystem is mounted on - * - * PARAMETERS: - * mt_entry - mount table entry - * - * RETURNS: - * RC_OK on success, or -1 if error occured - * and errno set appropriately - */ -int -fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - register fat_vol_t *vol = &fs_info->vol; - unsigned32 data_secs = 0; - char boot_rec[FAT_MAX_BPB_SIZE]; - char fs_info_sector[FAT_USEFUL_INFO_SIZE]; - ssize_t ret = 0; - int fd; - struct stat stat_buf; - int i = 0; - - rc = stat(mt_entry->dev, &stat_buf); - if (rc == -1) - return rc; - - /* rtmes feature: no block devices, all are character devices */ - if (!S_ISCHR(stat_buf.st_mode)) - set_errno_and_return_minus_one(ENOTBLK); - - /* check that device is registred as block device and lock it */ - vol->dd = rtems_disk_lookup(stat_buf.st_dev); - if (vol->dd == NULL) - set_errno_and_return_minus_one(ENOTBLK); - - vol->dev = stat_buf.st_dev; - - fd = open(mt_entry->dev, O_RDONLY); - if (fd == -1) - { - rtems_disk_release(vol->dd); - return -1; - } - - ret = read(fd, (void *)boot_rec, FAT_MAX_BPB_SIZE); - if ( ret != FAT_MAX_BPB_SIZE ) - { - close(fd); - rtems_disk_release(vol->dd); - set_errno_and_return_minus_one( EIO ); - } - close(fd); - - vol->bps = FAT_BR_BYTES_PER_SECTOR(boot_rec); - - if ( (vol->bps != 512) && - (vol->bps != 1024) && - (vol->bps != 2048) && - (vol->bps != 4096)) - { - rtems_disk_release(vol->dd); - set_errno_and_return_minus_one( EINVAL ); - } - - for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0; - i >>= 1, vol->sec_mul++); - for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0; - i >>= 1, vol->sec_log2++); - - vol->spc = FAT_BR_SECTORS_PER_CLUSTER(boot_rec); - for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0; - i >>= 1, vol->spc_log2++); - - /* - * According to M$ White Paper "bytes per cluster" value - * greater than 32K is invalid - */ - if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT) - { - rtems_disk_release(vol->dd); - set_errno_and_return_minus_one(EINVAL); - } - - for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0; - i >>= 1, vol->bpc_log2++); - - vol->fats = FAT_BR_FAT_NUM(boot_rec); - vol->fat_loc = FAT_BR_RESERVED_SECTORS_NUM(boot_rec); - - vol->rdir_entrs = FAT_BR_FILES_PER_ROOT_DIR(boot_rec); - - /* calculate the count of sectors occupied by the root directory */ - vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) / - vol->bps; - - vol->rdir_size = vol->rdir_secs << vol->sec_log2; - - if ( (FAT_BR_SECTORS_PER_FAT(boot_rec)) != 0) - vol->fat_length = FAT_BR_SECTORS_PER_FAT(boot_rec); - else - vol->fat_length = FAT_BR_SECTORS_PER_FAT32(boot_rec); - - vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length + - vol->rdir_secs; - - /* for FAT12/16 root dir starts at(sector) */ - vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length; - - if ( (FAT_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0) - vol->tot_secs = FAT_BR_TOTAL_SECTORS_NUM16(boot_rec); - else - vol->tot_secs = FAT_BR_TOTAL_SECTORS_NUM32(boot_rec); - - data_secs = vol->tot_secs - vol->data_fsec; - - vol->data_cls = data_secs / vol->spc; - - /* determine FAT type at least */ - if ( vol->data_cls < FAT_FAT12_MAX_CLN) - { - vol->type = FAT_FAT12; - vol->mask = FAT_FAT12_MASK; - vol->eoc_val = FAT_FAT12_EOC; - } - else - { - if ( vol->data_cls < FAT_FAT16_MAX_CLN) - { - vol->type = FAT_FAT16; - vol->mask = FAT_FAT16_MASK; - vol->eoc_val = FAT_FAT16_EOC; - } - else - { - vol->type = FAT_FAT32; - vol->mask = FAT_FAT32_MASK; - vol->eoc_val = FAT_FAT32_EOC; - } - } - - if (vol->type == FAT_FAT32) - { - vol->rdir_cl = FAT_BR_FAT32_ROOT_CLUSTER(boot_rec); - - vol->mirror = FAT_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR; - if (vol->mirror) - vol->afat = FAT_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_FAT_NUM; - else - vol->afat = 0; - - 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 - */ -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; -} - -/* 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 - */ -int -fat_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 !!! - * - */ -unsigned32 -fat_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 - */ -void -fat_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_boolean -fat_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) - */ -int -fat_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; -} -
\ No newline at end of file diff --git a/c/src/exec/libfs/src/dosfs/fat.h b/c/src/exec/libfs/src/dosfs/fat.h deleted file mode 100644 index f0aaf21c98..0000000000 --- a/c/src/exec/libfs/src/dosfs/fat.h +++ /dev/null @@ -1,488 +0,0 @@ -/* - * fat.h - * - * Constants/data structures/prototypes for low-level operations on a volume - * with FAT filesystem - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#ifndef __DOSFS_FAT_H__ -#define __DOSFS_FAT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <string.h> - -#include <rtems/seterr.h> - -/* XXX: temporary hack :(( */ -#ifndef set_errno_and_return_minus_one -#define set_errno_and_return_minus_one rtems_set_errno_and_return_minus_one -#endif /* set_errno_and_return_minus_one */ - -#include <rtems/score/cpu.h> -#include <errno.h> -#include <rtems/bdbuf.h> - -#ifndef RC_OK -#define RC_OK 0x00000000 -#endif - -/* - * Remember that all FAT file system on disk data structure is - * "little endian"! - * (derived from linux) - */ -/* - * Conversion from and to little-endian byte order. (no-op on i386/i486) - * - * Naming: Ca_b_c, where a: F = from, T = to, b: LE = little-endian, - * BE = big-endian, c: W = word (16 bits), L = longword (32 bits) - */ - -#if (CPU_BIG_ENDIAN == TRUE) -# define CF_LE_W(v) CPU_swap_u16(v) -# define CF_LE_L(v) CPU_swap_u32(v) -# define CT_LE_W(v) CPU_swap_u16(v) -# define CT_LE_L(v) CPU_swap_u32(v) -#else -# define CF_LE_W(v) (v) -# define CF_LE_L(v) (v) -# define CT_LE_W(v) (v) -# define CT_LE_L(v) (v) -#endif - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#define FAT_HASH_SIZE 2 -#define FAT_HASH_MODULE FAT_HASH_SIZE - - -#define FAT_SECTOR512_SIZE 512 /* sector size (bytes) */ -#define FAT_SECTOR512_BITS 9 /* log2(SECTOR_SIZE) */ - -/* maximum + 1 number of clusters for FAT12 */ -#define FAT_FAT12_MAX_CLN 4085 - -/* maximum + 1 number of clusters for FAT16 */ -#define FAT_FAT16_MAX_CLN 65525 - -#define FAT_FAT12 0x01 -#define FAT_FAT16 0x02 -#define FAT_FAT32 0x04 - -#define FAT_UNDEFINED_VALUE 0xFFFFFFFF - -#define FAT_FAT12_EOC 0x0FFF -#define FAT_FAT16_EOC 0xFFFF -#define FAT_FAT32_EOC 0x0FFFFFFF - -#define FAT_FAT12_FREE 0x0000 -#define FAT_FAT16_FREE 0x0000 -#define FAT_FAT32_FREE 0x00000000 - -#define FAT_GENFAT_EOC 0xFFFFFFFF -#define FAT_GENFAT_FREE 0x00000000 - -#define FAT_FAT12_SHIFT 0x04 - -#define FAT_FAT12_MASK 0x00000FFF -#define FAT_FAT16_MASK 0x0000FFFF -#define FAT_FAT32_MASK 0x0FFFFFFF - -#define FAT_MAX_BPB_SIZE 90 - -/* size of useful information in FSInfo sector */ -#define FAT_USEFUL_INFO_SIZE 12 - -#define FAT_VAL8(x, ofs) (unsigned8)(*((unsigned8 *)(x) + (ofs))) - -#define FAT_VAL16(x, ofs) \ - (unsigned16)( (*((unsigned8 *)(x) + (ofs))) | \ - ((*((unsigned8 *)(x) + (ofs) + 1)) << 8) ) - -#define FAT_VAL32(x, ofs) \ - (unsigned32)( (*((unsigned8 *)(x) + (ofs))) | \ - ((*((unsigned8 *)(x) + (ofs) + 1)) << 8) | \ - ((*((unsigned8 *)(x) + (ofs) + 2)) << 16) | \ - ((*((unsigned8 *)(x) + (ofs) + 3)) << 24) ) - -/* macros to access boot sector fields */ -#define FAT_BR_BYTES_PER_SECTOR(x) FAT_VAL16(x, 11) -#define FAT_BR_SECTORS_PER_CLUSTER(x) FAT_VAL8(x, 13) -#define FAT_BR_RESERVED_SECTORS_NUM(x) FAT_VAL16(x, 14) -#define FAT_BR_FAT_NUM(x) FAT_VAL8(x, 16) -#define FAT_BR_FILES_PER_ROOT_DIR(x) FAT_VAL16(x, 17) -#define FAT_BR_TOTAL_SECTORS_NUM16(x) FAT_VAL16(x, 19) -#define FAT_BR_MEDIA(x) FAT_VAL8(x, 21) -#define FAT_BR_SECTORS_PER_FAT(x) FAT_VAL16(x, 22) -#define FAT_BR_TOTAL_SECTORS_NUM32(x) FAT_VAL32(x, 32) -#define FAT_BR_SECTORS_PER_FAT32(x) FAT_VAL32(x, 36) -#define FAT_BR_EXT_FLAGS(x) FAT_VAL16(x, 40) -#define FAT_BR_FAT32_ROOT_CLUSTER(x) FAT_VAL32(x, 44) -#define FAT_BR_FAT32_FS_INFO_SECTOR(x) FAT_VAL16(x, 48) -#define FAT_FSINFO_LEAD_SIGNATURE(x) FAT_VAL32(x, 0) -/* - * I read FSInfo sector from offset 484 to access the information, so offsets - * of these fields a relative - */ -#define FAT_FSINFO_FREE_CLUSTER_COUNT(x) FAT_VAL32(x, 4) -#define FAT_FSINFO_NEXT_FREE_CLUSTER(x) FAT_VAL32(x, 8) - -#define FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET 488 - -#define FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET 492 - -#define FAT_RSRVD_CLN 0x02 - -#define FAT_FSINFO_LEAD_SIGNATURE_VALUE 0x41615252 - -#define FAT_FSI_LEADSIG_SIZE 0x04 - -#define FAT_FSI_INFO 484 - -#define MS_BYTES_PER_CLUSTER_LIMIT 0x8000 /* 32K */ - -#define FAT_BR_EXT_FLAGS_MIRROR 0x0080 - -#define FAT_BR_EXT_FLAGS_FAT_NUM 0x000F - - -#define FAT_DIRENTRY_SIZE 32 - -#define FAT_DIRENTRIES_PER_SEC512 16 - -/* - * Volume descriptor - * Description of the volume the FAT filesystem is located on - generally - * the fields of the structure corresponde to Boot Sector and BPB Srtucture - * (see M$ White Paper) fields - */ -typedef struct fat_vol_s -{ - unsigned16 bps; /* bytes per sector */ - unsigned8 sec_log2; /* log2 of bps */ - unsigned8 sec_mul; /* log2 of 512bts sectors number per sector */ - unsigned8 spc; /* sectors per cluster */ - unsigned8 spc_log2; /* log2 of spc */ - unsigned16 bpc; /* bytes per cluster */ - unsigned8 bpc_log2; /* log2 of bytes per cluster */ - unsigned8 fats; /* number of FATs */ - unsigned8 type; /* FAT type */ - unsigned32 mask; - unsigned32 eoc_val; - unsigned16 fat_loc; /* FAT start */ - unsigned32 fat_length; /* sectors per FAT */ - unsigned32 rdir_loc; /* root directory start */ - unsigned16 rdir_entrs; /* files per root directory */ - unsigned32 rdir_secs; /* sectors per root directory */ - unsigned32 rdir_size; /* root directory size in bytes */ - unsigned32 tot_secs; /* total count of sectors */ - unsigned32 data_fsec; /* first data sector */ - unsigned32 data_cls; /* count of data clusters */ - unsigned32 rdir_cl; /* first cluster of the root directory */ - unsigned16 info_sec; /* FSInfo Sector Structure location */ - unsigned32 free_cls; /* last known free clusters count */ - unsigned32 next_cl; /* next free cluster number */ - unsigned8 mirror; /* mirroring enabla/disable */ - unsigned32 afat_loc; /* active FAT location */ - unsigned8 afat; /* the number of active FAT */ - dev_t dev; /* device ID */ - disk_device *dd; /* disk device (see libblock) */ - void *private_data; /* reserved */ -} fat_vol_t; - - -typedef struct fat_cache_s -{ - unsigned32 blk_num; - rtems_boolean modified; - unsigned8 state; - bdbuf_buffer *buf; -} fat_cache_t; - -/* - * This structure identifies the instance of the filesystem on the FAT - * ("fat-file") level. - */ -typedef struct fat_fs_info_s -{ - fat_vol_t vol; /* volume descriptor */ - Chain_Control *vhash; /* "vhash" of fat-file descriptors */ - Chain_Control *rhash; /* "rhash" of fat-file descriptors */ - char *uino; /* array of unique ino numbers */ - unsigned32 index; - unsigned32 uino_pool_size; /* size */ - unsigned32 uino_base; - fat_cache_t c; /* cache */ - unsigned8 *sec_buf; /* just placeholder for anything */ -} fat_fs_info_t; - -/* - * if the name we looking for is file we store not only first data cluster - * number, but and cluster number and offset for directory entry for this - * name - */ -typedef struct fat_auxiliary_s -{ - unsigned32 cln; - unsigned32 ofs; -} fat_auxiliary_t; - -#define FAT_FAT_OFFSET(fat_type, cln) \ - ((fat_type) & FAT_FAT12 ? ((cln) + ((cln) >> 1)) : \ - (fat_type) & FAT_FAT16 ? ((cln) << 1) : \ - ((cln) << 2)) - -#define FAT_CLUSTER_IS_ODD(n) ((n) & 0x0001) - -#define FAT12_SHIFT 0x4 /* half of a byte */ - -/* initial size of array of unique ino */ -#define FAT_UINO_POOL_INIT_SIZE 0x100 - -/* cache support */ -#define FAT_CACHE_EMPTY 0x0 -#define FAT_CACHE_ACTUAL 0x1 - -#define FAT_OP_TYPE_READ 0x1 -#define FAT_OP_TYPE_GET 0x2 - -static inline unsigned32 -fat_cluster_num_to_sector_num( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln - ) -{ - register fat_fs_info_t *fs_info = mt_entry->fs_info; - - if ( (cln == 0) && (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16)) ) - return fs_info->vol.rdir_loc; - - return (((cln - FAT_RSRVD_CLN) << fs_info->vol.spc_log2) + - fs_info->vol.data_fsec); -} - -static inline unsigned32 -fat_cluster_num_to_sector512_num( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln - ) -{ - fat_fs_info_t *fs_info = mt_entry->fs_info; - - if (cln == 1) - return 1; - - return (fat_cluster_num_to_sector_num(mt_entry, cln) << - fs_info->vol.sec_mul); -} - -static inline int -fat_buf_access(fat_fs_info_t *fs_info, unsigned32 blk, int op_type, - bdbuf_buffer **buf) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned8 i; - rtems_boolean sec_of_fat; - - - if (fs_info->c.state == FAT_CACHE_EMPTY) - { - if (op_type == FAT_OP_TYPE_READ) - sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf); - else - sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - fs_info->c.blk_num = blk; - fs_info->c.state = FAT_CACHE_ACTUAL; - } - - sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) && - (fs_info->c.blk_num < fs_info->vol.rdir_loc)); - - if (fs_info->c.blk_num != blk) - { - if (fs_info->c.modified) - { - if (sec_of_fat && !fs_info->vol.mirror) - memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, - fs_info->vol.bps); - - sc = rtems_bdbuf_release_modified(fs_info->c.buf); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - fs_info->c.modified = 0; - - if (sec_of_fat && !fs_info->vol.mirror) - { - bdbuf_buffer *b; - - for (i = 1; i < fs_info->vol.fats; i++) - { - sc = rtems_bdbuf_get(fs_info->vol.dev, - fs_info->c.blk_num + - fs_info->vol.fat_length * i, - &b); - if ( sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(ENOMEM); - memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps); - sc = rtems_bdbuf_release_modified(b); - if ( sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(ENOMEM); - } - } - } - else - { - sc = rtems_bdbuf_release(fs_info->c.buf); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - } - if (op_type == FAT_OP_TYPE_READ) - sc = rtems_bdbuf_read(fs_info->vol.dev, blk, &fs_info->c.buf); - else - sc = rtems_bdbuf_get(fs_info->vol.dev, blk, &fs_info->c.buf); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - fs_info->c.blk_num = blk; - } - *buf = fs_info->c.buf; - return RC_OK; -} - - -static inline int -fat_buf_release(fat_fs_info_t *fs_info) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - unsigned8 i; - rtems_boolean sec_of_fat; - - if (fs_info->c.state == FAT_CACHE_EMPTY) - return RC_OK; - - sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) && - (fs_info->c.blk_num < fs_info->vol.rdir_loc)); - - if (fs_info->c.modified) - { - if (sec_of_fat && !fs_info->vol.mirror) - memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps); - - sc = rtems_bdbuf_release_modified(fs_info->c.buf); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - fs_info->c.modified = 0; - - if (sec_of_fat && !fs_info->vol.mirror) - { - bdbuf_buffer *b; - - for (i = 1; i < fs_info->vol.fats; i++) - { - sc = rtems_bdbuf_get(fs_info->vol.dev, - fs_info->c.blk_num + - fs_info->vol.fat_length * i, - &b); - if ( sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(ENOMEM); - memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps); - sc = rtems_bdbuf_release_modified(b); - if ( sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(ENOMEM); - } - } - } - else - { - sc = rtems_bdbuf_release(fs_info->c.buf); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - } - fs_info->c.state = FAT_CACHE_EMPTY; - return RC_OK; -} - -static inline void -fat_buf_mark_modified(fat_fs_info_t *fs_info) -{ - fs_info->c.modified = TRUE; -} - - - -ssize_t -_fat_block_read(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 start, - unsigned32 offset, - unsigned32 count, - void *buff); - -ssize_t -_fat_block_write(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 start, - unsigned32 offset, - unsigned32 count, - const void *buff); - -ssize_t -fat_cluster_read(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - void *buff); - -ssize_t -fat_cluster_write(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - const void *buff); - -int -fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry); - -int -fat_init_clusters_chain(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 start_cln); - -unsigned32 -fat_cluster_num_to_sector_num(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln); - -int -fat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry); - - -unsigned32 -fat_get_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry); - -rtems_boolean -fat_ino_is_unique(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 ino); - -void -fat_free_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 ino); - -int -fat_fat32_update_fsinfo_sector( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 free_count, - unsigned32 next_free - ); - -#ifdef __cplusplus -} -#endif - -#endif /* __DOSFS_FAT_H__ */ diff --git a/c/src/exec/libfs/src/dosfs/fat_fat_operations.c b/c/src/exec/libfs/src/dosfs/fat_fat_operations.c deleted file mode 100644 index 49b2ab70d3..0000000000 --- a/c/src/exec/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; -} diff --git a/c/src/exec/libfs/src/dosfs/fat_fat_operations.h b/c/src/exec/libfs/src/dosfs/fat_fat_operations.h deleted file mode 100644 index 59b6a84018..0000000000 --- a/c/src/exec/libfs/src/dosfs/fat_fat_operations.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * fat_fat_operations.h - * - * Constants/data structures/prototypes for operations on Files Allocation - * Table - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ -#ifndef __DOSFS_FAT_FAT_OPERATIONS_H__ -#define __DOSFS_FAT_FAT_OPERATIONS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <rtems.h> -#include <rtems/libio_.h> - -#include <rtems/bdbuf.h> -#include "fat.h" - -int -fat_get_fat_cluster(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - unsigned32 *ret_val); - -int -fat_set_fat_cluster(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - unsigned32 in_val); - -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 -fat_free_fat_clusters_chain( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 chain -); - -#ifdef __cplusplus -} -#endif - -#endif /* __DOSFS_FAT_FAT_OPERATIONS_H__ */ diff --git a/c/src/exec/libfs/src/dosfs/fat_file.c b/c/src/exec/libfs/src/dosfs/fat_file.c deleted file mode 100644 index 8046f47720..0000000000 --- a/c/src/exec/libfs/src/dosfs/fat_file.c +++ /dev/null @@ -1,978 +0,0 @@ -/* - * fat_file.c - * - * General operations on "fat-file" - * - * 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 <stdarg.h> -#include <errno.h> -#include <stdlib.h> -#include <assert.h> -#include <time.h> - -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -static inline void -_hash_insert(Chain_Control *hash, unsigned32 key1, unsigned32 key2, - fat_file_fd_t *el); - -static inline void -_hash_delete(Chain_Control *hash, unsigned32 key1, unsigned32 key2, - fat_file_fd_t *el); - -static inline int -_hash_search( - rtems_filesystem_mount_table_entry_t *mt_entry, - Chain_Control *hash, - unsigned32 key1, - unsigned32 key2, - void **ret -); - -static int -fat_file_lseek( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 file_cln, - unsigned32 *disk_cln -); - -/* fat_file_open -- - * Open fat-file. Two hash tables are accessed by key - * constructed from cluster num and offset of the node (i.e. - * files/directories are distinguished by location on the disk). - * First, hash table("vhash") consists of fat-file descriptors corresponded - * to "valid" files is accessed. Search is made by 2 fields equal to key - * constructed. If descriptor is found in the "vhash" - return it. - * Otherwise search is made in hash table("rhash") consits of fat-file - * descriptors corresponded to "removed-but-still-open" files with the - * same keys. - * If search failed, new fat-file descriptor is added to "vhash" - * with both key fields equal to constructed key. Otherwise new fat-file - * descriptor is added to "vhash" with first key field equal to key - * constructed and the second equal to an unique (unique among all values - * of second key fields) value. - * - * PARAMETERS: - * mt_entry - mount table entry - * cln - cluster num of the node - * ofs - offset of the node - * fat_fd - placeholder for returned fat-file descriptor - * - * RETURNS: - * RC_OK and pointer to opened descriptor on success, or -1 if error - * occured (errno set appropriately) - */ -int -fat_file_open( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - unsigned32 ofs, - fat_file_fd_t **fat_fd - ) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - fat_file_fd_t *lfat_fd = NULL; - unsigned32 key = 0; - - /* construct key */ - key = fat_construct_key(mt_entry, cln, ofs); - - /* access "valid" hash table */ - rc = _hash_search(mt_entry, fs_info->vhash, key, 0, (void **)&lfat_fd); - if ( rc == RC_OK ) - { - /* return pointer to fat_file_descriptor allocated before */ - (*fat_fd) = lfat_fd; - lfat_fd->links_num++; - return rc; - } - - /* access "removed-but-still-open" hash table */ - rc = _hash_search(mt_entry, fs_info->rhash, key, key, (void **)&lfat_fd); - - lfat_fd = (*fat_fd) = (fat_file_fd_t*)malloc(sizeof(fat_file_fd_t)); - if ( lfat_fd == NULL ) - set_errno_and_return_minus_one( ENOMEM ); - - lfat_fd->links_num = 1; - lfat_fd->flags &= ~FAT_FILE_REMOVED; - lfat_fd->map.last_cln = FAT_UNDEFINED_VALUE; - - if ( rc != RC_OK ) - lfat_fd->ino = key; - else - { - lfat_fd->ino = fat_get_unique_ino(mt_entry); - - if ( lfat_fd->ino == 0 ) - { - free((*fat_fd)); - /* - * XXX: kernel resource is unsufficient, but not the memory, - * but there is no suitable errno :( - */ - set_errno_and_return_minus_one( ENOMEM ); - } - } - _hash_insert(fs_info->vhash, key, lfat_fd->ino, lfat_fd); - - - /* - * other fields of fat-file descriptor will be initialized on upper - * level - */ - - return RC_OK; -} - - -/* fat_file_reopen -- - * Increment by 1 number of links - * - * PARAMETERS: - * fat_fd - fat-file descriptor - * - * RETURNS: - * RC_OK - */ -int -fat_file_reopen(fat_file_fd_t *fat_fd) -{ - fat_fd->links_num++; - return RC_OK; -} - -/* 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; - unsigned32 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->info_cln, fat_fd->info_ofs); - - 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); - } - } - return rc; -} - -/* fat_file_read -- - * Read 'count' bytes from 'start' position from fat-file. This - * interface hides the architecture of fat-file, represents it as - * linear file - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * start - offset in fat-file (in bytes) to read from - * count - count of bytes to read - * buf - buffer provided by user - * - * RETURNS: - * the number of bytes read on success, or -1 if error occured (errno - * set appropriately) - */ -ssize_t -fat_file_read( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 start, - unsigned32 count, - char *buf - ) -{ - int rc = RC_OK; - ssize_t ret = 0; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cmpltd = 0; - unsigned32 cur_cln = 0; - unsigned32 cl_start = 0; - unsigned32 save_cln = 0; - unsigned32 ofs = 0; - unsigned32 save_ofs; - unsigned32 sec = 0; - unsigned32 byte = 0; - unsigned32 c = 0; - - /* it couldn't be removed - otherwise cache update will be broken */ - if (count == 0) - return cmpltd; - - /* - * >= because start is offset and computed from 0 and file_size - * computed from 1 - */ - if ( start >= fat_fd->fat_file_size ) - return FAT_EOF; - - if ((count > fat_fd->fat_file_size) || - (start > fat_fd->fat_file_size - count)) - count = fat_fd->fat_file_size - start; - - if ((FAT_FD_OF_ROOT_DIR(fat_fd)) && - (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16))) - { - sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->cln); - sec += (start >> fs_info->vol.sec_log2); - byte = start & (fs_info->vol.bps - 1); - - ret = _fat_block_read(mt_entry, sec, byte, count, buf); - if ( ret < 0 ) - return -1; - - return ret; - } - - cl_start = start >> fs_info->vol.bpc_log2; - save_ofs = ofs = start & (fs_info->vol.bpc - 1); - - rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln); - if (rc != RC_OK) - return rc; - - while (count > 0) - { - c = MIN(count, (fs_info->vol.bpc - ofs)); - - sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln); - sec += (ofs >> fs_info->vol.sec_log2); - byte = ofs & (fs_info->vol.bps - 1); - - ret = _fat_block_read(mt_entry, sec, byte, c, buf + cmpltd); - if ( ret < 0 ) - return -1; - - count -= c; - cmpltd += c; - save_cln = cur_cln; - rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln); - if ( rc != RC_OK ) - return rc; - - ofs = 0; - } - - /* update cache */ - /* XXX: check this - I'm not sure :( */ - fat_fd->map.file_cln = cl_start + - ((save_ofs + cmpltd - 1) >> fs_info->vol.bpc_log2); - fat_fd->map.disk_cln = save_cln; - - return cmpltd; -} - -/* fat_file_write -- - * Write 'count' bytes of data from user supplied buffer to fat-file - * starting at offset 'start'. This interface hides the architecture - * of fat-file, represents it as linear file - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * start - offset(in bytes) to write from - * count - count - * buf - buffer provided by user - * - * RETURNS: - * number of bytes actually written to the file on success, or -1 if - * error occured (errno set appropriately) - */ -ssize_t -fat_file_write( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 start, - unsigned32 count, - const char *buf - ) -{ - int rc = 0; - ssize_t ret = 0; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cmpltd = 0; - unsigned32 cur_cln = 0; - unsigned32 save_cln = 0; /* FIXME: This might be incorrect, cf. below */ - unsigned32 cl_start = 0; - unsigned32 ofs = 0; - unsigned32 save_ofs; - unsigned32 sec = 0; - unsigned32 byte = 0; - unsigned32 c = 0; - - if ( count == 0 ) - return cmpltd; - - if ( start > fat_fd->fat_file_size ) - set_errno_and_return_minus_one( EIO ); - - if ((count > fat_fd->size_limit) || - (start > fat_fd->size_limit - count)) - set_errno_and_return_minus_one( EIO ); - - rc = fat_file_extend(mt_entry, fat_fd, start + count, &c); - if (rc != RC_OK) - return rc; - - /* - * check whether there was enough room on device to locate - * file of 'start + count' bytes - */ - if (c != (start + count)) - count = c - start; - - if ((FAT_FD_OF_ROOT_DIR(fat_fd)) && - (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16))) - { - sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->cln); - sec += (start >> fs_info->vol.sec_log2); - byte = start & (fs_info->vol.bps - 1); - - ret = _fat_block_write(mt_entry, sec, byte, count, buf); - if ( ret < 0 ) - return -1; - - return ret; - } - - cl_start = start >> fs_info->vol.bpc_log2; - save_ofs = ofs = start & (fs_info->vol.bpc - 1); - - rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln); - if (rc != RC_OK) - return rc; - - while (count > 0) - { - c = MIN(count, (fs_info->vol.bpc - ofs)); - - sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln); - sec += (ofs >> fs_info->vol.sec_log2); - byte = ofs & (fs_info->vol.bps - 1); - - ret = _fat_block_write(mt_entry, sec, byte, c, buf + cmpltd); - if ( ret < 0 ) - return -1; - - count -= c; - cmpltd += c; - save_cln = cur_cln; - rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln); - if ( rc != RC_OK ) - return rc; - - ofs = 0; - } - - /* update cache */ - /* XXX: check this - I'm not sure :( */ - fat_fd->map.file_cln = cl_start + - ((save_ofs + cmpltd - 1) >> fs_info->vol.bpc_log2); - fat_fd->map.disk_cln = save_cln; - - return cmpltd; -} - -/* fat_file_extend -- - * Extend fat-file. If new length less than current fat-file size - - * do nothing. Otherwise calculate necessary count of clusters to add, - * allocate it and add new clusters chain to the end of - * existing clusters chain. - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * new_length - new length - * a_length - placeholder for result - actual new length of file - * - * RETURNS: - * RC_OK and new length of file on success, or -1 if error occured (errno - * set appropriately) - */ -int -fat_file_extend( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 new_length, - unsigned32 *a_length - ) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 chain = 0; - unsigned32 bytes2add = 0; - unsigned32 cls2add = 0; - unsigned32 old_last_cl; - unsigned32 last_cl = 0; - unsigned32 bytes_remain = 0; - unsigned32 cls_added; - - *a_length = new_length; - - if (new_length <= fat_fd->fat_file_size) - return RC_OK; - - if ((FAT_FD_OF_ROOT_DIR(fat_fd)) && - (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16))) - set_errno_and_return_minus_one( ENOSPC ); - - bytes_remain = (fs_info->vol.bpc - - (fat_fd->fat_file_size & (fs_info->vol.bpc - 1))) & - (fs_info->vol.bpc - 1); - - bytes2add = new_length - fat_fd->fat_file_size; - - if (bytes2add > bytes_remain) - bytes2add -= bytes_remain; - else - bytes2add = 0; - - /* - * if in last cluster allocated for the file there is enough room to - * handle extention (hence we don't need to add even one cluster to the - * file ) - return - */ - if (bytes2add == 0) - return RC_OK; - - cls2add = ((bytes2add - 1) >> fs_info->vol.bpc_log2) + 1; - - rc = fat_scan_fat_for_free_clusters(mt_entry, &chain, cls2add, - &cls_added, &last_cl); - - /* this means that low level I/O error occured */ - if (rc != RC_OK) - return rc; - - /* this means that no space left on device */ - if ((cls_added == 0) && (bytes_remain == 0)) - set_errno_and_return_minus_one(ENOSPC); - - /* check wether we satisfied request for 'cls2add' clusters */ - if (cls2add != cls_added) - *a_length = new_length - - ((cls2add - cls_added - 1) << fs_info->vol.bpc_log2) - - (bytes2add & (fs_info->vol.bpc - 1)); - - /* add new chain to the end of existed */ - if ( fat_fd->fat_file_size == 0 ) - { - fat_fd->map.disk_cln = fat_fd->cln = chain; - fat_fd->map.file_cln = 0; - } - else - { - if (fat_fd->map.last_cln != FAT_UNDEFINED_VALUE) - { - old_last_cl = fat_fd->map.last_cln; - } - else - { - rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, - (fat_fd->fat_file_size - 1), &old_last_cl); - if ( rc != RC_OK ) - { - fat_free_fat_clusters_chain(mt_entry, chain); - return rc; - } - } - - rc = fat_set_fat_cluster(mt_entry, old_last_cl, chain); - if ( rc != RC_OK ) - { - fat_free_fat_clusters_chain(mt_entry, chain); - return rc; - } - fat_buf_release(fs_info); - } - - /* update number of the last cluster of the file if it changed */ - if (cls_added != 0) - { - fat_fd->map.last_cln = last_cl; - if (fat_fd->fat_file_type == FAT_DIRECTORY) - { - rc = fat_init_clusters_chain(mt_entry, chain); - if ( rc != RC_OK ) - { - fat_free_fat_clusters_chain(mt_entry, chain); - return rc; - } - } - } - - return RC_OK; -} - -/* fat_file_truncate -- - * Truncate fat-file. If new length greater than current fat-file size - - * do nothing. Otherwise find first cluster to free and free all clusters - * in the chain starting from this cluster. - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * new_length - new length - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -fat_file_truncate( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 new_length - ) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cur_cln = 0; - unsigned32 cl_start = 0; - unsigned32 new_last_cln = FAT_UNDEFINED_VALUE; - - - if ( new_length >= fat_fd->fat_file_size ) - return rc; - - assert(fat_fd->fat_file_size); - - cl_start = (new_length + fs_info->vol.bpc - 1) >> fs_info->vol.bpc_log2; - - if ((cl_start << fs_info->vol.bpc_log2) >= fat_fd->fat_file_size) - return RC_OK; - - if (cl_start != 0) - { - rc = fat_file_lseek(mt_entry, fat_fd, cl_start - 1, &new_last_cln); - if (rc != RC_OK) - return rc; - - } - - rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln); - if (rc != RC_OK) - return rc; - - rc = fat_free_fat_clusters_chain(mt_entry, cur_cln); - if (rc != RC_OK) - return rc; - - if (cl_start != 0) - { - rc = fat_set_fat_cluster(mt_entry, new_last_cln, FAT_GENFAT_EOC); - if ( rc != RC_OK ) - return rc; - fat_fd->map.file_cln = cl_start - 1; - fat_fd->map.disk_cln = new_last_cln; - fat_fd->map.last_cln = new_last_cln; - } - return RC_OK; -} - -/* fat_file_ioctl -- - * F_CLU_NUM: - * make mapping between serial number of the cluster in fat-file and - * its real number on the volume - * - * PARAMETERS: - * fat_fd - fat-file descriptor - * mt_entry - mount table entry - * cmd - command - * ... - * - * RETURNS: - * RC_OK on success, or -1 if error occured and errno set appropriately - */ -int -fat_file_ioctl( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - int cmd, - ...) -{ - int rc = RC_OK; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cur_cln = 0; - unsigned32 cl_start = 0; - unsigned32 pos = 0; - unsigned32 *ret; - va_list ap; - - va_start(ap, cmd); - - switch (cmd) - { - case F_CLU_NUM: - pos = va_arg(ap, int); - ret = va_arg(ap, int *); - - /* sanity check */ - if ( pos >= fat_fd->fat_file_size ) - set_errno_and_return_minus_one( EIO ); - - if ((FAT_FD_OF_ROOT_DIR(fat_fd)) && - (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16))) - { - /* cluster 0 (zero) reserved for root dir */ - *ret = 0; - return RC_OK; - } - - cl_start = pos >> fs_info->vol.bpc_log2; - - rc = fat_file_lseek(mt_entry, fat_fd, cl_start, &cur_cln); - if ( rc != RC_OK ) - return rc; - - *ret = cur_cln; - break; - - default: - errno = EINVAL; - rc = -1; - break; - } - return rc; -} - -/* fat_file_mark_removed -- - * Remove the fat-file descriptor from "valid" hash table, insert it - * into "removed-but-still-open" hash table and set up "removed" bit. - * - * PARAMETERS: - * fat_fd - fat-file descriptor - * mt_entry - mount table entry - * - * RETURNS: - * None - */ -void -fat_file_mark_removed( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd - ) -{ - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 key = 0; - - key = fat_construct_key(mt_entry, fat_fd->info_cln, fat_fd->info_ofs); - - _hash_delete(fs_info->vhash, key, fat_fd->ino, fat_fd); - - _hash_insert(fs_info->rhash, key, fat_fd->ino, fat_fd); - - fat_fd->flags |= FAT_FILE_REMOVED; -} - -/* fat_file_datasync -- - * Synchronize fat-file - flush all buffered data to the media. - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * - * RETURNS: - * RC_OK on success, or -1 if error occured and errno set appropriately - */ -int -fat_file_datasync( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd - ) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - fat_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 cur_cln = fat_fd->cln; - bdbuf_buffer *block = NULL; - unsigned32 sec = 0; - unsigned32 i = 0; - - if (fat_fd->fat_file_size == 0) - return RC_OK; - - /* - * we can use only one bdbuf :( and we also know that cache is useless - * for sync operation, so don't use it - */ - rc = fat_buf_release(fs_info); - if (rc != RC_OK) - return rc; - - /* for each cluster of the file ... */ - while ((cur_cln & fs_info->vol.mask) != fs_info->vol.eoc_val) - { - sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln); - /* for each sector in cluster ... */ - for ( i = 0; i < fs_info->vol.spc; i++ ) - { - /* ... sync it */ - sc = rtems_bdbuf_read(fs_info->vol.dev, (sec + i), &block); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one( EIO ); - - sc = rtems_bdbuf_sync(block); - if ( sc != RTEMS_SUCCESSFUL ) - set_errno_and_return_minus_one( EIO ); - } - - rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln); - if ( rc != RC_OK ) - return rc; - } - return rc; -} - -/* fat_file_size -- - * Calculate fat-file size - fat-file is nothing that clusters chain, so - * go through all clusters in the chain and count it. Only - * special case is root directory for FAT12/16 volumes. - * This function is used only for directories which are fat-files with - * non-zero length, hence 'fat_fd->cln' always contains valid data. - * Calculated size is stored in 'fat_file_size' field of fat-file - * descriptor. - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -fat_file_size( - 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; - unsigned32 cur_cln = fat_fd->cln; - unsigned32 save_cln = 0; - - /* Have we requested root dir size for FAT12/16? */ - if ((FAT_FD_OF_ROOT_DIR(fat_fd)) && - (fs_info->vol.type & (FAT_FAT12 | FAT_FAT16))) - { - fat_fd->fat_file_size = fs_info->vol.rdir_size; - return rc; - } - - fat_fd->fat_file_size = 0; - - while ((cur_cln & fs_info->vol.mask) != fs_info->vol.eoc_val) - { - save_cln = cur_cln; - rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln); - if ( rc != RC_OK ) - return rc; - - fat_fd->fat_file_size += fs_info->vol.bpc; - } - fat_fd->map.last_cln = save_cln; - return rc; -} - -/* hash support routines */ - -/* _hash_insert -- - * Insert elemnt into hash based on key 'key1' - * - * PARAMETERS: - * hash - hash element will be inserted into - * key1 - key on which insertion is based on - * key2 - not used during insertion - * el - element to insert - * - * RETURNS: - * None - */ -static inline void -_hash_insert(Chain_Control *hash, unsigned32 key1, unsigned32 key2, - fat_file_fd_t *el) -{ - _Chain_Append((hash) + ((key1) % FAT_HASH_MODULE), &(el)->link); -} - - -/* _hash_delete -- - * Remove element from hash - * - * PARAMETERS: - * hash - hash element will be removed from - * key1 - not used - * key2 - not used - * el - element to delete - * - * RETURNS: - * None - */ -static inline void -_hash_delete(Chain_Control *hash, unsigned32 key1, unsigned32 key2, - fat_file_fd_t *el) -{ - _Chain_Extract(&(el)->link); -} - -/* _hash_search -- - * Search element in hash. If both keys match pointer to found element - * is returned - * - * PARAMETERS: - * mt_entry - mount table entry - * hash - hash element will be removed from - * key1 - search key - * key2 - search key - * ret - placeholder for result - * - * RETURNS: - * 0 and pointer to found element on success, -1 otherwise - */ -static inline int -_hash_search( - rtems_filesystem_mount_table_entry_t *mt_entry, - Chain_Control *hash, - unsigned32 key1, - unsigned32 key2, - void **ret - ) -{ - unsigned32 mod = (key1) % FAT_HASH_MODULE; - Chain_Node *the_node = ((Chain_Control *)((hash) + mod))->first; - - for ( ; !_Chain_Is_tail((hash) + mod, the_node) ; ) - { - fat_file_fd_t *ffd = (fat_file_fd_t *)the_node; - unsigned32 ck = - fat_construct_key(mt_entry, ffd->info_cln, ffd->info_ofs); - - if ( (key1) == ck) - { - if ( ((key2) == 0) || ((key2) == ffd->ino) ) - { - *ret = (void *)the_node; - return 0; - } - } - the_node = the_node->next; - } - return -1; -} - -static int -fat_file_lseek( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 file_cln, - unsigned32 *disk_cln - ) -{ - int rc = RC_OK; -/* - assert(fat_fd->fat_file_size); - */ - if (file_cln == fat_fd->map.file_cln) - *disk_cln = fat_fd->map.disk_cln; - else - { - unsigned32 cur_cln; - unsigned32 count; - unsigned32 i; - - if (file_cln > fat_fd->map.file_cln) - { - cur_cln = fat_fd->map.disk_cln; - count = file_cln - fat_fd->map.file_cln; - } - else - { - cur_cln = fat_fd->cln; - count = file_cln; - } - - /* skip over the clusters */ - for (i = 0; i < count; i++) - { - rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln); - if ( rc != RC_OK ) - return rc; - } - - /* update cache */ - fat_fd->map.file_cln = file_cln; - fat_fd->map.disk_cln = cur_cln; - - *disk_cln = cur_cln; - } - return RC_OK; -} diff --git a/c/src/exec/libfs/src/dosfs/fat_file.h b/c/src/exec/libfs/src/dosfs/fat_file.h deleted file mode 100644 index 02baf3f1ef..0000000000 --- a/c/src/exec/libfs/src/dosfs/fat_file.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * fat_file.h - * - * Constants/data structures/prototypes for operations on "fat-file" - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ -#ifndef __DOSFS_FAT_FILE_H__ -#define __DOSFS_FAT_FILE_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <rtems.h> -#include <rtems/libio_.h> - -#include <time.h> - -/* "fat-file" representation - * - * the idea is: fat-file is nothing but a cluster chain, any open fat-file is - * represented in system by fat-file descriptor and has well-known - * file interface: - * - * fat_file_open() - * fat_file_close() - * fat_file_read() - * fat_file_write() - * - * Such interface hides the architecture of fat-file and represents it like - * linear file - */ - -typedef rtems_filesystem_node_types_t fat_file_type_t; - -#define FAT_DIRECTORY RTEMS_FILESYSTEM_DIRECTORY -#define FAT_FILE RTEMS_FILESYSTEM_MEMORY_FILE - -typedef struct fat_file_map_s -{ - unsigned32 file_cln; - unsigned32 disk_cln; - unsigned32 last_cln; -} fat_file_map_t; -/* - * descriptor of a fat-file - * - * To each particular clusters chain - */ -typedef struct fat_file_fd_s -{ - Chain_Node link; /* - * fat-file descriptors organized into hash; - * collision lists are handled via link - * field - */ - unsigned32 links_num; /* - * the number of fat_file_open call on - * this fat-file - */ - unsigned32 ino; /* inode, file serial number :)))) */ - fat_file_type_t fat_file_type; - unsigned32 size_limit; - unsigned32 fat_file_size; /* length */ - unsigned32 info_cln; - unsigned32 cln; - unsigned16 info_ofs; - unsigned char first_char; - unsigned8 flags; - fat_file_map_t map; - time_t mtime; - -} fat_file_fd_t; - - -#define FAT_FILE_REMOVED 0x01 - -#define FAT_FILE_IS_REMOVED(p)\ - (((p)->flags & FAT_FILE_REMOVED) ? 1 : 0) - -/* ioctl macros */ -#define F_CLU_NUM 0x01 - -/* - * Each file and directory on a MSDOS volume is unique identified by it - * location, i.e. location of it 32 Bytes Directory Entry Structure. We can - * distinguish them by cluster number it locates on and offset inside this - * cluster. But root directory on any volumes (FAT12/16/32) has no 32 Bytes - * Directory Entry Structure corresponded to it. So we assume 32 Bytes - * Directory Entry Structure of root directory locates at cluster 1 (invalid - * cluaster number) and offset 0 - */ -#define FAT_ROOTDIR_CLUSTER_NUM 0x01 - -#define FAT_FD_OF_ROOT_DIR(fat_fd) \ - ((fat_fd->info_cln == FAT_ROOTDIR_CLUSTER_NUM ) && \ - (fat_fd->info_ofs == 0)) - -#define FAT_EOF 0x00 - -/* fat_construct_key -- - * Construct key for hash access: convert (cluster num, offset) to - * (sector512 num, new offset) and than construct key as - * key = (sector512 num) << 4 | (new offset) - * - * PARAMETERS: - * cl - cluster number - * ofs - offset inside cluster 'cl' - * mt_entry - mount table entry - * - * RETURNS: - * constructed key - */ -static inline unsigned32 -fat_construct_key( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cl, - unsigned32 ofs) -{ - return ( ((fat_cluster_num_to_sector512_num(mt_entry, cl) + - (ofs >> FAT_SECTOR512_BITS)) << 4) + - ((ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) ); -} - -/* Prototypes for "fat-file" operations */ -int -fat_file_open(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - unsigned32 ofs, - fat_file_fd_t **fat_fd); - -int -fat_file_reopen(fat_file_fd_t *fat_fd); - -int -fat_file_close(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd); - -ssize_t -fat_file_read(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 start, - unsigned32 count, - char *buf); - -ssize_t -fat_file_write(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 start, - unsigned32 count, - const char *buf); - -int -fat_file_extend(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 new_length, - unsigned32 *a_length); - -int -fat_file_truncate(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 new_length); - -int -fat_file_datasync(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd); - - -int -fat_file_ioctl(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - int cmd, - ...); - -int -fat_file_size(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd); - -void -fat_file_mark_removed(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd); - -#ifdef __cplusplus -} -#endif - -#endif /* __DOSFS_FAT_FILE_H__ */ diff --git a/c/src/exec/libfs/src/dosfs/msdos.h b/c/src/exec/libfs/src/dosfs/msdos.h deleted file mode 100644 index a9216b1ed3..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * msdos.h - * - * The MSDOS filesystem constants/data structures/prototypes - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ -#ifndef __DOSFS_MSDOS_H__ -#define __DOSFS_MSDOS_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <rtems.h> -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_file.h" - -#ifndef RC_OK -#define RC_OK 0x00000000 -#endif - -#define MSDOS_NAME_NOT_FOUND_ERR 0xDD000001 - -/* - * This structure identifies the instance of the filesystem on the MSDOS - * level. - */ -typedef struct msdos_fs_info_s -{ - fat_fs_info_t fat; /* - * volume - * description - */ - rtems_filesystem_file_handlers_r *directory_handlers; /* - * a set of routines - * that handles the - * nodes of directory - * type - */ - rtems_filesystem_file_handlers_r *file_handlers; /* - * a set of routines - * that handles the - * nodes of file - * type - */ - rtems_id vol_sema; /* - * semaphore - * associated with - * the volume - */ - unsigned8 *cl_buf; /* - * just placeholder - * for anything - */ -} msdos_fs_info_t; - -/* a set of routines that handle the nodes which are directories */ -extern rtems_filesystem_file_handlers_r msdos_dir_handlers; - -/* a set of routines that handle the nodes which are files */ -extern rtems_filesystem_file_handlers_r msdos_file_handlers; - -/* Volume semaphore timeout value */ -#define MSDOS_VOLUME_SEMAPHORE_TIMEOUT 100 - -/* Node types */ -#define MSDOS_DIRECTORY RTEMS_FILESYSTEM_DIRECTORY -#define MSDOS_REGULAR_FILE RTEMS_FILESYSTEM_MEMORY_FILE - -typedef rtems_filesystem_node_types_t msdos_node_type_t; - -/* - * Macros for fetching fields from 32 bytes long FAT Directory Entry - * Structure (see M$ White Paper) - */ -#define MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE 32 /* 32 bytes */ - -#define MSDOS_DIR_NAME(x) (unsigned8 *)((x) + 0) -#define MSDOS_DIR_ATTR(x) (unsigned8 *)((x) + 11) -#define MSDOS_DIR_NT_RES(x) (unsigned8 *)((x) + 12) -#define MSDOS_DIR_CRT_TIME_TENTH(x) (unsigned8 *)((x) + 13) -#define MSDOS_DIR_CRT_TIME(x) (unsigned16 *)((x) + 14) -#define MSDOS_DIR_CRT_DATE(x) (unsigned16 *)((x) + 16) -#define MSDOS_DIR_LAST_ACCESS_DATE(x) (unsigned16 *)((x) + 18) -#define MSDOS_DIR_FIRST_CLUSTER_HI(x) (unsigned16 *)((x) + 20) -#define MSDOS_DIR_WRITE_TIME(x) (unsigned16 *)((x) + 22) -#define MSDOS_DIR_WRITE_DATE(x) (unsigned16 *)((x) + 24) -#define MSDOS_DIR_FIRST_CLUSTER_LOW(x) (unsigned16 *)((x) + 26) -#define MSDOS_DIR_FILE_SIZE(x) (unsigned32 *)((x) + 28) - -#define MSDOS_EXTRACT_CLUSTER_NUM(p) \ - (unsigned32)( (CF_LE_W(*MSDOS_DIR_FIRST_CLUSTER_LOW(p))) | \ - ((CF_LE_W((*MSDOS_DIR_FIRST_CLUSTER_HI(p))))<<16) ) - -/* - * Fields offset in 32 bytes long FAT Directory Entry - * Structure (see M$ White Paper) - */ -#define MSDOS_FILE_SIZE_OFFSET 28 -#define MSDOS_FILE_NAME_OFFSET 0 -#define MSDOS_FIRST_CLUSTER_HI_OFFSET 20 -#define MSDOS_FIRST_CLUSTER_LOW_OFFSET 26 -#define MSDOS_FILE_WDATE_OFFSET 24 -#define MSDOS_FILE_WTIME_OFFSET 22 - -/* - * Possible values of DIR_Attr field of 32 bytes long FAT Directory Entry - * Structure (see M$ White Paper) - */ -#define MSDOS_ATTR_READ_ONLY 0x01 -#define MSDOS_ATTR_HIDDEN 0x02 -#define MSDOS_ATTR_SYSTEM 0x04 -#define MSDOS_ATTR_VOLUME_ID 0x08 -#define MSDOS_ATTR_DIRECTORY 0x10 -#define MSDOS_ATTR_ARCHIVE 0x20 - -/* - * Possible values of DIR_Name[0] field of 32 bytes long FAT Directory Entry - * Structure (see M$ White Paper) - */ -#define MSDOS_THIS_DIR_ENTRY_EMPTY 0xE5 -#define MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY 0x00 - - -/* - * Macros for names parsing and formatting - */ -#define msdos_is_valid_name_char(_ch) (1) -#define msdos_is_separator(_ch) rtems_filesystem_is_separator(_ch) - -#define MSDOS_SHORT_NAME_LEN 11 /* 11 characters */ -#define MSDOS_NAME_MAX MSDOS_SHORT_NAME_LEN -#define MSDOS_NAME_MAX_WITH_DOT (MSDOS_NAME_MAX + 1) - -#define MSDOS_DOT_NAME ". " /* ".", padded to MSDOS_NAME chars */ -#define MSDOS_DOTDOT_NAME ".. " /* "..", padded to MSDOS_NAME chars */ - -typedef enum msdos_token_types_e -{ - MSDOS_NO_MORE_PATH, - MSDOS_CURRENT_DIR, - MSDOS_UP_DIR, - MSDOS_NAME, - MSDOS_INVALID_TOKEN -} msdos_token_types_t; - -/* Others macros */ -#define MSDOS_RES_NT_VALUE 0x00 -#define MSDOS_INIT_DIR_SIZE 0x00 - -/* "dot" entry offset in a directory */ -#define MSDOS_DOT_DIR_ENTRY_OFFSET 0x00 /* first entry in directory */ - -/* "dotdot" entry offset in a directory */ -#define MSDOS_DOTDOT_DIR_ENTRY_OFFSET 0x20 /* second entry in directory */ - -/* 'p' should be char* */ -#define DOT_NODE_P(p) ((char *)(p)) -#define DOTDOT_NODE_P(p) ((char *)((p) + MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)) - -/* Size limits for files and directories (see M$ White Paper) */ -#define MSDOS_MAX_DIR_LENGHT 0x200000 /* 2,097,152 bytes */ -#define MSDOS_MAX_FILE_SIZE 0xFFFFFFFF /* 4 Gb */ - -/* - * The number of 32 bytes long FAT Directory Entry - * Structures per 512 bytes sector - */ -#define MSDOS_DPS512_NUM 16 - -/* Prototypes */ -int -msdos_initialize(rtems_filesystem_mount_table_entry_t *temp_mt_entry); - -int -msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry); - -int -msdos_eval_path(const char *pathname, /* IN */ - int flags, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */); - -int -msdos_eval4make(const char *path, /* IN */ - rtems_filesystem_location_info_t *pathloc, /* IN/OUT */ - const char **name /* OUT */); - -int -msdos_unlink(rtems_filesystem_location_info_t *pathloc /* IN */); - -int -msdos_free_node_info(rtems_filesystem_location_info_t *pathloc /* IN */); - -rtems_filesystem_node_types_t -msdos_node_type(rtems_filesystem_location_info_t *pathloc); - -int -msdos_mknod(const char *path, /* IN */ - mode_t mode, /* IN */ - dev_t dev, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */); - -int -msdos_utime(rtems_filesystem_location_info_t *pathloc, /* IN */ - time_t actime, /* IN */ - time_t modtime /* IN */); - -int -msdos_initialize_support( - rtems_filesystem_mount_table_entry_t *temp_mt_entry, - rtems_filesystem_operations_table *op_table, - rtems_filesystem_file_handlers_r *file_handlers, - rtems_filesystem_file_handlers_r *directory_handlers -); - -int -msdos_file_open( - rtems_libio_t *iop, /* IN */ - const char *pathname, /* IN */ - unsigned32 flag, /* IN */ - unsigned32 mode /* IN */ -); - -int -msdos_file_close(rtems_libio_t *iop /* IN */); - -ssize_t -msdos_file_read( - rtems_libio_t *iop, /* IN */ - void *buffer, /* IN */ - unsigned32 count /* IN */ -); - -ssize_t -msdos_file_write( - rtems_libio_t *iop, /* IN */ - const void *buffer, /* IN */ - unsigned32 count /* IN */ -); - -int -msdos_file_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - -int -msdos_file_stat(rtems_filesystem_location_info_t *loc, /* IN */ - struct stat *buf /* OUT */); - -int -msdos_file_ftruncate( - rtems_libio_t *iop, /* IN */ - off_t length /* IN */ -); - -int -msdos_file_sync(rtems_libio_t *iop); - -int -msdos_file_datasync(rtems_libio_t *iop); - -int -msdos_file_ioctl( - rtems_libio_t *iop, /* IN */ - unsigned32 command, /* IN */ - void *buffer /* IN */ -); - -int -msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */); - -int -msdos_dir_open( - rtems_libio_t *iop, /* IN */ - const char *pathname, /* IN */ - unsigned32 flag, /* IN */ - unsigned32 mode /* IN */ -); - -int -msdos_dir_close(rtems_libio_t *iop /* IN */); - -ssize_t -msdos_dir_read( - rtems_libio_t *iop, /* IN */ - void *buffer, /* IN */ - unsigned32 count /* IN */ -); - -int -msdos_dir_lseek( - rtems_libio_t *iop, /* IN */ - off_t offset, /* IN */ - int whence /* IN */ -); - -int -msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */); - -int -msdos_dir_sync(rtems_libio_t *iop); - -int -msdos_dir_stat( - rtems_filesystem_location_info_t *loc, /* IN */ - struct stat *buf /* OUT */ -); - -int -msdos_creat_node(rtems_filesystem_location_info_t *parent_loc, - msdos_node_type_t type, - char *name, - mode_t mode); - -/* Misc prototypes */ -msdos_token_types_t msdos_get_token(const char *path, - char *token, - int *token_len); - -int -msdos_find_name(rtems_filesystem_location_info_t *parent_loc, - char *name); - -int -msdos_get_name_node(rtems_filesystem_location_info_t *parent_loc, - char *name, - fat_auxiliary_t *paux, - char *name_dir_entry); - -int -msdos_dir_info_remove(rtems_filesystem_location_info_t *pathloc); - -void -msdos_date_unix2dos(int unix_date, - unsigned short *time_val, - unsigned short *date); - -unsigned int -msdos_date_dos2unix(unsigned short time_val, unsigned short date); - -int -msdos_set_first_cluster_num(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd); - -int -msdos_set_file_size(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd); - -int -msdos_set_first_char4file_name(rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cl, - unsigned32 ofs, - unsigned char first_char); - -int -msdos_set_dir_wrt_time_and_date( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd -); - - -int -msdos_dir_is_empty(rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - rtems_boolean *ret_val); - -int -msdos_find_name_in_fat_file( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - char *name, - fat_auxiliary_t *paux, - char *name_dir_entry); - -int -msdos_find_node_by_cluster_num_in_fat_file( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 cl4find, - fat_auxiliary_t *paux, - char *dir_entry -); - -int -msdos_get_dotdot_dir_info_cluster_num_and_offset( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - fat_auxiliary_t *paux, - char *dir_entry -); - -#ifdef __cplusplus -} -#endif - -#endif /* __DOSFS_MSDOS_H__ */ diff --git a/c/src/exec/libfs/src/dosfs/msdos_create.c b/c/src/exec/libfs/src/dosfs/msdos_create.c deleted file mode 100644 index 4b4c7001ca..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_create.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Routine to create a new MSDOS filesystem node - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - * - */ -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <errno.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <rtems/libio_.h> -#include <time.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_creat_node -- - * Create a new node. If a new node is file, FAT 32 Bytes Directory - * Entry Structure (see M$ White Paper) is initialized, free space is - * found in parent directory and structure is written to the disk. - * In case of directory, all above steps present and also new cluster - * is allocated for a new directory and dot and dotdot nodes are created - * in alloceted cluster. - * - * PARAMETERS: - * parent_loc - parent (directory we are going to create node in) - * type - new node type (file or directory) - * name - new node name - * mode - mode - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately). - * - */ -int -msdos_creat_node( - rtems_filesystem_location_info_t *parent_loc, - msdos_node_type_t type, - char *name, - mode_t mode - ) -{ - int rc = RC_OK; - ssize_t ret = 0; - msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; - fat_file_fd_t *parent_fat_fd = parent_loc->node_access; - fat_file_fd_t *fat_fd = NULL; - time_t time_ret = 0; - unsigned16 time_val = 0; - unsigned16 date = 0; - fat_auxiliary_t aux; - unsigned char new_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - unsigned char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2]; - - memset(new_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2); - - /* set up name */ - strncpy(MSDOS_DIR_NAME(new_node), name, MSDOS_NAME_MAX); - - /* fill reserved field */ - *MSDOS_DIR_NT_RES(new_node) = MSDOS_RES_NT_VALUE; - - /* set up last write date and time */ - time_ret = time(NULL); - if ( time_ret == -1 ) - return -1; - - msdos_date_unix2dos(time_ret, &time_val, &date); - *MSDOS_DIR_WRITE_TIME(new_node) = CT_LE_W(time_val); - *MSDOS_DIR_WRITE_DATE(new_node) = CT_LE_W(date); - - /* initialize directory/file size */ - *MSDOS_DIR_FILE_SIZE(new_node) = MSDOS_INIT_DIR_SIZE; - - if (type == MSDOS_DIRECTORY) - *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_DIRECTORY; - else - *MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE; - - /* - * find free space in the parent directory and write new initialized - * FAT 32 Bytes Directory Entry Structure (see M$ White Paper) - * to the disk - */ - rc = msdos_get_name_node(parent_loc, NULL, &aux, new_node); - if ( rc != RC_OK ) - return rc; - - /* - * if we create a new file we are done, if directory there are more steps - * to do - */ - if (type == MSDOS_DIRECTORY) - { - /* open new directory as fat-file */ - rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd); - if (rc != RC_OK) - goto err; - - /* - * we opened fat-file for node we just created, so initialize fat-file - * descritor - */ - fat_fd->info_cln = aux.cln; - fat_fd->info_ofs = aux.ofs; - fat_fd->fat_file_size = 0; - fat_fd->fat_file_type = FAT_DIRECTORY; - fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; - - /* - * dot and dotdot entries are identical to new node except the - * names - */ - memcpy(DOT_NODE_P(dot_dotdot), new_node, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - memcpy(DOTDOT_NODE_P(dot_dotdot), new_node, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - memcpy(MSDOS_DIR_NAME(DOT_NODE_P(dot_dotdot)), MSDOS_DOT_NAME, - MSDOS_NAME_MAX); - memcpy(MSDOS_DIR_NAME(DOTDOT_NODE_P(dot_dotdot)), MSDOS_DOTDOT_NAME, - MSDOS_NAME_MAX); - - /* set up cluster num for dotdot entry */ - /* - * here we can ommit FAT32 condition because for all FAT types dirs - * right under root dir should contain 0 in dotdot entry but for - * FAT12/16 parent_fat_fd->cluster_num always contains such value - */ - if ((FAT_FD_OF_ROOT_DIR(parent_fat_fd)) && - (fs_info->fat.vol.type & FAT_FAT32)) - { - *MSDOS_DIR_FIRST_CLUSTER_LOW(DOTDOT_NODE_P(dot_dotdot)) = 0x0000; - *MSDOS_DIR_FIRST_CLUSTER_HI(DOTDOT_NODE_P(dot_dotdot)) = 0x0000; - } - else - { - *MSDOS_DIR_FIRST_CLUSTER_LOW(DOTDOT_NODE_P(dot_dotdot)) = - CT_LE_W((unsigned16)((parent_fat_fd->cln) & 0x0000FFFF)); - *MSDOS_DIR_FIRST_CLUSTER_HI(DOTDOT_NODE_P(dot_dotdot)) = - CT_LE_W((unsigned16)(((parent_fat_fd->cln) & 0xFFFF0000)>>16)); - } - - /* - * write dot and dotdot entries to new fat-file: currently fat-file - * correspondes to a new node is zero length, so it will be extended - * by one cluster and entries will be written - */ - ret = fat_file_write(parent_loc->mt_entry, fat_fd, 0, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2, - dot_dotdot); - if (ret < 0) - { - rc = -1; - goto error; - } - - /* increment fat-file size by cluster size */ - fat_fd->fat_file_size += fs_info->fat.vol.bpc; - - /* set up cluster num for dot entry */ - *MSDOS_DIR_FIRST_CLUSTER_LOW(DOT_NODE_P(dot_dotdot)) = - CT_LE_W((unsigned16)((fat_fd->cln) & 0x0000FFFF)); - *MSDOS_DIR_FIRST_CLUSTER_HI(DOT_NODE_P(dot_dotdot)) = - CT_LE_W((unsigned16)(((fat_fd->cln) & 0xFFFF0000) >> 16)); - - /* rewrite dot entry */ - ret = fat_file_write(parent_loc->mt_entry, fat_fd, 0, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE, - DOT_NODE_P(dot_dotdot)); - if (ret < 0) - { - rc = -1; - goto error; - } - - /* write first cluster num of a new directory to disk */ - rc = msdos_set_first_cluster_num(parent_loc->mt_entry, fat_fd); - if (rc != RC_OK) - goto error; - - fat_file_close(parent_loc->mt_entry, fat_fd); - } - return RC_OK; - -error: - fat_file_close(parent_loc->mt_entry, fat_fd); - -err: - /* mark 32bytes structure on the disk as free */ - msdos_set_first_char4file_name(parent_loc->mt_entry, aux.cln, aux.ofs, - 0xE5); - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_dir.c b/c/src/exec/libfs/src/dosfs/msdos_dir.c deleted file mode 100644 index 93449cd2fb..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_dir.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * MSDOS directory handlers implementation - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <rtems/libio_.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <dirent.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_dir_open -- - * Open fat-file which correspondes to the directory being opened and - * set offset field of file control block to zero. - * - * PARAMETERS: - * iop - file control block - * pathname - name - * flag - flags - * mode - mode - * - * RETURNS: - * RC_OK, if directory opened successfully, or -1 if error occured (errno - * set apropriately) - */ -int -msdos_dir_open(rtems_libio_t *iop, const char *pathname, unsigned32 flag, - unsigned32 mode) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one( EIO ); - - rc = fat_file_reopen(fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - iop->offset = 0; - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_dir_close -- - * Close fat-file which correspondes to the directory being closed - * - * PARAMETERS: - * iop - file control block - * - * RETURNS: - * RC_OK, if directory closed successfully, or -1 if error occured (errno - * set apropriately. - */ -int -msdos_dir_close(rtems_libio_t *iop) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one( EIO ); - - rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_dir_read -- - * This routine will read the next directory entry based on the directory - * offset. The offset should be equal to -n- time the size of an - * individual dirent structure. If n is not an integer multiple of the - * sizeof a dirent structure, an integer division will be performed to - * determine directory entry that will be returned in the buffer. Count - * should reflect -m- times the sizeof dirent bytes to be placed in the - * buffer. - * If there are not -m- dirent elements from the current directory - * position to the end of the exisiting file, the remaining entries will - * be placed in the buffer and the returned value will be equal to - * -m actual- times the size of a directory entry. - * - * PARAMETERS: - * iop - file control block - * buffer - buffer provided by user - * count - count of bytes to read - * - * RETURNS: - * the number of bytes read on success, or -1 if error occured (errno - * set apropriately). - */ -ssize_t -msdos_dir_read(rtems_libio_t *iop, void *buffer, unsigned32 count) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - fat_file_fd_t *tmp_fat_fd = NULL; - struct dirent tmp_dirent; - unsigned32 start = 0; - ssize_t ret = 0; - unsigned32 cmpltd = 0; - unsigned32 j = 0, i = 0; - unsigned32 bts2rd = 0; - unsigned32 cur_cln = 0; - - /* - * cast start and count - protect against using sizes that are not exact - * multiples of the -dirent- size. These could result in unexpected - * results - */ - start = iop->offset / sizeof(struct dirent); - count = (count / sizeof(struct dirent)) * sizeof(struct dirent); - - /* - * optimization: we know that root directory for FAT12/16 volumes is - * sequential set of sectors and any cluster is sequential set of sectors - * too, so read such set of sectors is quick operation for low-level IO - * layer. - */ - bts2rd = (FAT_FD_OF_ROOT_DIR(fat_fd) && - (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16))) ? - fat_fd->fat_file_size : - fs_info->fat.vol.bpc; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - while (count > 0) - { - /* - * fat-file is already opened by open call, so read it - * Always read directory fat-file from the beggining because of MSDOS - * directories feature :( - we should count elements currently - * present in the directory because there may be holes :) - */ - ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, (j * bts2rd), - bts2rd, fs_info->cl_buf); - if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - { - rtems_semaphore_release(fs_info->vol_sema); - set_errno_and_return_minus_one(EIO); - } - - for (i = 0; i < ret; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - { - if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) - { - rtems_semaphore_release(fs_info->vol_sema); - return cmpltd; - } - - if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_EMPTY) - continue; - - /* - * skip active entries until get the entry to start from - */ - if (start) - { - start--; - continue; - } - - /* - * Move the entry to the return buffer - * - * unfortunately there is no method to extract ino except to - * open fat-file descriptor :( ... so, open it - */ - - /* get number of cluster we are working with */ - rc = fat_file_ioctl(iop->pathinfo.mt_entry, fat_fd, F_CLU_NUM, - j * bts2rd, &cur_cln); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - rc = fat_file_open(iop->pathinfo.mt_entry, cur_cln, i, - &tmp_fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - tmp_fat_fd->info_cln = cur_cln; - tmp_fat_fd->info_ofs = i; - - /* fill in dirent structure */ - /* XXX: from what and in what d_off should be computed ?! */ - tmp_dirent.d_off = start + cmpltd; - tmp_dirent.d_reclen = sizeof(struct dirent); - tmp_dirent.d_ino = tmp_fat_fd->ino; - tmp_dirent.d_namlen = MSDOS_SHORT_NAME_LEN; - memcpy(tmp_dirent.d_name, MSDOS_DIR_NAME((fs_info->cl_buf + i)), - MSDOS_SHORT_NAME_LEN); - - /* d_name is null-terminated */ - tmp_dirent.d_name[MSDOS_SHORT_NAME_LEN] = 0; - memcpy(buffer + cmpltd, &tmp_dirent, sizeof(struct dirent)); - - iop->offset = iop->offset + sizeof(struct dirent); - cmpltd += (sizeof(struct dirent)); - count -= (sizeof(struct dirent)); - - /* inode number extracted, close fat-file */ - rc = fat_file_close(iop->pathinfo.mt_entry, tmp_fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - if (count <= 0) - break; - } - j++; - } - - rtems_semaphore_release(fs_info->vol_sema); - return cmpltd; -} - -/* msdos_dir_write -- - * no write for directory - */ - -/* msdos_dir_lseek -- - * - * This routine will behave in one of three ways based on the state of - * argument whence. Based on the state of its value the offset argument will - * be interpreted using one of the following methods: - * - * SEEK_SET - offset is the absolute byte offset from the start of the - * logical start of the dirent sequence that represents the - * directory - * SEEK_CUR - offset is used as the relative byte offset from the current - * directory position index held in the iop structure - * SEEK_END - N/A --> This will cause an assert. - * - * PARAMETERS: - * iop - file control block - * offset - offset - * whence - predefine directive - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno - * set apropriately). - */ -int -msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence) -{ - switch (whence) - { - case SEEK_SET: - case SEEK_CUR: - break; - /* - * Movement past the end of the directory via lseek is not a - * permitted operation - */ - case SEEK_END: - default: - set_errno_and_return_minus_one( EINVAL ); - break; - } - return RC_OK; -} - -/* msdos_dir_stat -- - * - * This routine will obtain the following information concerning the current - * directory: - * st_dev device id - * st_ino node serial number :) - * st_mode mode extracted from the node - * st_size total size in bytes - * st_blksize blocksize for filesystem I/O - * st_blocks number of blocks allocated - * stat_mtime time of last modification - * - * PARAMETERS: - * loc - this directory - * buf - stat buffer provided by user - * - * RETURNS: - * RC_OK and filled stat buffer on success, or -1 if error occured (errno - * set apropriately). - */ -int -msdos_dir_stat( - rtems_filesystem_location_info_t *loc, - struct stat *buf - ) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = loc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = loc->node_access; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - buf->st_dev = fs_info->fat.vol.dev; - buf->st_ino = fat_fd->ino; - buf->st_mode = S_IFDIR; - buf->st_rdev = 0ll; - buf->st_size = fat_fd->fat_file_size; - buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS; - buf->st_blksize = fs_info->fat.vol.bps; - buf->st_mtime = fat_fd->mtime; - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_dir_truncate -- - * No truncate for directory. - * - * PARAMETERS: - * - * RETURNS: - * - */ - -/* msdos_dir_sync -- - * The following routine does a syncronization on a MSDOS directory node. - * DIR_WrtTime, DIR_WrtDate and DIR_fileSize fields of 32 Bytes Directory - * Entry Structure(see M$ White Paper) should not be updated for - * directories, so only call to corresponding fat-file routine. - * - * PARAMETERS: - * iop - file control block - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - */ -int -msdos_dir_sync(rtems_libio_t *iop) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - fat_file_fd_t *fat_fd = iop->file_info; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd); - - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} - -/* msdos_dir_rmnod -- - * Remove directory node. - * - * Check that this directory node is not opened as fat-file, is empty and - * not filesystem root node. If all this conditions met then delete. - * - * PARAMETERS: - * pathloc - node description - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - */ -int -msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = pathloc->node_access; - rtems_boolean is_empty = FALSE; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - /* - * We deny attemp to delete open directory (if directory is current - * directory we assume it is open one) - */ - if (fat_fd->links_num > 1) - { - rtems_semaphore_release(fs_info->vol_sema); - set_errno_and_return_minus_one(EBUSY); - } - - /* - * You cannot remove a node that still has children - */ - rc = msdos_dir_is_empty(pathloc->mt_entry, fat_fd, &is_empty); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - if (!is_empty) - { - rtems_semaphore_release(fs_info->vol_sema); - set_errno_and_return_minus_one(ENOTEMPTY); - } - - /* - * You cannot remove the file system root node. - */ - if (pathloc->mt_entry->mt_fs_root.node_access == pathloc->node_access) - { - rtems_semaphore_release(fs_info->vol_sema); - set_errno_and_return_minus_one(EBUSY); - } - - /* - * You cannot remove a mountpoint. - * not used - mount() not implemenetd yet. - */ - - /* mark file removed */ - rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln, - fat_fd->info_ofs, - MSDOS_THIS_DIR_ENTRY_EMPTY); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - fat_file_mark_removed(pathloc->mt_entry, fat_fd); - - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_eval.c b/c/src/exec/libfs/src/dosfs/msdos_eval.c deleted file mode 100644 index 3eba0e63e8..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_eval.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * MSDOS evaluation routines - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#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" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_set_handlers -- - * Set handlers for the node with specified type(i.e. handlers for file - * or directory). - * - * PARAMETERS: - * loc - node description - * - * RETURNS: - * None - */ -static void -msdos_set_handlers(rtems_filesystem_location_info_t *loc) -{ - msdos_fs_info_t *fs_info = loc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = loc->node_access; - - if (fat_fd->fat_file_type == FAT_DIRECTORY) - loc->handlers = fs_info->directory_handlers; - else - loc->handlers = fs_info->file_handlers; -} - -/* msdos_eval_path -- - * - * The following routine evaluate path for a node that wishes to be - * accessed. Structure 'pathloc' is returned with a pointer to the - * node to be accessed. - * - * PARAMETERS: - * pathname - path for evaluation - * flags - flags - * pathloc - node description (IN/OUT) - * - * RETURNS: - * RC_OK and filled pathloc on success, or -1 if error occured - * (errno set appropriately) - * - */ -int -msdos_eval_path( - const char *pathname, - int flags, - rtems_filesystem_location_info_t *pathloc - ) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = NULL; - rtems_filesystem_location_info_t newloc; - int i = 0; - int len = 0; - msdos_token_types_t type = MSDOS_CURRENT_DIR; - char token[MSDOS_NAME_MAX + 1]; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - if (!pathloc->node_access) - { - errno = ENOENT; - rc = -1; - goto err; - } - - fat_fd = pathloc->node_access; - - rc = fat_file_reopen(fat_fd); - if (rc != RC_OK) - goto err; - - while ((type != MSDOS_NO_MORE_PATH) && (type != MSDOS_INVALID_TOKEN)) - { - type = msdos_get_token(&pathname[i], token, &len); - i += len; - - fat_fd = pathloc->node_access; - - switch (type) - { - case MSDOS_UP_DIR: - /* - * Only a directory can be decended into. - */ - if (fat_fd->fat_file_type != FAT_DIRECTORY) - { - errno = ENOTDIR; - rc = -1; - goto error; - } - - /* - * Am I at the root of this mounted filesystem? - */ - if (pathloc->node_access == - pathloc->mt_entry->mt_fs_root.node_access) - { - /* - * Am I at the root of all filesystems? - * XXX: MSDOS is not supposed to be base fs. - */ - if (pathloc->node_access == - rtems_filesystem_root.node_access) - { - break; /* Throw out the .. in this case */ - } - else - { - newloc = pathloc->mt_entry->mt_point_node; - *pathloc = newloc; - - rc = fat_file_close(pathloc->mt_entry, fat_fd); - if (rc != RC_OK) - goto err; - - rtems_semaphore_release(fs_info->vol_sema); - return (*pathloc->ops->evalpath_h)(&(pathname[i-len]), - flags, pathloc); - } - } - else - { - rc = msdos_find_name(pathloc, token); - if (rc != RC_OK) - { - if (rc == MSDOS_NAME_NOT_FOUND_ERR) - { - errno = ENOENT; - rc = -1; - } - goto error; - } - } - break; - - case MSDOS_NAME: - /* - * Only a directory can be decended into. - */ - if (fat_fd->fat_file_type != FAT_DIRECTORY) - { - errno = ENOTDIR; - rc = -1; - goto error; - } - - /* - * Otherwise find the token name in the present location and - * set the node access to the point we have found. - */ - rc = msdos_find_name(pathloc, token); - if (rc != RC_OK) - { - if (rc == MSDOS_NAME_NOT_FOUND_ERR) - { - errno = ENOENT; - rc = -1; - } - goto error; - } - break; - - case MSDOS_NO_MORE_PATH: - case MSDOS_CURRENT_DIR: - break; - - case MSDOS_INVALID_TOKEN: - errno = ENAMETOOLONG; - rc = -1; - goto error; - break; - - } - } - - /* - * Always return the root node. - * - * If we are at a node that is a mount point. Set loc to the - * new fs root node and let let the mounted filesystem set the handlers. - * - * NOTE: The behavior of stat() on a mount point appears to be - * questionable. - * NOTE: MSDOS filesystem currently doesn't support mount functionality -> - * action not implemented - */ - fat_fd = pathloc->node_access; - - msdos_set_handlers(pathloc); - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; - -error: - fat_file_close(pathloc->mt_entry, fat_fd); - -err: - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} - -/* msdos_eval4make -- - * The following routine evaluate path for a new node to be created. - * 'pathloc' is returned with a pointer to the parent of the new node. - * 'name' is returned with a pointer to the first character in the - * new node name. The parent node is verified to be a directory. - * - * PARAMETERS: - * path - path for evaluation - * pathloc - IN/OUT (start point for evaluation/parent directory for - * creation) - * name - new node name - * - * RETURNS: - * RC_OK, filled pathloc for parent directory and name of new node on - * success, or -1 if error occured (errno set appropriately) - */ -int -msdos_eval4make( - const char *path, - rtems_filesystem_location_info_t *pathloc, - const char **name - ) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = NULL; - rtems_filesystem_location_info_t newloc; - msdos_token_types_t type; - int i = 0; - int len; - char token[ MSDOS_NAME_MAX + 1 ]; - rtems_boolean done = 0; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - if (!pathloc->node_access) - { - errno = ENOENT; - rc = -1; - goto err; - } - - fat_fd = pathloc->node_access; - - rc = fat_file_reopen(fat_fd); - if (rc != RC_OK) - goto err; - - while (!done) - { - type = msdos_get_token(&path[i], token, &len); - i += len; - fat_fd = pathloc->node_access; - - switch (type) - { - case MSDOS_UP_DIR: - /* - * Only a directory can be decended into. - */ - if (fat_fd->fat_file_type != FAT_DIRECTORY) - { - errno = ENOTDIR; - rc = -1; - goto error; - } - - /* - * Am I at the root of this mounted filesystem? - */ - if (pathloc->node_access == - pathloc->mt_entry->mt_fs_root.node_access) - { - /* - * Am I at the root of all filesystems? - * XXX: MSDOS is not supposed to be base fs. - */ - if (pathloc->node_access == - rtems_filesystem_root.node_access) - { - break; /* Throw out the .. in this case */ - } - else - { - newloc = pathloc->mt_entry->mt_point_node; - *pathloc = newloc; - - rc = fat_file_close(pathloc->mt_entry, fat_fd); - if (rc != RC_OK) - goto err; - - rtems_semaphore_release(fs_info->vol_sema); - return (*pathloc->ops->evalformake_h)(&path[i-len], - pathloc, name); - } - } - else - { - rc = msdos_find_name(pathloc, token); - if (rc != RC_OK) - { - if (rc == MSDOS_NAME_NOT_FOUND_ERR) - { - errno = ENOENT; - rc = -1; - } - goto error; - } - } - break; - - case MSDOS_NAME: - /* - * Only a directory can be decended into. - */ - if (fat_fd->fat_file_type != FAT_DIRECTORY) - { - errno = ENOTDIR; - rc = -1; - goto error; - } - - /* - * Otherwise find the token name in the present location and - * set the node access to the point we have found. - */ - rc = msdos_find_name(pathloc, token); - if (rc) - { - if (rc != MSDOS_NAME_NOT_FOUND_ERR) - { - errno = ENOENT; - rc = -1; - goto error; - } - else - done = TRUE; - } - break; - - case MSDOS_NO_MORE_PATH: - errno = EEXIST; - rc = -1; - goto error; - break; - - case MSDOS_CURRENT_DIR: - break; - - case MSDOS_INVALID_TOKEN: - errno = ENAMETOOLONG; - rc = -1; - goto error; - break; - - } - } - - *name = &path[i - len]; - - /* - * We have evaluated the path as far as we can. - * Verify there is not any invalid stuff at the end of the name. - */ - for( ; path[i] != '\0'; i++) - { - if (!msdos_is_separator(path[i])) - { - errno = ENOENT; - rc = -1; - goto error; - } - } - - fat_fd = pathloc->node_access; - - if (fat_fd->fat_file_type != FAT_DIRECTORY) - { - errno = ENOTDIR; - rc = -1; - goto error; - } - - msdos_set_handlers(pathloc); - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; - -error: - fat_file_close(pathloc->mt_entry, fat_fd); - -err: - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_file.c b/c/src/exec/libfs/src/dosfs/msdos_file.c deleted file mode 100644 index da36827338..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_file.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * MSDOS file handlers implementation - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <assert.h> -#include <errno.h> - -#include <rtems.h> -#include <rtems/libio.h> -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_file_open -- - * Open fat-file which correspondes to the file - * - * PARAMETERS: - * iop - file control block - * pathname - name - * flag - flags - * mode - mode - * - * RETURNS: - * RC_OK, if file opened successfully, or -1 if error occured - * and errno set appropriately - */ -int -msdos_file_open(rtems_libio_t *iop, const char *pathname, unsigned32 flag, - unsigned32 mode) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - rc = fat_file_reopen(fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - if (iop->flags & LIBIO_FLAGS_APPEND) - iop->offset = fat_fd->fat_file_size; - - iop->size = fat_fd->fat_file_size; - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_file_close -- - * Close fat-file which correspondes to the file. If fat-file descriptor - * which correspondes to the file is not marked "removed", synchronize - * size, first cluster number, write time and date fields of the file. - * - * PARAMETERS: - * iop - file control block - * - * RETURNS: - * RC_OK, if file closed successfully, or -1 if error occured (errno set - * appropriately) - */ -int -msdos_file_close(rtems_libio_t *iop) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - /* - * if fat-file descriptor is not marked as "removed", synchronize - * size, first cluster number, write time and date fields of the file - */ - if (!FAT_FILE_IS_REMOVED(fat_fd)) - { - rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - } - - rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd); - - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} - -/* msdos_file_read -- - * This routine read from file pointed to by file control block into - * the specified data buffer provided by user - * - * PARAMETERS: - * iop - file control block - * buffer - buffer provided by user - * count - the number of bytes to read - * - * RETURNS: - * the number of bytes read on success, or -1 if error occured (errno set - * appropriately) - */ -ssize_t -msdos_file_read(rtems_libio_t *iop, void *buffer, unsigned32 count) -{ - ssize_t ret = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, iop->offset, count, - buffer); - - rtems_semaphore_release(fs_info->vol_sema); - return ret; -} - -/* msdos_file_write -- - * This routine writes the specified data buffer into the file pointed to - * by file control block. - * - * PARAMETERS: - * iop - file control block - * buffer - data to write - * count - count of bytes to write - * - * RETURNS: - * the number of bytes written on success, or -1 if error occured - * and errno set appropriately - */ -ssize_t -msdos_file_write(rtems_libio_t *iop,const void *buffer, unsigned32 count) -{ - ssize_t ret = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count, - buffer); - if (ret < 0) - { - rtems_semaphore_release(fs_info->vol_sema); - return -1; - } - - /* - * update file size in both fat-file descriptor and file control block if - * file was extended - */ - if (iop->offset + ret > fat_fd->fat_file_size) - fat_fd->fat_file_size = iop->offset + ret; - - iop->size = fat_fd->fat_file_size; - - rtems_semaphore_release(fs_info->vol_sema); - return ret; -} - -/* msdos_file_lseek -- - * Process lseek call to the file: extend file if lseek is up to the end - * of the file. - * - * PARAMETERS: - * iop - file control block - * offset - new offset - * whence - predefine directive - * - * RETURNS: - * new offset on success, or -1 if error occured (errno set - * appropriately). - */ -int -msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - unsigned32 real_size = 0; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - rc = fat_file_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset, - &real_size); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - if (real_size > fat_fd->fat_file_size) - fat_fd->fat_file_size = iop->offset = real_size; - - iop->size = fat_fd->fat_file_size; - - rtems_semaphore_release(fs_info->vol_sema); - return iop->offset; -} - -/* msdos_file_stat -- - * - * PARAMETERS: - * loc - node description - * buf - stat buffer provided by user - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -msdos_file_stat( - rtems_filesystem_location_info_t *loc, - struct stat *buf - ) -{ - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = loc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = loc->node_access; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - buf->st_dev = fs_info->fat.vol.dev; - buf->st_ino = fat_fd->ino; - buf->st_mode = S_IFREG; - buf->st_rdev = 0ll; - buf->st_size = fat_fd->fat_file_size; - buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS; - buf->st_blksize = fs_info->fat.vol.bps; - buf->st_mtime = fat_fd->mtime; - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_file_ftruncate -- - * Truncate the file (if new length is greater then current do nothing). - * - * PARAMETERS: - * iop - file control block - * length - new length - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately). - */ -int -msdos_file_ftruncate(rtems_libio_t *iop, off_t length) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - fat_file_fd_t *fat_fd = iop->file_info; - - if (length >= fat_fd->fat_file_size) - return RC_OK; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - /* - * fat_file_truncate do nothing if new length >= fat-file size, so update - * file size only if length < fat-file size - */ - if (length < fat_fd->fat_file_size) - iop->size = fat_fd->fat_file_size = length; - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_file_sync -- - * Synchronize file - synchronize file data and if file is not removed - * synchronize file metadata. - * - * PARAMETERS: - * iop - file control block - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -msdos_file_sync(rtems_libio_t *iop) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - fat_file_fd_t *fat_fd = iop->file_info; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - /* synchronize file data */ - rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - /* - * if fat-file descriptor is not marked "removed" - synchronize file - * metadata - */ - if (!FAT_FILE_IS_REMOVED(fat_fd)) - { - rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - } - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - -/* msdos_file_datasync -- - * Synchronize file - synchronize only file data (metadata is letf intact). - * - * PARAMETERS: - * iop - file control block - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -msdos_file_datasync(rtems_libio_t *iop) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - fat_file_fd_t *fat_fd = iop->file_info; - msdos_fs_info_t *fs_info = iop->pathinfo.mt_entry->fs_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - /* synchronize file data */ - rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd); - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} - - -/* msdos_file_ioctl -- - * - * - * PARAMETERS: - * iop - file control block - * ... - * - * RETURNS: - * - */ -int -msdos_file_ioctl(rtems_libio_t *iop,unsigned32 command, void *buffer) -{ - int rc = RC_OK; - - return rc; -} - -/* msdos_file_rmnod -- - * Remove node associated with a file - set up first name character to - * predefined value(and write it to the disk), and mark fat-file which - * correspondes to the file as "removed" - * - * PARAMETERS: - * pathloc - node description - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) - */ -int -msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = pathloc->node_access; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - /* mark file removed */ - rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln, - fat_fd->info_ofs, - MSDOS_THIS_DIR_ENTRY_EMPTY); - if (rc != RC_OK) - { - rtems_semaphore_release(fs_info->vol_sema); - return rc; - } - - fat_file_mark_removed(pathloc->mt_entry, fat_fd); - - rtems_semaphore_release(fs_info->vol_sema); - return RC_OK; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_free.c b/c/src/exec/libfs/src/dosfs/msdos_free.c deleted file mode 100644 index c0d5938dbb..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_free.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Free node handler implementation for the filesystem - * operations table. - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems.h> -#include <rtems/libio_.h> - -#include <errno.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_free_node_info -- - * Call fat-file close routine. - * - * PARAMETERS: - * pathloc - node description - * - * RETURNS: - * RC_OK on success, or -1 code if error occured - * - */ -int -msdos_free_node_info(rtems_filesystem_location_info_t *pathloc) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - rc = fat_file_close(pathloc->mt_entry, pathloc->node_access); - - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_fsunmount.c b/c/src/exec/libfs/src/dosfs/msdos_fsunmount.c deleted file mode 100644 index 9072a2fad5..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_fsunmount.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * MSDOS shut down handler implementation - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -#include <assert.h> -#include <rtems.h> -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_shut_down -- - * Shut down MSDOS filesystem - free all allocated resources (don't - * return if deallocation of some resource failed - free as much as - * possible). - * - * PARAMETERS: - * temp_mt_entry - mount table entry - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - * - */ -int -msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry) -{ - int rc = RC_OK; - msdos_fs_info_t *fs_info = temp_mt_entry->fs_info; - fat_file_fd_t *fat_fd = temp_mt_entry->mt_fs_root.node_access; - - /* close fat-file which correspondes to root directory */ - if (fat_file_close(temp_mt_entry, fat_fd) != RC_OK) - { - /* no return - try to free as much as possible */ - rc = -1; - } - - if (fat_shutdown_drive(temp_mt_entry) != RC_OK) - { - /* no return - try to free as much as possible */ - rc = -1; - } - - rtems_semaphore_delete(fs_info->vol_sema); - free(fs_info->cl_buf); - free(temp_mt_entry->fs_info); - - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_handlers_dir.c b/c/src/exec/libfs/src/dosfs/msdos_handlers_dir.c deleted file mode 100644 index e14d892add..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_handlers_dir.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Directory Handlers Table for MSDOS filesystem - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/libio.h> -#include "msdos.h" - -rtems_filesystem_file_handlers_r msdos_dir_handlers = { - msdos_dir_open, - msdos_dir_close, - msdos_dir_read, - NULL, /* msdos_dir_write */ - NULL, /* msdos_dir_ioctl */ - msdos_dir_lseek, - msdos_dir_stat, - NULL, - NULL, /* msdos_dir_ftruncate */ - NULL, - msdos_dir_sync, - msdos_dir_sync, - NULL, /* msdos_dir_fcntl */ - msdos_dir_rmnod -}; diff --git a/c/src/exec/libfs/src/dosfs/msdos_handlers_file.c b/c/src/exec/libfs/src/dosfs/msdos_handlers_file.c deleted file mode 100644 index ae627066de..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_handlers_file.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * File Operations Table for MSDOS filesystem - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/libio.h> -#include "msdos.h" - -rtems_filesystem_file_handlers_r msdos_file_handlers = { - msdos_file_open, - msdos_file_close, - msdos_file_read, - msdos_file_write, - msdos_file_ioctl, - msdos_file_lseek, - msdos_file_stat, - NULL, - msdos_file_ftruncate, - NULL, - msdos_file_sync, - msdos_file_datasync, - NULL, /* msdos_file_fcntl */ - msdos_file_rmnod -}; diff --git a/c/src/exec/libfs/src/dosfs/msdos_init.c b/c/src/exec/libfs/src/dosfs/msdos_init.c deleted file mode 100644 index 2d5bf6c9e0..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_init.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Init routine for MSDOS - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/libio_.h> -#include "msdos.h" - -rtems_filesystem_operations_table msdos_ops = { - msdos_eval_path, - msdos_eval4make, - NULL, /* msdos_link */ - msdos_file_rmnod, - msdos_node_type, - msdos_mknod, - NULL, /* msdos_chown */ - msdos_free_node_info, - NULL, - msdos_initialize, - NULL, - msdos_shut_down, /* msdos_shut_down */ - NULL, /* msdos_utime */ - NULL, - NULL, - NULL -}; - -/* msdos_initialize -- - * MSDOS filesystem initialization - * - * PARAMETERS: - * temp_mt_entry - mount table entry - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - * - */ -int -msdos_initialize(rtems_filesystem_mount_table_entry_t *temp_mt_entry) -{ - int rc = RC_OK; - - rc = msdos_initialize_support(temp_mt_entry, - &msdos_ops, - &msdos_file_handlers, - &msdos_dir_handlers); - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_initsupp.c b/c/src/exec/libfs/src/dosfs/msdos_initsupp.c deleted file mode 100644 index eee8a6f9b2..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_initsupp.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * MSDOS Initialization support routine implementation - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -#include <assert.h> -#include <rtems.h> -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_initialize_support -- - * MSDOS filesystem initialization - * - * PARAMETERS: - * temp_mt_entry - mount table entry - * op_table - filesystem operations table - * file_handlers - file operations table - * directory_handlers - directory operations table - * - * RETURNS: - * RC_OK and filled temp_mt_entry on success, or -1 if error occured - * (errno set apropriately) - * - */ -int -msdos_initialize_support( - rtems_filesystem_mount_table_entry_t *temp_mt_entry, - rtems_filesystem_operations_table *op_table, - rtems_filesystem_file_handlers_r *file_handlers, - rtems_filesystem_file_handlers_r *directory_handlers - ) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = NULL; - fat_file_fd_t *fat_fd = NULL; - unsigned32 cl_buf_size; - - fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t)); - if (!fs_info) - set_errno_and_return_minus_one(ENOMEM); - - temp_mt_entry->fs_info = fs_info; - - rc = fat_init_volume_info(temp_mt_entry); - if (rc != RC_OK) - { - free(fs_info); - return rc; - } - - fs_info->file_handlers = file_handlers; - fs_info->directory_handlers = directory_handlers; - - /* - * open fat-file which correspondes to root directory - * (so inode number 0x00000010 is always used for root directory) - */ - rc = fat_file_open(temp_mt_entry, FAT_ROOTDIR_CLUSTER_NUM, 0, &fat_fd); - if (rc != RC_OK) - { - fat_shutdown_drive(temp_mt_entry); - free(fs_info); - return rc; - } - - /* again: unfortunately "fat-file" is just almost fat file :( */ - fat_fd->fat_file_type = FAT_DIRECTORY; - fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; - fat_fd->info_cln = FAT_ROOTDIR_CLUSTER_NUM; - fat_fd->info_ofs = 0; - fat_fd->cln = fs_info->fat.vol.rdir_cl; - - fat_fd->map.file_cln = 0; - fat_fd->map.disk_cln = fat_fd->cln; - - /* if we have FAT12/16 */ - if ( fat_fd->cln == 0 ) - { - fat_fd->fat_file_size = fs_info->fat.vol.rdir_size; - cl_buf_size = (fs_info->fat.vol.bpc > fs_info->fat.vol.rdir_size) ? - fs_info->fat.vol.bpc : - fs_info->fat.vol.rdir_size; - } - else - { - rc = fat_file_size(temp_mt_entry, fat_fd); - if ( rc != RC_OK ) - { - fat_file_close(temp_mt_entry, fat_fd); - fat_shutdown_drive(temp_mt_entry); - free(fs_info); - return rc; - } - cl_buf_size = fs_info->fat.vol.bpc; - } - - fs_info->cl_buf = (char *)calloc(cl_buf_size, sizeof(char)); - if (fs_info->cl_buf == NULL) - { - fat_file_close(temp_mt_entry, fat_fd); - fat_shutdown_drive(temp_mt_entry); - free(fs_info); - set_errno_and_return_minus_one(ENOMEM); - } - - sc = rtems_semaphore_create(3, - 1, - RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO, - RTEMS_INHERIT_PRIORITY, - &fs_info->vol_sema); - if (sc != RTEMS_SUCCESSFUL) - { - fat_file_close(temp_mt_entry, fat_fd); - fat_shutdown_drive(temp_mt_entry); - free(fs_info->cl_buf); - free(fs_info); - set_errno_and_return_minus_one( EIO ); - } - - temp_mt_entry->mt_fs_root.node_access = fat_fd; - temp_mt_entry->mt_fs_root.handlers = directory_handlers; - temp_mt_entry->mt_fs_root.ops = op_table; - - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_misc.c b/c/src/exec/libfs/src/dosfs/msdos_misc.c deleted file mode 100644 index fe2779f7a8..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_misc.c +++ /dev/null @@ -1,1087 +0,0 @@ -/* - * Miscellaneous routines implementation for MSDOS filesystem - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdlib.h> -#include <sys/time.h> -#include <unistd.h> -#include <string.h> -#include <assert.h> -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* This copied from Linux */ -static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; - /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ - -#undef CONFIG_ATARI - -/* MS-DOS "device special files" */ -static const char *reserved_names[] = { -#ifndef CONFIG_ATARI /* GEMDOS is less stupid */ - "CON ","PRN ","NUL ","AUX ", - "LPT1 ","LPT2 ","LPT3 ","LPT4 ", - "COM1 ","COM2 ","COM3 ","COM4 ", -#endif - NULL }; - -static char bad_chars[] = "*?<>|\""; -#ifdef CONFIG_ATARI -/* GEMDOS is less restrictive */ -static char bad_if_strict[] = " "; -#else -static char bad_if_strict[] = "+=,; "; -#endif - -/* The following three functions copied from Linux */ -/* - * Formats an MS-DOS file name. Rejects invalid names - * - * conv is relaxed/normal/strict, name is proposed name, - * len is the length of the proposed name, res is the result name, - * dotsOK is if hidden files get dots. - */ -int -msdos_format_name(char conv, const char *name, int len, char *res, - char dotsOK) -{ - char *walk; - const char **reserved; - unsigned char c; - int space; - if (name[0] == '.') { /* dotfile because . and .. already done */ - if (!dotsOK) return -EINVAL; - /* Get rid of dot - test for it elsewhere */ - name++; len--; - } -#ifndef CONFIG_ATARI - space = 1; /* disallow names that _really_ start with a dot */ -#else - space = 0; /* GEMDOS does not care */ -#endif - c = 0; - for (walk = res; len && walk-res < 8; walk++) { - c = *name++; - len--; - if (conv != 'r' && strchr(bad_chars,c)) return -EINVAL; - if (conv == 's' && strchr(bad_if_strict,c)) return -EINVAL; - if (c >= 'A' && c <= 'Z' && conv == 's') return -EINVAL; - if (c < ' ' || c == ':' || c == '\\') return -EINVAL; -/* 0xE5 is legal as a first character, but we must substitute 0x05 */ -/* because 0xE5 marks deleted files. Yes, DOS really does this. */ -/* It seems that Microsoft hacked DOS to support non-US characters */ -/* after the 0xE5 character was already in use to mark deleted files. */ - if((res==walk) && (c==0xE5)) c=0x05; - if (c == '.') break; - space = (c == ' '); - *walk = (c >= 'a' && c <= 'z') ? c-32 : c; - } - if (space) return -EINVAL; - if (conv == 's' && len && c != '.') { - c = *name++; - len--; - if (c != '.') return -EINVAL; - } - while (c != '.' && len--) c = *name++; - if (c == '.') { - while (walk-res < 8) *walk++ = ' '; - while (len > 0 && walk-res < MSDOS_NAME_MAX) { - c = *name++; - len--; - if (conv != 'r' && strchr(bad_chars,c)) return -EINVAL; - if (conv == 's' && strchr(bad_if_strict,c)) - return -EINVAL; - if (c < ' ' || c == ':' || c == '\\') - return -EINVAL; - if (c == '.') { - if (conv == 's') - return -EINVAL; - break; - } - if (c >= 'A' && c <= 'Z' && conv == 's') return -EINVAL; - space = c == ' '; - *walk++ = c >= 'a' && c <= 'z' ? c-32 : c; - } - if (space) return -EINVAL; - if (conv == 's' && len) return -EINVAL; - } - while (walk-res < MSDOS_NAME_MAX) *walk++ = ' '; - for (reserved = reserved_names; *reserved; reserved++) - if (!strncmp(res,*reserved,8)) return -EINVAL; - return 0; -} - -/* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70) */ -unsigned int -msdos_date_dos2unix(unsigned short time_val,unsigned short date) -{ - int month,year,secs; - - month = ((date >> 5) & 15)-1; - year = date >> 9; - secs = (time_val & 31)*2+60*((time_val >> 5) & 63)+ - (time_val >> 11)*3600+86400* - ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && - month < 2 ? 1 : 0)+3653); - /* days since 1.1.70 plus 80's leap day */ - - return secs; -} - - -/* Convert linear UNIX date to a MS-DOS time/date pair */ -void msdos_date_unix2dos(int unix_date, - unsigned short *time_val, - unsigned short *date) -{ - int day,year,nl_day,month; - - *time_val = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+ - (((unix_date/3600) % 24) << 11); - day = unix_date/86400-3652; - year = day/365; - if ((year+3)/4+365*year > day) year--; - day -= (year+3)/4+365*year; - if (day == 59 && !(year & 3)) { - nl_day = day; - month = 2; - } - else { - nl_day = (year & 3) || day <= 59 ? day : day-1; - for (month = 0; month < 12; month++) - if (day_n[month] > nl_day) break; - } - *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); -} - - -/* msdos_get_token -- - * Routine to get a token (name or separator) from the path. - * - * PARAMETERS: - * path - path to get token from - * ret_token - returned token - * token_len - length of returned token - * - * RETURNS: - * token type, token and token length - * - */ -msdos_token_types_t -msdos_get_token(const char *path, char *ret_token, int *token_len) -{ - int rc = RC_OK; - register int i = 0; - msdos_token_types_t type = MSDOS_NAME; - char token[MSDOS_NAME_MAX_WITH_DOT+1]; - register char c; - - /* - * Copy a name into token. (Remember NULL is a token.) - */ - c = path[i]; - while ( (!msdos_is_separator(c)) && (i <= MSDOS_NAME_MAX_WITH_DOT) ) - { - token[i] = c; - if ( i == MSDOS_NAME_MAX_WITH_DOT ) - return MSDOS_INVALID_TOKEN; - if ( !msdos_is_valid_name_char(c) ) - return MSDOS_INVALID_TOKEN; - c = path [++i]; - } - - /* - * Copy a seperator into token. - */ - if ( i == 0 ) - { - token[i] = c; - if ( token[i] != '\0' ) - { - i++; - type = MSDOS_CURRENT_DIR; - } - else - type = MSDOS_NO_MORE_PATH; - } - else if (token[ i-1 ] != '\0') - token[i] = '\0'; - - /* - * Set token_len to the number of characters copied. - */ - *token_len = i; - - /* - * If we copied something that was not a seperator see if - * it was a special name. - */ - if ( type == MSDOS_NAME ) - { - if ( strcmp( token, "..") == 0 ) - { - strcpy(ret_token, MSDOS_DOTDOT_NAME); - type = MSDOS_UP_DIR; - return type; - } - - if ( strcmp( token, "." ) == 0 ) - { - strcpy(ret_token, MSDOS_DOT_NAME); - type = MSDOS_CURRENT_DIR; - return type; - } - - rc = msdos_format_name('r', token, *token_len, ret_token, 0); - if ( rc != RC_OK ) - return MSDOS_INVALID_TOKEN; - } - ret_token[MSDOS_NAME_MAX] = '\0'; - return type; -} - - -/* msdos_find_name -- - * Find the node which correspondes to the name, open fat-file which - * correspondes to the found node and close fat-file which correspondes - * to the node we searched in. - * - * PARAMETERS: - * parent_loc - parent node description - * name - name to find - * - * RETURNS: - * RC_OK and updated 'parent_loc' on success, or -1 if error - * occured (errno set apropriately) - * - */ -int -msdos_find_name( - rtems_filesystem_location_info_t *parent_loc, - char *name - ) -{ - int rc = RC_OK; - msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = NULL; - fat_auxiliary_t aux; - unsigned short time_val = 0; - unsigned short date = 0; - unsigned char node_entry[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - - memset(node_entry, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - - /* - * find the node which correspondes to the name in the directory pointed by - * 'parent_loc' - */ - rc = msdos_get_name_node(parent_loc, name, &aux, node_entry); - if (rc != RC_OK) - return rc; - - /* open fat-file corresponded to the found node */ - rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd); - if (rc != RC_OK) - return rc; - - /* - * I don't like this if, but: we should do it , or should write new file - * size and first cluster num to the disk after each write operation - * (even if one byte is written - that is TOO non-optimize) because - * otherwise real values of these fields stored in fat-file descriptor - * may be accidentely rewritten with wrong values stored on the disk - */ - if (fat_fd->links_num == 1) - { - fat_fd->info_cln = aux.cln; - fat_fd->info_ofs = aux.ofs; - fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(node_entry); - fat_fd->first_char = *MSDOS_DIR_NAME(node_entry); - - time_val = *MSDOS_DIR_WRITE_TIME(node_entry); - date = *MSDOS_DIR_WRITE_DATE(node_entry); - - fat_fd->mtime = msdos_date_dos2unix(CF_LE_W(time_val), CF_LE_W(date)); - - if ((*MSDOS_DIR_ATTR(node_entry)) & MSDOS_ATTR_DIRECTORY) - { - fat_fd->fat_file_type = FAT_DIRECTORY; - fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; - - rc = fat_file_size(parent_loc->mt_entry, fat_fd); - if (rc != RC_OK) - { - fat_file_close(parent_loc->mt_entry, fat_fd); - return rc; - } - } - else - { - fat_fd->fat_file_size = CF_LE_L(*MSDOS_DIR_FILE_SIZE(node_entry)); - fat_fd->fat_file_type = FAT_FILE; - fat_fd->size_limit = MSDOS_MAX_FILE_SIZE; - } - - /* these data is not actual for zero-length fat-file */ - fat_fd->map.file_cln = 0; - fat_fd->map.disk_cln = fat_fd->cln; - - if ((fat_fd->fat_file_size != 0) && - (fat_fd->fat_file_size <= fs_info->fat.vol.bpc)) - { - fat_fd->map.last_cln = fat_fd->cln; - } - else - { - fat_fd->map.last_cln = FAT_UNDEFINED_VALUE; - } - } - - /* close fat-file corresponded to the node we searched in */ - rc = fat_file_close(parent_loc->mt_entry, parent_loc->node_access); - if (rc != RC_OK) - { - fat_file_close(parent_loc->mt_entry, fat_fd); - return rc; - } - - /* update node_info_ptr field */ - parent_loc->node_access = fat_fd; - - return rc; -} - -/* msdos_get_name_node -- - * This routine is used in two ways: for a new mode creation (a) or for - * search the node which correspondes to the name parameter (b). - * In case (a) 'name' should be set up to NULL and 'name_dir_entry' should - * point to initialized 32 bytes structure described a new node. - * In case (b) 'name' should contain a valid string. - * - * (a): reading fat-file which correspondes to directory we are going to - * create node in. If free slot is found write contents of - * 'name_dir_entry' into it. If reach end of fat-file and no free - * slot found, write 32 bytes to the end of fat-file. - * - * (b): reading fat-file which correspondes to directory and trying to - * find slot with the name field == 'name' parameter - * - * - * PARAMETERS: - * parent_loc - node description to create node in or to find name in - * name - NULL or name to find - * paux - identify a node location on the disk - - * cluster num and offset inside the cluster - * name_dir_entry - node to create/placeholder for found node (IN/OUT) - * - * RETURNS: - * RC_OK, filled aux_struct_ptr and name_dir_entry on success, or -1 if - * error occured (errno set apropriately) - * - */ -int -msdos_get_name_node( - rtems_filesystem_location_info_t *parent_loc, - char *name, - fat_auxiliary_t *paux, - char *name_dir_entry - ) -{ - int rc = RC_OK; - ssize_t ret = 0; - msdos_fs_info_t *fs_info = parent_loc->mt_entry->fs_info; - fat_file_fd_t *fat_fd = parent_loc->node_access; - unsigned32 dotdot_cln = 0; - - /* find name in fat-file which correspondes to the directory */ - rc = msdos_find_name_in_fat_file(parent_loc->mt_entry, fat_fd, name, paux, - name_dir_entry); - if ((rc != RC_OK) && (rc != MSDOS_NAME_NOT_FOUND_ERR)) - return rc; - - /* if we search for valid name and name not found -> return */ - if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name != NULL)) - return rc; - - /* - * if we try to create new entry and the directory is not big enough - * currently - try to enlarge directory - */ - if ((rc == MSDOS_NAME_NOT_FOUND_ERR) && (name == NULL)) - { - ret = fat_file_write(parent_loc->mt_entry, fat_fd, - fat_fd->fat_file_size, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE, - name_dir_entry); - if (ret == -1) - return -1; - - /* on success directory is enlarged by a new cluster */ - fat_fd->fat_file_size += fs_info->fat.vol.bpc; - - /* get cluster num where a new node located */ - rc = fat_file_ioctl(parent_loc->mt_entry, fat_fd, F_CLU_NUM, - fat_fd->fat_file_size - 1, &paux->cln); - - if (rc != RC_OK) - return rc; - - /* - * if new cluster allocated succesfully then new node is at very - * beginning of the cluster (offset is computed in bytes) - */ - paux->ofs = 0; - return RC_OK; - } - - /* - * if we have deal with ".." - it is a special case :((( - * - * Really, we should return cluster num and offset not of ".." slot, but - * slot which correspondes to real directory name. - */ - if ((rc == RC_OK) && (name != NULL)) - { - if (strncmp(name, MSDOS_DOTDOT_NAME, MSDOS_SHORT_NAME_LEN) == 0) - { - dotdot_cln = MSDOS_EXTRACT_CLUSTER_NUM((name_dir_entry)); - - /* are we right under root dir ? */ - if (dotdot_cln == 0) - { - /* - * we can relax about first_char field - it never should be - * used for root dir - */ - paux->cln = FAT_ROOTDIR_CLUSTER_NUM; - paux->ofs = 0; - } - else - { - rc = msdos_get_dotdot_dir_info_cluster_num_and_offset( - parent_loc->mt_entry, - dotdot_cln, - paux, - name_dir_entry - ); - if (rc != RC_OK) - return rc; - } - } - } - return rc; -} - -/* - * msdos_get_dotdot_dir_info_cluster_num_and_offset - * - * Unfortunately, in general, we cann't work here in fat-file ideologic - * (open fat_file "..", get ".." and ".", open "..", find an entry ...) - * because if we open - * fat-file ".." it may happend that we have two different fat-file - * descriptors ( for real name of directory and ".." name ) for a single - * file ( cluster num of both pointers to the same cluster ) - * But...we do it because we protected by semaphore - * - */ - -/* msdos_get_dotdot_dir_info_cluster_num_and_offset -- - * Get cluster num and offset not of ".." slot, but slot which correspondes - * to real directory name. - * - * PARAMETERS: - * mt_entry - mount table entry - * cln - data cluster num extracted drom ".." slot - * paux - identify a node location on the disk - - * number of cluster and offset inside the cluster - * dir_entry - placeholder for found node - * - * RETURNS: - * RC_OK, filled 'paux' and 'dir_entry' on success, or -1 if error occured - * (errno set apropriately) - * - */ -int -msdos_get_dotdot_dir_info_cluster_num_and_offset( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cln, - fat_auxiliary_t *paux, - char *dir_entry - ) -{ - int rc = RC_OK; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - fat_file_fd_t *fat_fd = NULL; - unsigned char dot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - unsigned char dotdot_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - unsigned char cur_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE]; - unsigned32 cl4find = 0; - - memset(dot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - memset(dotdot_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - memset(cur_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - - /* - * open fat-file corresponded to ".." - */ - rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd); - if (rc != RC_OK) - return rc; - - fat_fd->info_cln = paux->cln; - fat_fd->info_ofs = paux->ofs; - fat_fd->cln = cln; - fat_fd->fat_file_type = FAT_DIRECTORY; - fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; - - fat_fd->map.file_cln = 0; - fat_fd->map.disk_cln = fat_fd->cln; - - rc = fat_file_size(mt_entry, fat_fd); - if (rc != RC_OK) - { - fat_file_close(mt_entry, fat_fd); - return rc; - } - - /* find "." node in opened directory */ - rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOT_NAME, paux, - dot_node); - - if (rc != RC_OK) - { - fat_file_close(mt_entry, fat_fd); - return rc; - } - - /* find ".." node in opened directory */ - rc = msdos_find_name_in_fat_file(mt_entry, fat_fd, MSDOS_DOTDOT_NAME, paux, - dotdot_node); - - if (rc != RC_OK) - { - fat_file_close(mt_entry, fat_fd); - return rc; - } - - cl4find = MSDOS_EXTRACT_CLUSTER_NUM(dot_node); - - /* close fat-file corresponded to ".." directory */ - rc = fat_file_close(mt_entry, fat_fd); - if ( rc != RC_OK ) - return rc; - - if ( (MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0) - { - /* - * we handle root dir for all FAT types in the same way with the - * ordinary directories ( through fat_file_* calls ) - */ - paux->cln = FAT_ROOTDIR_CLUSTER_NUM; - paux->ofs = 0; - } - - /* open fat-file corresponded to second ".." */ - rc = fat_file_open(mt_entry, paux->cln, paux->ofs, &fat_fd); - if (rc != RC_OK) - return rc; - - fat_fd->info_cln = paux->cln; - fat_fd->info_ofs = paux->ofs; - - if ((MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node)) == 0) - fat_fd->cln = fs_info->fat.vol.rdir_cl; - else - fat_fd->cln = MSDOS_EXTRACT_CLUSTER_NUM(dotdot_node); - - fat_fd->fat_file_type = FAT_DIRECTORY; - fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT; - - fat_fd->map.file_cln = 0; - fat_fd->map.disk_cln = fat_fd->cln; - - rc = fat_file_size(mt_entry, fat_fd); - if (rc != RC_OK) - { - fat_file_close(mt_entry, fat_fd); - return rc; - } - - /* in this directory find slot with specified cluster num */ - rc = msdos_find_node_by_cluster_num_in_fat_file(mt_entry, fat_fd, cl4find, - paux, dir_entry); - if (rc != RC_OK) - { - fat_file_close(mt_entry, fat_fd); - return rc; - } - rc = fat_file_close(mt_entry, fat_fd); - return rc; -} - - -/* msdos_set_dir_wrt_time_and_date -- - * Write last write date and time for a file to the disk (to corresponded - * 32bytes node) - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - * - */ -int -msdos_set_dir_wrt_time_and_date( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd - ) -{ - ssize_t ret1 = 0, ret2 = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned short time_val; - unsigned short date; - unsigned32 sec = 0; - unsigned32 byte = 0; - - msdos_date_unix2dos(fat_fd->mtime, &time_val, &date); - - /* - * calculate input for _fat_block_write: convert (cluster num, offset) to - * (sector num, new offset) - */ - sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln); - sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2); - /* byte points to start of 32bytes structure */ - byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1); - - time_val = CT_LE_W(time_val); - ret1 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WTIME_OFFSET, - 2, (char *)(&time_val)); - date = CT_LE_W(date); - ret2 = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_WDATE_OFFSET, - 2, (char *)(&date)); - - if ( (ret1 < 0) || (ret2 < 0) ) - return -1; - - return RC_OK; -} - -/* msdos_set_first_cluster_num -- - * Write number of first cluster of the file to the disk (to corresponded - * 32bytes slot) - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * - * RETURNS: - * RC_OK on success, or -1 if error occured - * - */ -int -msdos_set_first_cluster_num( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd - ) -{ - ssize_t ret1 = 0, ret2 = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 new_cln = fat_fd->cln; - unsigned16 le_cl_low = 0; - unsigned16 le_cl_hi = 0; - unsigned32 sec = 0; - unsigned32 byte = 0; - - /* - * calculate input for _fat_block_write: convert (cluster num, offset) to - * (sector num, new offset) - */ - sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln); - sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2); - /* byte from points to start of 32bytes structure */ - byte = fat_fd->info_ofs & (fs_info->fat.vol.bps - 1); - - le_cl_low = CT_LE_W((unsigned16)(new_cln & 0x0000FFFF)); - ret1 = _fat_block_write(mt_entry, sec, - byte + MSDOS_FIRST_CLUSTER_LOW_OFFSET, 2, - (char *)(&le_cl_low)); - le_cl_hi = CT_LE_W((unsigned16)((new_cln & 0xFFFF0000) >> 16)); - ret2 = _fat_block_write(mt_entry, sec, - byte + MSDOS_FIRST_CLUSTER_HI_OFFSET, 2, - (char *)(&le_cl_hi)); - if ( (ret1 < 0) || (ret2 < 0) ) - return -1; - - return RC_OK; -} - - -/* msdos_set_file size -- - * Write file size of the file to the disk (to corresponded 32bytes slot) - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - * - */ -int -msdos_set_file_size( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd - ) -{ - ssize_t ret = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 le_new_length = 0; - unsigned32 sec = 0; - unsigned32 byte = 0; - - sec = fat_cluster_num_to_sector_num(mt_entry, fat_fd->info_cln); - sec += (fat_fd->info_ofs >> fs_info->fat.vol.sec_log2); - byte = (fat_fd->info_ofs & (fs_info->fat.vol.bps - 1)); - - le_new_length = CT_LE_L((fat_fd->fat_file_size)); - ret = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_SIZE_OFFSET, 4, - (char *)(&le_new_length)); - if ( ret < 0 ) - return -1; - - return RC_OK; -} - -/* - * We should not check whether this routine is called for root dir - it - * never can happend - */ - -/* msdos_set_first_char4file_name -- - * Write first character of the name of the file to the disk (to - * corresponded 32bytes slot) - * - * PARAMETERS: - * mt_entry - mount table entry - * cl - number of cluster - * ofs - offset inside cluster - * fchar - character to set up - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately) - * - */ -int -msdos_set_first_char4file_name( - rtems_filesystem_mount_table_entry_t *mt_entry, - unsigned32 cl, - unsigned32 ofs, - unsigned char fchar - ) -{ - ssize_t ret = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 sec = 0; - unsigned32 byte = 0; - - sec = fat_cluster_num_to_sector_num(mt_entry, cl); - sec += (ofs >> fs_info->fat.vol.sec_log2); - byte = (ofs & (fs_info->fat.vol.bps - 1)); - - ret = _fat_block_write(mt_entry, sec, byte + MSDOS_FILE_NAME_OFFSET, 1, - &fchar); - if ( ret < 0) - return -1; - - return RC_OK; -} - -/* msdos_dir_is_empty -- - * Check whether directory which correspondes to the fat-file descriptor is - * empty. - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * ret_val - placeholder for result - * - * RETURNS: - * RC_OK on success, or -1 if error occured - * - */ -int -msdos_dir_is_empty( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - rtems_boolean *ret_val - ) -{ - ssize_t ret = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 j = 0, i = 0; - - /* dir is not empty */ - *ret_val = FALSE; - - while ((ret = fat_file_read(mt_entry, fat_fd, j * fs_info->fat.vol.bps, - fs_info->fat.vol.bps, - fs_info->cl_buf)) != FAT_EOF) - { - if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - return -1; - - assert(ret == fs_info->fat.vol.bps); - - for (i = 0; - i < fs_info->fat.vol.bps; - i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - { - if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_EMPTY) || - (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), MSDOS_DOT_NAME, - MSDOS_SHORT_NAME_LEN) == 0) || - (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), - MSDOS_DOTDOT_NAME, - MSDOS_SHORT_NAME_LEN) == 0)) - continue; - - if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) - { - *ret_val = TRUE; - return RC_OK; - } - return RC_OK; - } - j++; - } - *ret_val = TRUE; - return RC_OK; -} - - -/* msdos_find_name_in_fat_file -- - * This routine is used in two ways: for a new mode creation (a) or for - * search the node which correspondes to the 'name' parameter (b). - * In case (a) name should be set up to NULL and 'name_dir_entry' should - * point to initialized 32 bytes structure described a new node. - * In case (b) 'name' should contain a valid string. - * - * (a): reading fat-file corresponded to directory we are going to create - * node in. If found free slot write contents of name_dir_entry into - * it. - * - * (b): reading fat-file corresponded to directory and trying to find slot - * with the name field == name parameter - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * name - NULL or name to find - * paux - identify a node location on the disk - - * number of cluster and offset inside the cluster - * name_dir_entry - node to create/placeholder for found node - * - * RETURNS: - * RC_OK on success, or error code if error occured (errno set - * appropriately) - * - */ -int -msdos_find_name_in_fat_file( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - char *name, - fat_auxiliary_t *paux, - char *name_dir_entry - ) -{ - int rc = RC_OK; - ssize_t ret = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 i = 0, j = 0; - unsigned32 bts2rd = 0; - - if (FAT_FD_OF_ROOT_DIR(fat_fd) && - (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16))) - bts2rd = fat_fd->fat_file_size; - else - bts2rd = fs_info->fat.vol.bpc; - - while ((ret = fat_file_read(mt_entry, fat_fd, (j * bts2rd), bts2rd, - fs_info->cl_buf)) != FAT_EOF) - { - if (ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - set_errno_and_return_minus_one(EIO); - - assert(ret == bts2rd); - - for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - { - /* is the entry empty ? */ - if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) || - ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_EMPTY)) - { - /* whether we are looking for an empty entry */ - if (name == NULL) - { - /* get current cluster number */ - rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, - j * bts2rd, &paux->cln); - if (rc != RC_OK) - return rc; - - /* offset is computed in bytes */ - paux->ofs = i; - - /* write new node entry */ - ret = fat_file_write(mt_entry, fat_fd, j * bts2rd + i, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE, - name_dir_entry); - if (ret != MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - return -1; - - /* - * we don't update fat_file_size here - it should not - * increase - */ - return RC_OK; - } - - /* - * if name != NULL and there is no more entries in the - * directory - return name-not-found - */ - if (((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)) - return MSDOS_NAME_NOT_FOUND_ERR; - } - else - { - /* entry not empty and name != NULL -> compare names */ - if (name != NULL) - { - if (strncmp(MSDOS_DIR_NAME((fs_info->cl_buf + i)), name, - MSDOS_SHORT_NAME_LEN) == 0) - { - /* - * we get the entry we looked for - fill auxiliary - * structure and copy all 32 bytes of the entry - */ - rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, - j * bts2rd, &paux->cln); - if (rc != RC_OK) - return rc; - - /* offset is computed in bytes */ - paux->ofs = i; - memcpy(name_dir_entry,(fs_info->cl_buf + i), - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - return RC_OK; - } - } - } - } - j++; - } - return MSDOS_NAME_NOT_FOUND_ERR; -} - -/* msdos_find_node_by_cluster_num_in_fat_file -- - * Find node with specified number of cluster in fat-file. - * - * PARAMETERS: - * mt_entry - mount table entry - * fat_fd - fat-file descriptor - * cl4find - number of cluster to find - * paux - identify a node location on the disk - - * cluster num and offset inside the cluster - * dir_entry - placeholder for found node - * - * RETURNS: - * RC_OK on success, or error code if error occured - * - */ -int -msdos_find_node_by_cluster_num_in_fat_file( - rtems_filesystem_mount_table_entry_t *mt_entry, - fat_file_fd_t *fat_fd, - unsigned32 cl4find, - fat_auxiliary_t *paux, - char *dir_entry - ) -{ - int rc = RC_OK; - ssize_t ret = 0; - msdos_fs_info_t *fs_info = mt_entry->fs_info; - unsigned32 bts2rd = 0; - unsigned32 i = 0, j = 0; - - if (FAT_FD_OF_ROOT_DIR(fat_fd) && - (fs_info->fat.vol.type & (FAT_FAT12 | FAT_FAT16))) - bts2rd = fat_fd->fat_file_size; - else - bts2rd = fs_info->fat.vol.bpc; - - while ((ret = fat_file_read(mt_entry, fat_fd, j * bts2rd, bts2rd, - fs_info->cl_buf)) != FAT_EOF) - { - if ( ret < MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE ) - set_errno_and_return_minus_one( EIO ); - - assert(ret == bts2rd); - - for (i = 0; i < bts2rd; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE) - { - /* if this and all rest entries are empty - return not-found */ - if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY) - return MSDOS_NAME_NOT_FOUND_ERR; - - /* if this entry is empty - skip it */ - if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) == - MSDOS_THIS_DIR_ENTRY_EMPTY) - continue; - - /* if get a non-empty entry - compare clusters num */ - if (MSDOS_EXTRACT_CLUSTER_NUM((fs_info->cl_buf + i)) == cl4find) - { - /* on success fill aux structure and copy all 32 bytes */ - rc = fat_file_ioctl(mt_entry, fat_fd, F_CLU_NUM, j * bts2rd, - &paux->cln); - if (rc != RC_OK) - return rc; - - paux->ofs = i; - memcpy(dir_entry, fs_info->cl_buf + i, - MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); - return RC_OK; - } - } - j++; - } - return MSDOS_NAME_NOT_FOUND_ERR; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_mknod.c b/c/src/exec/libfs/src/dosfs/msdos_mknod.c deleted file mode 100644 index 5e32dbf3bf..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_mknod.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Routine for node creation in MSDOS filesystem. - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> -#include <rtems.h> - -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_mknod -- - * The following function checks spelling and formats name for a new node, - * determines type of the node to be created and creates it. - * - * PARAMETERS: - * token - non-formatted name of a new node - * mode - node type - * dev - dev - * pathloc - parent directory description - * - * RETURNS: - * RC_OK on succes, or -1 if error occured and set errno - * - */ -int -msdos_mknod( - const char *token, - mode_t mode, - dev_t dev, - rtems_filesystem_location_info_t *pathloc - ) -{ - int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = pathloc->mt_entry->fs_info; - msdos_token_types_t type = 0; - char new_name[ MSDOS_NAME_MAX + 1 ]; - int len; - - /* check spelling and format new node name */ - msdos_get_token(token, new_name, &len); - - /* - * Figure out what type of msdos node this is. - */ - if (S_ISDIR(mode)) - { - type = MSDOS_DIRECTORY; - } - else if (S_ISREG(mode)) - { - type = MSDOS_REGULAR_FILE; - } - else - set_errno_and_return_minus_one(EINVAL); - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - set_errno_and_return_minus_one(EIO); - - /* Create an MSDOS node */ - rc = msdos_creat_node(pathloc, type, new_name, mode); - - rtems_semaphore_release(fs_info->vol_sema); - return rc; -} diff --git a/c/src/exec/libfs/src/dosfs/msdos_node_type.c b/c/src/exec/libfs/src/dosfs/msdos_node_type.c deleted file mode 100644 index 517dabda3f..0000000000 --- a/c/src/exec/libfs/src/dosfs/msdos_node_type.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * The following returns the type of node that the loc refers to. - * - * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia - * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.OARcorp.com/rtems/license.html. - * - * @(#) $Id$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <stdlib.h> -#include <rtems.h> - -#include <rtems/libio_.h> - -#include "fat.h" -#include "fat_fat_operations.h" -#include "fat_file.h" - -#include "msdos.h" - -/* msdos_node_type -- - * Determine type of the node that the pathloc refers to. - * - * PARAMETERS: - * pathloc - node description - * - * RETURNS: - * node type - * - */ -rtems_filesystem_node_types_t -msdos_node_type(rtems_filesystem_location_info_t *pathloc) -{ - fat_file_fd_t *fat_fd; - - /* - * we don't need to obtain the volume semaphore here because node_type_h - * call always follows evalpath_h call(hence link increment occured) and - * hence node_access memory can't be freed during processing node_type_h - * call - */ - fat_fd = pathloc->node_access; - - return fat_fd->fat_file_type; -} |