2009-04-29 Chris Johns <chrisj@rtems.org>

* libcsupport/include/rtems/libio.h: Add rtems_off64_t for
        internal use. Update the internal off_t to the 64bit offset.

        * libnetworking/lib/ftpfs.c, libnetworking/lib/tftpDriver.c,
        libfs/src/nfsclient/src/nfs.c, libfs/src/imfs/imfs_fifo.c,
        libfs/src/imfs/memfile.c, libfs/src/imfs/imfs_directory.c,
        libfs/src/imfs/imfs.h, libfs/src/imfs/deviceio.c: Change off_t to
        rtems_off64_t.

        * libmisc/shell/main_msdosfmt.c: Add an info level so the format
        code can tell the user what is happening. Add more options to
        control the format configuration.

        * libfs/src/dosfs/msdos_format.c: Add a print function to display
        the format progress and print statements. Select a better default
        cluster size depending on the size of the disk. This lowers the
        size of the FAT on large disks. Read and maintain the MRB
        partition information.

        * libfs/src/dosfs/dosfs.h, libfs/src/dosfs/fat.h,
        libfs/src/dosfs/fat_file.c, libfs/src/dosfs/fat_file.h,
        libfs/src/dosfs/msdos.h, libfs/src/dosfs/msdos_conv.c,
        libfs/src/dosfs/msdos_create.c, libfs/src/dosfs/msdos_file.c,
        libfs/src/dosfs/msdos_handlers_dir.c,
        libfs/src/dosfs/msdos_handlers_file.c,
        libfs/src/dosfs/msdos_init.c, libfs/src/dosfs/msdos_initsupp.c,
        libfs/src/dosfs/msdos_misc.c, libfs/src/dosfs/msdos_mknod.c: Add
        long file name support. Change off_t to rtems_off64_t.
This commit is contained in:
Chris Johns
2009-04-29 08:31:27 +00:00
parent 8c44190a91
commit 07d6fd513f
27 changed files with 1761 additions and 598 deletions

View File

@@ -39,6 +39,11 @@
extern "C" {
#endif
/*
* A 64bit file offset for internal use by RTEMS. Based on the newlib type.
*/
typedef _off64_t rtems_off64_t;
/*
* Valid RTEMS file types.
*/
@@ -83,9 +88,9 @@ typedef int (*rtems_filesystem_ioctl_t)(
void *buffer
);
typedef off_t (*rtems_filesystem_lseek_t)(
typedef rtems_off64_t (*rtems_filesystem_lseek_t)(
rtems_libio_t *iop,
off_t length,
rtems_off64_t length,
int whence
);
@@ -101,7 +106,7 @@ typedef int (*rtems_filesystem_fchmod_t)(
typedef int (*rtems_filesystem_ftruncate_t)(
rtems_libio_t *iop,
off_t length
rtems_off64_t length
);
typedef int (*rtems_filesystem_fpathconf_t)(
@@ -347,8 +352,8 @@ typedef enum
struct rtems_libio_tt {
rtems_driver_name_t *driver;
off_t size; /* size of file */
off_t offset; /* current offset into file */
rtems_off64_t size; /* size of file */
rtems_off64_t offset; /* current offset into file */
uint32_t flags;
rtems_filesystem_location_info_t pathinfo;
rtems_id sem;
@@ -366,7 +371,7 @@ struct rtems_libio_tt {
typedef struct {
rtems_libio_t *iop;
off_t offset;
rtems_off64_t offset;
char *buffer;
uint32_t count;
uint32_t flags;
@@ -441,10 +446,10 @@ typedef int (*rtems_libio_ioctl_t)(
void *buffer
);
typedef int (*rtems_libio_lseek_t)(
int fd,
off_t offset,
int whence
typedef rtems_off64_t (*rtems_libio_lseek_t)(
int fd,
rtems_off64_t offset,
int whence
);
/*

View File

@@ -32,6 +32,11 @@ extern rtems_filesystem_operations_table msdos_ops;
#define MSDOS_FMT_FAT16 2
#define MSDOS_FMT_FAT32 3
#define MSDOS_FMT_INFO_LEVEL_NONE (0)
#define MSDOS_FMT_INFO_LEVEL_INFO (1)
#define MSDOS_FMT_INFO_LEVEL_DETAIL (2)
#define MSDOS_FMT_INFO_LEVEL_DEBUG (3)
/*
* data to be filled out for formatter: parameters for format call
* any parameter set to 0 or NULL will be automatically detected/computed
@@ -51,6 +56,7 @@ typedef struct {
/* value. This can optimize clusters */
/* to be located at start of track */
/* or start of flash block */
int info_level; /* The amount of info to output */
} msdos_format_request_param_t;
/*=========================================================================*\

View File

@@ -250,7 +250,7 @@ extern "C" {
#define FAT_GET_FSINFO_TRAIL_SIGNATURE(x) FAT_GET_VAL32(x,508)
#define FAT_SET_FSINFO_TRAIL_SIGNATURE(x,val) FAT_SET_VAL32(x,508,val)
#define FAT_FSINFO_TRAIL_SIGNATURE_VALUE (0x000055AA)
#define FAT_FSINFO_TRAIL_SIGNATURE_VALUE (0xAA550000)
/*
* I read FSInfo sector from offset 484 to access the information, so offsets
* of these fields a relative
@@ -351,15 +351,31 @@ typedef struct fat_fs_info_s
} 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
* FAT position is a the cluster and the offset into the
* cluster.
*/
typedef struct fat_auxiliary_s
typedef struct fat_pos_s
{
uint32_t cln;
uint32_t ofs;
} fat_auxiliary_t;
} fat_pos_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. We also add the LFN start offset so we can delete it the whole
* file name. We can then use this to delete the file.
*/
typedef struct fat_dir_pos_s
{
fat_pos_t sname;
fat_pos_t lname;
} fat_dir_pos_t;
/*
* Set the long name entries to this value for a short file name.
*/
#define FAT_FILE_SHORT_NAME (0xffffffff)
#define FAT_FAT_OFFSET(fat_type, cln) \
((fat_type) & FAT_FAT12 ? ((cln) + ((cln) >> 1)) : \
@@ -380,6 +396,17 @@ typedef struct fat_auxiliary_s
#define FAT_OP_TYPE_READ 0x1
#define FAT_OP_TYPE_GET 0x2
static inline void
fat_dir_pos_init(
fat_dir_pos_t *dir_pos
)
{
dir_pos->sname.cln = 0;
dir_pos->sname.ofs = 0;
dir_pos->lname.cln = FAT_FILE_SHORT_NAME;
dir_pos->lname.ofs = FAT_FILE_SHORT_NAME;
}
static inline uint32_t
fat_cluster_num_to_sector_num(
rtems_filesystem_mount_table_entry_t *mt_entry,

View File

@@ -33,20 +33,20 @@
#include "fat_file.h"
static inline void
_hash_insert(Chain_Control *hash, uint32_t key1, uint32_t key2,
_hash_insert(rtems_chain_control *hash, uint32_t key1, uint32_t key2,
fat_file_fd_t *el);
static inline void
_hash_delete(Chain_Control *hash, uint32_t key1, uint32_t key2,
_hash_delete(rtems_chain_control *hash, uint32_t key1, uint32_t key2,
fat_file_fd_t *el);
static inline int
_hash_search(
rtems_filesystem_mount_table_entry_t *mt_entry,
Chain_Control *hash,
rtems_chain_control *hash,
uint32_t key1,
uint32_t key2,
fat_file_fd_t **ret
fat_file_fd_t **ret
);
static off_t
@@ -75,8 +75,7 @@ fat_file_lseek(
*
* PARAMETERS:
* mt_entry - mount table entry
* cln - cluster num of the node
* ofs - offset of the node
* pos - cluster and offset of the node
* fat_fd - placeholder for returned fat-file descriptor
*
* RETURNS:
@@ -86,8 +85,7 @@ fat_file_lseek(
int
fat_file_open(
rtems_filesystem_mount_table_entry_t *mt_entry,
uint32_t cln,
uint32_t ofs,
fat_dir_pos_t *dir_pos,
fat_file_fd_t **fat_fd
)
{
@@ -97,7 +95,7 @@ fat_file_open(
uint32_t key = 0;
/* construct key */
key = fat_construct_key(mt_entry, cln, ofs);
key = fat_construct_key(mt_entry, &dir_pos->sname);
/* access "valid" hash table */
rc = _hash_search(mt_entry, fs_info->vhash, key, 0, &lfat_fd);
@@ -116,10 +114,14 @@ fat_file_open(
if ( lfat_fd == NULL )
rtems_set_errno_and_return_minus_one( ENOMEM );
memset(lfat_fd, 0, sizeof(fat_file_fd_t));
lfat_fd->links_num = 1;
lfat_fd->flags &= ~FAT_FILE_REMOVED;
lfat_fd->map.last_cln = FAT_UNDEFINED_VALUE;
lfat_fd->dir_pos = *dir_pos;
if ( rc != RC_OK )
lfat_fd->ino = key;
else
@@ -138,7 +140,6 @@ fat_file_open(
}
_hash_insert(fs_info->vhash, key, lfat_fd->ino, lfat_fd);
/*
* other fields of fat-file descriptor will be initialized on upper
* level
@@ -203,7 +204,7 @@ fat_file_close(
return rc;
}
key = fat_construct_key(mt_entry, fat_fd->info_cln, fat_fd->info_ofs);
key = fat_construct_key(mt_entry, &fat_fd->dir_pos.sname);
if (fat_fd->flags & FAT_FILE_REMOVED)
{
@@ -582,6 +583,8 @@ fat_file_extend(
}
}
fat_fd->fat_file_size = new_length;
return RC_OK;
}
@@ -736,7 +739,7 @@ fat_file_mark_removed(
fat_fs_info_t *fs_info = mt_entry->fs_info;
uint32_t key = 0;
key = fat_construct_key(mt_entry, fat_fd->info_cln, fat_fd->info_ofs);
key = fat_construct_key(mt_entry, &fat_fd->dir_pos.sname);
_hash_delete(fs_info->vhash, key, fat_fd->ino, fat_fd);
@@ -869,10 +872,10 @@ fat_file_size(
* None
*/
static inline void
_hash_insert(Chain_Control *hash, uint32_t key1, uint32_t key2,
_hash_insert(rtems_chain_control *hash, uint32_t key1, uint32_t key2,
fat_file_fd_t *el)
{
_Chain_Append((hash) + ((key1) % FAT_HASH_MODULE), &(el)->link);
rtems_chain_append((hash) + ((key1) % FAT_HASH_MODULE), &(el)->link);
}
@@ -889,10 +892,10 @@ _hash_insert(Chain_Control *hash, uint32_t key1, uint32_t key2,
* None
*/
static inline void
_hash_delete(Chain_Control *hash, uint32_t key1, uint32_t key2,
_hash_delete(rtems_chain_control *hash, uint32_t key1, uint32_t key2,
fat_file_fd_t *el)
{
_Chain_Extract(&(el)->link);
rtems_chain_extract(&(el)->link);
}
/* _hash_search --
@@ -912,20 +915,19 @@ _hash_delete(Chain_Control *hash, uint32_t key1, uint32_t key2,
static inline int
_hash_search(
rtems_filesystem_mount_table_entry_t *mt_entry,
Chain_Control *hash,
rtems_chain_control *hash,
uint32_t key1,
uint32_t key2,
fat_file_fd_t **ret
)
{
uint32_t mod = (key1) % FAT_HASH_MODULE;
Chain_Node *the_node = ((Chain_Control *)((hash) + mod))->first;
uint32_t mod = (key1) % FAT_HASH_MODULE;
rtems_chain_node *the_node = ((rtems_chain_control *)((hash) + mod))->first;
for ( ; !_Chain_Is_tail((hash) + mod, the_node) ; )
for ( ; !rtems_chain_is_tail((hash) + mod, the_node) ; )
{
fat_file_fd_t *ffd = (fat_file_fd_t *)the_node;
uint32_t ck =
fat_construct_key(mt_entry, ffd->info_cln, ffd->info_ofs);
uint32_t ck = fat_construct_key(mt_entry, &ffd->dir_pos.sname);
if ( (key1) == ck)
{

View File

@@ -20,6 +20,8 @@
#include <time.h>
#include "fat.h"
#ifdef __cplusplus
extern "C" {
#endif
@@ -57,30 +59,27 @@ typedef struct fat_file_map_s
*/
typedef struct fat_file_fd_s
{
Chain_Node link; /*
* fat-file descriptors organized into hash;
* collision lists are handled via link
* field
*/
uint32_t links_num; /*
* the number of fat_file_open call on
* this fat-file
*/
uint32_t ino; /* inode, file serial number :)))) */
fat_file_type_t fat_file_type;
uint32_t size_limit;
uint32_t fat_file_size; /* length */
uint32_t info_cln;
uint32_t cln;
uint16_t info_ofs;
unsigned char first_char;
uint8_t flags;
fat_file_map_t map;
time_t mtime;
rtems_chain_node link; /*
* fat-file descriptors organized into hash;
* collision lists are handled via link
* field
*/
uint32_t links_num; /*
* the number of fat_file_open call on
* this fat-file
*/
uint32_t ino; /* inode, file serial number :)))) */
fat_file_type_t fat_file_type;
uint32_t size_limit;
uint32_t fat_file_size; /* length */
uint32_t cln;
fat_dir_pos_t dir_pos;
uint8_t flags;
fat_file_map_t map;
time_t mtime;
} fat_file_fd_t;
#define FAT_FILE_REMOVED 0x01
#define FAT_FILE_IS_REMOVED(p)\
@@ -101,8 +100,8 @@ typedef struct fat_file_fd_s
#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))
((fat_fd->dir_pos.sname.cln == FAT_ROOTDIR_CLUSTER_NUM) && \
(fat_fd->dir_pos.sname.ofs == 0))
#define FAT_EOF 0x00
@@ -122,19 +121,17 @@ typedef struct fat_file_fd_s
static inline uint32_t
fat_construct_key(
rtems_filesystem_mount_table_entry_t *mt_entry,
uint32_t cl,
uint32_t ofs)
fat_pos_t *pos)
{
return ( ((fat_cluster_num_to_sector512_num(mt_entry, cl) +
(ofs >> FAT_SECTOR512_BITS)) << 4) +
((ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) );
return ( ((fat_cluster_num_to_sector512_num(mt_entry, pos->cln) +
(pos->ofs >> FAT_SECTOR512_BITS)) << 4) +
((pos->ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) );
}
/* Prototypes for "fat-file" operations */
int
fat_file_open(rtems_filesystem_mount_table_entry_t *mt_entry,
uint32_t cln,
uint32_t ofs,
fat_dir_pos_t *dir_pos,
fat_file_fd_t **fat_fd);
int

View File

@@ -84,8 +84,10 @@ typedef rtems_filesystem_node_types_t msdos_node_type_t;
#define MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE 32 /* 32 bytes */
#define MSDOS_DIR_NAME(x) (char *)((x) + 0)
#define MSDOS_DIR_ENTRY_TYPE(x) (uint8_t *)((x) + 0)
#define MSDOS_DIR_ATTR(x) (uint8_t *)((x) + 11)
#define MSDOS_DIR_NT_RES(x) (uint8_t *)((x) + 12)
#define MSDOS_DIR_LFN_CHECKSUM(x) (uint8_t *)((x) + 13)
#define MSDOS_DIR_CRT_TIME_TENTH(x) (uint8_t *)((x) + 13)
#define MSDOS_DIR_CRT_TIME(x) (uint16_t *)((x) + 14)
#define MSDOS_DIR_CRT_DATE(x) (uint16_t *)((x) + 16)
@@ -121,6 +123,19 @@ typedef rtems_filesystem_node_types_t msdos_node_type_t;
#define MSDOS_ATTR_VOLUME_ID 0x08
#define MSDOS_ATTR_DIRECTORY 0x10
#define MSDOS_ATTR_ARCHIVE 0x20
#define MSDOS_ATTR_LFN (MSDOS_ATTR_READ_ONLY | \
MSDOS_ATTR_HIDDEN | \
MSDOS_ATTR_SYSTEM | \
MSDOS_ATTR_VOLUME_ID)
#define MSDOS_ATTR_LFN_MASK (MSDOS_ATTR_READ_ONLY | \
MSDOS_ATTR_HIDDEN | \
MSDOS_ATTR_SYSTEM | \
MSDOS_ATTR_VOLUME_ID | \
MSDOS_ATTR_DIRECTORY | \
MSDOS_ATTR_ARCHIVE)
#define MSDOS_LAST_LONG_ENTRY 0x40
#define MSDOS_LAST_LONG_ENTRY_MASK 0x3F
#define MSDOS_DT_2SECONDS_MASK 0x1F /* seconds divided by 2 */
#define MSDOS_DT_2SECONDS_SHIFT 0
@@ -144,22 +159,35 @@ typedef rtems_filesystem_node_types_t msdos_node_type_t;
#define MSDOS_THIS_DIR_ENTRY_EMPTY 0xE5
#define MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY 0x00
/*
* Number of characters per directory entry for a long filename.
*/
#define MSDOS_LFN_LEN_PER_ENTRY (13)
/*
* 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_BASE_LEN 8 /* 8 characters */
#define MSDOS_SHORT_EXT_LEN 3 /* 3 characters */
#define MSDOS_SHORT_NAME_LEN (MSDOS_SHORT_BASE_LEN+\
MSDOS_SHORT_EXT_LEN) /* 11 chars */
#define MSDOS_NAME_MAX_LNF_LEN (255)
#define MSDOS_NAME_MAX MSDOS_SHORT_NAME_LEN
#define MSDOS_NAME_MAX_WITH_DOT (MSDOS_NAME_MAX + 1)
#define MSDOS_NAME_MAX_LFN_WITH_DOT (260)
#define MSDOS_DOT_NAME ". " /* ".", padded to MSDOS_NAME chars */
#define MSDOS_DOTDOT_NAME ".. " /* "..", padded to MSDOS_NAME chars */
extern const char const* MSDOS_DOT_NAME; /* ".", padded to MSDOS_NAME chars */
extern const char const* MSDOS_DOTDOT_NAME; /* ".", padded to MSDOS_NAME chars */
typedef enum msdos_name_types_e
{
MSDOS_NAME_INVALID = 0, /* Unknown name type. Has invalid characters. */
MSDOS_NAME_SHORT, /* Name can be short. */
MSDOS_NAME_LONG /* Name is long; cannot be short. */
} msdos_name_type_t;
typedef enum msdos_token_types_e
{
@@ -258,9 +286,9 @@ ssize_t msdos_file_write(
size_t count /* IN */
);
off_t msdos_file_lseek(
rtems_off64_t msdos_file_lseek(
rtems_libio_t *iop, /* IN */
off_t offset, /* IN */
rtems_off64_t offset, /* IN */
int whence /* IN */
);
@@ -272,7 +300,7 @@ int msdos_file_stat(
int
msdos_file_ftruncate(
rtems_libio_t *iop, /* IN */
off_t length /* IN */
rtems_off64_t length /* IN */
);
int msdos_file_sync(rtems_libio_t *iop);
@@ -285,6 +313,12 @@ int msdos_file_ioctl(
void *buffer /* IN */
);
int
msdos_dir_chmod(
rtems_filesystem_location_info_t *pathloc, /* IN */
mode_t mode /* IN */
);
int msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */);
int msdos_file_link(
@@ -308,12 +342,18 @@ ssize_t msdos_dir_read(
size_t count /* IN */
);
off_t msdos_dir_lseek(
rtems_off64_t msdos_dir_lseek(
rtems_libio_t *iop, /* IN */
off_t offset, /* IN */
rtems_off64_t offset, /* IN */
int whence /* IN */
);
int
msdos_file_chmod(
rtems_filesystem_location_info_t *pathloc, /* IN */
mode_t mode /* IN */
);
int msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */);
int msdos_dir_sync(rtems_libio_t *iop);
@@ -324,31 +364,39 @@ int msdos_dir_stat(
);
int msdos_creat_node(rtems_filesystem_location_info_t *parent_loc,
msdos_node_type_t type,
char *name,
mode_t mode,
const fat_file_fd_t *link_fd);
msdos_node_type_t type,
const char *name,
int name_len,
mode_t mode,
const fat_file_fd_t *link_fd);
/* Misc prototypes */
msdos_token_types_t msdos_get_token(const char *path,
char *token,
int *token_len);
msdos_token_types_t msdos_get_token(const char *path,
const char **token,
int *token_len);
int msdos_find_name(
rtems_filesystem_location_info_t *parent_loc,
char *name
const char *name,
int name_len
);
int msdos_get_name_node(
rtems_filesystem_location_info_t *parent_loc,
char *name,
fat_auxiliary_t *paux,
bool create_node,
const char *name,
int name_len,
msdos_name_type_t name_type,
fat_dir_pos_t *dir_pos,
char *name_dir_entry
);
int msdos_dir_info_remove(rtems_filesystem_location_info_t *pathloc);
int msdos_filename_unix2dos(char *un, int unlen, char *dn);
msdos_name_type_t msdos_long_to_short(const char *lfn, int lfn_len,
char* sfn, int sfn_len);
int msdos_filename_unix2dos(const char *un, int unlen, char *dn);
void msdos_date_unix2dos(
unsigned int tsp, unsigned short *ddp,
@@ -368,9 +416,8 @@ int msdos_set_file_size(
int msdos_set_first_char4file_name(
rtems_filesystem_mount_table_entry_t *mt_entry,
uint32_t cl,
uint32_t ofs,
unsigned char first_char
fat_dir_pos_t *dir_pos,
unsigned char first_char
);
int msdos_set_dir_wrt_time_and_date(
@@ -388,8 +435,11 @@ int msdos_dir_is_empty(
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,
bool create_node,
const char *name,
int name_len,
msdos_name_type_t name_type,
fat_dir_pos_t *dir_pos,
char *name_dir_entry
);
@@ -397,14 +447,14 @@ int msdos_find_node_by_cluster_num_in_fat_file(
rtems_filesystem_mount_table_entry_t *mt_entry,
fat_file_fd_t *fat_fd,
uint32_t cl4find,
fat_auxiliary_t *paux,
fat_dir_pos_t *dir_pos,
char *dir_entry
);
int msdos_get_dotdot_dir_info_cluster_num_and_offset(
rtems_filesystem_mount_table_entry_t *mt_entry,
uint32_t cln,
fat_auxiliary_t *paux,
fat_dir_pos_t *dir_pos,
char *dir_entry
);

View File

@@ -169,6 +169,39 @@ msdos_date_dos2unix(unsigned int dd, unsigned int dt)
}
static const uint8_t msdos_map[] = {
0, 0, 0, 0, 0, 0, 0, 0, /* 00-07 */
0, 0, 0, 0, 0, 0, 0, 0, /* 08-0f */
0, 0, 0, 0, 0, 0, 0, 0, /* 10-17 */
0, 0, 0, 0, 0, 0, 0, 0, /* 18-1f */
0, '!', 0, '#', '$', '%', '&', '\'', /* 20-27 */
'(', ')', 0, '+', 0, '-', 0, 0, /* 28-2f */
'0', '1', '2', '3', '4', '5', '6', '7', /* 30-37 */
'8', '9', 0, 0, 0, 0, 0, 0, /* 38-3f */
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 40-47 */
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 48-4f */
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 50-57 */
'X', 'Y', 'Z', 0, 0, 0, '^', '_', /* 58-5f */
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 60-67 */
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 68-6f */
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 70-77 */
'X', 'Y', 'Z', '{', 0, '}', '~', 0, /* 78-7f */
0, 0, 0, 0, 0, 0, 0, 0, /* 80-87 */
0, 0, 0, 0, 0, 0, 0, 0, /* 88-8f */
0, 0, 0, 0, 0, 0, 0, 0, /* 90-97 */
0, 0, 0, 0, 0, 0, 0, 0, /* 98-9f */
0, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* a0-a7 */
0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* a8-af */
0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* b0-b7 */
0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* b8-bf */
0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* c0-c7 */
0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* c8-cf */
0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, /* d0-d7 */
0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, /* d8-df */
0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* e0-e7 */
0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* e8-ef */
0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0xf6, /* f0-f7 */
0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0x98, /* f8-ff */
#if OLD_TABLE
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -201,13 +234,14 @@ static const uint8_t msdos_map[] = {
/* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif
};
/*
* Convert a unix filename to a DOS filename. Return -1 if wrong name is
* supplied.
*/
int
msdos_filename_unix2dos(char *un, int unlen, char *dn)
msdos_filename_unix2dos(const char *un, int unlen, char *dn)
{
int i;
uint8_t c;
@@ -233,6 +267,14 @@ msdos_filename_unix2dos(char *un, int unlen, char *dn)
return 0;
}
/*
* Remove any dots from the start of a file name.
*/
while (unlen && (*un == '.')) {
un++;
unlen--;
}
/*
* Copy the unix filename into the dos filename string upto the end
* of string, a '.', or 8 characters. Whichever happens first stops
@@ -240,8 +282,9 @@ msdos_filename_unix2dos(char *un, int unlen, char *dn)
* upper case.
*/
for (i = 0; i <= 7 && unlen && (c = *un) && c != '.'; i++) {
if ((dn[i] = msdos_map[c]) == 0)
return -1;
if (msdos_map[c] == 0)
break;
dn[i] = msdos_map[c];
un++;
unlen--;
}
@@ -264,8 +307,9 @@ msdos_filename_unix2dos(char *un, int unlen, char *dn)
* Filenames in this form are probably inaccessable under dos.
*/
for (i = 8; i <= 10 && unlen && (c = *un); i++) {
if ((dn[i] = msdos_map[c]) == 0)
return -1;
if (msdos_map[c] == 0)
break;
dn[i] = msdos_map[c];
un++;
unlen--;
}

View File

@@ -17,6 +17,7 @@
#include <errno.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtems/libio_.h>
@@ -29,7 +30,14 @@
#include "msdos.h"
/* msdos_creat_node --
* Create a new node. If a new node is file, FAT 32 Bytes Directory
* Create a new node. Determine if the name is a long name. If long we to
* scan the directory to create a short entry.
*
*
* If a new node is file, FAT 32 Bytes Directory
* Entry Structure 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
@@ -48,52 +56,55 @@
*
*/
int
msdos_creat_node(
rtems_filesystem_location_info_t *parent_loc,
msdos_node_type_t type,
char *name,
mode_t mode,
const fat_file_fd_t *link_fd
)
msdos_creat_node(rtems_filesystem_location_info_t *parent_loc,
msdos_node_type_t type,
const char *name,
int name_len,
mode_t mode,
const fat_file_fd_t *link_fd)
{
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;
uint16_t time_val = 0;
uint16_t date = 0;
fat_auxiliary_t aux;
char new_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2];
char link_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
uint32_t sec = 0;
uint32_t byte = 0;
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;
uint16_t time_val = 0;
uint16_t date = 0;
fat_dir_pos_t dir_pos;
msdos_name_type_t name_type;
char short_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2];
char link_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
uint32_t sec = 0;
uint32_t byte = 0;
memset(new_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
fat_dir_pos_init(&dir_pos);
memset(short_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);
name_type = msdos_long_to_short (name, name_len,
MSDOS_DIR_NAME(short_node),
MSDOS_NAME_MAX);
/* fill reserved field */
*MSDOS_DIR_NT_RES(new_node) = MSDOS_RES_NT_VALUE;
*MSDOS_DIR_NT_RES(short_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);
msdos_date_unix2dos(time_ret, &date, &time_val);
*MSDOS_DIR_WRITE_TIME(short_node) = CT_LE_W(time_val);
*MSDOS_DIR_WRITE_DATE(short_node) = CT_LE_W(date);
/* initialize directory/file size */
*MSDOS_DIR_FILE_SIZE(new_node) = MSDOS_INIT_DIR_SIZE;
*MSDOS_DIR_FILE_SIZE(short_node) = MSDOS_INIT_DIR_SIZE;
if (type == MSDOS_DIRECTORY){
*MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_DIRECTORY;
if (type == MSDOS_DIRECTORY) {
*MSDOS_DIR_ATTR(short_node) |= MSDOS_ATTR_DIRECTORY;
}
else if (type == MSDOS_HARD_LINK) {
/*
@@ -105,51 +116,52 @@ msdos_creat_node(
* read the original directory entry
*/
sec = fat_cluster_num_to_sector_num(parent_loc->mt_entry,
link_fd->info_cln);
sec += (link_fd->info_ofs >> fs_info->fat.vol.sec_log2);
byte = (link_fd->info_ofs & (fs_info->fat.vol.bps - 1));
link_fd->dir_pos.sname.cln);
sec += (link_fd->dir_pos.sname.ofs >> fs_info->fat.vol.sec_log2);
byte = (link_fd->dir_pos.sname.ofs & (fs_info->fat.vol.bps - 1));
ret = _fat_block_read(parent_loc->mt_entry,
sec, byte, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
sec, byte, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
link_node);
if (ret < 0) {
return -1;
return -1;
}
/*
* copy various attributes
*/
*MSDOS_DIR_ATTR(new_node) =*MSDOS_DIR_ATTR(link_node);
*MSDOS_DIR_CRT_TIME_TENTH(new_node)=*MSDOS_DIR_CRT_TIME_TENTH(link_node);
*MSDOS_DIR_CRT_TIME(new_node) =*MSDOS_DIR_CRT_TIME(link_node);
*MSDOS_DIR_CRT_DATE(new_node) =*MSDOS_DIR_CRT_DATE(link_node);
*MSDOS_DIR_ATTR(short_node) =*MSDOS_DIR_ATTR(link_node);
*MSDOS_DIR_CRT_TIME_TENTH(short_node)=*MSDOS_DIR_CRT_TIME_TENTH(link_node);
*MSDOS_DIR_CRT_TIME(short_node) =*MSDOS_DIR_CRT_TIME(link_node);
*MSDOS_DIR_CRT_DATE(short_node) =*MSDOS_DIR_CRT_DATE(link_node);
/*
* copy/set "file size", "first cluster"
*/
*MSDOS_DIR_FILE_SIZE(new_node) =*MSDOS_DIR_FILE_SIZE(link_node);
*MSDOS_DIR_FILE_SIZE(short_node) =*MSDOS_DIR_FILE_SIZE(link_node);
*MSDOS_DIR_FIRST_CLUSTER_LOW(new_node) =
*MSDOS_DIR_FIRST_CLUSTER_LOW(short_node) =
*MSDOS_DIR_FIRST_CLUSTER_LOW(link_node);
*MSDOS_DIR_FIRST_CLUSTER_HI(new_node) =
*MSDOS_DIR_FIRST_CLUSTER_HI(short_node) =
*MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
/*
* set "archive bit" due to changes
*/
*MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
*MSDOS_DIR_ATTR(short_node) |= MSDOS_ATTR_ARCHIVE;
/*
* set "last access" date to today
*/
*MSDOS_DIR_LAST_ACCESS_DATE(new_node) = CT_LE_W(date);
*MSDOS_DIR_LAST_ACCESS_DATE(short_node) = CT_LE_W(date);
}
else { /* regular file... */
*MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
*MSDOS_DIR_ATTR(short_node) |= MSDOS_ATTR_ARCHIVE;
}
/*
* find free space in the parent directory and write new initialized
* FAT 32 Bytes Directory Entry Structure to the disk
*/
rc = msdos_get_name_node(parent_loc, NULL, &aux, new_node);
rc = msdos_get_name_node(parent_loc, true, name, name_len,
name_type, &dir_pos, short_node);
if ( rc != RC_OK )
return rc;
@@ -160,7 +172,7 @@ msdos_creat_node(
if (type == MSDOS_DIRECTORY)
{
/* open new directory as fat-file */
rc = fat_file_open(parent_loc->mt_entry, aux.cln, aux.ofs, &fat_fd);
rc = fat_file_open(parent_loc->mt_entry, &dir_pos, &fat_fd);
if (rc != RC_OK)
goto err;
@@ -168,8 +180,6 @@ msdos_creat_node(
* 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;
@@ -178,9 +188,9 @@ msdos_creat_node(
* dot and dotdot entries are identical to new node except the
* names
*/
memcpy(DOT_NODE_P(dot_dotdot), new_node,
memcpy(DOT_NODE_P(dot_dotdot), short_node,
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
memcpy(DOTDOT_NODE_P(dot_dotdot), new_node,
memcpy(DOTDOT_NODE_P(dot_dotdot), short_node,
MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
memcpy(MSDOS_DIR_NAME(DOT_NODE_P(dot_dotdot)), MSDOS_DOT_NAME,
MSDOS_NAME_MAX);
@@ -253,9 +263,8 @@ 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);
/* mark the used 32bytes structure on the disk as free */
msdos_set_first_char4file_name(parent_loc->mt_entry, &dir_pos, 0xE5);
return rc;
}
@@ -287,21 +296,21 @@ err:
*/
int
msdos_file_link(rtems_filesystem_location_info_t *to_loc,
rtems_filesystem_location_info_t *par_loc,
const char *token
rtems_filesystem_location_info_t *par_loc,
const char *name
)
{
int rc = RC_OK;
rtems_status_code sc = RTEMS_SUCCESSFUL;
msdos_fs_info_t *fs_info = to_loc->mt_entry->fs_info;
fat_file_fd_t *to_fat_fd = to_loc->node_access;
char new_name[ MSDOS_NAME_MAX + 1 ];
const char *token;
int len;
/*
* check spelling and format new node name
*/
if (MSDOS_NAME != msdos_get_token(token, new_name, &len)) {
if (MSDOS_NAME != msdos_get_token(name, &token, &len)) {
rtems_set_errno_and_return_minus_one(ENAMETOOLONG);
}
/*
@@ -324,8 +333,8 @@ msdos_file_link(rtems_filesystem_location_info_t *to_loc,
* create new directory entry as "hard link",
* copying relevant info from existing file
*/
rc = msdos_creat_node(par_loc,MSDOS_HARD_LINK,new_name,S_IFREG,
to_loc->node_access);
rc = msdos_creat_node(par_loc,MSDOS_HARD_LINK,name,len,S_IFREG,
to_loc->node_access);
/*
* set file size and first cluster number of old entry to 0
*/

View File

@@ -14,6 +14,7 @@
#include "config.h"
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
@@ -145,7 +146,7 @@ msdos_format_dirent_with_dot(char *dst,const char *src)
src_tmp = src;
len = i;
while (i-- > 0) {
*dst++ = *src_tmp++;
*dst++ = tolower(*src_tmp++);
}
/*
* find last non-blank character of extension
@@ -164,7 +165,7 @@ msdos_format_dirent_with_dot(char *dst,const char *src)
len += i + 1; /* extension + dot */
src_tmp = src + MSDOS_SHORT_BASE_LEN;
while (i-- > 0) {
*dst++ = *src_tmp++;
*dst++ = tolower(*src_tmp++);
len++;
}
}
@@ -210,6 +211,9 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
uint32_t j = 0, i = 0;
uint32_t bts2rd = 0;
uint32_t cur_cln = 0;
uint32_t lfn_start = FAT_FILE_SHORT_NAME;
uint8_t lfn_checksum = 0;
int lfn_entries = 0;
/*
* cast start and count - protect against using sizes that are not exact
@@ -253,80 +257,211 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
for (i = 0; i < ret; i += MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE)
{
if ((*MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
char* entry = (char*) fs_info->cl_buf + i;
/*
* Is this directory from here on empty ?
*/
if ((*MSDOS_DIR_ENTRY_TYPE(entry)) ==
MSDOS_THIS_DIR_ENTRY_AND_REST_EMPTY)
{
rtems_semaphore_release(fs_info->vol_sema);
return cmpltd;
}
/* have to look at the DIR_NAME as "raw" 8-bit data */
if ((*(uint8_t *)MSDOS_DIR_NAME(fs_info->cl_buf + i)) ==
MSDOS_THIS_DIR_ENTRY_EMPTY)
/* Is the directory entry empty */
if ((*MSDOS_DIR_ENTRY_TYPE(entry)) == MSDOS_THIS_DIR_ENTRY_EMPTY)
continue;
/* Is the directory entry empty a volume label */
if (((*MSDOS_DIR_ATTR(entry)) & MSDOS_ATTR_VOLUME_ID) &&
((*MSDOS_DIR_ATTR(entry) & MSDOS_ATTR_LFN_MASK) != MSDOS_ATTR_LFN))
continue;
/*
* skip active entries until get the entry to start from
* Check the attribute to see if the entry is for a long file
* name.
*/
if (start)
if ((*MSDOS_DIR_ATTR(entry) & MSDOS_ATTR_LFN_MASK) ==
MSDOS_ATTR_LFN)
{
start--;
continue;
int o;
char* p;
int q;
/*
* Is this is the first entry of a LFN ?
*/
if (lfn_start == FAT_FILE_SHORT_NAME)
{
/*
* The first entry must have the last long entry flag set.
*/
if ((*MSDOS_DIR_ENTRY_TYPE(entry) &
MSDOS_LAST_LONG_ENTRY) == 0)
continue;
/*
* Remember the start location of the long file name.
*/
lfn_start =
((j * bts2rd) + i) / MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE;
/*
* Get the number of entries so we can count down and
* also the checksum of the short entry.
*/
lfn_entries = (*MSDOS_DIR_ENTRY_TYPE(entry) &
MSDOS_LAST_LONG_ENTRY_MASK);
lfn_checksum = *MSDOS_DIR_LFN_CHECKSUM(entry);
memset (tmp_dirent.d_name, 0, sizeof(tmp_dirent.d_name));
}
/*
* If the entry number or the check sum do not match
* forget this series of long directory entries. These could
* be orphaned entries depending on the history of the
* disk.
*/
if ((lfn_entries != (*MSDOS_DIR_ENTRY_TYPE(entry) &
MSDOS_LAST_LONG_ENTRY_MASK)) ||
(lfn_checksum != *MSDOS_DIR_LFN_CHECKSUM(entry)))
{
lfn_start = FAT_FILE_SHORT_NAME;
continue;
}
/*
* Extract the file name into the directory entry. The data is
* stored in UNICODE characters (16bit). No translation is
* currently supported.
*
* The DOS maximum length is 255 characters without the
* trailing nul character. We need to range check the length to
* fit in the directory entry name field.
*/
lfn_entries--;
p = entry + 1;
o = lfn_entries * MSDOS_LFN_LEN_PER_ENTRY;
for (q = 0; q < MSDOS_LFN_LEN_PER_ENTRY; q++)
{
if (o >= (sizeof(tmp_dirent.d_name) - 1))
break;
tmp_dirent.d_name[o++] = *p;
if (*p == '\0')
break;
switch (q)
{
case 4:
p += 5;
break;
case 10:
p += 4;
break;
default:
p += 2;
break;
}
}
}
/*
* 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)
else
{
rtems_semaphore_release(fs_info->vol_sema);
return rc;
fat_dir_pos_t dir_pos;
/*
* Skip active entries until get the entry to start from.
*/
if (start)
{
lfn_start = FAT_FILE_SHORT_NAME;
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;
}
fat_dir_pos_init(&dir_pos);
dir_pos.sname.cln = cur_cln;
dir_pos.sname.ofs = i;
rc = fat_file_open(iop->pathinfo.mt_entry, &dir_pos, &tmp_fat_fd);
if (rc != RC_OK)
{
rtems_semaphore_release(fs_info->vol_sema);
return rc;
}
/* 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;
/*
* If a long file name check if the correct number of
* entries have been found and if the checksum is correct.
* If not return the short file name.
*/
if (lfn_start != FAT_FILE_SHORT_NAME)
{
uint8_t cs = 0;
uint8_t* p = (uint8_t*) entry;
int i;
for (i = 0; i < 11; i++, p++)
cs = ((cs & 1) ? 0x80 : 0) + (cs >> 1) + *p;
if (lfn_entries || (lfn_checksum != cs))
lfn_start = FAT_FILE_SHORT_NAME;
}
if (lfn_start == FAT_FILE_SHORT_NAME)
{
/*
* convert dir entry from fixed 8+3 format (without dot)
* to 0..8 + 1dot + 0..3 format
*/
tmp_dirent.d_namlen = msdos_format_dirent_with_dot(
tmp_dirent.d_name, entry); /* src text */
}
else
{
tmp_dirent.d_namlen = strlen(tmp_dirent.d_name);
}
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;
}
}
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;
/*
* convert dir entry from fixed 8+3 format (without dot)
* to 0..8 + 1dot + 0..3 format
*/
tmp_dirent.d_namlen = msdos_format_dirent_with_dot(
tmp_dirent.d_name,
(char *) fs_info->cl_buf + i); /* src text */
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;
}
@@ -363,8 +498,8 @@ msdos_dir_read(rtems_libio_t *iop, void *buffer, size_t count)
* RC_OK on success, or -1 if error occured (errno
* set apropriately).
*/
off_t
msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence)
rtems_off64_t
msdos_dir_lseek(rtems_libio_t *iop, rtems_off64_t offset, int whence)
{
switch (whence)
{
@@ -471,6 +606,24 @@ msdos_dir_sync(rtems_libio_t *iop)
return rc;
}
/* msdos_dir_chmod --
* Change the attributes of the directory. This currently does
* nothing and returns no error.
*
* PARAMETERS:
* pathloc - node description
* mode - the new mode
*
* RETURNS:
* RC_OK always
*/
int
msdos_dir_chmod(rtems_filesystem_location_info_t *pathloc,
mode_t mode)
{
return RC_OK;
}
/* msdos_dir_rmnod --
* Remove directory node.
*
@@ -498,7 +651,7 @@ msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
rtems_set_errno_and_return_minus_one(EIO);
/*
* We deny attemp to delete open directory (if directory is current
* We deny attempts to delete open directory (if directory is current
* directory we assume it is open one)
*/
if (fat_fd->links_num > 1)
@@ -538,8 +691,7 @@ msdos_dir_rmnod(rtems_filesystem_location_info_t *pathloc)
*/
/* mark file removed */
rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
fat_fd->info_ofs,
rc = msdos_set_first_char4file_name(pathloc->mt_entry, &fat_fd->dir_pos,
MSDOS_THIS_DIR_ENTRY_EMPTY);
if (rc != RC_OK)
{

View File

@@ -82,9 +82,9 @@ msdos_eval_path(
fat_file_fd_t *fat_fd = NULL;
rtems_filesystem_location_info_t newloc;
int i = 0;
int len = 0;
int token_len = 0;
msdos_token_types_t type = MSDOS_CURRENT_DIR;
char token[MSDOS_NAME_MAX + 1];
const char *token;
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
@@ -106,8 +106,8 @@ msdos_eval_path(
while ((type != MSDOS_NO_MORE_PATH) && (type != MSDOS_INVALID_TOKEN))
{
type = msdos_get_token(&pathname[i], token, &len);
i += len;
type = msdos_get_token(&pathname[i], &token, &token_len);
i += token_len;
fat_fd = pathloc->node_access;
@@ -149,13 +149,13 @@ msdos_eval_path(
goto err;
rtems_semaphore_release(fs_info->vol_sema);
return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),
return (*pathloc->ops->evalpath_h)(&(pathname[i-token_len]),
flags, pathloc);
}
}
else
{
rc = msdos_find_name(pathloc, token);
rc = msdos_find_name(pathloc, token, token_len);
if (rc != RC_OK)
{
if (rc == MSDOS_NAME_NOT_FOUND_ERR)
@@ -183,7 +183,7 @@ msdos_eval_path(
* 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);
rc = msdos_find_name(pathloc, token, token_len);
if (rc != RC_OK)
{
if (rc == MSDOS_NAME_NOT_FOUND_ERR)
@@ -264,8 +264,8 @@ msdos_eval4make(
rtems_filesystem_location_info_t newloc;
msdos_token_types_t type;
int i = 0;
int len;
char token[ MSDOS_NAME_MAX + 1 ];
int token_len;
const char *token;
bool done = false;
sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
@@ -288,8 +288,8 @@ msdos_eval4make(
while (!done)
{
type = msdos_get_token(&path[i], token, &len);
i += len;
type = msdos_get_token(&path[i], &token, &token_len);
i += token_len;
fat_fd = pathloc->node_access;
switch (type)
@@ -330,13 +330,13 @@ msdos_eval4make(
goto err;
rtems_semaphore_release(fs_info->vol_sema);
return (*pathloc->ops->evalformake_h)(&path[i-len],
return (*pathloc->ops->evalformake_h)(&path[i-token_len],
pathloc, name);
}
}
else
{
rc = msdos_find_name(pathloc, token);
rc = msdos_find_name(pathloc, token, token_len);
if (rc != RC_OK)
{
if (rc == MSDOS_NAME_NOT_FOUND_ERR)
@@ -361,10 +361,10 @@ msdos_eval4make(
}
/*
* Otherwise find the token name in the present location and
* 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);
rc = msdos_find_name(pathloc, token, token_len);
if (rc)
{
if (rc != MSDOS_NAME_NOT_FOUND_ERR)
@@ -396,7 +396,7 @@ msdos_eval4make(
}
}
*name = &path[i - len];
*name = &path[i - token_len];
/*
* We have evaluated the path as far as we can.

View File

@@ -223,8 +223,8 @@ msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
* new offset on success, or -1 if error occured (errno set
* appropriately).
*/
off_t
msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence)
rtems_off64_t
msdos_file_lseek(rtems_libio_t *iop, rtems_off64_t offset, int whence)
{
int rc = RC_OK;
rtems_status_code sc = RTEMS_SUCCESSFUL;
@@ -302,7 +302,7 @@ msdos_file_stat(
* RC_OK on success, or -1 if error occured (errno set appropriately).
*/
int
msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
msdos_file_ftruncate(rtems_libio_t *iop, rtems_off64_t length)
{
int rc = RC_OK;
rtems_status_code sc = RTEMS_SUCCESSFUL;
@@ -444,6 +444,24 @@ msdos_file_ioctl(rtems_libio_t *iop,uint32_t command, void *buffer)
return rc;
}
/* msdos_file_chmod --
* Change the attributes of the file. This currently does
* nothing and returns no error.
*
* PARAMETERS:
* pathloc - node description
* mode - the new mode
*
* RETURNS:
* RC_OK always
*/
int
msdos_file_chmod(rtems_filesystem_location_info_t *pathloc,
mode_t mode)
{
return RC_OK;
}
/* 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
@@ -469,8 +487,8 @@ msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc)
rtems_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,
rc = msdos_set_first_char4file_name(pathloc->mt_entry,
&fat_fd->dir_pos,
MSDOS_THIS_DIR_ENTRY_EMPTY);
if (rc != RC_OK)
{

View File

@@ -31,6 +31,7 @@
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
@@ -65,6 +66,58 @@ typedef struct {
uint32_t vol_id;
} msdos_format_param_t;
/*
* Formatted output.
*/
static void
msdos_format_printf (const msdos_format_request_param_t *rqdata,
int info_level,
const char *format, ...)
{
va_list args;
va_start (args, format);
if (rqdata->info_level >= info_level)
{
vfprintf (stdout, format, args);
fflush (stdout);
}
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
static int msdos_format_read_sec
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| function to read a sector |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
int fd, /* file descriptor index */
uint32_t start_sector, /* sector number to write to */
uint32_t sector_size, /* size of sector */
char *buffer /* buffer with read data into */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| 0, if success, -1 and errno if failed |
\*=========================================================================*/
{
int ret_val = 0;
if (0 > lseek(fd,((off_t)start_sector)*sector_size,SEEK_SET)) {
ret_val = -1;
}
if (ret_val == 0) {
if (0 > read(fd,buffer,sector_size)) {
ret_val = -1;
}
}
return ret_val;
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
@@ -100,7 +153,7 @@ static int msdos_format_write_sec
return ret_val;
}
/*=========================================================================*\
/*=========================================================================* \
| Function: |
\*-------------------------------------------------------------------------*/
static int msdos_format_fill_sectors
@@ -111,6 +164,7 @@ static int msdos_format_fill_sectors
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
const msdos_format_request_param_t *rqdata,
int fd, /* file descriptor index */
uint32_t start_sector, /* sector number to fill to */
uint32_t sector_cnt, /* number of sectors to fill to */
@@ -124,7 +178,9 @@ static int msdos_format_fill_sectors
{
int ret_val = 0;
char *fill_buffer = NULL;
uint32_t total_sectors = sector_cnt;
int last_percent = -1;
/*
* allocate and fill buffer
*/
@@ -138,15 +194,31 @@ static int msdos_format_fill_sectors
memset(fill_buffer,fill_byte,sector_size);
}
}
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"Filling : ");
/*
* write to consecutive sectors
*/
while ((ret_val == 0) &&
(sector_cnt > 0)) {
int percent = (sector_cnt * 100) / total_sectors;
if (percent != last_percent) {
if ((percent & 1) == 0)
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, ".");
last_percent = percent;
}
ret_val = msdos_format_write_sec(fd,start_sector,sector_size,fill_buffer);
start_sector++;
sector_cnt--;
}
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "\n");
if (ret_val)
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO,
"filling error on sector: %d\n", start_sector);
/*
* cleanup
*/
@@ -311,7 +383,8 @@ static int msdos_format_determine_fmt_params
uint32_t fatdata_sect_cnt;
uint32_t onebit;
uint32_t sectors_per_cluster_adj = 0;
uint64_t total_size = 0;
memset(fmt_params,0,sizeof(*fmt_params));
/*
* this one is fixed in this implementation.
@@ -320,6 +393,10 @@ static int msdos_format_determine_fmt_params
if (ret_val == 0) {
fmt_params->bytes_per_sector = dd->block_size;
fmt_params->totl_sector_cnt = dd->size;
total_size = dd->block_size * dd->size;
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"bytes per sector: %d\ntotal sectors: %d\ntotal size: %lu\n",
dd->block_size, dd->size, total_size);
}
/*
* determine number of FATs
@@ -336,6 +413,11 @@ static int msdos_format_determine_fmt_params
ret_val = EINVAL;
}
}
if (ret_val == 0)
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"number of fats: %d\n", fmt_params->fat_num);
/*
* Now we get sort of a loop when determining things:
* The FAT type (FAT12/16/32) is determined ONLY from the
@@ -396,21 +478,26 @@ static int msdos_format_determine_fmt_params
* are a compromise concerning capacity and efficency
*/
if (fmt_params->totl_sector_cnt
< ((uint32_t)FAT_FAT12_MAX_CLN)*8) {
fmt_params->fattype = FAT_FAT12;
/* start trying with small clusters */
fmt_params->sectors_per_cluster = 2;
< ((uint32_t)FAT_FAT12_MAX_CLN)*8) {
fmt_params->fattype = FAT_FAT12;
/* start trying with small clusters */
fmt_params->sectors_per_cluster = 2;
}
else if (fmt_params->totl_sector_cnt
< ((uint32_t)FAT_FAT16_MAX_CLN)*32) {
fmt_params->fattype = FAT_FAT16;
/* start trying with small clusters */
fmt_params->sectors_per_cluster = 2;
< ((uint32_t)FAT_FAT16_MAX_CLN)*32) {
fmt_params->fattype = FAT_FAT16;
/* start trying with small clusters */
fmt_params->sectors_per_cluster = 2;
}
else {
fmt_params->fattype = FAT_FAT32;
/* start trying with small clusters... */
fmt_params->sectors_per_cluster = 1;
uint32_t gigs = (total_size + (1024 * 1024 * 1024)) / (1024 * 1024 * 1024);
int b;
fmt_params->fattype = FAT_FAT32;
/* scale with the size of disk... */
for (b = 31; b > 0; b--)
if ((gigs & (1 << b)) != 0)
break;
fmt_params->sectors_per_cluster = 1 << b;
}
}
/*
@@ -428,7 +515,7 @@ static int msdos_format_determine_fmt_params
* sectors_per_cluster*bytes_per_sector must not be bigger than 32K
*/
for (onebit = 128;onebit >= 1;onebit = onebit>>1) {
if (fmt_params->sectors_per_cluster > onebit) {
if (fmt_params->sectors_per_cluster >= onebit) {
fmt_params->sectors_per_cluster = onebit;
if (fmt_params->sectors_per_cluster
<= 32768L/fmt_params->bytes_per_sector) {
@@ -440,6 +527,9 @@ static int msdos_format_determine_fmt_params
}
if (ret_val == 0) {
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"sectors per cluster: %d\n", fmt_params->sectors_per_cluster);
if (fmt_params->fattype == FAT_FAT32) {
/* recommended: for FAT32, always set reserved sector count to 32 */
fmt_params->rsvd_sector_cnt = 32;
@@ -649,9 +739,15 @@ static int msdos_format_gen_mbr
total_sectors_num32 = fmt_params->totl_sector_cnt;
}
/*
* finally we are there: let's fill in the values into the MBR
* finally we are there: let's fill in the values into the MBR
* but first clear the MRB leaving the partition table.
*/
memset(mbr,0,FAT_TOTAL_MBR_SIZE);
#define RTEMS_IDE_PARTITION_TABLE_OFFSET 0x1be
#define RTEMS_IDE_PARTITION_TABLE_SIZE (4 * 16)
memset(mbr,0,RTEMS_IDE_PARTITION_TABLE_OFFSET);
memset(mbr + RTEMS_IDE_PARTITION_TABLE_OFFSET + RTEMS_IDE_PARTITION_TABLE_SIZE,
0,
FAT_TOTAL_MBR_SIZE - (RTEMS_IDE_PARTITION_TABLE_OFFSET + RTEMS_IDE_PARTITION_TABLE_SIZE));
/*
* FIXME: fill jmpBoot and Boot code...
* with 0xEB,....
@@ -672,9 +768,9 @@ static int msdos_format_gen_mbr
FAT_SET_BR_TOTAL_SECTORS_NUM16(mbr , total_sectors_num16);
FAT_SET_BR_MEDIA(mbr , fmt_params->media_code);
FAT_SET_BR_SECTORS_PER_TRACK(mbr , 0); /* only needed for INT13... */
FAT_SET_BR_NUMBER_OF_HEADS(mbr , 0); /* only needed for INT13... */
FAT_SET_BR_HIDDEN_SECTORS(mbr , 0); /* only needed for INT13... */
FAT_SET_BR_SECTORS_PER_TRACK(mbr , 255); /* only needed for INT13... */
FAT_SET_BR_NUMBER_OF_HEADS(mbr , 6); /* only needed for INT13... */
FAT_SET_BR_HIDDEN_SECTORS(mbr , 1); /* only needed for INT13... */
FAT_SET_BR_TOTAL_SECTORS_NUM32(mbr , total_sectors_num32);
if (fmt_params->fattype != FAT_FAT32) {
@@ -749,7 +845,6 @@ static int msdos_format_gen_fsinfo
| 0, if success, -1 and errno if failed |
\*=========================================================================*/
{
/*
* clear fsinfo sector data
*/
@@ -760,9 +855,9 @@ static int msdos_format_gen_fsinfo
FAT_SET_FSINFO_LEAD_SIGNATURE (fsinfo,FAT_FSINFO_LEAD_SIGNATURE_VALUE );
FAT_SET_FSINFO_STRUC_SIGNATURE(fsinfo,FAT_FSINFO_STRUC_SIGNATURE_VALUE);
FAT_SET_FSINFO_TRAIL_SIGNATURE(fsinfo,FAT_FSINFO_TRAIL_SIGNATURE_VALUE);
/*
* write "empty" values for free cluster count and next cluster number
*/
/*
* write "empty" values for free cluster count and next cluster number
*/
FAT_SET_FSINFO_FREE_CLUSTER_COUNT(fsinfo+FAT_FSI_INFO,
0xffffffff);
FAT_SET_FSINFO_NEXT_FREE_CLUSTER (fsinfo+FAT_FSI_INFO,
@@ -800,9 +895,13 @@ int msdos_format
int i;
msdos_format_param_t fmt_params;
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO,
"formating: %s\n", devname);
/*
* sanity check on device
*/
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"stat check: %s\n", devname);
if (ret_val == 0) {
rc = stat(devname, &stat_buf);
ret_val = rc;
@@ -828,7 +927,9 @@ int msdos_format
* open device for writing
*/
if (ret_val == 0) {
fd = open(devname, O_WRONLY);
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"open device\n");
fd = open(devname, O_RDWR);
if (fd == -1)
{
ret_val= -1;
@@ -848,7 +949,8 @@ int msdos_format
(rqdata != NULL) &&
!(rqdata->quick_format)) {
ret_val = msdos_format_fill_sectors
(fd,
(rqdata,
fd,
0, /* start sector */
fmt_params.totl_sector_cnt, /* sector count */
fmt_params.bytes_per_sector,
@@ -858,27 +960,45 @@ int msdos_format
* create master boot record
*/
if (ret_val == 0) {
ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params);
}
/*
* write master boot record to disk
* also write copy of MBR to disk
*/
if (ret_val == 0) {
ret_val = msdos_format_write_sec(fd,
0,
fmt_params.bytes_per_sector,
tmp_sec);
}
if ((ret_val == 0) &&
(fmt_params.mbr_copy_sec != 0)) {
/*
* write copy of MBR
* Read the current MBR to obtain the partition table.
*/
ret_val = msdos_format_write_sec(fd,
fmt_params.mbr_copy_sec ,
fmt_params.bytes_per_sector,
tmp_sec);
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"read MRB sector\n");
ret_val = msdos_format_read_sec(fd,
0,
fmt_params.bytes_per_sector,
tmp_sec);
if (ret_val == 0) {
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"generate MRB sector\n");
ret_val = msdos_format_gen_mbr(tmp_sec,&fmt_params);
}
/*
* write master boot record to disk
* also write copy of MBR to disk
*/
if (ret_val == 0) {
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"write MRB sector\n");
ret_val = msdos_format_write_sec(fd,
0,
fmt_params.bytes_per_sector,
tmp_sec);
}
if ((ret_val == 0) &&
(fmt_params.mbr_copy_sec != 0)) {
/*
* write copy of MBR
*/
msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL,
"write back up MRB sector\n");
ret_val = msdos_format_write_sec(fd,
fmt_params.mbr_copy_sec ,
fmt_params.bytes_per_sector,
tmp_sec);
}
}
/*
* for FAT32: initialize info sector on disk
@@ -903,7 +1023,8 @@ int msdos_format
*/
if (ret_val == 0) {
ret_val = msdos_format_fill_sectors
(fd,
(rqdata,
fd,
fmt_params.rsvd_sector_cnt, /* start sector */
fmt_params.fat_num*fmt_params.sectors_per_fat,/* sector count */
fmt_params.bytes_per_sector,
@@ -915,7 +1036,8 @@ int msdos_format
*/
if (ret_val == 0) {
ret_val = msdos_format_fill_sectors
(fd,
(rqdata,
fd,
fmt_params.root_dir_start_sec, /* start sector */
fmt_params.root_dir_fmt_sec_cnt, /* sector count */
fmt_params.bytes_per_sector,

View File

@@ -26,7 +26,7 @@ const rtems_filesystem_file_handlers_r msdos_dir_handlers = {
NULL, /* msdos_dir_ioctl */
msdos_dir_lseek,
msdos_dir_stat,
NULL,
msdos_dir_chmod,
NULL, /* msdos_dir_ftruncate */
NULL,
msdos_dir_sync,

View File

@@ -26,7 +26,7 @@ const rtems_filesystem_file_handlers_r msdos_file_handlers = {
msdos_file_ioctl,
msdos_file_lseek,
msdos_file_stat,
NULL,
msdos_file_chmod,
msdos_file_ftruncate,
NULL,
msdos_file_sync,

View File

@@ -42,7 +42,8 @@ const rtems_filesystem_operations_table msdos_ops = {
};
/* msdos_initialize --
* MSDOS filesystem initialization
* MSDOS filesystem initialization. Called when mounting an
* MSDOS filesystem.
*
* PARAMETERS:
* temp_mt_entry - mount table entry

View File

@@ -57,6 +57,7 @@ msdos_initialize_support(
rtems_status_code sc = RTEMS_SUCCESSFUL;
msdos_fs_info_t *fs_info = NULL;
fat_file_fd_t *fat_fd = NULL;
fat_dir_pos_t root_pos;
uint32_t cl_buf_size;
fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t));
@@ -79,7 +80,9 @@ msdos_initialize_support(
* 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);
fat_dir_pos_init(&root_pos);
root_pos.sname.cln = FAT_ROOTDIR_CLUSTER_NUM;
rc = fat_file_open(temp_mt_entry, &root_pos, &fat_fd);
if (rc != RC_OK)
{
fat_shutdown_drive(temp_mt_entry);
@@ -90,8 +93,6 @@ msdos_initialize_support(
/* 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;

File diff suppressed because it is too large Load Diff

View File

@@ -36,7 +36,7 @@
* determines type of the node to be created and creates it.
*
* PARAMETERS:
* token - non-formatted name of a new node
* name - file name to create
* mode - node type
* dev - dev
* pathloc - parent directory description
@@ -46,7 +46,7 @@
*
*/
int msdos_mknod(
const char *token,
const char *name,
mode_t mode,
dev_t dev,
rtems_filesystem_location_info_t *pathloc
@@ -56,12 +56,7 @@ int msdos_mknod(
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.
*/
@@ -82,7 +77,7 @@ int msdos_mknod(
rtems_set_errno_and_return_minus_one(EIO);
/* Create an MSDOS node */
rc = msdos_creat_node(pathloc, type, new_name, mode, NULL);
rc = msdos_creat_node(pathloc, type, name, strlen(name), mode, NULL);
rtems_semaphore_release(fs_info->vol_sema);
return rc;

View File

@@ -206,12 +206,14 @@ int device_ioctl(
/*
* device_lseek
*
* This handler eats all lseek() operations.
* This handler eats all lseek() operations and does not create
* an error. It assumes all devices can handle the seek. The
* writes fail.
*/
off_t device_lseek(
rtems_off64_t device_lseek(
rtems_libio_t *iop,
off_t offset,
rtems_off64_t offset,
int whence
)
{
@@ -232,7 +234,7 @@ off_t device_lseek(
int device_ftruncate(
rtems_libio_t *iop,
off_t length
rtems_off64_t length
)
{
return 0;

View File

@@ -98,15 +98,15 @@ typedef uint8_t *block_p;
typedef block_p *block_ptr;
typedef struct {
off_t size; /* size of file in bytes */
block_ptr indirect; /* array of 128 data blocks pointers */
block_ptr doubly_indirect; /* 128 indirect blocks */
block_ptr triply_indirect; /* 128 doubly indirect blocks */
rtems_off64_t size; /* size of file in bytes */
block_ptr indirect; /* array of 128 data blocks pointers */
block_ptr doubly_indirect; /* 128 indirect blocks */
block_ptr triply_indirect; /* 128 doubly indirect blocks */
} IMFS_memfile_t;
typedef struct {
off_t size; /* size of file in bytes */
block_p direct; /* pointer to file image */
rtems_off64_t size; /* size of file in bytes */
block_p direct; /* pointer to file image */
} IMFS_linearfile_t;
/*
@@ -380,7 +380,7 @@ extern int IMFS_memfile_remove(
extern int memfile_ftruncate(
rtems_libio_t *iop, /* IN */
off_t length /* IN */
rtems_off64_t length /* IN */
);
extern int imfs_dir_open(
@@ -400,9 +400,9 @@ extern ssize_t imfs_dir_read(
size_t count /* IN */
);
extern off_t imfs_dir_lseek(
extern rtems_off64_t imfs_dir_lseek(
rtems_libio_t *iop, /* IN */
off_t offset, /* IN */
rtems_off64_t offset, /* IN */
int whence /* IN */
);
@@ -444,9 +444,9 @@ extern int memfile_ioctl(
void *buffer /* IN */
);
extern off_t memfile_lseek(
extern rtems_off64_t memfile_lseek(
rtems_libio_t *iop, /* IN */
off_t offset, /* IN */
rtems_off64_t offset, /* IN */
int whence /* IN */
);
@@ -483,15 +483,15 @@ extern int device_ioctl(
void *buffer /* IN */
);
extern off_t device_lseek(
extern rtems_off64_t device_lseek(
rtems_libio_t *iop, /* IN */
off_t offset, /* IN */
rtems_off64_t offset, /* IN */
int whence /* IN */
);
extern int device_ftruncate(
rtems_libio_t *iop, /* IN */
off_t length /* IN */
rtems_off64_t length /* IN */
);
extern int IMFS_utime(

View File

@@ -182,9 +182,9 @@ int imfs_dir_close(
* SEEK_END - N/A --> This will cause an assert.
*/
off_t imfs_dir_lseek(
rtems_off64_t imfs_dir_lseek(
rtems_libio_t *iop,
off_t offset,
rtems_off64_t offset,
int whence
)
{

View File

@@ -119,10 +119,10 @@ int IMFS_fifo_ioctl(
IMFS_FIFO_RETURN(err);
}
off_t IMFS_fifo_lseek(
rtems_off64_t IMFS_fifo_lseek(
rtems_libio_t *iop,
off_t offset,
int whence
rtems_off64_t offset,
int whence
)
{
off_t err = pipe_lseek(LIBIO2PIPE(iop), offset, whence, iop);

View File

@@ -214,9 +214,9 @@ int memfile_ioctl(
* This routine processes the lseek() system call.
*/
off_t memfile_lseek(
rtems_off64_t memfile_lseek(
rtems_libio_t *iop,
off_t offset,
rtems_off64_t offset,
int whence
)
{
@@ -251,7 +251,7 @@ off_t memfile_lseek(
int memfile_ftruncate(
rtems_libio_t *iop,
off_t length
rtems_off64_t length
)
{
IMFS_jnode_t *the_jnode;

View File

@@ -2737,9 +2737,9 @@ static int nfs_file_ioctl(
#define nfs_link_ioctl 0
#endif
static off_t nfs_file_lseek(
static rtems_off64_t nfs_file_lseek(
rtems_libio_t *iop,
off_t length,
rtems_off64_t length,
int whence
)
{
@@ -2770,9 +2770,9 @@ static off_t nfs_file_lseek(
return iop->offset;
}
static off_t nfs_dir_lseek(
static rtems_off64_t nfs_dir_lseek(
rtems_libio_t *iop,
off_t length,
rtems_off64_t length,
int whence
)
{
@@ -2818,29 +2818,29 @@ struct fattr {
struct stat
{
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
dev_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
rtems_off64_t st_size;
/* SysV/sco doesn't have the rest... But Solaris, eabi does. */
#if defined(__svr4__) && !defined(__PPC__) && !defined(__sun__)
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
#else
time_t st_atime;
long st_spare1;
time_t st_mtime;
long st_spare2;
time_t st_ctime;
long st_spare3;
long st_blksize;
long st_blocks;
long st_spare4[2];
time_t st_atime;
long st_spare1;
time_t st_mtime;
long st_spare2;
time_t st_ctime;
long st_spare3;
long st_blksize;
long st_blocks;
long st_spare4[2];
#endif
};
#endif
@@ -3009,7 +3009,7 @@ sattr arg;
*/
static int nfs_file_ftruncate(
rtems_libio_t *iop,
off_t length
rtems_off64_t length
)
{
sattr arg;

View File

@@ -42,7 +42,8 @@ int rtems_shell_main_msdos_format(
fattype: MSDOS_FMT_FATANY,
media: 0,
quick_format: TRUE,
cluster_align: 0
cluster_align: 0,
info_level: 0
};
const char* driver = NULL;
@@ -51,7 +52,7 @@ int rtems_shell_main_msdos_format(
for (arg = 1; arg < argc; arg++) {
if (argv[arg][0] == '-') {
switch (argv[arg][1]) {
case 'v':
case 'V':
arg++;
if (arg == argc) {
fprintf (stderr, "error: no volume label.\n");
@@ -59,6 +60,15 @@ int rtems_shell_main_msdos_format(
}
rqdata.VolLabel = argv[arg];
break;
case 's':
arg++;
if (arg == argc) {
fprintf (stderr, "error: sectors per cluster count.\n");
return 1;
}
rqdata.sectors_per_cluster = rtems_shell_str2int(argv[arg]);
break;
case 'r':
arg++;
@@ -90,6 +100,10 @@ int rtems_shell_main_msdos_format(
}
break;
case 'v':
rqdata.info_level++;
break;
default:
fprintf (stderr, "error: invalid option: %s\n", argv[arg]);
return 1;
@@ -111,6 +125,19 @@ int rtems_shell_main_msdos_format(
}
printf ("msdos format: %s\n", driver);
if (rqdata.info_level)
{
printf (" %-20s: %s\n", "OEMName", "RTEMS");
printf (" %-20s: %s\n", "VolLabel", "RTEMSDisk");
printf (" %-20s: %i\n", "sectors per cluster", rqdata.sectors_per_cluster);
printf (" %-20s: %i\n", "fats", rqdata.fat_num);
printf (" %-20s: %i\n", "files per root dir", rqdata.files_per_root_dir);
printf (" %-20s: %i\n", "fat type", rqdata.fattype);
printf (" %-20s: %d\n", "media", rqdata.media);
printf (" %-20s: %d\n", "quick_format", rqdata.quick_format);
printf (" %-20s: %i\n", "cluster align", rqdata.cluster_align);
}
if (msdos_format (driver, &rqdata) < 0) {
fprintf (stderr, "error: format failed: %s\n", strerror (errno));

View File

@@ -986,7 +986,7 @@ static int rtems_ftpfs_close( rtems_libio_t *iop)
}
/* Dummy version to let fopen( *,"w") work properly */
static int rtems_ftpfs_ftruncate( rtems_libio_t *iop, off_t count)
static int rtems_ftpfs_ftruncate( rtems_libio_t *iop, rtems_off64_t count)
{
return 0;
}

View File

@@ -984,7 +984,7 @@ static ssize_t rtems_tftp_write(
*/
static int rtems_tftp_ftruncate(
rtems_libio_t *iop __attribute__((unused)),
off_t count __attribute__((unused))
rtems_off64_t count __attribute__((unused))
)
{
return 0;