summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/dosfs
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-13 11:33:51 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2012-03-13 12:23:37 +0100
commit3b7c123c8d910eb60ab3b38dec6224e2de9847c9 (patch)
treea67335010c15af5efb5e27224ae9204883c2b5b8 /cpukit/libfs/src/dosfs
parentAdd missing BSD sections. (diff)
downloadrtems-3b7c123c8d910eb60ab3b38dec6224e2de9847c9.tar.bz2
Filesystem: Reference counting for locations
o A new data structure rtems_filesystem_global_location_t was introduced to be used for o the mount point location in the mount table entry, o the file system root location in the mount table entry, o the root directory location in the user environment, and o the current directory location in the user environment. During the path evaluation global start locations are obtained to ensure that the current file system instance will be not unmounted in the meantime. o The user environment uses now reference counting and is protected from concurrent access. o The path evaluation process was completely rewritten and simplified. The IMFS, RFS, NFS, and DOSFS use now a generic path evaluation method. Recursive calls in the path evaluation have been replaced with iteration to avoid stack overflows. Only the evaluation of symbolic links is recursive. No dynamic memory allocations and intermediate buffers are used in the high level path evaluation. No global locks are held during the file system instance specific path evaluation process. o Recursive symbolic link evaluation is now limited by RTEMS_FILESYSTEM_SYMLOOP_MAX. Applications can retrieve this value via sysconf(). o The device file system (devFS) uses now no global variables and allocation from the workspace. Node names are allocated from the heap. o The upper layer lseek() performs now some parameter checks. o The upper layer ftruncate() performs now some parameter checks. o unmask() is now restricted to the RWX flags and protected from concurrent access. o The fchmod_h and rmnod_h file system node handlers are now a file system operation. o The unlink_h operation has been removed. All nodes are now destroyed with the rmnod_h operation. o New lock_h, unlock_h, clonenod_h, and are_nodes_equal_h file system operations. o The path evaluation and file system operations are now protected by per file system instance lock and unlock operations. o Fix and test file descriptor duplicate in fcntl(). o New test fstests/fsnofs01.
Diffstat (limited to 'cpukit/libfs/src/dosfs')
-rw-r--r--cpukit/libfs/src/dosfs/msdos.h125
-rw-r--r--cpukit/libfs/src/dosfs/msdos_create.c19
-rw-r--r--cpukit/libfs/src/dosfs/msdos_dir.c120
-rw-r--r--cpukit/libfs/src/dosfs/msdos_eval.c416
-rw-r--r--cpukit/libfs/src/dosfs/msdos_file.c88
-rw-r--r--cpukit/libfs/src/dosfs/msdos_free.c25
-rw-r--r--cpukit/libfs/src/dosfs/msdos_fsunmount.c22
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_dir.c6
-rw-r--r--cpukit/libfs/src/dosfs/msdos_handlers_file.c6
-rw-r--r--cpukit/libfs/src/dosfs/msdos_init.c43
-rw-r--r--cpukit/libfs/src/dosfs/msdos_initsupp.c6
-rw-r--r--cpukit/libfs/src/dosfs/msdos_misc.c97
-rw-r--r--cpukit/libfs/src/dosfs/msdos_mknod.c35
-rw-r--r--cpukit/libfs/src/dosfs/msdos_node_type.c8
-rw-r--r--cpukit/libfs/src/dosfs/msdos_rename.c42
-rw-r--r--cpukit/libfs/src/dosfs/msdos_rmnod.c79
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;
+}