diff options
Diffstat (limited to 'cpukit/libfs/src/dosfs')
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos.h | 125 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_create.c | 19 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_dir.c | 120 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_eval.c | 416 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_file.c | 88 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_free.c | 25 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_fsunmount.c | 22 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_handlers_dir.c | 6 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_handlers_file.c | 6 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_init.c | 43 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_initsupp.c | 6 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_misc.c | 97 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_mknod.c | 35 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_node_type.c | 8 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_rename.c | 42 | ||||
-rw-r--r-- | cpukit/libfs/src/dosfs/msdos_rmnod.c | 79 |
16 files changed, 272 insertions, 865 deletions
diff --git a/cpukit/libfs/src/dosfs/msdos.h b/cpukit/libfs/src/dosfs/msdos.h index 5e24d6ad1d..9bdfd881ec 100644 --- a/cpukit/libfs/src/dosfs/msdos.h +++ b/cpukit/libfs/src/dosfs/msdos.h @@ -168,7 +168,6 @@ typedef rtems_filesystem_node_types_t msdos_node_type_t; /* * Macros for names parsing and formatting */ -#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 */ @@ -224,44 +223,40 @@ typedef enum msdos_token_types_e #define MSDOS_DPS512_NUM 16 /* Prototypes */ -int msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry); +void msdos_shut_down(rtems_filesystem_mount_table_entry_t *temp_mt_entry); -int msdos_eval_path( - const char *pathname, /* IN */ - size_t pathnamelen, /* 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 */ -); +void msdos_eval_path(rtems_filesystem_eval_path_context_t *ctx); -int msdos_unlink(rtems_filesystem_location_info_t *pathloc /* IN */); +void msdos_free_node_info(const rtems_filesystem_location_info_t *pathloc); -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); +rtems_filesystem_node_types_t msdos_node_type( + const rtems_filesystem_location_info_t *loc +); int msdos_mknod( - const char *path, /* IN */ - mode_t mode, /* IN */ - dev_t dev, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN/OUT */ + const rtems_filesystem_location_info_t *loc, + const char *name, + size_t namelen, + mode_t mode, + dev_t dev ); -int msdos_utime( - rtems_filesystem_location_info_t *pathloc, /* IN */ - time_t actime, /* IN */ - time_t modtime /* IN */ +int msdos_rmnod( + const rtems_filesystem_location_info_t *parentloc, + const rtems_filesystem_location_info_t *loc ); -int msdos_rename(rtems_filesystem_location_info_t *old_parent_loc, - rtems_filesystem_location_info_t *old_loc, - rtems_filesystem_location_info_t *new_parent_loc, - const char *new_name); +int msdos_rename( + const rtems_filesystem_location_info_t *old_parent_loc, + const rtems_filesystem_location_info_t *old_loc, + const rtems_filesystem_location_info_t *new_parent_loc, + const char *new_name, + size_t new_namelen +); + +void msdos_lock(rtems_filesystem_mount_table_entry_t *mt_entry); + +void msdos_unlock(rtems_filesystem_mount_table_entry_t *mt_entry); int msdos_initialize_support( rtems_filesystem_mount_table_entry_t *temp_mt_entry, @@ -273,8 +268,8 @@ int msdos_initialize_support( int msdos_file_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ - uint32_t flag, /* IN */ - uint32_t mode /* IN */ + int oflag, /* IN */ + mode_t mode /* IN */ ); int msdos_file_close(rtems_libio_t *iop /* IN */); @@ -298,8 +293,8 @@ off_t msdos_file_lseek( ); int msdos_file_stat( - rtems_filesystem_location_info_t *loc, /* IN */ - struct stat *buf /* OUT */ + const rtems_filesystem_location_info_t *loc, + struct stat *buf ); int @@ -312,26 +307,11 @@ 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 */ - uint32_t command, /* IN */ - 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 *parent_pathloc, /* IN */ - rtems_filesystem_location_info_t *pathloc /* IN */); - int msdos_dir_open( rtems_libio_t *iop, /* IN */ const char *pathname, /* IN */ - uint32_t flag, /* IN */ - uint32_t mode /* IN */ + int oflag, /* IN */ + mode_t mode /* IN */ ); int msdos_dir_close(rtems_libio_t *iop /* IN */); @@ -348,34 +328,21 @@ off_t msdos_dir_lseek( 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 *parent_pathloc, /* IN */ - 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 */ + const rtems_filesystem_location_info_t *loc, + struct stat *buf ); -int 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 msdos_creat_node(const 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); /* Misc prototypes */ -msdos_token_types_t msdos_get_token(const char *path, - int pathlen, - const char **token, - int *token_len); int msdos_find_name( rtems_filesystem_location_info_t *parent_loc, @@ -384,13 +351,13 @@ int msdos_find_name( ); int msdos_get_name_node( - rtems_filesystem_location_info_t *parent_loc, - 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 + const rtems_filesystem_location_info_t *parent_loc, + 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); diff --git a/cpukit/libfs/src/dosfs/msdos_create.c b/cpukit/libfs/src/dosfs/msdos_create.c index ec5862a178..263df36353 100644 --- a/cpukit/libfs/src/dosfs/msdos_create.c +++ b/cpukit/libfs/src/dosfs/msdos_create.c @@ -55,12 +55,12 @@ * */ int -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) +msdos_creat_node(const 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; @@ -83,9 +83,16 @@ msdos_creat_node(rtems_filesystem_location_info_t *parent_loc, memset(short_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2); + if (name_len > MSDOS_NAME_MAX_LFN_WITH_DOT) { + rtems_set_errno_and_return_minus_one(ENAMETOOLONG); + } + name_type = msdos_long_to_short (name, name_len, MSDOS_DIR_NAME(short_node), MSDOS_NAME_MAX); + if (name_type == MSDOS_NAME_INVALID) { + rtems_set_errno_and_return_minus_one(EINVAL); + } /* fill reserved field */ *MSDOS_DIR_NT_RES(short_node) = MSDOS_RES_NT_VALUE; diff --git a/cpukit/libfs/src/dosfs/msdos_dir.c b/cpukit/libfs/src/dosfs/msdos_dir.c index 494b9fbae6..725fd254d0 100644 --- a/cpukit/libfs/src/dosfs/msdos_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_dir.c @@ -33,20 +33,10 @@ /* 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, uint32_t flag, - uint32_t mode) +msdos_dir_open(rtems_libio_t *iop, const char *pathname, int oflag, + mode_t mode) { int rc = RC_OK; rtems_status_code sc = RTEMS_SUCCESSFUL; @@ -529,9 +519,9 @@ msdos_dir_lseek(rtems_libio_t *iop, off_t offset, int whence) */ int msdos_dir_stat( - rtems_filesystem_location_info_t *loc, - struct stat *buf - ) + const 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; @@ -594,103 +584,3 @@ msdos_dir_sync(rtems_libio_t *iop) rtems_semaphore_release(fs_info->vol_sema); 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. - * - * 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 *parent_pathloc, - 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; - bool is_empty = false; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - rtems_set_errno_and_return_minus_one(EIO); - - /* - * 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); - rtems_set_errno_and_return_minus_one(ENOTEMPTY); - } - - /* - * We deny attempts 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); - rtems_set_errno_and_return_minus_one(EBUSY); - } - - /* - * You cannot remove the file system root node. - */ - if (rtems_filesystem_is_root_location(pathloc)) - { - rtems_semaphore_release(fs_info->vol_sema); - rtems_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->dir_pos, - 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/cpukit/libfs/src/dosfs/msdos_eval.c b/cpukit/libfs/src/dosfs/msdos_eval.c index 9b5e0c835d..0ab5971e62 100644 --- a/cpukit/libfs/src/dosfs/msdos_eval.c +++ b/cpukit/libfs/src/dosfs/msdos_eval.c @@ -52,384 +52,58 @@ msdos_set_handlers(rtems_filesystem_location_info_t *loc) 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, - size_t pathnamelen, - int flags, - rtems_filesystem_location_info_t *pathloc - ) +static bool msdos_is_directory( + rtems_filesystem_eval_path_context_t *ctx, + void *arg +) { - 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 token_len = 0; - msdos_token_types_t type = MSDOS_CURRENT_DIR; - const char *token; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - rtems_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], pathnamelen, &token, &token_len); - pathnamelen -= token_len; - i += token_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 = ENOTSUP; - rc = -1; - goto error; - } + rtems_filesystem_location_info_t *currentloc = + rtems_filesystem_eval_path_get_currentloc( ctx ); + fat_file_fd_t *fat_fd = currentloc->node_access; - /* - * Am I at the root of this mounted filesystem? - */ - if (rtems_filesystem_is_root_location(pathloc)) - { - /* - * 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-token_len]), - pathnamelen + token_len, - flags, pathloc); - } - } - else - { - rc = msdos_find_name(pathloc, token, token_len); - 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 = ENOTSUP; - 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, token_len); - 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; + return fat_fd->fat_file_type == MSDOS_DIRECTORY; } -/* 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 - ) +static rtems_filesystem_eval_path_generic_status msdos_eval_token( + rtems_filesystem_eval_path_context_t *ctx, + void *arg, + const char *token, + size_t tokenlen +) { - 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 token_len; - const char *token; - bool done = false; - - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - rtems_set_errno_and_return_minus_one(EIO); - - if (!pathloc->node_access) - { - errno = ENOENT; - rc = -1; - goto err; + rtems_filesystem_eval_path_generic_status status = + RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE; + + if (rtems_filesystem_is_current_directory(token, tokenlen)) { + rtems_filesystem_eval_path_clear_token(ctx); + status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; + } else { + rtems_filesystem_location_info_t *currentloc = + rtems_filesystem_eval_path_get_currentloc(ctx); + int rc = msdos_find_name(currentloc, token, tokenlen); + + if (rc == RC_OK) { + rtems_filesystem_eval_path_clear_token(ctx); + msdos_set_handlers(currentloc); + if (rtems_filesystem_eval_path_has_path(ctx)) { + status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE; + } + } else if (rc == MSDOS_NAME_NOT_FOUND_ERR) { + status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY; + } else { + rtems_filesystem_eval_path_error(ctx, 0); } + } - 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], strlen(&path[i]), &token, &token_len); - i += token_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 (rtems_filesystem_is_root_location(pathloc)) - { - /* - * 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-token_len], - pathloc, name); - } - } - else - { - rc = msdos_find_name(pathloc, token, token_len); - 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, token_len); - 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 - token_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; + return status; +} -error: - fat_file_close(pathloc->mt_entry, fat_fd); +static const rtems_filesystem_eval_path_generic_config msdos_eval_config = { + .is_directory = msdos_is_directory, + .eval_token = msdos_eval_token +}; -err: - rtems_semaphore_release(fs_info->vol_sema); - return rc; +void msdos_eval_path(rtems_filesystem_eval_path_context_t *ctx) +{ + rtems_filesystem_eval_path_generic(ctx, NULL, &msdos_eval_config); } diff --git a/cpukit/libfs/src/dosfs/msdos_file.c b/cpukit/libfs/src/dosfs/msdos_file.c index 5378a25914..b2f98b890d 100644 --- a/cpukit/libfs/src/dosfs/msdos_file.c +++ b/cpukit/libfs/src/dosfs/msdos_file.c @@ -41,8 +41,8 @@ * and errno set appropriately */ int -msdos_file_open(rtems_libio_t *iop, const char *pathname, uint32_t flag, - uint32_t mode) +msdos_file_open(rtems_libio_t *iop, const char *pathname, int oflag, + mode_t mode) { int rc = RC_OK; rtems_status_code sc = RTEMS_SUCCESSFUL; @@ -268,9 +268,9 @@ msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence) */ int msdos_file_stat( - rtems_filesystem_location_info_t *loc, - struct stat *buf - ) + const 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; @@ -426,81 +426,3 @@ msdos_file_datasync(rtems_libio_t *iop) 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,uint32_t command, void *buffer) -{ - int rc = RC_OK; - - 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 - * 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 *parent_pathloc, - 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) - rtems_set_errno_and_return_minus_one(EIO); - - /* mark file removed */ - rc = msdos_set_first_char4file_name(pathloc->mt_entry, - &fat_fd->dir_pos, - 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/cpukit/libfs/src/dosfs/msdos_free.c b/cpukit/libfs/src/dosfs/msdos_free.c index 90fc586a10..da99dc5d36 100644 --- a/cpukit/libfs/src/dosfs/msdos_free.c +++ b/cpukit/libfs/src/dosfs/msdos_free.c @@ -29,28 +29,9 @@ /* 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) +void +msdos_free_node_info(const 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) - rtems_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; + fat_file_close(pathloc->mt_entry, pathloc->node_access); } diff --git a/cpukit/libfs/src/dosfs/msdos_fsunmount.c b/cpukit/libfs/src/dosfs/msdos_fsunmount.c index 310da9c8ff..37b7730525 100644 --- a/cpukit/libfs/src/dosfs/msdos_fsunmount.c +++ b/cpukit/libfs/src/dosfs/msdos_fsunmount.c @@ -38,33 +38,19 @@ * PARAMETERS: * temp_mt_entry - mount table entry * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set apropriately). - * */ -int +void 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; + fat_file_fd_t *fat_fd = temp_mt_entry->mt_fs_root->location.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; - } + fat_file_close(temp_mt_entry, fat_fd); - if (fat_shutdown_drive(temp_mt_entry) != RC_OK) - { - /* no return - try to free as much as possible */ - rc = -1; - } + fat_shutdown_drive(temp_mt_entry); rtems_semaphore_delete(fs_info->vol_sema); free(fs_info->cl_buf); free(temp_mt_entry->fs_info); - - return rc; } diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c index 933960a3e2..193d796dd9 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_dir.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_dir.c @@ -26,10 +26,8 @@ const rtems_filesystem_file_handlers_r msdos_dir_handlers = { rtems_filesystem_default_ioctl, msdos_dir_lseek, msdos_dir_stat, - msdos_dir_chmod, - rtems_filesystem_default_ftruncate, + rtems_filesystem_default_ftruncate_directory, msdos_dir_sync, msdos_dir_sync, - rtems_filesystem_default_fcntl, - msdos_dir_rmnod + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/dosfs/msdos_handlers_file.c b/cpukit/libfs/src/dosfs/msdos_handlers_file.c index 8990236303..fefb6795d9 100644 --- a/cpukit/libfs/src/dosfs/msdos_handlers_file.c +++ b/cpukit/libfs/src/dosfs/msdos_handlers_file.c @@ -23,13 +23,11 @@ const rtems_filesystem_file_handlers_r msdos_file_handlers = { msdos_file_close, msdos_file_read, msdos_file_write, - msdos_file_ioctl, + rtems_filesystem_default_ioctl, msdos_file_lseek, msdos_file_stat, - msdos_file_chmod, msdos_file_ftruncate, msdos_file_sync, msdos_file_datasync, - rtems_filesystem_default_fcntl, - msdos_file_rmnod + rtems_filesystem_default_fcntl }; diff --git a/cpukit/libfs/src/dosfs/msdos_init.c b/cpukit/libfs/src/dosfs/msdos_init.c index 217e0c1f3a..8941ec45dc 100644 --- a/cpukit/libfs/src/dosfs/msdos_init.c +++ b/cpukit/libfs/src/dosfs/msdos_init.c @@ -4,6 +4,9 @@ * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru> * + * Modifications to support reference counting in the file system are + * Copyright (c) 2012 embedded brains GmbH. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. @@ -19,27 +22,59 @@ #include "dosfs.h" #include "msdos.h" +static int msdos_clone_node_info(rtems_filesystem_location_info_t *loc) +{ + fat_file_fd_t *fat_fd = loc->node_access; + + return fat_file_reopen(fat_fd); +} + const rtems_filesystem_operations_table msdos_ops = { - .evalpath_h = msdos_eval_path, - .evalformake_h = msdos_eval4make, + .lock_h = msdos_lock, + .unlock_h = msdos_unlock, + .eval_path_h = msdos_eval_path, .link_h = rtems_filesystem_default_link, - .unlink_h = msdos_file_rmnod, + .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal, .node_type_h = msdos_node_type, .mknod_h = msdos_mknod, + .rmnod_h = msdos_rmnod, + .fchmod_h = rtems_filesystem_default_fchmod, .chown_h = rtems_filesystem_default_chown, + .clonenod_h = msdos_clone_node_info, .freenod_h = msdos_free_node_info, .mount_h = rtems_filesystem_default_mount, .fsmount_me_h = rtems_dosfs_initialize, .unmount_h = rtems_filesystem_default_unmount, .fsunmount_me_h = msdos_shut_down, .utime_h = rtems_filesystem_default_utime, - .eval_link_h = rtems_filesystem_default_evaluate_link, .symlink_h = rtems_filesystem_default_symlink, .readlink_h = rtems_filesystem_default_readlink, .rename_h = msdos_rename, .statvfs_h = rtems_filesystem_default_statvfs }; +void msdos_lock(rtems_filesystem_mount_table_entry_t *mt_entry) +{ + msdos_fs_info_t *fs_info = mt_entry->fs_info; + rtems_status_code sc = rtems_semaphore_obtain( + fs_info->vol_sema, + RTEMS_WAIT, + RTEMS_NO_TIMEOUT + ); + if (sc != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(0xdeadbeef); + } +} + +void msdos_unlock(rtems_filesystem_mount_table_entry_t *mt_entry) +{ + msdos_fs_info_t *fs_info = mt_entry->fs_info; + rtems_status_code sc = rtems_semaphore_release(fs_info->vol_sema); + if (sc != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(0xdeadbeef); + } +} + /* msdos_initialize -- * MSDOS filesystem initialization. Called when mounting an * MSDOS filesystem. diff --git a/cpukit/libfs/src/dosfs/msdos_initsupp.c b/cpukit/libfs/src/dosfs/msdos_initsupp.c index fc10fda71a..27905d08ca 100644 --- a/cpukit/libfs/src/dosfs/msdos_initsupp.c +++ b/cpukit/libfs/src/dosfs/msdos_initsupp.c @@ -141,9 +141,9 @@ msdos_initialize_support( rtems_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; + temp_mt_entry->mt_fs_root->location.node_access = fat_fd; + temp_mt_entry->mt_fs_root->location.handlers = directory_handlers; + temp_mt_entry->mt_fs_root->location.ops = op_table; return rc; } diff --git a/cpukit/libfs/src/dosfs/msdos_misc.c b/cpukit/libfs/src/dosfs/msdos_misc.c index f272d842a2..f27b4aea9c 100644 --- a/cpukit/libfs/src/dosfs/msdos_misc.c +++ b/cpukit/libfs/src/dosfs/msdos_misc.c @@ -257,89 +257,6 @@ msdos_long_to_short(const char *lfn, int lfn_len, char* sfn, int sfn_len) return type; } -/* 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, - int pathlen, - const char **ret_token, - int *ret_token_len) -{ - msdos_token_types_t type = MSDOS_NAME; - int i = 0; - - *ret_token = NULL; - *ret_token_len = 0; - - if (pathlen == 0) - return MSDOS_NO_MORE_PATH; - - /* - * Check for a separator. - */ - while (!msdos_is_separator(path[i]) && (i < pathlen)) - { - if ( !msdos_is_valid_name_char(path[i]) ) - return MSDOS_INVALID_TOKEN; - ++i; - if ( i == MSDOS_NAME_MAX_LFN_WITH_DOT ) - return MSDOS_INVALID_TOKEN; - } - - *ret_token = path; - - /* - * If it is just a separator then it is the current dir. - */ - if ( i == 0 ) - { - if ( (*path != '\0') && pathlen ) - { - i++; - type = MSDOS_CURRENT_DIR; - } - else - type = MSDOS_NO_MORE_PATH; - } - - /* - * Set the token and token_len to the token start and length. - */ - *ret_token_len = i; - - /* - * If we copied something that was not a seperator see if - * it was a special name. - */ - if ( type == MSDOS_NAME ) - { - if ((i == 2) && ((*ret_token)[0] == '.') && ((*ret_token)[1] == '.')) - { - type = MSDOS_UP_DIR; - return type; - } - - if ((i == 1) && ((*ret_token)[0] == '.')) - { - type = MSDOS_CURRENT_DIR; - return type; - } - } - - 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 @@ -491,13 +408,13 @@ msdos_find_name( */ int msdos_get_name_node( - rtems_filesystem_location_info_t *parent_loc, - 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 + const rtems_filesystem_location_info_t *parent_loc, + 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 rc = RC_OK; diff --git a/cpukit/libfs/src/dosfs/msdos_mknod.c b/cpukit/libfs/src/dosfs/msdos_mknod.c index ad4ad50d00..195addaf9f 100644 --- a/cpukit/libfs/src/dosfs/msdos_mknod.c +++ b/cpukit/libfs/src/dosfs/msdos_mknod.c @@ -31,31 +31,16 @@ #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: - * name - file name to create - * 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 *name, - mode_t mode, - dev_t dev, - rtems_filesystem_location_info_t *pathloc + const rtems_filesystem_location_info_t *parentloc, + const char *name, + size_t namelen, + mode_t mode, + dev_t dev ) { 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; + msdos_node_type_t type = 0; /* * Figure out what type of msdos node this is. @@ -71,14 +56,8 @@ int msdos_mknod( else rtems_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) - rtems_set_errno_and_return_minus_one(EIO); - /* Create an MSDOS node */ - rc = msdos_creat_node(pathloc, type, name, strlen(name), mode, NULL); + rc = msdos_creat_node(parentloc, type, name, namelen, mode, NULL); - rtems_semaphore_release(fs_info->vol_sema); return rc; } diff --git a/cpukit/libfs/src/dosfs/msdos_node_type.c b/cpukit/libfs/src/dosfs/msdos_node_type.c index 877cf60492..be6fb9f57e 100644 --- a/cpukit/libfs/src/dosfs/msdos_node_type.c +++ b/cpukit/libfs/src/dosfs/msdos_node_type.c @@ -32,17 +32,17 @@ #include "msdos.h" /* msdos_node_type -- - * Determine type of the node that the pathloc refers to. + * Determine type of the node that the loc refers to. * * PARAMETERS: - * pathloc - node description + * loc - node description * * RETURNS: * node type * */ rtems_filesystem_node_types_t -msdos_node_type(rtems_filesystem_location_info_t *pathloc) +msdos_node_type(const rtems_filesystem_location_info_t *loc) { fat_file_fd_t *fat_fd; @@ -52,7 +52,7 @@ msdos_node_type(rtems_filesystem_location_info_t *pathloc) * hence node_access memory can't be freed during processing node_type_h * call */ - fat_fd = pathloc->node_access; + fat_fd = loc->node_access; return fat_fd->fat_file_type; } diff --git a/cpukit/libfs/src/dosfs/msdos_rename.c b/cpukit/libfs/src/dosfs/msdos_rename.c index 1d285bd01d..8490d58370 100644 --- a/cpukit/libfs/src/dosfs/msdos_rename.c +++ b/cpukit/libfs/src/dosfs/msdos_rename.c @@ -30,53 +30,28 @@ /* msdos_rename -- * Rename the node by removing the exitsing directory entry and creating a * new one. - * - * PARAMETERS: - * old_parent_loc - node description for the "old parent" node - * old_loc - node description for the "old" node - * new_parent_loc - node description for the "parent" node - * name - name of new node - * - * RETURNS: - * RC_OK on success, or -1 if error occured (errno set appropriately) */ int -msdos_rename(rtems_filesystem_location_info_t *old_parent_loc, - rtems_filesystem_location_info_t *old_loc, - rtems_filesystem_location_info_t *new_parent_loc, - const char *new_name) +msdos_rename( + const rtems_filesystem_location_info_t *old_parent_loc, + const rtems_filesystem_location_info_t *old_loc, + const rtems_filesystem_location_info_t *new_parent_loc, + const char *new_name, + size_t new_namelen +) { int rc = RC_OK; - rtems_status_code sc = RTEMS_SUCCESSFUL; - msdos_fs_info_t *fs_info = new_parent_loc->mt_entry->fs_info; fat_file_fd_t *old_fat_fd = old_loc->node_access; - const char *token; - int len; - - /* - * check spelling and format new node name - */ - if (MSDOS_NAME != msdos_get_token(new_name, strlen(new_name), &token, &len)) { - rtems_set_errno_and_return_minus_one(ENAMETOOLONG); - } - /* - * lock volume - */ - sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT, - MSDOS_VOLUME_SEMAPHORE_TIMEOUT); - if (sc != RTEMS_SUCCESSFUL) - rtems_set_errno_and_return_minus_one(EIO); /* * create new directory entry as "hard link", copying relevant info from * existing file */ rc = msdos_creat_node(new_parent_loc, - MSDOS_HARD_LINK,new_name,len,S_IFREG, + MSDOS_HARD_LINK,new_name,new_namelen,S_IFREG, old_fat_fd); if (rc != RC_OK) { - rtems_semaphore_release(fs_info->vol_sema); return rc; } @@ -87,6 +62,5 @@ msdos_rename(rtems_filesystem_location_info_t *old_parent_loc, &old_fat_fd->dir_pos, MSDOS_THIS_DIR_ENTRY_EMPTY); - rtems_semaphore_release(fs_info->vol_sema); return rc; } diff --git a/cpukit/libfs/src/dosfs/msdos_rmnod.c b/cpukit/libfs/src/dosfs/msdos_rmnod.c new file mode 100644 index 0000000000..56431b2133 --- /dev/null +++ b/cpukit/libfs/src/dosfs/msdos_rmnod.c @@ -0,0 +1,79 @@ +/* + * 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.rtems.com/license/LICENSE. + * + * @(#) $Id$ + */ + +#if HAVE_CONFIG_H + #include "config.h" +#endif + +#include "msdos.h" + +int +msdos_rmnod(const rtems_filesystem_location_info_t *parent_pathloc, + const rtems_filesystem_location_info_t *pathloc) +{ + int rc = RC_OK; + fat_file_fd_t *fat_fd = pathloc->node_access; + + if (fat_fd->fat_file_type == MSDOS_DIRECTORY) + { + bool is_empty = false; + + /* + * 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) + { + return rc; + } + + if (!is_empty) + { + rtems_set_errno_and_return_minus_one(ENOTEMPTY); + } + + /* + * We deny attempts to delete open directory (if directory is current + * directory we assume it is open one) + */ + if (fat_fd->links_num > 1) + { + rtems_set_errno_and_return_minus_one(EBUSY); + } + + /* + * You cannot remove the file system root node. + */ + if (rtems_filesystem_location_is_root(pathloc)) + { + rtems_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->dir_pos, + MSDOS_THIS_DIR_ENTRY_EMPTY); + if (rc != RC_OK) + { + return rc; + } + + fat_file_mark_removed(pathloc->mt_entry, fat_fd); + + return rc; +} |