mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
2003-08-04 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
PR 441/filesystem *src/dosfs/msdos.h: add rename support to DOSFS *src/dosfs/msdos_create.c: add rename support to DOSFS *src/dosfs/msdos_file.c: add rename support to DOSFS *src/dosfs/msdos_init.c: add rename support to DOSFS *src/dosfs/msdos_mknod.c: add rename support to DOSFS
This commit is contained in:
@@ -77,6 +77,7 @@ extern rtems_filesystem_file_handlers_r msdos_file_handlers;
|
||||
/* Node types */
|
||||
#define MSDOS_DIRECTORY RTEMS_FILESYSTEM_DIRECTORY
|
||||
#define MSDOS_REGULAR_FILE RTEMS_FILESYSTEM_MEMORY_FILE
|
||||
#define MSDOS_HARD_LINK RTEMS_FILESYSTEM_HARD_LINK /* pseudo type */
|
||||
|
||||
typedef rtems_filesystem_node_types_t msdos_node_type_t;
|
||||
|
||||
@@ -300,6 +301,11 @@ msdos_file_ioctl(
|
||||
int
|
||||
msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc /* IN */);
|
||||
|
||||
int
|
||||
msdos_file_link(rtems_filesystem_location_info_t *to_loc,
|
||||
rtems_filesystem_location_info_t *pa_loc,
|
||||
const char *token);
|
||||
|
||||
int
|
||||
msdos_dir_open(
|
||||
rtems_libio_t *iop, /* IN */
|
||||
@@ -341,7 +347,8 @@ int
|
||||
msdos_creat_node(rtems_filesystem_location_info_t *parent_loc,
|
||||
msdos_node_type_t type,
|
||||
char *name,
|
||||
mode_t mode);
|
||||
mode_t mode,
|
||||
const fat_file_fd_t *link_fd);
|
||||
|
||||
/* Misc prototypes */
|
||||
msdos_token_types_t msdos_get_token(const char *path,
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
* type - new node type (file or directory)
|
||||
* name - new node name
|
||||
* mode - mode
|
||||
* link_info - fs_info of existing node for a pseudo "hard-link"
|
||||
* (see msdos_file.c, msdos_link for documentation)
|
||||
*
|
||||
* RETURNS:
|
||||
* RC_OK on success, or -1 if error occured (errno set appropriately).
|
||||
@@ -50,7 +52,8 @@ msdos_creat_node(
|
||||
rtems_filesystem_location_info_t *parent_loc,
|
||||
msdos_node_type_t type,
|
||||
char *name,
|
||||
mode_t mode
|
||||
mode_t mode,
|
||||
const fat_file_fd_t *link_fd
|
||||
)
|
||||
{
|
||||
int rc = RC_OK;
|
||||
@@ -62,8 +65,11 @@ msdos_creat_node(
|
||||
unsigned16 time_val = 0;
|
||||
unsigned16 date = 0;
|
||||
fat_auxiliary_t aux;
|
||||
unsigned char new_node[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
|
||||
unsigned char new_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
|
||||
unsigned char dot_dotdot[MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2];
|
||||
unsigned char link_node [MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE];
|
||||
unsigned32 sec = 0;
|
||||
unsigned32 byte = 0;
|
||||
|
||||
memset(new_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE);
|
||||
memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2);
|
||||
@@ -86,10 +92,58 @@ msdos_creat_node(
|
||||
/* initialize directory/file size */
|
||||
*MSDOS_DIR_FILE_SIZE(new_node) = MSDOS_INIT_DIR_SIZE;
|
||||
|
||||
if (type == MSDOS_DIRECTORY)
|
||||
if (type == MSDOS_DIRECTORY) {
|
||||
*MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_DIRECTORY;
|
||||
else
|
||||
}
|
||||
else if (type == MSDOS_HARD_LINK) {
|
||||
/*
|
||||
* when we establish a (temporary) hard link,
|
||||
* we must copy some information from the original
|
||||
* node to the newly created
|
||||
*/
|
||||
/*
|
||||
* 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));
|
||||
|
||||
ret = _fat_block_read(parent_loc->mt_entry,
|
||||
sec, byte, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE,
|
||||
link_node);
|
||||
if (ret < 0) {
|
||||
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);
|
||||
|
||||
/*
|
||||
* copy/set "file size", "first cluster"
|
||||
*/
|
||||
*MSDOS_DIR_FILE_SIZE(new_node) =*MSDOS_DIR_FILE_SIZE(link_node);
|
||||
|
||||
*MSDOS_DIR_FIRST_CLUSTER_LOW(new_node) =
|
||||
*MSDOS_DIR_FIRST_CLUSTER_LOW(link_node);
|
||||
*MSDOS_DIR_FIRST_CLUSTER_HI(new_node) =
|
||||
*MSDOS_DIR_FIRST_CLUSTER_HI(link_node);
|
||||
/*
|
||||
* set "archive bit" due to changes
|
||||
*/
|
||||
*MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
|
||||
/*
|
||||
* set "last access" date to today
|
||||
*/
|
||||
*MSDOS_DIR_LAST_ACCESS_DATE(new_node) = CT_LE_W(date);
|
||||
}
|
||||
else { /* regular file... */
|
||||
*MSDOS_DIR_ATTR(new_node) |= MSDOS_ATTR_ARCHIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
* find free space in the parent directory and write new initialized
|
||||
@@ -204,3 +258,90 @@ err:
|
||||
0xE5);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* msdos_file_link --
|
||||
* Replacement for a file "link" operation.
|
||||
* MSDOS FAT FS does not support links, but this call is needed to
|
||||
* allow "rename" operations. The current NEWLIB rename performs a link
|
||||
* from the old to the new name and then deletes the old filename.
|
||||
*
|
||||
* This pseudo-"link" operation will create a new directory entry,
|
||||
* copy the file size and cluster information from the "old"
|
||||
* to the "new" directory entry and then clear the file size and cluster
|
||||
* info from the "old" filename, leaving this file as
|
||||
* a valid, but empty entry.
|
||||
*
|
||||
* When this "link" call is part of a "rename" sequence, the "old"
|
||||
* entry will be deleted in a subsequent "rmnod" call
|
||||
*
|
||||
* This function has been implemented by Thomas Doerfler,
|
||||
* <Thomas.Doerfler@imd-systems.de>
|
||||
*
|
||||
* PARAMETERS:
|
||||
* to_loc - node description for "existing" node
|
||||
* par_loc - node description for "new" node
|
||||
* token - name of new node
|
||||
*
|
||||
* RETURNS:
|
||||
* RC_OK on success, or -1 if error occured (errno set appropriately)
|
||||
*/
|
||||
int
|
||||
msdos_file_link(rtems_filesystem_location_info_t *to_loc,
|
||||
rtems_filesystem_location_info_t *par_loc,
|
||||
const char *token
|
||||
)
|
||||
{
|
||||
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;
|
||||
fat_file_fd_t *par_fat_fd = par_loc->node_access;
|
||||
char new_name[ MSDOS_NAME_MAX + 1 ];
|
||||
int len;
|
||||
|
||||
/*
|
||||
* check spelling and format new node name
|
||||
*/
|
||||
if (MSDOS_NAME != msdos_get_token(token, new_name, &len)) {
|
||||
set_errno_and_return_minus_one(ENAMETOOLONG);
|
||||
}
|
||||
/*
|
||||
* verify, that the existing node can be linked to
|
||||
* check that nodes are in same FS/volume?
|
||||
*/
|
||||
if (to_loc->mt_entry->fs_info != par_loc->mt_entry->fs_info) {
|
||||
set_errno_and_return_minus_one(EXDEV);
|
||||
}
|
||||
/*
|
||||
* lock volume
|
||||
*/
|
||||
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 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);
|
||||
/*
|
||||
* set file size and first cluster number of old entry to 0
|
||||
*/
|
||||
if (rc == RC_OK) {
|
||||
to_fat_fd->fat_file_size = 0;
|
||||
to_fat_fd->cln = FAT_EOF;
|
||||
rc = msdos_set_first_cluster_num(to_loc->mt_entry, to_fat_fd);
|
||||
if (rc == RC_OK) {
|
||||
rc = msdos_set_file_size(par_loc->mt_entry, to_fat_fd);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* FIXME: check error/abort handling
|
||||
*/
|
||||
rtems_semaphore_release(fs_info->vol_sema);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
rtems_filesystem_operations_table msdos_ops = {
|
||||
msdos_eval_path,
|
||||
msdos_eval4make,
|
||||
NULL, /* msdos_link */
|
||||
#if 0
|
||||
NULL, /* msdos_link */
|
||||
#else
|
||||
msdos_file_link, /* msdos_link (pseudo-functionality) */
|
||||
#endif
|
||||
msdos_file_rmnod,
|
||||
msdos_node_type,
|
||||
msdos_mknod,
|
||||
|
||||
@@ -83,7 +83,7 @@ msdos_mknod(
|
||||
set_errno_and_return_minus_one(EIO);
|
||||
|
||||
/* Create an MSDOS node */
|
||||
rc = msdos_creat_node(pathloc, type, new_name, mode);
|
||||
rc = msdos_creat_node(pathloc, type, new_name, mode, NULL);
|
||||
|
||||
rtems_semaphore_release(fs_info->vol_sema);
|
||||
return rc;
|
||||
|
||||
Reference in New Issue
Block a user