summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src
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
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')
-rw-r--r--cpukit/libfs/src/defaults/default_are_nodes_equal.c27
-rw-r--r--cpukit/libfs/src/defaults/default_chown.c11
-rw-r--r--cpukit/libfs/src/defaults/default_clone.c26
-rw-r--r--cpukit/libfs/src/defaults/default_eval_path.c27
-rw-r--r--cpukit/libfs/src/defaults/default_evalformake.c32
-rw-r--r--cpukit/libfs/src/defaults/default_evalpath.c25
-rw-r--r--cpukit/libfs/src/defaults/default_evaluate_link.c23
-rw-r--r--cpukit/libfs/src/defaults/default_fchmod.c9
-rw-r--r--cpukit/libfs/src/defaults/default_fcntl.c4
-rw-r--r--cpukit/libfs/src/defaults/default_freenode.c13
-rw-r--r--cpukit/libfs/src/defaults/default_fstat.c14
-rw-r--r--cpukit/libfs/src/defaults/default_fsunmount.c3
-rw-r--r--cpukit/libfs/src/defaults/default_ftruncate.c5
-rw-r--r--cpukit/libfs/src/defaults/default_ftruncate_directory.c28
-rw-r--r--cpukit/libfs/src/defaults/default_handlers.c4
-rw-r--r--cpukit/libfs/src/defaults/default_link.c13
-rw-r--r--cpukit/libfs/src/defaults/default_lock_and_unlock.c33
-rw-r--r--cpukit/libfs/src/defaults/default_mknod.c14
-rw-r--r--cpukit/libfs/src/defaults/default_node_type.c2
-rw-r--r--cpukit/libfs/src/defaults/default_open.c14
-rw-r--r--cpukit/libfs/src/defaults/default_ops.c11
-rw-r--r--cpukit/libfs/src/defaults/default_readlink.c11
-rw-r--r--cpukit/libfs/src/defaults/default_rename.c14
-rw-r--r--cpukit/libfs/src/defaults/default_rmnod.c9
-rw-r--r--cpukit/libfs/src/defaults/default_statvfs.c9
-rw-r--r--cpukit/libfs/src/defaults/default_symlink.c12
-rw-r--r--cpukit/libfs/src/defaults/default_unlink.c22
-rw-r--r--cpukit/libfs/src/defaults/default_utime.c12
-rw-r--r--cpukit/libfs/src/devfs/devclose.c4
-rw-r--r--cpukit/libfs/src/devfs/devfs.h126
-rw-r--r--cpukit/libfs/src/devfs/devfs_eval.c131
-rw-r--r--cpukit/libfs/src/devfs/devfs_init.c114
-rw-r--r--cpukit/libfs/src/devfs/devfs_mknod.c95
-rw-r--r--cpukit/libfs/src/devfs/devfs_node_type.c2
-rw-r--r--cpukit/libfs/src/devfs/devfs_show.c42
-rw-r--r--cpukit/libfs/src/devfs/devioctl.c4
-rw-r--r--cpukit/libfs/src/devfs/devopen.c8
-rw-r--r--cpukit/libfs/src/devfs/devread.c4
-rw-r--r--cpukit/libfs/src/devfs/devstat.c39
-rw-r--r--cpukit/libfs/src/devfs/devwrite.c4
-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
-rw-r--r--cpukit/libfs/src/imfs/deviceio.c12
-rw-r--r--cpukit/libfs/src/imfs/fifoimfs_init.c16
-rw-r--r--cpukit/libfs/src/imfs/imfs.h186
-rw-r--r--cpukit/libfs/src/imfs/imfs_chown.c17
-rw-r--r--cpukit/libfs/src/imfs/imfs_creat.c47
-rw-r--r--cpukit/libfs/src/imfs/imfs_debug.c17
-rw-r--r--cpukit/libfs/src/imfs/imfs_directory.c131
-rw-r--r--cpukit/libfs/src/imfs/imfs_eval.c731
-rw-r--r--cpukit/libfs/src/imfs/imfs_fchmod.c10
-rw-r--r--cpukit/libfs/src/imfs/imfs_fifo.c14
-rw-r--r--cpukit/libfs/src/imfs/imfs_fsunmount.c33
-rw-r--r--cpukit/libfs/src/imfs/imfs_getchild.c66
-rw-r--r--cpukit/libfs/src/imfs/imfs_gtkn.c91
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_device.c8
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_directory.c12
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_link.c8
-rw-r--r--cpukit/libfs/src/imfs/imfs_handlers_memfile.c8
-rw-r--r--cpukit/libfs/src/imfs/imfs_init.c20
-rw-r--r--cpukit/libfs/src/imfs/imfs_initsupp.c29
-rw-r--r--cpukit/libfs/src/imfs/imfs_link.c33
-rw-r--r--cpukit/libfs/src/imfs/imfs_load_tar.c78
-rw-r--r--cpukit/libfs/src/imfs/imfs_mknod.c98
-rw-r--r--cpukit/libfs/src/imfs/imfs_mount.c54
-rw-r--r--cpukit/libfs/src/imfs/imfs_ntype.c27
-rw-r--r--cpukit/libfs/src/imfs/imfs_readlink.c11
-rw-r--r--cpukit/libfs/src/imfs/imfs_rename.c56
-rw-r--r--cpukit/libfs/src/imfs/imfs_rmnod.c92
-rw-r--r--cpukit/libfs/src/imfs/imfs_stat.c53
-rw-r--r--cpukit/libfs/src/imfs/imfs_symlink.c37
-rw-r--r--cpukit/libfs/src/imfs/imfs_unlink.c82
-rw-r--r--cpukit/libfs/src/imfs/imfs_unmount.c63
-rw-r--r--cpukit/libfs/src/imfs/imfs_utime.c16
-rw-r--r--cpukit/libfs/src/imfs/ioman.c54
-rw-r--r--cpukit/libfs/src/imfs/memfile.c15
-rw-r--r--cpukit/libfs/src/imfs/miniimfs_init.c20
-rw-r--r--cpukit/libfs/src/nfsclient/src/librtemsNfs.h2
-rw-r--r--cpukit/libfs/src/nfsclient/src/nfs.c1165
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-dir.h41
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-file.c4
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-file.h4
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-link.c5
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c8
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c46
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c18
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c54
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems.c884
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-rtems.h32
-rw-r--r--cpukit/libfs/src/rfs/rtems-rfs-shell.c10
104 files changed, 2080 insertions, 4575 deletions
diff --git a/cpukit/libfs/src/defaults/default_are_nodes_equal.c b/cpukit/libfs/src/defaults/default_are_nodes_equal.c
new file mode 100644
index 0000000000..c1e7777c40
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_are_nodes_equal.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+bool rtems_filesystem_default_are_nodes_equal(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
+)
+{
+ return a->node_access == b->node_access;
+}
diff --git a/cpukit/libfs/src/defaults/default_chown.c b/cpukit/libfs/src/defaults/default_chown.c
index 82cb0b694f..55c7da9d15 100644
--- a/cpukit/libfs/src/defaults/default_chown.c
+++ b/cpukit/libfs/src/defaults/default_chown.c
@@ -9,14 +9,17 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_chown(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- uid_t owner, /* IN */
- gid_t group /* IN */
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_clone.c b/cpukit/libfs/src/defaults/default_clone.c
new file mode 100644
index 0000000000..5224b01d19
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_clone.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+int rtems_filesystem_default_clonenode(
+ rtems_filesystem_location_info_t *loc
+)
+{
+ return 0;
+}
diff --git a/cpukit/libfs/src/defaults/default_eval_path.c b/cpukit/libfs/src/defaults/default_eval_path.c
new file mode 100644
index 0000000000..e639f9985c
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_eval_path.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+void rtems_filesystem_default_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
+)
+{
+ ctx->pathlen = 0;
+ rtems_filesystem_location_detach(&ctx->currentloc);
+}
diff --git a/cpukit/libfs/src/defaults/default_evalformake.c b/cpukit/libfs/src/defaults/default_evalformake.c
deleted file mode 100644
index 891d961dc1..0000000000
--- a/cpukit/libfs/src/defaults/default_evalformake.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file
- *
- * @ingroup LibIO
- *
- * @brief rtems_filesystem_default_evalformake() implementation.
- */
-
-/*
- * Copyright (c) 2010
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * D-82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * 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.
- */
-
-#include <rtems/libio.h>
-#include <rtems/seterr.h>
-
-int rtems_filesystem_default_evalformake(
- const char *path,
- rtems_filesystem_location_info_t *pathloc,
- const char **name
-)
-{
- rtems_set_errno_and_return_minus_one( ENOTSUP );
-}
diff --git a/cpukit/libfs/src/defaults/default_evalpath.c b/cpukit/libfs/src/defaults/default_evalpath.c
deleted file mode 100644
index 1e3f762cbe..0000000000
--- a/cpukit/libfs/src/defaults/default_evalpath.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * COPYRIGHT (c) 2010.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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$
- */
-
-#include <rtems/libio.h>
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
-int rtems_filesystem_default_evalpath(
- const char *pathname, /* IN */
- size_t pathnamelen, /* IN */
- int flags, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
-)
-{
- rtems_set_errno_and_return_minus_one( ENOTSUP );
-}
-
diff --git a/cpukit/libfs/src/defaults/default_evaluate_link.c b/cpukit/libfs/src/defaults/default_evaluate_link.c
deleted file mode 100644
index a82c73729f..0000000000
--- a/cpukit/libfs/src/defaults/default_evaluate_link.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * COPYRIGHT (c) 2010.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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$
- */
-
-#include <rtems/libio.h>
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
-int rtems_filesystem_default_evaluate_link(
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- int flags /* IN */
-)
-{
- rtems_set_errno_and_return_minus_one( ENOTSUP );
-}
-
diff --git a/cpukit/libfs/src/defaults/default_fchmod.c b/cpukit/libfs/src/defaults/default_fchmod.c
index cda32c82d5..652e24322f 100644
--- a/cpukit/libfs/src/defaults/default_fchmod.c
+++ b/cpukit/libfs/src/defaults/default_fchmod.c
@@ -9,13 +9,16 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_fchmod(
- rtems_filesystem_location_info_t *loc,
- mode_t mode
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_fcntl.c b/cpukit/libfs/src/defaults/default_fcntl.c
index d9d8602e40..0374a4f4fa 100644
--- a/cpukit/libfs/src/defaults/default_fcntl.c
+++ b/cpukit/libfs/src/defaults/default_fcntl.c
@@ -14,8 +14,8 @@
#include <rtems/seterr.h>
int rtems_filesystem_default_fcntl(
- int cmd,
- rtems_libio_t *iop
+ rtems_libio_t *iop,
+ int cmd
)
{
return 0;
diff --git a/cpukit/libfs/src/defaults/default_freenode.c b/cpukit/libfs/src/defaults/default_freenode.c
index bb231d13f7..2a5f8f1338 100644
--- a/cpukit/libfs/src/defaults/default_freenode.c
+++ b/cpukit/libfs/src/defaults/default_freenode.c
@@ -9,14 +9,15 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-int rtems_filesystem_default_freenode(
- rtems_filesystem_location_info_t *pathloc /* IN */
+void rtems_filesystem_default_freenode(
+ const rtems_filesystem_location_info_t *loc
)
{
- return 0;
+ /* Do nothing */
}
-
diff --git a/cpukit/libfs/src/defaults/default_fstat.c b/cpukit/libfs/src/defaults/default_fstat.c
index 6c8d501a21..564d4e6201 100644
--- a/cpukit/libfs/src/defaults/default_fstat.c
+++ b/cpukit/libfs/src/defaults/default_fstat.c
@@ -9,14 +9,18 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
-#include <rtems/seterr.h>
int rtems_filesystem_default_fstat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
)
{
- rtems_set_errno_and_return_minus_one( ENOTSUP );
+ buf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO;
+
+ return 0;
}
diff --git a/cpukit/libfs/src/defaults/default_fsunmount.c b/cpukit/libfs/src/defaults/default_fsunmount.c
index e879f5c2f8..ba4a0a1fa4 100644
--- a/cpukit/libfs/src/defaults/default_fsunmount.c
+++ b/cpukit/libfs/src/defaults/default_fsunmount.c
@@ -13,9 +13,8 @@
#include <rtems/libio_.h>
#include <rtems/seterr.h>
-int rtems_filesystem_default_fsunmount(
+void rtems_filesystem_default_fsunmount(
rtems_filesystem_mount_table_entry_t *mt_entry /* IN */
)
{
- return 0;
}
diff --git a/cpukit/libfs/src/defaults/default_ftruncate.c b/cpukit/libfs/src/defaults/default_ftruncate.c
index b1e958f36c..ad8777487d 100644
--- a/cpukit/libfs/src/defaults/default_ftruncate.c
+++ b/cpukit/libfs/src/defaults/default_ftruncate.c
@@ -9,7 +9,10 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
diff --git a/cpukit/libfs/src/defaults/default_ftruncate_directory.c b/cpukit/libfs/src/defaults/default_ftruncate_directory.c
new file mode 100644
index 0000000000..e438154d77
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_ftruncate_directory.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+#include <rtems/seterr.h>
+
+int rtems_filesystem_default_ftruncate_directory(
+ rtems_libio_t *iop,
+ off_t length
+)
+{
+ rtems_set_errno_and_return_minus_one( EISDIR );
+}
diff --git a/cpukit/libfs/src/defaults/default_handlers.c b/cpukit/libfs/src/defaults/default_handlers.c
index ce6288bbd9..286c2b4157 100644
--- a/cpukit/libfs/src/defaults/default_handlers.c
+++ b/cpukit/libfs/src/defaults/default_handlers.c
@@ -29,10 +29,8 @@ const rtems_filesystem_file_handlers_r rtems_filesystem_handlers_default = {
.ioctl_h = rtems_filesystem_default_ioctl,
.lseek_h = rtems_filesystem_default_lseek,
.fstat_h = rtems_filesystem_default_fstat,
- .fchmod_h = rtems_filesystem_default_fchmod,
.ftruncate_h = rtems_filesystem_default_ftruncate,
.fsync_h = rtems_filesystem_default_fsync,
.fdatasync_h = rtems_filesystem_default_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .rmnod_h = rtems_filesystem_default_rmnod
+ .fcntl_h = rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/defaults/default_link.c b/cpukit/libfs/src/defaults/default_link.c
index d9bc913b27..40b70a89f8 100644
--- a/cpukit/libfs/src/defaults/default_link.c
+++ b/cpukit/libfs/src/defaults/default_link.c
@@ -9,16 +9,19 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_link(
- rtems_filesystem_location_info_t *to_loc, /* IN */
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- const char *name /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
}
-
diff --git a/cpukit/libfs/src/defaults/default_lock_and_unlock.c b/cpukit/libfs/src/defaults/default_lock_and_unlock.c
new file mode 100644
index 0000000000..de29a076f1
--- /dev/null
+++ b/cpukit/libfs/src/defaults/default_lock_and_unlock.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/libio_.h>
+
+void rtems_filesystem_default_lock(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+)
+{
+ rtems_libio_lock();
+}
+
+void rtems_filesystem_default_unlock(
+ rtems_filesystem_mount_table_entry_t *mt_entry
+)
+{
+ rtems_libio_unlock();
+}
diff --git a/cpukit/libfs/src/defaults/default_mknod.c b/cpukit/libfs/src/defaults/default_mknod.c
index fcd03be4c2..17a208a772 100644
--- a/cpukit/libfs/src/defaults/default_mknod.c
+++ b/cpukit/libfs/src/defaults/default_mknod.c
@@ -9,15 +9,19 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_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 *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_node_type.c b/cpukit/libfs/src/defaults/default_node_type.c
index a118a04f72..6627fbf5dd 100644
--- a/cpukit/libfs/src/defaults/default_node_type.c
+++ b/cpukit/libfs/src/defaults/default_node_type.c
@@ -22,7 +22,7 @@
#include <rtems/libio.h>
rtems_filesystem_node_types_t rtems_filesystem_default_node_type(
- rtems_filesystem_location_info_t *pathloc
+ const rtems_filesystem_location_info_t *loc
)
{
return RTEMS_FILESYSTEM_INVALID_NODE_TYPE;
diff --git a/cpukit/libfs/src/defaults/default_open.c b/cpukit/libfs/src/defaults/default_open.c
index b119fbf5be..aa856bfb8f 100644
--- a/cpukit/libfs/src/defaults/default_open.c
+++ b/cpukit/libfs/src/defaults/default_open.c
@@ -9,16 +9,18 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
-#include <rtems/seterr.h>
int rtems_filesystem_default_open(
rtems_libio_t *iop,
- const char *pathname,
- uint32_t flag,
- uint32_t mode
+ const char *path,
+ int oflag,
+ mode_t mode
)
{
- rtems_set_errno_and_return_minus_one( ENOTSUP );
+ return 0;
}
diff --git a/cpukit/libfs/src/defaults/default_ops.c b/cpukit/libfs/src/defaults/default_ops.c
index 575cf6b2d4..dfd1ba2009 100644
--- a/cpukit/libfs/src/defaults/default_ops.c
+++ b/cpukit/libfs/src/defaults/default_ops.c
@@ -22,20 +22,23 @@
#include <rtems/libio.h>
const rtems_filesystem_operations_table rtems_filesystem_operations_default = {
- .evalpath_h = rtems_filesystem_default_evalpath,
- .evalformake_h = rtems_filesystem_default_evalformake,
+ .lock_h = rtems_filesystem_default_lock,
+ .unlock_h = rtems_filesystem_default_unlock,
+ .eval_path_h = rtems_filesystem_default_eval_path,
.link_h = rtems_filesystem_default_link,
- .unlink_h = rtems_filesystem_default_unlink,
+ .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
.node_type_h = rtems_filesystem_default_node_type,
.mknod_h = rtems_filesystem_default_mknod,
+ .rmnod_h = rtems_filesystem_default_rmnod,
+ .fchmod_h = rtems_filesystem_default_fchmod,
.chown_h = rtems_filesystem_default_chown,
+ .clonenod_h = rtems_filesystem_default_clonenode,
.freenod_h = rtems_filesystem_default_freenode,
.mount_h = rtems_filesystem_default_mount,
.fsmount_me_h = rtems_filesystem_default_fsmount,
.unmount_h = rtems_filesystem_default_unmount,
.fsunmount_me_h = rtems_filesystem_default_fsunmount,
.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 = rtems_filesystem_default_rename,
diff --git a/cpukit/libfs/src/defaults/default_readlink.c b/cpukit/libfs/src/defaults/default_readlink.c
index 1d07970999..028eb3f75a 100644
--- a/cpukit/libfs/src/defaults/default_readlink.c
+++ b/cpukit/libfs/src/defaults/default_readlink.c
@@ -9,14 +9,17 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
ssize_t rtems_filesystem_default_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- char *buf, /* OUT */
- size_t bufsize
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_rename.c b/cpukit/libfs/src/defaults/default_rename.c
index 93bf15f2e0..748d74b3ec 100644
--- a/cpukit/libfs/src/defaults/default_rename.c
+++ b/cpukit/libfs/src/defaults/default_rename.c
@@ -9,15 +9,19 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_rename(
- rtems_filesystem_location_info_t *old_parent_loc, /* IN */
- rtems_filesystem_location_info_t *old_loc, /* IN */
- rtems_filesystem_location_info_t *new_parent_loc, /* IN */
- const char *name /* IN */
+ const rtems_filesystem_location_info_t *oldparentloc,
+ const rtems_filesystem_location_info_t *oldloc,
+ const rtems_filesystem_location_info_t *newparentloc,
+ const char *name,
+ size_t namelen
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_rmnod.c b/cpukit/libfs/src/defaults/default_rmnod.c
index 776ee4b659..8c1014bb98 100644
--- a/cpukit/libfs/src/defaults/default_rmnod.c
+++ b/cpukit/libfs/src/defaults/default_rmnod.c
@@ -9,13 +9,16 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_rmnod(
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_statvfs.c b/cpukit/libfs/src/defaults/default_statvfs.c
index 22d891815f..f26ecc6a7c 100644
--- a/cpukit/libfs/src/defaults/default_statvfs.c
+++ b/cpukit/libfs/src/defaults/default_statvfs.c
@@ -9,13 +9,16 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_statvfs(
- rtems_filesystem_location_info_t *loc, /* IN */
- struct statvfs *buf /* OUT */
+ const rtems_filesystem_location_info_t *loc,
+ struct statvfs *buf
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_symlink.c b/cpukit/libfs/src/defaults/default_symlink.c
index 8985d76aef..95ae455379 100644
--- a/cpukit/libfs/src/defaults/default_symlink.c
+++ b/cpukit/libfs/src/defaults/default_symlink.c
@@ -9,14 +9,18 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_symlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- const char *link_name, /* IN */
- const char *node_name
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
diff --git a/cpukit/libfs/src/defaults/default_unlink.c b/cpukit/libfs/src/defaults/default_unlink.c
deleted file mode 100644
index cf633c6ce1..0000000000
--- a/cpukit/libfs/src/defaults/default_unlink.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * COPYRIGHT (c) 2010.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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$
- */
-
-#include <rtems/libio.h>
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
-int rtems_filesystem_default_unlink(
- rtems_filesystem_location_info_t *parent_pathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
-)
-{
- rtems_set_errno_and_return_minus_one( ENOTSUP );
-}
diff --git a/cpukit/libfs/src/defaults/default_utime.c b/cpukit/libfs/src/defaults/default_utime.c
index 77a2f2e8d6..b1f57c7f5b 100644
--- a/cpukit/libfs/src/defaults/default_utime.c
+++ b/cpukit/libfs/src/defaults/default_utime.c
@@ -9,16 +9,18 @@
* $Id$
*/
-#include <rtems/libio.h>
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
#include <rtems/libio_.h>
#include <rtems/seterr.h>
int rtems_filesystem_default_utime(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- time_t actime, /* IN */
- time_t modtime /* IN */
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
)
{
rtems_set_errno_and_return_minus_one( ENOTSUP );
}
-
diff --git a/cpukit/libfs/src/devfs/devclose.c b/cpukit/libfs/src/devfs/devclose.c
index 773cade5c6..f69ac291fe 100644
--- a/cpukit/libfs/src/devfs/devclose.c
+++ b/cpukit/libfs/src/devfs/devclose.c
@@ -21,9 +21,7 @@ int devFS_close(
{
rtems_libio_open_close_args_t args;
rtems_status_code status;
- rtems_device_name_t *np;
-
- np = (rtems_device_name_t *)iop->pathinfo.node_access;
+ const devFS_node *np = iop->pathinfo.node_access;
args.iop = iop;
args.flags = 0;
diff --git a/cpukit/libfs/src/devfs/devfs.h b/cpukit/libfs/src/devfs/devfs.h
index 6e4f2478c7..758edf932b 100644
--- a/cpukit/libfs/src/devfs/devfs.h
+++ b/cpukit/libfs/src/devfs/devfs.h
@@ -17,38 +17,54 @@ extern "C" {
/**
* This structure define the type of device table
*/
-
-typedef struct
-{
- /** This member points to device name which is a null-terminated string */
- const char *device_name;
+typedef struct {
+ /** This member points to device name which is not a null-terminated string */
+ const char *name;
/** This member is the name length of a device */
- uint32_t device_name_length;
+ size_t namelen;
/** major number of a device */
rtems_device_major_number major;
/** minor number of a device */
rtems_device_minor_number minor;
/** device creation mode, only device file can be created */
mode_t mode;
+} devFS_node;
-} rtems_device_name_t;
+typedef struct {
+ devFS_node *nodes;
+ size_t count;
+} devFS_data;
+/**
+ * The following defines the device-only filesystem operating
+ * operations.
+ */
+extern const rtems_filesystem_operations_table devFS_ops;
/**
- * This routine associates RTEMS status code with errno
+ * The following defines the device-only filesystem operating
+ * handlers.
*/
-extern int rtems_deviceio_errno(rtems_status_code code);
-
+extern const rtems_filesystem_file_handlers_r devFS_file_handlers;
/**
- * The following defines the device table size. This values
- * is configured during application configuration time by
- * the user. The default value is set to 4.
+ * This routine associates RTEMS status code with errno
*/
-extern uint32_t rtems_device_table_size;
+extern int rtems_deviceio_errno(rtems_status_code code);
+
+static inline const devFS_data *devFS_get_data(
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ return loc->mt_entry->immutable_fs_info;
+}
+
+extern void devFS_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
+);
/**
* This handler maps open operation to rtems_io_open.
@@ -62,8 +78,8 @@ extern uint32_t rtems_device_table_size;
extern int devFS_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
);
@@ -142,8 +158,8 @@ extern int devFS_ioctl(
*/
extern int devFS_stat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
);
@@ -153,63 +169,15 @@ extern int devFS_stat(
* Since this is a device-only filesystem, so there is only
* one node type in the system.
*
- * @param pathloc contains filesytem access information, this
+ * @param loc contains filesytem access information, this
* parameter is ignored
* @retval always returns RTEMS_FILESYSTEM_DEVICE
*/
extern rtems_filesystem_node_types_t devFS_node_type(
- rtems_filesystem_location_info_t *pathloc
+ const rtems_filesystem_location_info_t*loc
);
-
-
-/**
- * This routine is invoked to determine if 'pathname' exists.
- * This routine first check access flags, then it searches
- * the device table to get the information.
- *
- * @param pathname device name to be searched
- * @param flags access flags
- * @param pathloc contains filesystem access information
- * @retval upon success(pathname exists), this routines
- * returns 0; if 'flag' is invalid, it returns -1 and errno
- * is set to EIO; otherwise, it returns -1 and errno is set to ENOENT
- */
-
-extern int devFS_evaluate_path(
- const char *pathname,
- size_t pathnamelen,
- int flags,
- rtems_filesystem_location_info_t *pathloc
-);
-
-
-/**
- * This routine is given a path to evaluate and a valid start
- * location. It is responsible for finding the parent node for
- * a requested make command, setting pathloc information to
- * identify the parent node, and setting the name pointer to
- * the first character of the name of the new node. In device
- * only filesystem, devices do not has a tree hierarchy, there
- * are no parent-child relationship. So this routine is rather
- * simple, it just set *name to path and returns
- *
- * @param path device path to be evaluated
- * @param pathloc contains filesystem access information, this
- * parameter is ignored
- * @param name
- * @retval always returns 0
- */
-
-extern int devFS_evaluate_for_make(
- const char *path,
- rtems_filesystem_location_info_t *pathloc,
- const char **name
-);
-
-
-
/**
* This routine is invoked upon registration of a new device
* file. It is responsible for creating a item in the main
@@ -217,21 +185,15 @@ extern int devFS_evaluate_for_make(
* sequential order, when found a empty slot, it fills the slot
* with proper values.
*
- * @param path the device file name to be registered
- * @param mode file mode, this parameter is ignored
- * @param dev device major and minor number
- * @param pathloc contains filesystem access information
- * @retval upon success, this routine returns 0; if 'path'
- * already exist, it returns -1 and errno is set to EEXIST;
- * if device table is full, it returns -1 and errno is set
- * to ENOMEM
+ * @see rtems_filesystem_mknod_t.
*/
extern int devFS_mknod(
- const char *path,
- 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
);
@@ -266,11 +228,9 @@ extern int devFS_initialize(
*
* This routine is intended for debugging, and can be used by shell
* program to provide user with the system information.
- *
- * @retval 0
*/
-extern int devFS_Show(void);
+extern void devFS_Show(void);
#ifdef __cplusplus
}
diff --git a/cpukit/libfs/src/devfs/devfs_eval.c b/cpukit/libfs/src/devfs/devfs_eval.c
index a3169fb3fa..b7a31ee921 100644
--- a/cpukit/libfs/src/devfs/devfs_eval.c
+++ b/cpukit/libfs/src/devfs/devfs_eval.c
@@ -7,79 +7,84 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/seterr.h>
-#include <fcntl.h>
-#include <assert.h>
-#include "devfs.h"
-
-/**
- * The following defines the device-only filesystem operating
- * handlers.
- */
+#include <string.h>
-extern rtems_filesystem_operations_table devFS_ops;
-
-/**
- * The following defines the device-only filesystem operating
- * handlers.
- */
-
-extern rtems_filesystem_file_handlers_r devFS_file_handlers;
+#include "devfs.h"
-int devFS_evaluate_path(
- const char *pathname,
- size_t pathnamelen,
- int flags,
- rtems_filesystem_location_info_t *pathloc
+static devFS_node *devFS_search_node(
+ const devFS_data *data,
+ const char *path,
+ size_t pathlen,
+ devFS_node **free_node_ptr
)
{
- int i;
- rtems_device_name_t *device_name_table;
-
- /* see if 'flags' is valid */
- if ( !rtems_libio_is_valid_perms( flags ) )
- rtems_set_errno_and_return_minus_one( EPERM );
-
- /* get the device name table */
- device_name_table = (rtems_device_name_t *)pathloc->node_access;
- if (!device_name_table)
- rtems_set_errno_and_return_minus_one( EFAULT );
-
- for (i = 0; i < rtems_device_table_size; i++) {
- if (!device_name_table[i].device_name)
- continue;
-
- if (strncmp(pathname, device_name_table[i].device_name, pathnamelen) != 0)
- continue;
-
- if (device_name_table[i].device_name[pathnamelen] != '\0')
- continue;
-
- /* find the device, set proper values */
- pathloc->node_access = (void *)&device_name_table[i];
- pathloc->handlers = &devFS_file_handlers;
- pathloc->ops = &devFS_ops;
- pathloc->mt_entry = rtems_filesystem_root.mt_entry;
- return 0;
+ size_t i = 0;
+ size_t n = data->count;
+ devFS_node *nodes = data->nodes;
+ devFS_node *node = NULL;
+ devFS_node *free_node = NULL;
+
+ for (i = 0; (free_node == NULL || node == NULL) && i < n; ++i) {
+ devFS_node *current = nodes + i;
+
+ if (current->name != NULL) {
+ if (
+ current->namelen == pathlen
+ && memcmp(current->name, path, pathlen) == 0
+ ) {
+ node = current;
+ }
+ } else {
+ free_node = current;
+ }
}
- /* no such file or directory */
- rtems_set_errno_and_return_minus_one( ENOENT );
-}
-
+ *free_node_ptr = free_node;
+ return node;
+}
-int devFS_evaluate_for_make(
- const char *path,
- rtems_filesystem_location_info_t *pathloc,
- const char **name
+void devFS_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
)
{
- /* we do nothing, just set name to path */
- *name = path;
- return 0;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ devFS_node *free_node;
+ devFS_node *node = devFS_search_node(
+ devFS_get_data(currentloc),
+ rtems_filesystem_eval_path_get_path(ctx),
+ rtems_filesystem_eval_path_get_pathlen(ctx),
+ &free_node
+ );
+ int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
+
+ if (node != NULL) {
+ if ((eval_flags & RTEMS_LIBIO_EXCLUSIVE) == 0) {
+ currentloc->node_access = node;
+ rtems_filesystem_eval_path_clear_path(ctx);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, EEXIST);
+ }
+ } else {
+ if ((eval_flags & RTEMS_LIBIO_MAKE) != 0) {
+ if (free_node != NULL) {
+ free_node->mode = S_IRWXU | S_IRWXG | S_IRWXO;
+ currentloc->node_access = free_node;
+ rtems_filesystem_eval_path_set_token(
+ ctx,
+ rtems_filesystem_eval_path_get_path(ctx),
+ rtems_filesystem_eval_path_get_pathlen(ctx)
+ );
+ rtems_filesystem_eval_path_clear_path(ctx);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOSPC);
+ }
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOENT);
+ }
+ }
}
-
diff --git a/cpukit/libfs/src/devfs/devfs_init.c b/cpukit/libfs/src/devfs/devfs_init.c
index bd741e41a2..070aced2a4 100644
--- a/cpukit/libfs/src/devfs/devfs_init.c
+++ b/cpukit/libfs/src/devfs/devfs_init.c
@@ -7,85 +7,65 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <stdlib.h>
-#include <rtems.h>
-#include <rtems/seterr.h>
-#include <rtems/score/wkspace.h>
#include "devfs.h"
-rtems_filesystem_operations_table devFS_ops =
-{
- devFS_evaluate_path,
- devFS_evaluate_for_make,
- rtems_filesystem_default_link,
- rtems_filesystem_default_unlink,
- devFS_node_type,
- devFS_mknod,
- rtems_filesystem_default_chown,
- rtems_filesystem_default_freenode,
- rtems_filesystem_default_mount,
- devFS_initialize,
- rtems_filesystem_default_unmount,
- rtems_filesystem_default_fsunmount,
- rtems_filesystem_default_utime,
- rtems_filesystem_default_evaluate_link,
- rtems_filesystem_default_symlink,
- rtems_filesystem_default_readlink,
- rtems_filesystem_default_rename,
- rtems_filesystem_default_statvfs
+const rtems_filesystem_operations_table devFS_ops = {
+ .lock_h = rtems_filesystem_default_lock,
+ .unlock_h = rtems_filesystem_default_unlock,
+ .eval_path_h = devFS_eval_path,
+ .link_h = rtems_filesystem_default_link,
+ .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
+ .node_type_h = devFS_node_type,
+ .mknod_h = devFS_mknod,
+ .rmnod_h = rtems_filesystem_default_rmnod,
+ .fchmod_h = rtems_filesystem_default_fchmod,
+ .chown_h = rtems_filesystem_default_chown,
+ .clonenod_h = rtems_filesystem_default_clonenode,
+ .freenod_h = rtems_filesystem_default_freenode,
+ .mount_h = rtems_filesystem_default_mount,
+ .fsmount_me_h = devFS_initialize,
+ .unmount_h = rtems_filesystem_default_unmount,
+ .fsunmount_me_h = rtems_filesystem_default_fsunmount,
+ .utime_h = rtems_filesystem_default_utime,
+ .symlink_h = rtems_filesystem_default_symlink,
+ .readlink_h = rtems_filesystem_default_readlink,
+ .rename_h = rtems_filesystem_default_rename,
+ .statvfs_h = rtems_filesystem_default_statvfs
};
-
-rtems_filesystem_file_handlers_r devFS_file_handlers =
-{
- devFS_open,
- devFS_close,
- devFS_read,
- devFS_write,
- devFS_ioctl,
- rtems_filesystem_default_lseek,
- devFS_stat,
- rtems_filesystem_default_fchmod,
- rtems_filesystem_default_ftruncate,
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- rtems_filesystem_default_rmnod
+const rtems_filesystem_file_handlers_r devFS_file_handlers = {
+ .open_h = devFS_open,
+ .close_h = devFS_close,
+ .read_h = devFS_read,
+ .write_h = devFS_write,
+ .ioctl_h = devFS_ioctl,
+ .lseek_h = rtems_filesystem_default_lseek,
+ .fstat_h = devFS_stat,
+ .ftruncate_h = rtems_filesystem_default_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
-
-
int devFS_initialize(
- rtems_filesystem_mount_table_entry_t *temp_mt_entry,
- const void *data
+ rtems_filesystem_mount_table_entry_t *mt_entry,
+ const void *data
)
{
- rtems_device_name_t *device_name_table;
-
- /* allocate device only filesystem name table */
- device_name_table = (rtems_device_name_t *)_Workspace_Allocate(
- sizeof( rtems_device_name_t ) * ( rtems_device_table_size )
- );
-
- /* no memory for device filesystem */
- if (!device_name_table)
- rtems_set_errno_and_return_minus_one( ENOMEM );
-
- memset(
- device_name_table, 0,
- sizeof( rtems_device_name_t ) * ( rtems_device_table_size )
- );
-
- /* set file handlers */
- temp_mt_entry->mt_fs_root.handlers = &devFS_file_handlers;
- temp_mt_entry->mt_fs_root.ops = &devFS_ops;
+ int rv = 0;
- /* Set the node_access to device name table */
- temp_mt_entry->mt_fs_root.node_access = (void *)device_name_table;
+ if (data != NULL) {
+ mt_entry->immutable_fs_info = data;
+ mt_entry->mt_fs_root->location.handlers = &devFS_file_handlers;
+ mt_entry->mt_fs_root->location.ops = &devFS_ops;
+ } else {
+ errno = EINVAL;
+ rv = -1;
+ }
- return 0;
+ return rv;
}
diff --git a/cpukit/libfs/src/devfs/devfs_mknod.c b/cpukit/libfs/src/devfs/devfs_mknod.c
index 4a8b8b3523..9760c5e5c7 100644
--- a/cpukit/libfs/src/devfs/devfs_mknod.c
+++ b/cpukit/libfs/src/devfs/devfs_mknod.c
@@ -7,75 +7,52 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
#include <stdlib.h>
+#include <string.h>
-#include <rtems/seterr.h>
#include "devfs.h"
int devFS_mknod(
- const char *path,
- 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 i;
- int slot;
- rtems_device_name_t *device_name_table;
- rtems_device_major_number major;
- rtems_device_minor_number minor;
- ISR_Level level;
-
- /*
- * This is a special case. In rtems_filesystem_initialize,
- * a special device '/dev' will be created. We check this
- * condition and do not create the '/dev' and the 'path'
- * actually passed in is 'dev', not '/dev'. Just return 0 to
- * indicate we are OK.
- */
-
- if ((path[0] == 'd') && (path[1] == 'e') &&
- (path[2] == 'v') && (path[3] == '\0'))
- return 0;
-
- /* must be a character device or a block device */
- if (!S_ISBLK(mode) && !S_ISCHR(mode))
- rtems_set_errno_and_return_minus_one( EINVAL );
- else
- rtems_filesystem_split_dev_t(dev, major, minor);
-
- /* Find an empty slot in device name table */
- device_name_table = (rtems_device_name_t *)pathloc->node_access;
- if (!device_name_table)
- rtems_set_errno_and_return_minus_one( EFAULT );
-
- for (slot = -1, i = 0; i < rtems_device_table_size; i++){
- if (device_name_table[i].device_name == NULL)
- slot = i;
- else
- if (strcmp(path, device_name_table[i].device_name) == 0)
- rtems_set_errno_and_return_minus_one( EEXIST );
+ int rv = 0;
+
+ if (namelen != 3 || name [0] != 'd' || name [1] != 'e' || name [2] != 'v') {
+ if (S_ISBLK(mode) || S_ISCHR(mode)) {
+ char *dupname = malloc(namelen);
+
+ if (dupname != NULL) {
+ devFS_node *node = parentloc->node_access;
+
+ node->name = dupname;
+ node->namelen = namelen;
+ node->major = rtems_filesystem_dev_major_t(dev);
+ node->minor = rtems_filesystem_dev_minor_t(dev);
+ node->mode = mode;
+ memcpy(dupname, name, namelen);
+ } else {
+ errno = ENOMEM;
+ rv = -1;
+ }
+ } else {
+ errno = ENOTSUP;
+ rv = -1;
+ }
+ } else {
+ if (!S_ISDIR(mode)) {
+ errno = ENOTSUP;
+ rv = -1;
+ }
}
- if (slot == -1)
- rtems_set_errno_and_return_minus_one( ENOMEM );
-
- _ISR_Disable(level);
- device_name_table[slot].device_name = path;
- device_name_table[slot].device_name_length = strlen(path);
- device_name_table[slot].major = major;
- device_name_table[slot].minor = minor;
- device_name_table[slot].mode = mode;
- _ISR_Enable(level);
-
- return 0;
+ return rv;
}
-
diff --git a/cpukit/libfs/src/devfs/devfs_node_type.c b/cpukit/libfs/src/devfs/devfs_node_type.c
index 0bede52d2d..c4bd488680 100644
--- a/cpukit/libfs/src/devfs/devfs_node_type.c
+++ b/cpukit/libfs/src/devfs/devfs_node_type.c
@@ -13,7 +13,7 @@
#include "devfs.h"
rtems_filesystem_node_types_t devFS_node_type(
- rtems_filesystem_location_info_t *pathloc
+ const rtems_filesystem_location_info_t *loc
)
{
/*
diff --git a/cpukit/libfs/src/devfs/devfs_show.c b/cpukit/libfs/src/devfs/devfs_show.c
index e449caf49f..6d30d3f5d6 100644
--- a/cpukit/libfs/src/devfs/devfs_show.c
+++ b/cpukit/libfs/src/devfs/devfs_show.c
@@ -7,30 +7,38 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/seterr.h>
#include "devfs.h"
-int devFS_Show(void)
+void devFS_Show(void)
{
- int i;
- rtems_filesystem_location_info_t *temp_loc;
- rtems_device_name_t *device_name_table;
+ rtems_filesystem_location_info_t *rootloc = &rtems_filesystem_root->location;
- temp_loc = &rtems_filesystem_root;
- device_name_table = (rtems_device_name_t *)temp_loc->node_access;
- if (!device_name_table)
- rtems_set_errno_and_return_minus_one( EFAULT );
+ if (rootloc->ops == &devFS_ops) {
+ const devFS_data *data = devFS_get_data(rootloc);
+ size_t i = 0;
+ size_t n = data->count;
+ devFS_node *nodes = data->nodes;
- for (i = 0; i < rtems_device_table_size; i++){
- if (device_name_table[i].device_name){
- printk("/%s %d %d\n", device_name_table[i].device_name,
- device_name_table[i].major, device_name_table[i].minor);
+ for (i = 0; i < n; ++i) {
+ devFS_node *current = nodes + i;
+
+ if (current->name != NULL) {
+ size_t j = 0;
+ size_t m = current->namelen;
+
+ printk("/");
+ for (j = 0; j < m; ++j) {
+ printk("%c", current->name [j]);
+ }
+ printk(
+ " %lu %lu\n",
+ (unsigned long) current->major,
+ (unsigned long) current->minor
+ );
+ }
}
}
- return 0;
}
-
-
diff --git a/cpukit/libfs/src/devfs/devioctl.c b/cpukit/libfs/src/devfs/devioctl.c
index 15965b8c0e..457596fdc4 100644
--- a/cpukit/libfs/src/devfs/devioctl.c
+++ b/cpukit/libfs/src/devfs/devioctl.c
@@ -23,9 +23,7 @@ int devFS_ioctl(
{
rtems_libio_ioctl_args_t args;
rtems_status_code status;
- rtems_device_name_t *np;
-
- np = (rtems_device_name_t *)iop->pathinfo.node_access;
+ const devFS_node *np = iop->pathinfo.node_access;
args.iop = iop;
args.command = command;
diff --git a/cpukit/libfs/src/devfs/devopen.c b/cpukit/libfs/src/devfs/devopen.c
index 67be3678e1..1b100e1cc7 100644
--- a/cpukit/libfs/src/devfs/devopen.c
+++ b/cpukit/libfs/src/devfs/devopen.c
@@ -18,15 +18,13 @@
int devFS_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
rtems_libio_open_close_args_t args;
rtems_status_code status;
- rtems_device_name_t *np;
-
- np = (rtems_device_name_t *)iop->pathinfo.node_access;
+ const devFS_node *np = iop->pathinfo.node_access;
args.iop = iop;
args.flags = iop->flags;
diff --git a/cpukit/libfs/src/devfs/devread.c b/cpukit/libfs/src/devfs/devread.c
index 10f74e81c9..31d3f35db9 100644
--- a/cpukit/libfs/src/devfs/devread.c
+++ b/cpukit/libfs/src/devfs/devread.c
@@ -23,9 +23,7 @@ ssize_t devFS_read(
{
rtems_libio_rw_args_t args;
rtems_status_code status;
- rtems_device_name_t *np;
-
- np = (rtems_device_name_t *)iop->pathinfo.node_access;
+ const devFS_node *np = iop->pathinfo.node_access;
args.iop = iop;
args.offset = iop->offset;
diff --git a/cpukit/libfs/src/devfs/devstat.c b/cpukit/libfs/src/devfs/devstat.c
index e0c52b8b3d..1b780cc58b 100644
--- a/cpukit/libfs/src/devfs/devstat.c
+++ b/cpukit/libfs/src/devfs/devstat.c
@@ -7,40 +7,25 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems.h>
-#include <rtems/io.h>
-#include <rtems/seterr.h>
-#include <rtems/libio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
#include "devfs.h"
int devFS_stat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
)
{
- rtems_device_name_t *the_dev;
-
- the_dev = (rtems_device_name_t *)loc->node_access;
+ int rv = 0;
+ const devFS_node *the_dev = loc->node_access;
- /*
- * stat() invokes devFS_evaluate_path() which checks that node_access
- * is not NULL. So this should NEVER be NULL unless someone breaks
- * other code in this filesystem.
- */
- #if defined(RTEMS_DEBUG)
- if (!the_dev)
- rtems_set_errno_and_return_minus_one( EFAULT );
- #endif
+ if (the_dev != NULL) {
+ buf->st_rdev = rtems_filesystem_make_dev_t( the_dev->major, the_dev->minor );
+ buf->st_mode = the_dev->mode;
+ } else {
+ rv = rtems_filesystem_default_fstat(loc, buf);
+ }
- buf->st_rdev = rtems_filesystem_make_dev_t( the_dev->major, the_dev->minor );
- buf->st_mode = the_dev->mode;
- return 0;
+ return rv;
}
-
-
diff --git a/cpukit/libfs/src/devfs/devwrite.c b/cpukit/libfs/src/devfs/devwrite.c
index 5389c69bc5..2b3aac412b 100644
--- a/cpukit/libfs/src/devfs/devwrite.c
+++ b/cpukit/libfs/src/devfs/devwrite.c
@@ -23,9 +23,7 @@ ssize_t devFS_write(
{
rtems_libio_rw_args_t args;
rtems_status_code status;
- rtems_device_name_t *np;
-
- np = (rtems_device_name_t *)iop->pathinfo.node_access;
+ const devFS_node *np = iop->pathinfo.node_access;
args.iop = iop;
args.offset = iop->offset;
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;
+}
diff --git a/cpukit/libfs/src/imfs/deviceio.c b/cpukit/libfs/src/imfs/deviceio.c
index bb66703be9..69f409e472 100644
--- a/cpukit/libfs/src/imfs/deviceio.c
+++ b/cpukit/libfs/src/imfs/deviceio.c
@@ -15,15 +15,13 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/devfs.h>
-
#include "imfs.h"
+#include <rtems/devfs.h>
+
/*
* device_open
*
@@ -33,8 +31,8 @@
int device_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
rtems_libio_open_close_args_t args;
diff --git a/cpukit/libfs/src/imfs/fifoimfs_init.c b/cpukit/libfs/src/imfs/fifoimfs_init.c
index 13dc373eec..d2af7af8e5 100644
--- a/cpukit/libfs/src/imfs/fifoimfs_init.c
+++ b/cpukit/libfs/src/imfs/fifoimfs_init.c
@@ -20,26 +20,29 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
#include "imfs.h"
const rtems_filesystem_operations_table fifoIMFS_ops = {
- .evalpath_h = IMFS_eval_path,
- .evalformake_h = IMFS_evaluate_for_make,
+ .lock_h = rtems_filesystem_default_lock,
+ .unlock_h = rtems_filesystem_default_unlock,
+ .eval_path_h = IMFS_eval_path,
.link_h = IMFS_link,
- .unlink_h = IMFS_unlink,
+ .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
.node_type_h = IMFS_node_type,
.mknod_h = IMFS_mknod,
+ .rmnod_h = IMFS_rmnod,
+ .fchmod_h = IMFS_fchmod,
.chown_h = IMFS_chown,
+ .clonenod_h = rtems_filesystem_default_clonenode,
.freenod_h = rtems_filesystem_default_freenode,
.mount_h = IMFS_mount,
.fsmount_me_h = fifoIMFS_initialize,
.unmount_h = IMFS_unmount,
.fsunmount_me_h = IMFS_fsunmount,
.utime_h = IMFS_utime,
- .eval_link_h = IMFS_evaluate_link,
.symlink_h = IMFS_symlink,
.readlink_h = IMFS_readlink,
.rename_h = IMFS_rename,
@@ -54,8 +57,7 @@ int fifoIMFS_initialize(
return IMFS_initialize_support(
mt_entry,
&fifoIMFS_ops,
- &IMFS_memfile_handlers,
- &IMFS_directory_handlers,
+ &IMFS_link_handlers,
&IMFS_fifo_handlers
);
}
diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h
index b412c2a1fe..2a851acae4 100644
--- a/cpukit/libfs/src/imfs/imfs.h
+++ b/cpukit/libfs/src/imfs/imfs.h
@@ -18,13 +18,9 @@
#ifndef _RTEMS_IMFS_H
#define _RTEMS_IMFS_H
-#include <rtems.h>
-#include <rtems/chain.h>
-
-#include <sys/types.h>
#include <limits.h>
-#include <rtems/libio.h>
+#include <rtems/libio_.h>
#include <rtems/pipe.h>
#ifdef __cplusplus
@@ -32,15 +28,6 @@ extern "C" {
#endif
/*
- * File name macros
- */
-
-#define IMFS_is_valid_name_char( _ch ) ( 1 )
-
-#define IMFS_is_separator( _ch ) \
- rtems_filesystem_is_separator( _ch )
-
-/*
* Data types
*/
@@ -226,22 +213,11 @@ typedef struct {
ino_t ino_count;
const rtems_filesystem_file_handlers_r *memfile_handlers;
const rtems_filesystem_file_handlers_r *directory_handlers;
+ const rtems_filesystem_file_handlers_r *link_handlers;
const rtems_filesystem_file_handlers_r *fifo_handlers;
} IMFS_fs_info_t;
/*
- * Type defination for tokens returned from IMFS_get_token
- */
-
-typedef enum {
- IMFS_NO_MORE_PATH,
- IMFS_CURRENT_DIR,
- IMFS_UP_DIR,
- IMFS_NAME,
- IMFS_INVALID_TOKEN
-} IMFS_token_types;
-
-/*
* Shared Data
*/
@@ -276,29 +252,18 @@ extern int miniIMFS_initialize(
extern int IMFS_initialize_support(
rtems_filesystem_mount_table_entry_t *mt_entry,
const rtems_filesystem_operations_table *op_table,
- const rtems_filesystem_file_handlers_r *memfile_handlers,
- const rtems_filesystem_file_handlers_r *directory_handlers,
+ const rtems_filesystem_file_handlers_r *link_handlers,
const rtems_filesystem_file_handlers_r *fifo_handlers
);
-extern int IMFS_fsunmount(
+extern void IMFS_fsunmount(
rtems_filesystem_mount_table_entry_t *mt_entry
);
extern int rtems_tarfs_load(
- char *mountpoint,
- uint8_t *tar_image,
- size_t tar_size
-);
-
-/*
- * Returns the number of characters copied from path to token.
- */
-extern IMFS_token_types IMFS_get_token(
- const char *path,
- int pathlen,
- char *token,
- int *token_len
+ const char *mountpoint,
+ uint8_t *tar_image,
+ size_t tar_size
);
extern void IMFS_dump( void );
@@ -309,88 +274,59 @@ extern void IMFS_dump( void );
*/
extern int IMFS_memfile_maximum_size( void );
-extern void IMFS_initialize_jnode(
- IMFS_jnode_t *the_jnode,
- IMFS_jnode_types_t type,
- IMFS_jnode_t *the_parent,
- char *name,
- mode_t mode
-);
-
-extern IMFS_jnode_t *IMFS_find_match_in_dir(
- IMFS_jnode_t *directory, /* IN */
- char *name /* IN */
-);
extern rtems_filesystem_node_types_t IMFS_node_type(
- rtems_filesystem_location_info_t *pathloc /* IN */
+ const rtems_filesystem_location_info_t *loc
);
extern int IMFS_stat(
- rtems_filesystem_location_info_t *loc, /* IN */
- struct stat *buf /* OUT */
-);
-
-extern int IMFS_Set_handlers(
- rtems_filesystem_location_info_t *loc
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
);
-extern int IMFS_evaluate_link(
- rtems_filesystem_location_info_t *node, /* IN/OUT */
- int flags /* IN */
-);
+extern void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc );
-extern int IMFS_eval_path(
- const char *pathname, /* IN */
- size_t pathnamelen, /* IN */
- int flags, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+extern void IMFS_eval_path(
+ rtems_filesystem_eval_path_context_t *ctx
);
extern int IMFS_link(
- rtems_filesystem_location_info_t *to_loc, /* IN */
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- const char *token /* IN */
-);
-
-extern int IMFS_unlink(
- rtems_filesystem_location_info_t *parent_pathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
);
extern int IMFS_chown(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- uid_t owner, /* IN */
- gid_t group /* IN */
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
);
extern int IMFS_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 *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
);
extern IMFS_jnode_t *IMFS_allocate_node(
IMFS_jnode_types_t type, /* IN */
const char *name, /* IN */
+ size_t namelen, /* IN */
mode_t mode /* IN */
);
extern IMFS_jnode_t *IMFS_create_root_node(void);
extern IMFS_jnode_t *IMFS_create_node(
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- IMFS_jnode_types_t type, /* IN */
- const char *name, /* IN */
- mode_t mode, /* IN */
- const IMFS_types_union *info /* IN */
-);
-
-extern int IMFS_evaluate_for_make(
- const char *path, /* IN */
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- const char **name /* OUT */
+ const rtems_filesystem_location_info_t *pathloc, /* IN */
+ IMFS_jnode_types_t type, /* IN */
+ const char *name, /* IN */
+ size_t namelen, /* IN */
+ mode_t mode, /* IN */
+ const IMFS_types_union *info /* IN */
);
extern int IMFS_mount(
@@ -413,8 +349,8 @@ extern int memfile_ftruncate(
extern int imfs_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 */
);
extern int imfs_dir_close(
@@ -433,21 +369,11 @@ extern off_t imfs_dir_lseek(
int whence /* IN */
);
-extern int imfs_dir_fstat(
- rtems_filesystem_location_info_t *loc, /* IN */
- struct stat *buf /* OUT */
-);
-
-extern int imfs_dir_rmnod(
- rtems_filesystem_location_info_t *parent_pathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
-);
-
extern int memfile_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 */
);
extern int memfile_close(
@@ -481,8 +407,8 @@ extern off_t memfile_lseek(
extern int device_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 */
);
extern int device_close(
@@ -519,33 +445,35 @@ extern int device_ftruncate(
);
extern int IMFS_utime(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- time_t actime, /* IN */
- time_t modtime /* IN */
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
);
extern int IMFS_fchmod(
- rtems_filesystem_location_info_t *loc,
- mode_t mode
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
);
extern int IMFS_symlink(
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- const char *link_name,
- const char *node_name
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
);
extern ssize_t IMFS_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- char *buf, /* OUT */
- size_t bufsize
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
);
extern int IMFS_rename(
- rtems_filesystem_location_info_t *old_loc, /* IN */
- rtems_filesystem_location_info_t *old_parent_loc, /* IN */
- rtems_filesystem_location_info_t *new_parent_loc, /* IN */
- const char *new_name /* IN */
+ const rtems_filesystem_location_info_t *oldparentloc,
+ const rtems_filesystem_location_info_t *oldloc,
+ const rtems_filesystem_location_info_t *newparentloc,
+ const char *name,
+ size_t namelen
);
extern int IMFS_fdatasync(
@@ -561,8 +489,8 @@ extern void IMFS_check_node_remove(
);
extern int IMFS_rmnod(
- rtems_filesystem_location_info_t *parent_pathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
);
/*
diff --git a/cpukit/libfs/src/imfs/imfs_chown.c b/cpukit/libfs/src/imfs/imfs_chown.c
index 7f0c7b5688..e31b89e0b0 100644
--- a/cpukit/libfs/src/imfs/imfs_chown.c
+++ b/cpukit/libfs/src/imfs/imfs_chown.c
@@ -15,18 +15,19 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
#include "imfs.h"
+#include <unistd.h>
+
+#include <rtems/libio_.h>
+
int IMFS_chown(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- uid_t owner, /* IN */
- gid_t group /* IN */
+ const rtems_filesystem_location_info_t *loc,
+ uid_t owner,
+ gid_t group
)
{
IMFS_jnode_t *jnode;
@@ -34,7 +35,7 @@ int IMFS_chown(
uid_t st_uid;
#endif
- jnode = (IMFS_jnode_t *) pathloc->node_access;
+ jnode = (IMFS_jnode_t *) loc->node_access;
/*
* Verify I am the owner of the node or the super user.
diff --git a/cpukit/libfs/src/imfs/imfs_creat.c b/cpukit/libfs/src/imfs/imfs_creat.c
index 3b602d0c14..37e3ac0578 100644
--- a/cpukit/libfs/src/imfs/imfs_creat.c
+++ b/cpukit/libfs/src/imfs/imfs_creat.c
@@ -14,35 +14,32 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
+#include "imfs.h"
+
#include <stdlib.h>
#include <string.h>
-#include "imfs.h"
-#include <rtems/libio_.h>
/*
* Create an IMFS filesystem node of an arbitrary type that is NOT
* the root directory node.
*/
IMFS_jnode_t *IMFS_create_node(
- rtems_filesystem_location_info_t *parent_loc,
- IMFS_jnode_types_t type,
- const char *name,
- mode_t mode,
- const IMFS_types_union *info
+ const rtems_filesystem_location_info_t *parent_loc,
+ IMFS_jnode_types_t type,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ const IMFS_types_union *info
)
{
IMFS_jnode_t *node;
IMFS_jnode_t *parent;
IMFS_fs_info_t *fs_info;
- /*
- * MUST have a parent node to call this routine.
- */
- if ( parent_loc == NULL )
- return NULL;
+ IMFS_assert( parent_loc != NULL );
parent = parent_loc->node_access;
fs_info = parent_loc->mt_entry->fs_info;
@@ -51,13 +48,16 @@ IMFS_jnode_t *IMFS_create_node(
* Reject creation of FIFOs if support is disabled.
*/
if ( type == IMFS_FIFO &&
- fs_info->fifo_handlers == &rtems_filesystem_handlers_default )
+ fs_info->fifo_handlers == &rtems_filesystem_handlers_default ) {
+ errno = ENOTSUP;
+
return NULL;
+ }
/*
* Allocate filesystem node and fill in basic information
*/
- node = IMFS_allocate_node( type, name, mode & ~rtems_filesystem_umask );
+ node = IMFS_allocate_node( type, name, namelen, mode );
if ( !node )
return NULL;
@@ -104,25 +104,36 @@ IMFS_jnode_t *IMFS_create_node(
IMFS_jnode_t *IMFS_allocate_node(
IMFS_jnode_types_t type,
const char *name,
+ size_t namelen,
mode_t mode
)
{
IMFS_jnode_t *node;
struct timeval tv;
+ if ( namelen > IMFS_NAME_MAX ) {
+ errno = ENAMETOOLONG;
+
+ return NULL;
+ }
+
/*
* Allocate an IMFS jnode
*/
node = calloc( 1, sizeof( IMFS_jnode_t ) );
- if ( !node )
+ if ( !node ) {
+ errno = ENOMEM;
+
return NULL;
+ }
/*
* Fill in the basic information
*/
node->st_nlink = 1;
node->type = type;
- strncpy( node->name, name, IMFS_NAME_MAX );
+ memcpy( node->name, name, namelen );
+ node->name [namelen] = '\0';
/*
* Fill in the mode and permission information for the jnode structure.
@@ -155,7 +166,7 @@ IMFS_jnode_t *IMFS_create_root_node(void)
/*
* Allocate filesystem node and fill in basic information
*/
- node = IMFS_allocate_node( IMFS_DIRECTORY, "", (S_IFDIR | 0755) );
+ node = IMFS_allocate_node( IMFS_DIRECTORY, "", 0, (S_IFDIR | 0755) );
if ( !node )
return NULL;
diff --git a/cpukit/libfs/src/imfs/imfs_debug.c b/cpukit/libfs/src/imfs/imfs_debug.c
index f8bdf1ce41..091237275d 100644
--- a/cpukit/libfs/src/imfs/imfs_debug.c
+++ b/cpukit/libfs/src/imfs/imfs_debug.c
@@ -12,21 +12,14 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h> /* for close */
-#include <inttypes.h>
+#include "imfs.h"
+#include <inttypes.h>
+#include <unistd.h>
#include <stdio.h>
-#include <sys/stat.h>
-
-#include "imfs.h"
-#include <rtems/libio_.h>
/*
* IMFS_print_jnode
@@ -142,7 +135,7 @@ void IMFS_dump( void )
{
fprintf(stdout, "*************** Dump of Entire IMFS ***************\n" );
fprintf(stdout, "/\n" );
- IMFS_dump_directory( rtems_filesystem_root.node_access, 0 );
+ IMFS_dump_directory( rtems_filesystem_root->location.node_access, 0 );
fprintf(stdout, "*************** End of Dump ***************\n" );
}
diff --git a/cpukit/libfs/src/imfs/imfs_directory.c b/cpukit/libfs/src/imfs/imfs_directory.c
index 7e0c125104..8ef05b4d1d 100644
--- a/cpukit/libfs/src/imfs/imfs_directory.c
+++ b/cpukit/libfs/src/imfs/imfs_directory.c
@@ -12,23 +12,14 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <rtems/chain.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
+#include "imfs.h"
+
#include <string.h>
#include <dirent.h>
-#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
/*
* imfs_dir_open
*
@@ -40,8 +31,8 @@
int imfs_dir_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
IMFS_jnode_t *the_jnode;
@@ -203,115 +194,3 @@ off_t imfs_dir_lseek(
return 0;
}
-
-
-
-/*
- * imfs_dir_fstat
- *
- * This routine will obtain the following information concerning the current
- * directory:
- * st_dev 0ll
- * st_ino 1
- * st_mode mode extracted from the jnode
- * st_nlink number of links to this node
- * st_uid uid extracted from the jnode
- * st_gid gid extracted from the jnode
- * st_rdev 0ll
- * st_size the number of bytes in the directory
- * This is calculated by taking the number of entries
- * in the directory and multiplying by the size of a
- * dirent structure
- * st_blksize 0
- * st_blocks 0
- * stat_atime time of last access
- * stat_mtime time of last modification
- * stat_ctime time of the last change
- *
- * This information will be returned to the calling function in a -stat- struct
- *
- */
-
-int imfs_dir_fstat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
-)
-{
- rtems_chain_node *the_node;
- rtems_chain_control *the_chain;
- IMFS_jnode_t *the_jnode;
-
-
- the_jnode = (IMFS_jnode_t *) loc->node_access;
-
- buf->st_dev = 0ll;
- buf->st_ino = the_jnode->st_ino;
- buf->st_mode = the_jnode->st_mode;
- buf->st_nlink = the_jnode->st_nlink;
- buf->st_uid = the_jnode->st_uid;
- buf->st_gid = the_jnode->st_gid;
- buf->st_rdev = 0ll;
- buf->st_blksize = 0;
- buf->st_blocks = 0;
- buf->st_atime = the_jnode->stat_atime;
- buf->st_mtime = the_jnode->stat_mtime;
- buf->st_ctime = the_jnode->stat_ctime;
-
- buf->st_size = 0;
-
- the_chain = &the_jnode->info.directory.Entries;
-
- /* Run through the chain and count the number of directory entries */
- /* that are subordinate to this directory node */
- for ( the_node = rtems_chain_first( the_chain );
- !rtems_chain_is_tail( the_chain, the_node ) ;
- the_node = the_node->next ) {
-
- buf->st_size = buf->st_size + sizeof( struct dirent );
- }
-
- return 0;
-}
-
-/*
- * IMFS_dir_rmnod
- *
- * This routine is available from the optable to remove a node
- * from the IMFS file system.
- */
-
-int imfs_dir_rmnod(
- rtems_filesystem_location_info_t *parent_pathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
-)
-{
- IMFS_jnode_t *the_jnode;
-
- the_jnode = (IMFS_jnode_t *) pathloc->node_access;
-
- /*
- * You cannot remove a node that still has children
- */
-
- if ( ! rtems_chain_is_empty( &the_jnode->info.directory.Entries ) )
- rtems_set_errno_and_return_minus_one( ENOTEMPTY );
-
- /*
- * You cannot remove the file system root node.
- */
-
- if ( rtems_filesystem_is_root_location(pathloc) )
- rtems_set_errno_and_return_minus_one( EBUSY );
-
- /*
- * You cannot remove a mountpoint.
- */
-
- if ( the_jnode->info.directory.mt_fs != NULL )
- rtems_set_errno_and_return_minus_one( EBUSY );
-
- IMFS_create_orphan( the_jnode );
- IMFS_check_node_remove( the_jnode );
-
- return 0;
-}
diff --git a/cpukit/libfs/src/imfs/imfs_eval.c b/cpukit/libfs/src/imfs/imfs_eval.c
index 78fafca536..43f2ee40e0 100644
--- a/cpukit/libfs/src/imfs/imfs_eval.c
+++ b/cpukit/libfs/src/imfs/imfs_eval.c
@@ -4,684 +4,189 @@
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
- *
- * $Id$
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdlib.h>
-
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-#define RTEMS_LIBIO_PERMS_RX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_READ)
-#define RTEMS_LIBIO_PERMS_WX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_WRITE)
-
-#define MAXSYMLINK 5
-
-int IMFS_Set_handlers(
- rtems_filesystem_location_info_t *loc
-)
+void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
{
- IMFS_jnode_t *node = loc->node_access;
- IMFS_fs_info_t *fs_info;
+ IMFS_jnode_t *node = loc->node_access;
+ IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info;
+ const rtems_filesystem_file_handlers_r *handlers;
- fs_info = loc->mt_entry->fs_info;
- switch( node->type ) {
+ switch ( node->type ) {
case IMFS_DIRECTORY:
- loc->handlers = fs_info->directory_handlers;
+ handlers = &IMFS_directory_handlers;
break;
case IMFS_DEVICE:
- loc->handlers = &IMFS_device_handlers;
+ handlers = &IMFS_device_handlers;
break;
- case IMFS_SYM_LINK:
case IMFS_HARD_LINK:
- loc->handlers = &IMFS_link_handlers;
- break;
- case IMFS_LINEAR_FILE:
- loc->handlers = fs_info->memfile_handlers;
+ case IMFS_SYM_LINK:
+ handlers = fs_info->link_handlers;
break;
case IMFS_MEMORY_FILE:
- loc->handlers = fs_info->memfile_handlers;
+ case IMFS_LINEAR_FILE:
+ handlers = &IMFS_memfile_handlers;
break;
case IMFS_FIFO:
- loc->handlers = fs_info->fifo_handlers;
+ handlers = fs_info->fifo_handlers;
+ break;
+ default:
+ IMFS_assert( 0 );
break;
}
- return 0;
-}
-
-/*
- * IMFS_evaluate_permission
- *
- * The following routine evaluates that we have permission
- * to do flags on the node.
- */
-static int IMFS_evaluate_permission(
- rtems_filesystem_location_info_t *node,
- int flags
-)
-{
- uid_t st_uid;
- gid_t st_gid;
- IMFS_jnode_t *jnode;
- int flags_to_test;
-
- if ( !rtems_libio_is_valid_perms( flags ) )
- rtems_set_errno_and_return_minus_one( EPERM );
-
- jnode = node->node_access;
-
-#if defined(RTEMS_POSIX_API)
- st_uid = geteuid();
- st_gid = getegid();
-#else
- st_uid = jnode->st_uid;
- st_gid = jnode->st_gid;
-#endif
-
- /*
- * Check if I am owner or a group member or someone else.
- */
-
- flags_to_test = flags;
-
- if ( st_uid == jnode->st_uid )
- flags_to_test <<= 6;
- else if ( st_gid == jnode->st_gid )
- flags_to_test <<= 3;
- else {
- /* must be other - do nothing */;
- }
-
- /*
- * If all of the flags are set we have permission
- * to do this.
- */
- if ( ( flags_to_test & jnode->st_mode) == flags_to_test )
- return 1;
-
- return 0;
+ loc->handlers = handlers;
}
-/*
- * IMFS_evaluate_hard_link
- *
- * The following routine evaluates a hardlink to the actual node.
- */
-
-static int IMFS_evaluate_hard_link(
- rtems_filesystem_location_info_t *node, /* IN/OUT */
- int flags /* IN */
+static bool IMFS_is_directory(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg
)
{
- IMFS_jnode_t *jnode = node->node_access;
- int result = 0;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc( ctx );
+ IMFS_jnode_t *node = currentloc->node_access;
- /*
- * Check for things that should never happen.
- */
- IMFS_assert( jnode->type == IMFS_HARD_LINK );
-
- /*
- * Set the hard link value and the handlers.
- */
- node->node_access = jnode->info.hard_link.link_node;
-
- IMFS_Set_handlers( node );
-
- /*
- * Verify we have the correct permissions for this node.
- */
-
- if ( !IMFS_evaluate_permission( node, flags ) )
- rtems_set_errno_and_return_minus_one( EACCES );
-
- return result;
+ return node->type == IMFS_DIRECTORY;
}
-
-/*
- * IMFS_evaluate_sym_link
- *
- * The following routine evaluates a symbolic link to the actual node.
- */
-
-static int IMFS_evaluate_sym_link(
- rtems_filesystem_location_info_t *node, /* IN/OUT */
- int flags /* IN */
+static IMFS_jnode_t *IMFS_search_in_directory(
+ IMFS_jnode_t *dir,
+ const char *token,
+ size_t tokenlen
)
{
- IMFS_jnode_t *jnode = node->node_access;
- int result = 0;
- int i;
-
- /*
- * Check for things that should never happen.
- */
- IMFS_assert( jnode->type == IMFS_SYM_LINK );
- IMFS_assert( jnode->Parent );
-
- /*
- * Move the node_access to either the symbolic links parent or
- * root depending on the symbolic links path.
- */
- node->node_access = jnode->Parent;
-
- rtems_filesystem_get_sym_start_loc(
- jnode->info.sym_link.name,
- &i,
- node
- );
-
- /*
- * Use eval path to evaluate the path of the symbolic link.
- */
- result = IMFS_eval_path(
- &jnode->info.sym_link.name[i],
- strlen( &jnode->info.sym_link.name[i] ),
- flags,
- node
- );
-
- IMFS_Set_handlers( node );
-
- /*
- * Verify we have the correct permissions for this node.
- */
- if ( !IMFS_evaluate_permission( node, flags ) )
- rtems_set_errno_and_return_minus_one( EACCES );
-
- return result;
-}
+ if ( rtems_filesystem_is_current_directory( token, tokenlen ) ) {
+ return dir;
+ } else {
+ if ( rtems_filesystem_is_parent_directory( token, tokenlen ) ) {
+ return dir->Parent;
+ } else {
+ rtems_chain_control *entries = &dir->info.directory.Entries;
+ rtems_chain_node *current = rtems_chain_first( entries );
+ rtems_chain_node *tail = rtems_chain_tail( entries );
-/*
- * IMFS_evaluate_link
- *
- * The following routine returns the real node pointed to by a link.
- */
-int IMFS_evaluate_link(
- rtems_filesystem_location_info_t *node, /* IN/OUT */
- int flags /* IN */
-)
-{
- IMFS_jnode_t *jnode;
- int result = 0;
+ while ( current != tail ) {
+ IMFS_jnode_t *entry = (IMFS_jnode_t *) current;
+ bool match = strncmp( entry->name, token, tokenlen ) == 0
+ && entry->name [tokenlen] == '\0';
- do {
- jnode = node->node_access;
+ if ( match ) {
+ return entry;
+ }
- /*
- * Increment and check the link counter.
- */
+ current = rtems_chain_next( current );
+ }
- rtems_filesystem_link_counts ++;
- if ( rtems_filesystem_link_counts > MAXSYMLINK ) {
- rtems_filesystem_link_counts = 0;
- rtems_set_errno_and_return_minus_one( ELOOP );
+ return NULL;
}
-
- /*
- * Follow the Link node.
- */
-
- if ( jnode->type == IMFS_HARD_LINK )
- result = IMFS_evaluate_hard_link( node, flags );
-
- else if (jnode->type == IMFS_SYM_LINK )
- result = IMFS_evaluate_sym_link( node, flags );
-
- } while ( ( result == 0 ) && ( ( jnode->type == IMFS_SYM_LINK ) ||
- ( jnode->type == IMFS_HARD_LINK ) ) );
-
- /*
- * Clear link counter.
- */
-
- rtems_filesystem_link_counts = 0;
-
- return result;
-}
-
-/*
- * IMFS_skip_separator
- *
- * Skip the separator in the path.
- */
-static void IMFS_skip_separator (
- const char *path, /* IN */
- size_t *len, /* IN/OUT */
- int *index /* IN/OUT */
-)
-{
- while ( IMFS_is_separator( path[*index] ) && path[*index] && *len ) {
- ++(*index);
- --(*len);
}
}
-/*
- * IMFS_evaluate_for_make
- *
- * 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.
- */
-
-int IMFS_evaluate_for_make(
- const char *path, /* IN */
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- const char **name /* OUT */
- )
+static rtems_filesystem_global_location_t **IMFS_is_mount_point(
+ IMFS_jnode_t *node
+)
{
- int i = 0;
- int len;
- IMFS_token_types type;
- char token[ IMFS_NAME_MAX + 1 ];
- IMFS_jnode_t *node;
- bool done = false;
- size_t pathlen;
- int result;
-
- /*
- * This was filled in by the caller and is valid in the
- * mount table.
- */
- node = pathloc->node_access;
-
- /*
- * Get the path length.
- */
- pathlen = strlen( path );
- /*
- * Evaluate all tokens until we are done or an error occurs.
- */
-
- while( !done ) {
-
- type = IMFS_get_token( &path[i], pathlen, token, &len );
- pathlen -= len;
- i += len;
-
- if ( !pathloc->node_access )
- rtems_set_errno_and_return_minus_one( ENOENT );
-
- /*
- * I cannot move out of this directory without execute permission.
- */
+ rtems_filesystem_global_location_t **fs_root_ptr = NULL;
- if ( type != IMFS_NO_MORE_PATH )
- if ( node->type == IMFS_DIRECTORY )
- if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) )
- rtems_set_errno_and_return_minus_one( EACCES );
-
- node = pathloc->node_access;
-
- switch( type ) {
-
- case IMFS_UP_DIR:
- /*
- * Am I at the root of all filesystems? (chroot'ed?)
- */
-
- if ( pathloc->node_access == rtems_filesystem_root.node_access )
- break; /* Throw out the .. in this case */
-
-
- /*
- * Am I at the root of this mounted filesystem?
- */
-
- if ( rtems_filesystem_is_root_location( pathloc ) ) {
-
- /*
- * Am I at the root of all filesystems?
- */
-
- if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
- break;
-
- } else {
- *pathloc = pathloc->mt_entry->mt_point_node;
- return (*pathloc->ops->evalformake_h)( &path[i-len], pathloc, name );
- }
- } else {
-
- if ( !node->Parent )
- rtems_set_errno_and_return_minus_one( ENOENT );
-
- node = node->Parent;
- }
-
- pathloc->node_access = node;
- break;
-
- case IMFS_NAME:
-
- if ( node->type == IMFS_HARD_LINK ) {
-
- result = IMFS_evaluate_link( pathloc, 0 );
- if ( result == -1 )
- return -1;
-
- } else if ( node->type == IMFS_SYM_LINK ) {
-
- result = IMFS_evaluate_link( pathloc, 0 );
-
- if ( result == -1 )
- return -1;
- }
-
- node = pathloc->node_access;
- if ( !node )
- rtems_set_errno_and_return_minus_one( ENOTDIR );
-
- /*
- * Only a directory can be decended into.
- */
-
- if ( node->type != IMFS_DIRECTORY )
- rtems_set_errno_and_return_minus_one( ENOTDIR );
-
- /*
- * Find the token name in the present location.
- */
-
- node = IMFS_find_match_in_dir( node, token );
-
- /*
- * If there is no node we have found the name of the node we
- * wish to create.
- */
-
- if ( ! node )
- done = true;
- else {
- if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) {
- IMFS_skip_separator( path, &pathlen, &i);
- if ((path[i] != '.') || (path[i + 1] != '.')) {
- *pathloc = node->info.directory.mt_fs->mt_fs_root;
- return (*pathloc->ops->evalformake_h)( &path[i],
- pathloc,
- name );
- }
- i += 2;
- pathlen -= 2;
- node = node->Parent;
- }
- pathloc->node_access = node;
- }
- break;
-
- case IMFS_NO_MORE_PATH:
- rtems_set_errno_and_return_minus_one( EEXIST );
- break;
-
- case IMFS_INVALID_TOKEN:
- rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
- break;
-
- case IMFS_CURRENT_DIR:
- break;
+ if ( node->type == IMFS_DIRECTORY ) {
+ if ( node->info.directory.mt_fs != NULL ) {
+ fs_root_ptr = &node->info.directory.mt_fs->mt_fs_root;
}
}
- *name = &path[ i - len ];
-
- /*
- * We have evaluated the path as far as we can.
- * Verify there is not any invalid stuff at the end of the name.
- */
-
- for( ; path[i] != '\0'; i++) {
- if ( !IMFS_is_separator( path[ i ] ) )
- rtems_set_errno_and_return_minus_one( ENOENT );
- }
-
- /*
- * Verify we can execute and write to this directory.
- */
-
- result = IMFS_Set_handlers( pathloc );
-
- /*
- * The returned node must be a directory
- */
- node = pathloc->node_access;
- if ( node->type != IMFS_DIRECTORY )
- rtems_set_errno_and_return_minus_one( ENOTDIR );
-
- /*
- * We must have Write and execute permission on the returned node.
- */
-
- if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_WX ) )
- rtems_set_errno_and_return_minus_one( EACCES );
-
- return result;
+ return fs_root_ptr;
}
-/*
- * IMFS_eval_path
- *
- * The following routine evaluate path for a node that wishes to be
- * accessed with mode. pathloc is returned with a pointer to the
- * node to be accessed.
- */
-
-int IMFS_eval_path(
- const char *pathname, /* IN */
- size_t pathnamelen, /* IN */
- int flags, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
- )
+static rtems_filesystem_eval_path_generic_status IMFS_eval_token(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg,
+ const char *token,
+ size_t tokenlen
+)
{
- int i = 0;
- int len;
- IMFS_token_types type = IMFS_CURRENT_DIR;
- char token[ IMFS_NAME_MAX + 1 ];
- IMFS_jnode_t *node;
- int result;
-
- if ( !rtems_libio_is_valid_perms( flags ) ) {
- rtems_set_errno_and_return_minus_one( EIO );
- }
-
- /*
- * This was filled in by the caller and is valid in the
- * mount table.
- */
-
- node = pathloc->node_access;
-
- /*
- * Evaluate all tokens until we are done or an error occurs.
- */
-
- while( (type != IMFS_NO_MORE_PATH) && (type != IMFS_INVALID_TOKEN) ) {
-
- type = IMFS_get_token( &pathname[i], pathnamelen, token, &len );
- pathnamelen -= len;
- i += len;
-
- if ( !pathloc->node_access )
- rtems_set_errno_and_return_minus_one( ENOENT );
+ rtems_filesystem_eval_path_generic_status status =
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc( ctx );
+ IMFS_jnode_t *dir = currentloc->node_access;
+ bool access_ok = rtems_filesystem_eval_path_check_access(
+ ctx,
+ RTEMS_LIBIO_PERMS_SEARCH,
+ dir->st_mode,
+ dir->st_uid,
+ dir->st_gid
+ );
- /*
- * I cannot move out of this directory without execute permission.
- */
- if ( type != IMFS_NO_MORE_PATH )
- if ( node->type == IMFS_DIRECTORY )
- if ( !IMFS_evaluate_permission( pathloc, RTEMS_LIBIO_PERMS_SEARCH ) )
- rtems_set_errno_and_return_minus_one( EACCES );
+ if ( access_ok ) {
+ IMFS_jnode_t *entry = IMFS_search_in_directory( dir, token, tokenlen );
- node = pathloc->node_access;
+ if ( entry != NULL ) {
+ bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
+ int eval_flags = rtems_filesystem_eval_path_get_flags( ctx );
+ bool follow_hard_link = (eval_flags & RTEMS_LIBIO_FOLLOW_HARD_LINK) != 0;
+ bool follow_sym_link = (eval_flags & RTEMS_LIBIO_FOLLOW_SYM_LINK) != 0;
- switch( type ) {
- case IMFS_UP_DIR:
- /*
- * Am I at the root of all filesystems? (chroot'ed?)
- */
+ rtems_filesystem_eval_path_clear_token( ctx );
- if ( pathloc->node_access == rtems_filesystem_root.node_access )
- break; /* Throw out the .. in this case */
+ if ( entry->type == IMFS_HARD_LINK && (follow_hard_link || !terminal)) {
+ entry = entry->info.hard_link.link_node;
+ }
- /*
- * Am I at the root of this mounted filesystem?
- */
+ if ( entry->type == IMFS_SYM_LINK && (follow_sym_link || !terminal)) {
+ const char *target = entry->info.sym_link.name;
- if ( rtems_filesystem_is_root_location( pathloc ) ) {
+ rtems_filesystem_eval_path_recursive( ctx, target, strlen( target ) );
+ } else {
+ rtems_filesystem_global_location_t **fs_root_ptr =
+ IMFS_is_mount_point( entry );
- /*
- * Am I at the root of all filesystems?
- */
+ if ( fs_root_ptr == NULL ) {
+ currentloc->node_access = entry;
+ IMFS_Set_handlers( currentloc );
- if ( pathloc->node_access == rtems_filesystem_root.node_access ) {
- break; /* Throw out the .. in this case */
- } else {
- *pathloc = pathloc->mt_entry->mt_point_node;
- return (*pathloc->ops->evalpath_h)(&(pathname[i-len]),
- pathnamelen+len,
- flags,pathloc);
+ if ( !terminal ) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
}
} else {
-
- if ( !node->Parent )
- rtems_set_errno_and_return_minus_one( ENOENT );
-
- node = node->Parent;
- pathloc->node_access = node;
-
- }
-
- pathloc->node_access = node;
- break;
-
- case IMFS_NAME:
- /*
- * If we are at a link follow it.
- */
- if ( node->type == IMFS_HARD_LINK ) {
- IMFS_evaluate_hard_link( pathloc, 0 );
- node = pathloc->node_access;
-
- /*
- * It would be a design error if we evaluated the link and
- * was broken.
- */
- IMFS_assert( node );
-
- } else if ( node->type == IMFS_SYM_LINK ) {
- result = IMFS_evaluate_sym_link( pathloc, 0 );
-
- /*
- * In contrast to a hard link, it is possible to have a broken
- * symbolic link.
- */
- node = pathloc->node_access;
- if ( result == -1 )
- return -1;
- }
-
- /*
- * Only a directory can be decended into.
- */
- if ( node->type != IMFS_DIRECTORY )
- rtems_set_errno_and_return_minus_one( ENOTDIR );
-
- /*
- * Find the token name in the current node.
- */
- node = IMFS_find_match_in_dir( node, token );
- if ( !node )
- rtems_set_errno_and_return_minus_one( ENOENT );
-
- /*
- * If we are at a node that is a mount point so current directory
- * actually exists on the mounted file system and not in the node that
- * contains the mount point node. For example a stat of the mount
- * point should return the details of the root of the mounted file
- * system not the mount point node of parent file system.
- *
- * If the node we have just moved to is a mount point do not loop and
- * get the token because the token may be suitable for the mounted
- * file system and not the IMFS. For example the IMFS length is
- * limited. If the token is a parent directory move back up otherwise
- * set loc to the new fs root node and let them finish evaluating the
- * path.
- */
- if (( node->type == IMFS_DIRECTORY ) && ( node->info.directory.mt_fs != NULL )) {
- IMFS_skip_separator( pathname, &pathnamelen, &i);
- if ((pathname[i] != '.') || (pathname[i + 1] != '.')) {
- *pathloc = node->info.directory.mt_fs->mt_fs_root;
- return (*pathloc->ops->evalpath_h)( &pathname[i],
- pathnamelen,
- flags, pathloc );
+ access_ok = rtems_filesystem_eval_path_check_access(
+ ctx,
+ RTEMS_LIBIO_PERMS_EXEC,
+ entry->st_mode,
+ entry->st_uid,
+ entry->st_gid
+ );
+ if ( access_ok ) {
+ rtems_filesystem_eval_path_restart( ctx, fs_root_ptr );
}
- i += 2;
- pathnamelen -= 2;
- node = node->Parent;
}
-
- /*
- * Set the node access to the point we have found.
- */
- pathloc->node_access = node;
- break;
-
- case IMFS_NO_MORE_PATH:
- case IMFS_CURRENT_DIR:
- break;
-
- case IMFS_INVALID_TOKEN:
- rtems_set_errno_and_return_minus_one( ENAMETOOLONG );
- 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.
- */
-
- if ( node->type == IMFS_DIRECTORY ) {
- if ( node->info.directory.mt_fs != NULL ) {
- *pathloc = node->info.directory.mt_fs->mt_fs_root;
- return (*pathloc->ops->evalpath_h)( &pathname[i-len],
- pathnamelen+len,
- flags, pathloc );
+ }
} else {
- result = IMFS_Set_handlers( pathloc );
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
}
- } else {
- result = IMFS_Set_handlers( pathloc );
}
- /*
- * Verify we have the correct permissions for this node.
- */
+ return status;
+}
- if ( !IMFS_evaluate_permission( pathloc, flags ) )
- rtems_set_errno_and_return_minus_one( EACCES );
+static const rtems_filesystem_eval_path_generic_config IMFS_eval_config = {
+ .is_directory = IMFS_is_directory,
+ .eval_token = IMFS_eval_token
+};
- return result;
+void IMFS_eval_path( rtems_filesystem_eval_path_context_t *ctx )
+{
+ rtems_filesystem_eval_path_generic( ctx, NULL, &IMFS_eval_config );
}
diff --git a/cpukit/libfs/src/imfs/imfs_fchmod.c b/cpukit/libfs/src/imfs/imfs_fchmod.c
index 54a093de2f..4236a2901b 100644
--- a/cpukit/libfs/src/imfs/imfs_fchmod.c
+++ b/cpukit/libfs/src/imfs/imfs_fchmod.c
@@ -12,18 +12,14 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
#include "imfs.h"
int IMFS_fchmod(
- rtems_filesystem_location_info_t *loc,
- mode_t mode
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
)
{
IMFS_jnode_t *jnode;
diff --git a/cpukit/libfs/src/imfs/imfs_fifo.c b/cpukit/libfs/src/imfs/imfs_fifo.c
index e447b26a70..790471e472 100644
--- a/cpukit/libfs/src/imfs/imfs_fifo.c
+++ b/cpukit/libfs/src/imfs/imfs_fifo.c
@@ -11,13 +11,9 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <stdlib.h>
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
#include "imfs.h"
#define JNODE2PIPE(_jnode) ( (_jnode)->info.fifo.pipe )
@@ -35,8 +31,8 @@ do { \
static int IMFS_fifo_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
IMFS_jnode_t *jnode = iop->pathinfo.node_access;
@@ -138,10 +134,8 @@ const rtems_filesystem_file_handlers_r IMFS_fifo_handlers = {
IMFS_fifo_ioctl,
IMFS_fifo_lseek,
IMFS_stat,
- IMFS_fchmod,
rtems_filesystem_default_ftruncate,
rtems_filesystem_default_fsync,
rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- IMFS_rmnod,
+ rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/imfs/imfs_fsunmount.c b/cpukit/libfs/src/imfs/imfs_fsunmount.c
index b65c20e60d..49ade1bab9 100644
--- a/cpukit/libfs/src/imfs/imfs_fsunmount.c
+++ b/cpukit/libfs/src/imfs/imfs_fsunmount.c
@@ -12,20 +12,10 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h> /* for mkdir */
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
#include "imfs.h"
-#include <rtems/libio_.h>
-
-#if defined(IMFS_DEBUG)
-#include <stdio.h>
-#endif
/*
* IMFS_fsunmount
@@ -43,7 +33,7 @@
#define jnode_get_first_child( jnode ) \
((IMFS_jnode_t *)( rtems_chain_head( jnode_get_control( jnode ) )->next))
-int IMFS_fsunmount(
+void IMFS_fsunmount(
rtems_filesystem_mount_table_entry_t *temp_mt_entry
)
{
@@ -57,29 +47,24 @@ int IMFS_fsunmount(
* associated memory space
*/
- jnode = (IMFS_jnode_t *)temp_mt_entry->mt_fs_root.node_access;
- loc = temp_mt_entry->mt_fs_root;
+ loc = temp_mt_entry->mt_fs_root->location;
+ jnode = (IMFS_jnode_t *)loc.node_access;
/*
* Set this to null to indicate that it is being unmounted.
*/
- temp_mt_entry->mt_fs_root.node_access = NULL;
+ temp_mt_entry->mt_fs_root->location.node_access = NULL;
do {
next = jnode->Parent;
loc.node_access = (void *)jnode;
IMFS_Set_handlers( &loc );
- if ( jnode->type != IMFS_DIRECTORY ) {
- result = IMFS_unlink( NULL, &loc );
+ if ( jnode->type != IMFS_DIRECTORY || jnode_has_no_children( jnode ) ) {
+ result = IMFS_rmnod( NULL, &loc );
if (result != 0)
- return -1;
- jnode = next;
- } else if ( jnode_has_no_children( jnode ) ) {
- result = IMFS_unlink( NULL, &loc );
- if (result != 0)
- return -1;
+ rtems_fatal_error_occurred(0xdeadbeef);
jnode = next;
}
if ( jnode != NULL ) {
@@ -89,6 +74,4 @@ int IMFS_fsunmount(
}
}
} while (jnode != NULL);
-
- return 0;
}
diff --git a/cpukit/libfs/src/imfs/imfs_getchild.c b/cpukit/libfs/src/imfs/imfs_getchild.c
deleted file mode 100644
index 1cfeb2a537..0000000000
--- a/cpukit/libfs/src/imfs/imfs_getchild.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * IMFS_find_match_in_dir()
- *
- * This routine returns the child name in the given directory.
- *
- * COPYRIGHT (c) 1989-1999.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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 <errno.h>
-#include <string.h>
-#include "imfs.h"
-
-static const char dotname[2] = ".";
-static const char dotdotname[3] = "..";
-
-IMFS_jnode_t *IMFS_find_match_in_dir(
- IMFS_jnode_t *directory,
- char *name
-)
-{
- rtems_chain_node *the_node;
- rtems_chain_control *the_chain;
- IMFS_jnode_t *the_jnode;
-
- /*
- * Check for fatal errors. A NULL directory show a problem in the
- * the IMFS code.
- */
- IMFS_assert( directory );
- IMFS_assert( name );
-
- /*
- * Check for "." and ".."
- */
-
- if ( !strcmp( name, dotname ) )
- return directory;
-
- if ( !strcmp( name, dotdotname ) )
- return directory->Parent;
-
- the_chain = &directory->info.directory.Entries;
-
- for ( the_node = rtems_chain_first( the_chain );
- !rtems_chain_is_tail( the_chain, the_node );
- the_node = the_node->next ) {
-
- the_jnode = (IMFS_jnode_t *) the_node;
-
- if ( !strcmp( name, the_jnode->name ) )
- return the_jnode;
- }
-
- return 0;
-}
diff --git a/cpukit/libfs/src/imfs/imfs_gtkn.c b/cpukit/libfs/src/imfs/imfs_gtkn.c
deleted file mode 100644
index b15b2f1136..0000000000
--- a/cpukit/libfs/src/imfs/imfs_gtkn.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * IMFS_get_token
- *
- * Routine to get a token (name or separator) from the path
- * the length of the token is returned in token_len.
- *
- * COPYRIGHT (c) 1989-1999.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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 <stdlib.h>
-#include <string.h>
-
-#include "imfs.h"
-#include <rtems/libio_.h>
-
-IMFS_token_types IMFS_get_token(
- const char *path,
- int pathlen,
- char *token,
- int *token_len
-)
-{
- register int i = 0;
- IMFS_token_types type = IMFS_NAME;
- register char c;
-
- /*
- * Copy a name into token. (Remember NULL is a token.)
- */
- c = path[i];
- while ( (!IMFS_is_separator(c)) && (i < pathlen) && (i <= IMFS_NAME_MAX) ) {
-
- token[i] = c;
-
- if ( i == IMFS_NAME_MAX )
- return IMFS_INVALID_TOKEN;
-
- if ( !IMFS_is_valid_name_char(c) )
- type = IMFS_INVALID_TOKEN;
-
- c = path [++i];
- }
-
- /*
- * Copy a seperator into token.
- */
-
- if ( i == 0 ) {
- token[i] = c;
-
- if ( (token[i] != '\0') && pathlen ) {
- i++;
- type = IMFS_CURRENT_DIR;
- } else {
- type = IMFS_NO_MORE_PATH;
- }
- } else if (token[ i-1 ] != '\0') {
- token[i] = '\0';
- }
-
- /*
- * Set token_len to the number of characters copied.
- */
-
- *token_len = i;
-
- /*
- * If we copied something that was not a seperator see if
- * it was a special name.
- */
-
- if ( type == IMFS_NAME ) {
- if ( strcmp( token, "..") == 0 )
- type = IMFS_UP_DIR;
- else if ( strcmp( token, "." ) == 0 )
- type = IMFS_CURRENT_DIR;
- }
-
- return type;
-}
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_device.c b/cpukit/libfs/src/imfs/imfs_handlers_device.c
index 8e249bda33..a6edfb1f77 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_device.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_device.c
@@ -12,11 +12,9 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
#include "imfs.h"
/*
@@ -31,10 +29,8 @@ const rtems_filesystem_file_handlers_r IMFS_device_handlers = {
device_ioctl,
device_lseek,
IMFS_stat,
- IMFS_fchmod,
device_ftruncate,
rtems_filesystem_default_fsync,
rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- IMFS_rmnod
+ rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_directory.c b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
index 5ca715825e..4778f45599 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_directory.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_directory.c
@@ -12,11 +12,9 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
#include "imfs.h"
/*
@@ -30,11 +28,9 @@ const rtems_filesystem_file_handlers_r IMFS_directory_handlers = {
rtems_filesystem_default_write,
rtems_filesystem_default_ioctl,
imfs_dir_lseek,
- imfs_dir_fstat,
- IMFS_fchmod,
- rtems_filesystem_default_ftruncate,
+ IMFS_stat,
+ rtems_filesystem_default_ftruncate_directory,
rtems_filesystem_default_fsync,
IMFS_fdatasync,
- rtems_filesystem_default_fcntl,
- imfs_dir_rmnod
+ rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_link.c b/cpukit/libfs/src/imfs/imfs_handlers_link.c
index d8bbec82d4..967aa1410f 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_link.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_link.c
@@ -12,11 +12,9 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
#include "imfs.h"
/*
@@ -31,10 +29,8 @@ const rtems_filesystem_file_handlers_r IMFS_link_handlers = {
rtems_filesystem_default_ioctl,
rtems_filesystem_default_lseek,
IMFS_stat, /* stat */
- rtems_filesystem_default_fchmod,
rtems_filesystem_default_ftruncate,
rtems_filesystem_default_fsync,
rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- IMFS_rmnod
+ rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
index ee859ee98d..10e47fd0f8 100644
--- a/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
+++ b/cpukit/libfs/src/imfs/imfs_handlers_memfile.c
@@ -12,11 +12,9 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
#include "imfs.h"
/*
@@ -31,10 +29,8 @@ const rtems_filesystem_file_handlers_r IMFS_memfile_handlers = {
memfile_ioctl,
memfile_lseek,
IMFS_stat,
- IMFS_fchmod,
memfile_ftruncate,
IMFS_fdatasync, /* fsync */
IMFS_fdatasync,
- rtems_filesystem_default_fcntl,
- IMFS_rmnod
+ rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/imfs/imfs_init.c b/cpukit/libfs/src/imfs/imfs_init.c
index c74d493b40..2a7d890a09 100644
--- a/cpukit/libfs/src/imfs/imfs_init.c
+++ b/cpukit/libfs/src/imfs/imfs_init.c
@@ -18,28 +18,29 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/libio_.h>
-
#include "imfs.h"
const rtems_filesystem_operations_table IMFS_ops = {
- .evalpath_h = IMFS_eval_path,
- .evalformake_h = IMFS_evaluate_for_make,
+ .lock_h = rtems_filesystem_default_lock,
+ .unlock_h = rtems_filesystem_default_unlock,
+ .eval_path_h = IMFS_eval_path,
.link_h = IMFS_link,
- .unlink_h = IMFS_unlink,
+ .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
.node_type_h = IMFS_node_type,
.mknod_h = IMFS_mknod,
+ .rmnod_h = IMFS_rmnod,
+ .fchmod_h = IMFS_fchmod,
.chown_h = IMFS_chown,
+ .clonenod_h = rtems_filesystem_default_clonenode,
.freenod_h = rtems_filesystem_default_freenode,
.mount_h = IMFS_mount,
.fsmount_me_h = IMFS_initialize,
.unmount_h = IMFS_unmount,
.fsunmount_me_h = IMFS_fsunmount,
.utime_h = IMFS_utime,
- .eval_link_h = IMFS_evaluate_link,
.symlink_h = IMFS_symlink,
.readlink_h = IMFS_readlink,
.rename_h = IMFS_rename,
@@ -54,8 +55,7 @@ int IMFS_initialize(
return IMFS_initialize_support(
mt_entry,
&IMFS_ops,
- &IMFS_memfile_handlers,
- &IMFS_directory_handlers,
- &rtems_filesystem_handlers_default /* for fifos */
+ &IMFS_link_handlers,
+ &rtems_filesystem_handlers_default /* for fifos */
);
}
diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c
index 47e1d392e8..61ad6a70f2 100644
--- a/cpukit/libfs/src/imfs/imfs_initsupp.c
+++ b/cpukit/libfs/src/imfs/imfs_initsupp.c
@@ -12,21 +12,12 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h> /* for mkdir */
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-#if defined(IMFS_DEBUG)
-#include <stdio.h>
-#endif
+#include <stdlib.h>
/*
* IMFS_determine_bytes_per_block
@@ -66,8 +57,7 @@ static int IMFS_determine_bytes_per_block(
int IMFS_initialize_support(
rtems_filesystem_mount_table_entry_t *temp_mt_entry,
const rtems_filesystem_operations_table *op_table,
- const rtems_filesystem_file_handlers_r *memfile_handlers,
- const rtems_filesystem_file_handlers_r *directory_handlers,
+ const rtems_filesystem_file_handlers_r *link_handlers,
const rtems_filesystem_file_handlers_r *fifo_handlers
)
{
@@ -87,9 +77,9 @@ int IMFS_initialize_support(
*
* NOTE: UNIX root is 755 and owned by root/root (0/0).
*/
- temp_mt_entry->mt_fs_root.node_access = IMFS_create_root_node();
- 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 = IMFS_create_root_node();
+ temp_mt_entry->mt_fs_root->location.handlers = &IMFS_directory_handlers;
+ temp_mt_entry->mt_fs_root->location.ops = op_table;
temp_mt_entry->pathconf_limits_and_options = IMFS_LIMITS_AND_OPTIONS;
/*
@@ -97,7 +87,7 @@ int IMFS_initialize_support(
*/
fs_info = calloc( 1, sizeof( IMFS_fs_info_t ) );
if ( !fs_info ) {
- free(temp_mt_entry->mt_fs_root.node_access);
+ free(temp_mt_entry->mt_fs_root->location.node_access);
rtems_set_errno_and_return_minus_one(ENOMEM);
}
temp_mt_entry->fs_info = fs_info;
@@ -108,11 +98,10 @@ int IMFS_initialize_support(
fs_info->instance = imfs_instance++;
fs_info->ino_count = 1;
- fs_info->memfile_handlers = memfile_handlers;
- fs_info->directory_handlers = directory_handlers;
+ fs_info->link_handlers = link_handlers;
fs_info->fifo_handlers = fifo_handlers;
- jnode = temp_mt_entry->mt_fs_root.node_access;
+ jnode = temp_mt_entry->mt_fs_root->location.node_access;
jnode->st_ino = fs_info->ino_count;
return 0;
diff --git a/cpukit/libfs/src/imfs/imfs_link.c b/cpukit/libfs/src/imfs/imfs_link.c
index c7dc6475f9..130c529d75 100644
--- a/cpukit/libfs/src/imfs/imfs_link.c
+++ b/cpukit/libfs/src/imfs/imfs_link.c
@@ -16,51 +16,36 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
int IMFS_link(
- rtems_filesystem_location_info_t *to_loc, /* IN */
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- const char *token /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
)
{
IMFS_types_union info;
IMFS_jnode_t *new_node;
- char new_name[ IMFS_NAME_MAX + 1 ];
- int i;
/*
* Verify this node can be linked to.
*/
- info.hard_link.link_node = to_loc->node_access;
+ info.hard_link.link_node = targetloc->node_access;
if ( info.hard_link.link_node->st_nlink >= LINK_MAX )
rtems_set_errno_and_return_minus_one( EMLINK );
/*
- * Remove any separators at the end of the string.
- */
- IMFS_get_token( token, strlen( token ), new_name, &i );
-
- /*
* Create a new link node.
- *
- * NOTE: Coverity Id 19 reports this as a leak
- * While technically not a leak, it indicated that IMFS_create_node
- * was ONLY passed a NULL when we created the root node. We
- * added a new IMFS_create_root_node() so this path no longer
- * existed. The result was simpler code which should not have
- * this path.
*/
new_node = IMFS_create_node(
- parent_loc,
+ parentloc,
IMFS_HARD_LINK,
- new_name,
+ name,
+ namelen,
( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
&info
);
diff --git a/cpukit/libfs/src/imfs/imfs_load_tar.c b/cpukit/libfs/src/imfs/imfs_load_tar.c
index 69c69c3e6d..0ae0f7cf88 100644
--- a/cpukit/libfs/src/imfs/imfs_load_tar.c
+++ b/cpukit/libfs/src/imfs/imfs_load_tar.c
@@ -21,16 +21,12 @@
* pointing to addresses in the TAR image.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <tar.h>
+#include "imfs.h"
+#include <sys/stat.h>
#include <string.h>
+#include <tar.h>
-#include <rtems.h>
-#include <rtems/libio_.h>
-#include <rtems/imfs.h>
#include <rtems/untar.h>
/*
@@ -80,13 +76,11 @@
* create_node.
*/
int rtems_tarfs_load(
- char *mountpoint,
+ const char *mountpoint,
uint8_t *tar_image,
- size_t tar_size
+ size_t tar_size
)
{
- rtems_filesystem_location_info_t root_loc;
- rtems_filesystem_location_info_t loc;
const char *hdr_ptr;
char filename[100];
char full_filename[256];
@@ -97,26 +91,27 @@ int rtems_tarfs_load(
int offset;
unsigned long nblocks;
IMFS_jnode_t *node;
- int status;
-
- status = rtems_filesystem_evaluate_path(
- mountpoint,
- strlen(mountpoint),
- 0,
- &root_loc,
- 0
+ int rv = 0;
+ int eval_flags = RTEMS_LIBIO_FOLLOW_LINK;
+ rtems_filesystem_eval_path_context_t ctx;
+ rtems_filesystem_location_info_t rootloc;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_start( &ctx, mountpoint, eval_flags );
+
+ rtems_filesystem_eval_path_extract_currentloc( &ctx, &rootloc );
+ rtems_filesystem_eval_path_set_flags(
+ &ctx,
+ RTEMS_LIBIO_MAKE | RTEMS_LIBIO_EXCLUSIVE
);
- if (status != 0)
- return -1;
-
- if (root_loc.ops != &IMFS_ops && root_loc.ops != &fifoIMFS_ops)
- return -1;
+ if (rootloc.ops != &IMFS_ops && rootloc.ops != &fifoIMFS_ops) {
+ rv = -1;
+ }
/*
* Create an IMFS node structure pointing to tar image memory.
*/
offset = 0;
- while (1) {
+ while ( rv == 0 ) {
if (offset + 512 > tar_size)
break;
@@ -154,22 +149,23 @@ int rtems_tarfs_load(
}
/*
* Create a LINEAR_FILE node
- *
- * NOTE: Coverity Id 20 reports this as a leak.
- * While technically not a leak, it indicated that
- * IMFS_create_node was ONLY passed a NULL when we created the
- * root node. We added a new IMFS_create_root_node() so this
- * path no longer existed. The result was simpler code which
- * should not have this path.
*/
else if (linkflag == REGTYPE) {
- const char *name;
-
- loc = root_loc;
- if (IMFS_evaluate_for_make(filename, &loc, &name) == 0) {
+ rtems_filesystem_location_free( currentloc );
+ rtems_filesystem_location_clone( currentloc, &rootloc );
+ rtems_filesystem_eval_path_set_path(
+ &ctx,
+ filename,
+ strlen( filename )
+ );
+ rtems_filesystem_eval_path_continue( &ctx );
+
+ if ( !rtems_filesystem_location_is_null( currentloc ) ) {
node = IMFS_create_node(
- &loc,
- IMFS_LINEAR_FILE, (char *)name,
+ currentloc,
+ IMFS_LINEAR_FILE,
+ rtems_filesystem_eval_path_get_token( &ctx ),
+ rtems_filesystem_eval_path_get_tokenlen( &ctx ),
(file_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG,
NULL
);
@@ -181,6 +177,10 @@ int rtems_tarfs_load(
offset += 512 * nblocks;
}
}
- return status;
+
+ rtems_filesystem_location_free( &rootloc );
+ rtems_filesystem_eval_path_cleanup( &ctx );
+
+ return rv;
}
diff --git a/cpukit/libfs/src/imfs/imfs_mknod.c b/cpukit/libfs/src/imfs/imfs_mknod.c
index 747391e9fd..47f7dca0e8 100644
--- a/cpukit/libfs/src/imfs/imfs_mknod.c
+++ b/cpukit/libfs/src/imfs/imfs_mknod.c
@@ -6,6 +6,9 @@
* COPYRIGHT (c) 1989-2010.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
@@ -14,65 +17,60 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdlib.h>
-
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
+
+static void get_type_and_info_by_mode_and_dev(
+ mode_t mode,
+ dev_t dev,
+ IMFS_jnode_types_t *type,
+ IMFS_types_union *info
+)
+{
+ if ( S_ISDIR( mode ) ) {
+ *type = IMFS_DIRECTORY;
+ } else if ( S_ISREG( mode ) ) {
+ *type = IMFS_MEMORY_FILE;
+ } else if ( S_ISBLK( mode ) || S_ISCHR( mode ) ) {
+ *type = IMFS_DEVICE;
+ rtems_filesystem_split_dev_t(
+ dev,
+ info->device.major,
+ info->device.minor
+ );
+ } else if (S_ISFIFO( mode )) {
+ *type = IMFS_FIFO;
+ } else {
+ IMFS_assert( 0 );
+ }
+}
int IMFS_mknod(
- const char *token, /* IN */
- mode_t mode, /* IN */
- dev_t dev, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
)
{
- IMFS_token_types type = 0;
- IMFS_jnode_t *new_node;
- int result;
- char new_name[ IMFS_NAME_MAX + 1 ];
- IMFS_types_union info;
+ int rv = 0;
+ IMFS_jnode_types_t type;
+ IMFS_types_union info;
+ IMFS_jnode_t *new_node;
- IMFS_get_token( token, strlen( token ), new_name, &result );
+ get_type_and_info_by_mode_and_dev( mode, dev, &type, &info );
- /*
- * Figure out what type of IMFS node this is.
- */
- if ( S_ISDIR(mode) )
- type = IMFS_DIRECTORY;
- else if ( S_ISREG(mode) )
- type = IMFS_MEMORY_FILE;
- else if ( S_ISBLK(mode) || S_ISCHR(mode) ) {
- type = IMFS_DEVICE;
- rtems_filesystem_split_dev_t( dev, info.device.major, info.device.minor );
- } else if (S_ISFIFO(mode))
- type = IMFS_FIFO;
- else
- IMFS_assert( 0 );
+ new_node = IMFS_create_node( parentloc, type, name, namelen, mode, &info );
+ if ( new_node != NULL ) {
+ IMFS_jnode_t *parent = parentloc->node_access;
- /*
- * Allocate and fill in an IMFS jnode
- *
- * NOTE: Coverity Id 21 reports this as a leak.
- * While technically not a leak, it indicated that IMFS_create_node
- * was ONLY passed a NULL when we created the root node. We
- * added a new IMFS_create_root_node() so this path no longer
- * existed. The result was simpler code which should not have
- * this path.
- */
- new_node = IMFS_create_node( pathloc, type, new_name, mode, &info );
- if ( !new_node )
- rtems_set_errno_and_return_minus_one( ENOMEM );
+ IMFS_update_ctime( parent );
+ IMFS_update_mtime( parent );
+ } else {
+ rv = -1;
+ }
- IMFS_update_ctime(new_node->Parent);
- IMFS_update_mtime(new_node->Parent);
- return 0;
+ return rv;
}
diff --git a/cpukit/libfs/src/imfs/imfs_mount.c b/cpukit/libfs/src/imfs/imfs_mount.c
index 3ec16da3f7..243e5a0e30 100644
--- a/cpukit/libfs/src/imfs/imfs_mount.c
+++ b/cpukit/libfs/src/imfs/imfs_mount.c
@@ -1,16 +1,12 @@
/*
* IMFS_mount
*
- * This routine will look at a mount table entry that we are going to
- * add to the mount table. If the mount point rtems_filesystem
- * location_info_t struct refers to a node that is a directory,
- * the node will be marked as a mount point by setting its directory.mt_fs
- * pointer to point to the mount table entry that we are about to add
- * to the mount table chain.
- *
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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,35 +15,27 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-int IMFS_mount(
- rtems_filesystem_mount_table_entry_t *mt_entry
-)
+int IMFS_mount( rtems_filesystem_mount_table_entry_t *mt_entry )
{
- IMFS_jnode_t *node;
-
- node = mt_entry->mt_point_node.node_access;
-
- /*
- * Is the node that we are mounting onto a directory node ?
- */
-
- if ( node->type != IMFS_DIRECTORY )
- rtems_set_errno_and_return_minus_one( ENOTDIR );
-
- /*
- * Set mt_fs pointer to point to the mount table entry for
- * the mounted file system.
- */
-
- node->info.directory.mt_fs = mt_entry;
- return 0;
+ int rv = 0;
+ IMFS_jnode_t *node = mt_entry->mt_point_node->location.node_access;
+
+ if ( node->type == IMFS_DIRECTORY ) {
+ if ( node->info.directory.mt_fs == NULL ) {
+ node->info.directory.mt_fs = mt_entry;
+ } else {
+ errno = EBUSY;
+ rv = -1;
+ }
+ } else {
+ errno = ENOTDIR;
+ rv = -1;
+ }
+
+ return rv;
}
diff --git a/cpukit/libfs/src/imfs/imfs_ntype.c b/cpukit/libfs/src/imfs/imfs_ntype.c
index f80182b144..f399707c0c 100644
--- a/cpukit/libfs/src/imfs/imfs_ntype.c
+++ b/cpukit/libfs/src/imfs/imfs_ntype.c
@@ -7,6 +7,9 @@
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
@@ -15,18 +18,30 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
#include "imfs.h"
rtems_filesystem_node_types_t IMFS_node_type(
- rtems_filesystem_location_info_t *pathloc /* IN */
+ const rtems_filesystem_location_info_t *loc
)
{
- IMFS_jnode_t *node;
+ const IMFS_jnode_t *node = loc->node_access;
+ IMFS_jnode_types_t imfs_type = node->type;
+ rtems_filesystem_node_types_t type;
+
+ switch ( imfs_type ) {
+ case IMFS_HARD_LINK:
+ type = node->info.hard_link.link_node->type;
+ break;
+ case IMFS_LINEAR_FILE:
+ type = RTEMS_FILESYSTEM_MEMORY_FILE;
+ break;
+ default:
+ type = imfs_type;
+ break;
+ }
- node = pathloc->node_access;
- return node->type;
+ return type;
}
diff --git a/cpukit/libfs/src/imfs/imfs_readlink.c b/cpukit/libfs/src/imfs/imfs_readlink.c
index b598fcf2c1..6786806abd 100644
--- a/cpukit/libfs/src/imfs/imfs_readlink.c
+++ b/cpukit/libfs/src/imfs/imfs_readlink.c
@@ -15,18 +15,15 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
ssize_t IMFS_readlink(
- rtems_filesystem_location_info_t *loc,
- char *buf, /* OUT */
- size_t bufsize
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t bufsize
)
{
IMFS_jnode_t *node;
diff --git a/cpukit/libfs/src/imfs/imfs_rename.c b/cpukit/libfs/src/imfs/imfs_rename.c
index 95c27fa9fd..855d026c36 100644
--- a/cpukit/libfs/src/imfs/imfs_rename.c
+++ b/cpukit/libfs/src/imfs/imfs_rename.c
@@ -15,40 +15,50 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
int IMFS_rename(
- rtems_filesystem_location_info_t *old_parent_loc, /* IN */
- rtems_filesystem_location_info_t *old_loc, /* IN */
- rtems_filesystem_location_info_t *new_parent_loc, /* IN */
- const char *new_name /* IN */
+ const rtems_filesystem_location_info_t *oldparentloc,
+ const rtems_filesystem_location_info_t *oldloc,
+ const rtems_filesystem_location_info_t *newparentloc,
+ const char *name,
+ size_t namelen
)
{
- IMFS_jnode_t *the_jnode;
- IMFS_jnode_t *new_parent;
+ int rv = 0;
+ IMFS_jnode_t *node = oldloc->node_access;
+ IMFS_jnode_t *new_parent = newparentloc->node_access;
- the_jnode = old_loc->node_access;
-
- strncpy( the_jnode->name, new_name, IMFS_NAME_MAX );
+ /*
+ * FIXME: Due to insufficient checks we can create inaccessible nodes with
+ * this operation.
+ */
- if ( the_jnode->Parent != NULL )
- rtems_chain_extract( (rtems_chain_node *) the_jnode );
+ if ( node->Parent != NULL ) {
+ if ( namelen < IMFS_NAME_MAX ) {
+ memcpy( node->name, name, namelen );
+ node->name [namelen] = '\0';
- new_parent = new_parent_loc->node_access;
- the_jnode->Parent = new_parent;
+ rtems_chain_extract( &node->Node );
- rtems_chain_append( &new_parent->info.directory.Entries, &the_jnode->Node );
+ node->Parent = new_parent;
+ rtems_chain_append(
+ &new_parent->info.directory.Entries,
+ &node->Node
+ );
- /*
- * Update the time.
- */
- IMFS_update_ctime( the_jnode );
+ IMFS_update_ctime( node );
+ } else {
+ errno = ENAMETOOLONG;
+ rv = -1;
+ }
+ } else {
+ errno = EINVAL;
+ rv = -1;
+ }
- return 0;
+ return rv;
}
diff --git a/cpukit/libfs/src/imfs/imfs_rmnod.c b/cpukit/libfs/src/imfs/imfs_rmnod.c
index 25c7cde084..c50041942f 100644
--- a/cpukit/libfs/src/imfs/imfs_rmnod.c
+++ b/cpukit/libfs/src/imfs/imfs_rmnod.c
@@ -7,6 +7,9 @@
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
@@ -15,17 +18,13 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <stdlib.h>
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/libio_.h>
-
#include "imfs.h"
+#include <stdlib.h>
+
void IMFS_create_orphan( IMFS_jnode_t *jnode )
{
if ( jnode->Parent != NULL ) {
@@ -40,10 +39,7 @@ void IMFS_create_orphan( IMFS_jnode_t *jnode )
void IMFS_check_node_remove( IMFS_jnode_t *jnode )
{
- if ( !rtems_libio_is_file_open( jnode ) && jnode->st_nlink < 1 ) {
- if ( rtems_filesystem_current.node_access == jnode )
- rtems_filesystem_current.node_access = NULL;
-
+ if ( jnode->st_nlink < 1 ) {
switch ( jnode->type ) {
case IMFS_MEMORY_FILE:
IMFS_memfile_remove( jnode );
@@ -59,19 +55,75 @@ void IMFS_check_node_remove( IMFS_jnode_t *jnode )
}
}
-/*
- * IMFS_rmnod
- */
+static int IMFS_rmnod_directory(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ IMFS_jnode_t *node = loc->node_access;
+ int rv = 0;
+
+ if ( !rtems_chain_is_empty( &node->info.directory.Entries ) ) {
+ errno = ENOTEMPTY;
+ rv = -1;
+ } else if (
+ rtems_filesystem_location_is_root( loc )
+ || node->info.directory.mt_fs != NULL
+ ) {
+ errno = EBUSY;
+ rv = -1;
+ }
+
+ return rv;
+}
+
+static int IMFS_rmnod_hard_link(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ int rv = 0;
+ IMFS_jnode_t *node = loc->node_access;
+ IMFS_jnode_t *target = node->info.hard_link.link_node;
+
+ if ( target->st_nlink == 1) {
+ rtems_filesystem_location_info_t target_loc = *loc;
+
+ target_loc.node_access = target;
+ IMFS_Set_handlers( &target_loc );
+
+ rv = (*target_loc.ops->rmnod_h)( parentloc, &target_loc );
+ } else {
+ --target->st_nlink;
+ IMFS_update_ctime( target );
+ }
+
+ return rv;
+}
int IMFS_rmnod(
- rtems_filesystem_location_info_t *parent_pathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
)
{
- IMFS_jnode_t *jnode = (IMFS_jnode_t *) pathloc->node_access;
+ int rv = 0;
+ IMFS_jnode_t *node = loc->node_access;
- IMFS_create_orphan( jnode );
- IMFS_check_node_remove( jnode );
+ switch ( node->type ) {
+ case IMFS_DIRECTORY:
+ rv = IMFS_rmnod_directory( parentloc, loc );
+ break;
+ case IMFS_HARD_LINK:
+ rv = IMFS_rmnod_hard_link( parentloc, loc );
+ break;
+ default:
+ break;
+ }
+
+ if ( rv == 0 ) {
+ IMFS_create_orphan( node );
+ IMFS_check_node_remove( node );
+ }
- return 0;
+ return rv;
}
diff --git a/cpukit/libfs/src/imfs/imfs_stat.c b/cpukit/libfs/src/imfs/imfs_stat.c
index 5bc1eae579..66d1ca2ba9 100644
--- a/cpukit/libfs/src/imfs/imfs_stat.c
+++ b/cpukit/libfs/src/imfs/imfs_stat.c
@@ -6,6 +6,9 @@
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
@@ -14,31 +17,45 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-#include <string.h>
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
+
+#include <dirent.h>
+#include <string.h>
+
+static size_t IMFS_directory_size( const IMFS_jnode_t *the_jnode )
+{
+ size_t size = 0;
+ const rtems_chain_control *chain = &the_jnode->info.directory.Entries;
+ const rtems_chain_node *current = rtems_chain_immutable_first( chain );
+ const rtems_chain_node *tail = rtems_chain_immutable_tail( chain );
+
+ while ( current != tail ) {
+ size += sizeof(struct dirent);
+ current = rtems_chain_immutable_next( current );
+ }
+
+ return size;
+}
int IMFS_stat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
)
{
- IMFS_fs_info_t *fs_info;
- IMFS_jnode_t *the_jnode;
- IMFS_device_t *io;
-
- the_jnode = loc->node_access;
+ IMFS_fs_info_t *fs_info = loc->mt_entry->fs_info;
+ IMFS_jnode_t *the_jnode = loc->node_access;
+ IMFS_device_t *io = &the_jnode->info.device;
+ if ( the_jnode->type == IMFS_HARD_LINK ) {
+ the_jnode = the_jnode->info.hard_link.link_node;
+ }
switch ( the_jnode->type ) {
case IMFS_DEVICE:
- io = &the_jnode->info.device;
buf->st_rdev = rtems_filesystem_make_dev_t( io->major, io->minor );
break;
@@ -47,12 +64,15 @@ int IMFS_stat(
buf->st_size = the_jnode->info.file.size;
break;
+ case IMFS_DIRECTORY:
+ buf->st_size = IMFS_directory_size( the_jnode );
+ break;
+
case IMFS_SYM_LINK:
buf->st_size = strlen( the_jnode->info.sym_link.name );
break;
case IMFS_FIFO:
- buf->st_size = 0;
break;
default:
@@ -64,7 +84,6 @@ int IMFS_stat(
* The device number of the IMFS is the major number and the minor is the
* instance.
*/
- fs_info = loc->mt_entry->fs_info;
buf->st_dev =
rtems_filesystem_make_dev_t( IMFS_DEVICE_MAJOR_NUMBER, fs_info->instance );
@@ -78,7 +97,9 @@ int IMFS_stat(
buf->st_mtime = the_jnode->stat_mtime;
buf->st_ctime = the_jnode->stat_ctime;
- buf->st_blksize = imfs_rq_memfile_bytes_per_block;
+ if ( the_jnode->type != IMFS_DIRECTORY ) {
+ buf->st_blksize = imfs_rq_memfile_bytes_per_block;
+ }
return 0;
}
diff --git a/cpukit/libfs/src/imfs/imfs_symlink.c b/cpukit/libfs/src/imfs/imfs_symlink.c
index 863ad23510..5a1d06ad19 100644
--- a/cpukit/libfs/src/imfs/imfs_symlink.c
+++ b/cpukit/libfs/src/imfs/imfs_symlink.c
@@ -16,54 +16,39 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
+
+#include <stdlib.h>
int IMFS_symlink(
- rtems_filesystem_location_info_t *parent_loc,
- const char *link_name,
- const char *node_name
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
)
{
IMFS_types_union info;
IMFS_jnode_t *new_node;
- char new_name[ IMFS_NAME_MAX + 1 ];
- int i;
-
- /*
- * Remove any separators at the end of the string.
- */
- IMFS_get_token( node_name, strlen( node_name ), new_name, &i );
/*
* Duplicate link name
*/
- info.sym_link.name = strdup(link_name);
+ info.sym_link.name = strdup(target);
if (info.sym_link.name == NULL) {
rtems_set_errno_and_return_minus_one(ENOMEM);
}
/*
* Create a new link node.
- *
- * NOTE: Coverity CID 22 notes this as a resource leak.
- * While technically not a leak, it indicated that IMFS_create_node
- * was ONLY passed a NULL when we created the root node. We
- * added a new IMFS_create_root_node() so this path no longer
- * existed. The result was simpler code which should not have
- * this path.
*/
new_node = IMFS_create_node(
- parent_loc,
+ parentloc,
IMFS_SYM_LINK,
- new_name,
+ name,
+ namelen,
( S_IFLNK | ( S_IRWXU | S_IRWXG | S_IRWXO )),
&info
);
diff --git a/cpukit/libfs/src/imfs/imfs_unlink.c b/cpukit/libfs/src/imfs/imfs_unlink.c
deleted file mode 100644
index 0ec176ed03..0000000000
--- a/cpukit/libfs/src/imfs/imfs_unlink.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * IMFS_unlink
- *
- * Routine to remove a link node from the tree.
- *
- * COPYRIGHT (c) 1989-1999.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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 <errno.h>
-#include <stdlib.h>
-
-#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-
-int IMFS_unlink(
- rtems_filesystem_location_info_t *parentloc, /* IN */
- rtems_filesystem_location_info_t *loc /* IN */
-)
-{
- IMFS_jnode_t *node;
- rtems_filesystem_location_info_t the_link;
- int result = 0;
-
- node = loc->node_access;
-
- /*
- * Decrement the link counter of node pointed to and free the
- * space.
- */
-
- /*
- * If this is the last last pointer to the node
- * free the node.
- */
-
- if ( node->type == IMFS_HARD_LINK ) {
-
- if ( !node->info.hard_link.link_node )
- rtems_set_errno_and_return_minus_one( EINVAL );
-
- the_link = *loc;
- the_link.node_access = node->info.hard_link.link_node;
- IMFS_Set_handlers( &the_link );
-
- /*
- * If removing the last hard link to a node, then we need
- * to remove the node that is a link and the node itself.
- */
-
- if ( node->info.hard_link.link_node->st_nlink == 1)
- {
- result = (*the_link.handlers->rmnod_h)( parentloc, &the_link );
- if ( result != 0 )
- return -1;
- }
- else
- {
- node->info.hard_link.link_node->st_nlink --;
- IMFS_update_ctime( node->info.hard_link.link_node );
- }
- }
-
- /*
- * Now actually free the node we were asked to free.
- */
-
- result = (*loc->handlers->rmnod_h)( parentloc, loc );
-
- return result;
-}
diff --git a/cpukit/libfs/src/imfs/imfs_unmount.c b/cpukit/libfs/src/imfs/imfs_unmount.c
index ee1482bfa5..47acec9320 100644
--- a/cpukit/libfs/src/imfs/imfs_unmount.c
+++ b/cpukit/libfs/src/imfs/imfs_unmount.c
@@ -1,17 +1,12 @@
/*
* IMFS_unmount
*
- * This routine will look at a mount table entry that we are going to
- * add to the mount table. If the mount point
- * rtems_filesystem_location_info_t struct refers to a node that is a
- * directory that has a file system mounted on it, the node will be
- * marked as a mount point by * setting its directory.mt_fs pointer
- * to NULL. This indicates that a directory is no longer mounted on
- * this node.
- *
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
@@ -20,43 +15,27 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-
#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-int IMFS_unmount(
- rtems_filesystem_mount_table_entry_t *mt_entry
-)
+int IMFS_unmount( rtems_filesystem_mount_table_entry_t *mt_entry )
{
- IMFS_jnode_t *node;
-
- node = mt_entry->mt_point_node.node_access;
-
- /*
- * Is the node that we are mounting onto a directory node ?
- */
-
- if ( node->type != IMFS_DIRECTORY )
- rtems_set_errno_and_return_minus_one( ENOTDIR );
-
- /*
- * Did the node indicate that there was a directory mounted here?
- */
-
- if ( node->info.directory.mt_fs == NULL )
- rtems_set_errno_and_return_minus_one( EINVAL ); /* XXX */
-
- /*
- * Set the mt_fs pointer to indicate that there is no longer
- * a file system mounted to this point.
- */
-
- node->info.directory.mt_fs = NULL;
-
- return 0;
+ int rv = 0;
+ IMFS_jnode_t *node = mt_entry->mt_point_node->location.node_access;
+
+ if ( node->type == IMFS_DIRECTORY ) {
+ if ( node->info.directory.mt_fs == mt_entry ) {
+ node->info.directory.mt_fs = NULL;
+ } else {
+ errno = EINVAL;
+ rv = -1;
+ }
+ } else {
+ errno = ENOTDIR;
+ rv = -1;
+ }
+
+ return rv;
}
diff --git a/cpukit/libfs/src/imfs/imfs_utime.c b/cpukit/libfs/src/imfs/imfs_utime.c
index 2867e13ed6..b16af11b30 100644
--- a/cpukit/libfs/src/imfs/imfs_utime.c
+++ b/cpukit/libfs/src/imfs/imfs_utime.c
@@ -15,24 +15,22 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <errno.h>
-#include <sys/time.h>
-
-#include <rtems/libio_.h>
#include "imfs.h"
+#include <sys/time.h>
+
int IMFS_utime(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- time_t actime, /* IN */
- time_t modtime /* IN */
+ const rtems_filesystem_location_info_t *loc,
+ time_t actime,
+ time_t modtime
)
{
IMFS_jnode_t *the_jnode;
- the_jnode = (IMFS_jnode_t *) pathloc->node_access;
+ the_jnode = (IMFS_jnode_t *) loc->node_access;
the_jnode->stat_atime = actime;
the_jnode->stat_mtime = modtime;
diff --git a/cpukit/libfs/src/imfs/ioman.c b/cpukit/libfs/src/imfs/ioman.c
index 0dce7e7239..c0dbee5d05 100644
--- a/cpukit/libfs/src/imfs/ioman.c
+++ b/cpukit/libfs/src/imfs/ioman.c
@@ -5,6 +5,9 @@
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
+ * 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.
@@ -13,19 +16,13 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
#include <string.h>
-#include <rtems.h>
#include <rtems/libio_.h>
-#include <rtems/seterr.h>
-#include "imfs.h"
/*
* rtems_io_register_name
@@ -52,42 +49,23 @@ rtems_status_code rtems_io_register_name(
return RTEMS_SUCCESSFUL;
}
-/*
- * rtems_io_lookup_name
- *
- * This version is reentrant.
- *
- * XXX - This is dependent upon IMFS and should not be.
- * Suggest adding a filesystem routine to fill in the device_info.
- */
-
rtems_status_code rtems_io_lookup_name(
const char *name,
rtems_driver_name_t *device_info
)
{
- IMFS_jnode_t *the_jnode;
- rtems_filesystem_location_info_t loc;
- int result;
- rtems_filesystem_node_types_t node_type;
-
- result = rtems_filesystem_evaluate_path(
- name, strlen( name ), 0x00, &loc, true );
- the_jnode = loc.node_access;
-
- node_type = (*loc.ops->node_type_h)( &loc );
-
- if ( (result != 0) || node_type != RTEMS_FILESYSTEM_DEVICE ) {
- rtems_filesystem_freenode( &loc );
- return RTEMS_UNSATISFIED;
+ rtems_status_code sc = RTEMS_SUCCESSFUL;
+ struct stat st;
+ int rv = stat( name, &st );
+
+ if ( rv == 0 && S_ISCHR( st.st_mode ) ) {
+ device_info->device_name = name;
+ device_info->device_name_length = strlen( name );
+ device_info->major = rtems_filesystem_dev_major_t( st.st_rdev );
+ device_info->minor = rtems_filesystem_dev_minor_t( st.st_rdev );
+ } else {
+ sc = RTEMS_UNSATISFIED;
}
- device_info->device_name = name;
- device_info->device_name_length = strlen( name );
- device_info->major = the_jnode->info.device.major;
- device_info->minor = the_jnode->info.device.minor;
-
- rtems_filesystem_freenode( &loc );
-
- return RTEMS_SUCCESSFUL;
+ return sc;
}
diff --git a/cpukit/libfs/src/imfs/memfile.c b/cpukit/libfs/src/imfs/memfile.c
index 35c1eee0ec..65810c0bca 100644
--- a/cpukit/libfs/src/imfs/memfile.c
+++ b/cpukit/libfs/src/imfs/memfile.c
@@ -18,18 +18,13 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
+#include "imfs.h"
+
#include <stdlib.h>
#include <string.h>
-#include <errno.h>
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include "imfs.h"
-#include <rtems/libio_.h>
-#include <rtems/seterr.h>
#define MEMFILE_STATIC
@@ -86,8 +81,8 @@ void memfile_free_block(
int memfile_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
IMFS_jnode_t *the_jnode;
diff --git a/cpukit/libfs/src/imfs/miniimfs_init.c b/cpukit/libfs/src/imfs/miniimfs_init.c
index b43a5318e8..a4db968e3c 100644
--- a/cpukit/libfs/src/imfs/miniimfs_init.c
+++ b/cpukit/libfs/src/imfs/miniimfs_init.c
@@ -18,28 +18,29 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/libio_.h>
-
#include "imfs.h"
static const rtems_filesystem_operations_table miniIMFS_ops = {
- .evalpath_h = IMFS_eval_path,
- .evalformake_h = IMFS_evaluate_for_make,
+ .lock_h = rtems_filesystem_default_lock,
+ .unlock_h = rtems_filesystem_default_unlock,
+ .eval_path_h = IMFS_eval_path,
.link_h = rtems_filesystem_default_link,
- .unlink_h = rtems_filesystem_default_unlink,
+ .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
.node_type_h = IMFS_node_type,
.mknod_h = IMFS_mknod,
+ .rmnod_h = IMFS_rmnod,
+ .fchmod_h = rtems_filesystem_default_fchmod,
.chown_h = rtems_filesystem_default_chown,
+ .clonenod_h = rtems_filesystem_default_clonenode,
.freenod_h = rtems_filesystem_default_freenode,
.mount_h = IMFS_mount,
.fsmount_me_h = miniIMFS_initialize,
.unmount_h = rtems_filesystem_default_unmount,
- .fsunmount_me_h = rtems_filesystem_default_unmount,
+ .fsunmount_me_h = rtems_filesystem_default_fsunmount,
.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 = rtems_filesystem_default_rename,
@@ -54,8 +55,7 @@ int miniIMFS_initialize(
return IMFS_initialize_support(
mt_entry,
&miniIMFS_ops,
- &rtems_filesystem_handlers_default, /* for memfiles */
- &rtems_filesystem_handlers_default, /* for directories */
+ &rtems_filesystem_handlers_default, /* for links */
&rtems_filesystem_handlers_default /* for fifos */
);
}
diff --git a/cpukit/libfs/src/nfsclient/src/librtemsNfs.h b/cpukit/libfs/src/nfsclient/src/librtemsNfs.h
index fc17d1de7f..4e8247ced0 100644
--- a/cpukit/libfs/src/nfsclient/src/librtemsNfs.h
+++ b/cpukit/libfs/src/nfsclient/src/librtemsNfs.h
@@ -123,7 +123,7 @@ rpcUdpCleanup(void);
* Supply zero values to have the
* driver chose reasonable defaults.
*/
-int
+void
nfsInit(int smallPoolDepth, int bigPoolDepth);
/* Driver cleanup code
diff --git a/cpukit/libfs/src/nfsclient/src/nfs.c b/cpukit/libfs/src/nfsclient/src/nfs.c
index 80e757cbdf..ee1185367f 100644
--- a/cpukit/libfs/src/nfsclient/src/nfs.c
+++ b/cpukit/libfs/src/nfsclient/src/nfs.c
@@ -4,7 +4,12 @@
/* Author: Till Straumann <strauman@slac.stanford.edu> 2002 */
-/* Hacked on by others. */
+/*
+ * Hacked on by others.
+ *
+ * Modifications to support reference counting in the file system are
+ * Copyright (c) 2012 embedded brains GmbH.
+ */
/*
* Authorship
@@ -74,6 +79,7 @@
#include <mount_prot.h>
#include "rpcio.h"
+#include "librtemsNfs.h"
/* Configurable parameters */
@@ -201,6 +207,21 @@ static struct timeval _nfscalltimeout = { 10, 0 }; /* {secs, us } */
#define UNLOCK(s) do { rtems_semaphore_release((s)); \
} while (0)
+static inline char *
+nfs_dupname(const char *name, size_t namelen)
+{
+ char *dupname = malloc(namelen + 1);
+
+ if (dupname != NULL) {
+ memcpy(dupname, name, namelen);
+ dupname [namelen] = '\0';
+ } else {
+ errno = ENOMEM;
+ }
+
+ return dupname;
+}
+
/*****************************************
Types with Associated XDR Routines
*****************************************/
@@ -214,12 +235,6 @@ typedef struct strbuf {
u_int max;
} strbuf;
-static bool_t
-xdr_strbuf(XDR *xdrs, strbuf *obj)
-{
- return xdr_string(xdrs, &obj->buf, obj->max);
-}
-
/* Read 'readlink' results into a 'strbuf'.
* This is convenient as it avoids
* one extra step of copying / lenght
@@ -562,9 +577,9 @@ typedef struct NfsNodeRec_ {
*****************************************/
static ssize_t nfs_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- char *buf, /* OUT */
- size_t len
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t len
);
static int updateAttr(NfsNode node, int force);
@@ -591,10 +606,10 @@ static int updateAttr(NfsNode node, int force);
static int
nfs_sattr(NfsNode node, sattr *arg, u_long mask);
-extern struct _rtems_filesystem_operations_table nfs_fs_ops;
-static struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers;
-static struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers;
-static struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers;
+extern const struct _rtems_filesystem_operations_table nfs_fs_ops;
+static const struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers;
+static const struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers;
+static const struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers;
static rtems_driver_address_table drvNfs;
int
@@ -603,64 +618,6 @@ nfsMountsShow(FILE*);
rtems_status_code
rtems_filesystem_resolve_location(char *buf, int len, rtems_filesystem_location_info_t *loc);
-
-/*****************************************
- Inline Routines
- *****************************************/
-
-
-/* * * * * * * * * * * * * * * * * *
- Trivial Operations on a NfsNode
- * * * * * * * * * * * * * * * * * */
-
-/* determine if a location 'l' is an NFS root node */
-static inline int
-locIsRoot(rtems_filesystem_location_info_t *l)
-{
-NfsNode me = (NfsNode) l->node_access;
-NfsNode r;
- r = (NfsNode)l->mt_entry->mt_fs_root.node_access;
- return SERP_ATTR(r).fileid == SERP_ATTR(me).fileid &&
- SERP_ATTR(r).fsid == SERP_ATTR(me).fsid;
-}
-
-/* determine if a location 'l' is an NFS node */
-static inline int
-locIsNfs(rtems_filesystem_location_info_t *l)
-{
- return l->ops == &nfs_fs_ops;
-}
-
-/* determine if two locations refer to the
- * same entity. We know that 'nfsloc' is a
- * location inside nfs. However, we needn't
- * know anything about 'anyloc'.
- */
-static inline int
-locAreEqual(
- rtems_filesystem_location_info_t *nfsloc,
- rtems_filesystem_location_info_t *anyloc
-)
-{
-NfsNode na = (NfsNode) nfsloc->node_access;
-NfsNode nb;
-
- if (!locIsNfs(anyloc))
- return 0;
-
- nb = (NfsNode) anyloc->node_access;
-
- if (na->nfs != nb->nfs)
- return 0;
-
- updateAttr(nb, 0);
-
- return SERP_ATTR(na).fileid == SERP_ATTR(nb).fileid &&
- SERP_ATTR(na).fsid == SERP_ATTR(nb).fsid;
-}
-
-
-
/*****************************************
Global Variables
*****************************************/
@@ -1326,409 +1283,229 @@ enum clnt_stat stat = RPC_FAILED;
RTEMS File System Operations for NFS
*****************************************/
-#if 0 /* for reference */
-
-struct rtems_filesystem_location_info_tt
-{
- void *node_access;
- rtems_filesystem_file_handlers_r *handlers;
- rtems_filesystem_operations_table *ops;
- rtems_filesystem_mount_table_entry_t *mt_entry;
-};
-
-#endif
-
-/*
- * Evaluate a path letting 'pathloc' travel along.
- *
- * The important semantics of this operation are:
- *
- * If this routine returns -1, the caller assumes
- * pathloc to be _invalid_ and hence it will not
- * invoke rtems_filesystem_freenode() on it.
- *
- * OTOH, if evalpath returns 0,
- * rtems_filesystem_freenode() will eventually be
- * called which results in our freeing the associated
- * NfsNode attached to node_access.
- *
- * Therefore, this routine will _always_ allocate
- * a NfsNode and pass it out to *pathloc (provided
- * that the evaluation succeeds).
- *
- * However, if the evaluation finds that it has to
- * step across FS boundaries (mount point or a symlink
- * pointing outside), the NfsNode is destroyed
- * before passing control to the new FS' evalpath_h()
- *
- */
-
-union nfs_evalpath_arg {
- int i;
- const char **c;
- };
-
-STATIC int nfs_do_evalpath(
- const char *pathname, /* IN */
- int pathnamelen, /* IN */
- union nfs_evalpath_arg *arg,
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- int forMake
+static bool nfs_is_directory(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg
)
{
-char *del = 0, *part;
-int e = 0;
-NfsNode node = pathloc->node_access;
-char *p = malloc(MAXPATHLEN+1);
-Nfs nfs = (Nfs)pathloc->mt_entry->fs_info;
-RpcUdpServer server = nfs->server;
-unsigned long flags;
-#if DEBUG & DEBUG_COUNT_NODES
-unsigned long niu,siu;
-#endif
+ bool is_dir = false;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ NfsNode node = currentloc->node_access;
+ int force_update = 0;
- if ( !p ) {
- e = ENOMEM;
- goto cleanup;
+ if (updateAttr(node, force_update) == 0) {
+ is_dir = SERP_ATTR(node).type == NFDIR;
}
- memset(p, 0, MAXPATHLEN+1);
- memcpy(p, pathname, pathnamelen);
- LOCK(nfsGlob.lock);
- node = nfsNodeClone(node);
- UNLOCK(nfsGlob.lock);
-
- /* from here on, the NFS is protected from being unmounted
- * since the node refcount is > 1
- */
-
- /* clone the node */
- if ( !node ) {
- /* nodeClone sets errno */
- pathloc->node_access = 0;
- if ( ! (e = errno) ) {
- /* if we have no node, e must not be zero! */
- e = ENOMEM;
- }
- goto cleanup;
- }
-
- pathloc->node_access = node;
-
- /* Special case: the RTEMS filesystem code
- * may emit '..' on a regular file node to
- * find the parent directory :-(.
- * (eval.c: rtems_filesystem_evaluate_parent())
- * Try to catch this case here:
- */
- if ( NFDIR != SERP_ATTR(node).type && '.'==*p && '.'==*(p+1) ) {
- for ( part = p+2; '/'==*part; part++ )
- /* skip trailing '/' */;
- if ( !*part ) {
- /* this is it; back out dir and let them look up the dir itself... */
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir));
- *(p+1)=0;
- }
- }
-
- for (part=p; part && *part; part=del) {
-
- if ( NFLNK == SERP_ATTR(node).type ) {
- /* follow midpath link */
- char *b = malloc(NFS_MAXPATHLEN+1);
- int l;
-
- if (!b) {
- e = ENOMEM;
- goto cleanup;
- }
- if (nfs_readlink(pathloc, b, NFS_MAXPATHLEN+1)) {
- free(b);
- e = errno;
- goto cleanup;
- }
-
- /* prepend the link value to the rest of the path */
- if ( (l=strlen(b)) + strlen(part) + 1 > NFS_MAXPATHLEN ) {
- free(b);
- e = EINVAL;
- goto cleanup;
- }
- /* swap string buffers and reset delimiter */
- b[l++] = DELIM;
- strcpy(b+l,part);
- part = b;
- b = p;
- p = del = part;
-
- free(b);
-
- /* back up the directory filehandle (only necessary
- * if we don't back out to the root
- */
- if (! (DELIM == *part) ) {
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir));
-
- if (updateAttr(node, 1 /* force */)) {
- e = errno;
- goto cleanup;
- }
- }
- }
+ return is_dir;
+}
- /* find delimiter and eat /// sequences
- * (only if we don't restart at the root)
- */
- if ( DELIM != *part && (del = strchr(part, DELIM))) {
- do {
- *del++=0;
- } while (DELIM==*del);
- }
+static NfsNode nfs_search_in_directory(
+ Nfs nfs,
+ NfsNode node,
+ char *part
+)
+{
+ int rv;
- /* refuse to backup over the root */
- if ( 0==strcmp(part,UPDIR)
- && locAreEqual(pathloc, &rtems_filesystem_root) ) {
- part++;
- }
+ /* lookup one element */
+ SERP_ARGS(node).diroparg.name = part;
- /* cross mountpoint upwards */
- if ( (0==strcmp(part,UPDIR) && locIsRoot(pathloc)) /* cross mountpoint up */
- || DELIM == *part /* link starts at root */
- ) {
- int rval;
+ /* remember args / directory fh */
+ memcpy( &node->args, &SERP_FILE(node), sizeof(node->args));
#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr,
- "Crossing mountpoint upwards\n");
+ fprintf(stderr,"Looking up '%s'\n",part);
#endif
- if (DELIM == *part) {
- *pathloc = rtems_filesystem_root;
- } else {
- *pathloc = pathloc->mt_entry->mt_point_node;
- /* re-append the rest of the path */
- if (del)
- while ( 0 == *--del )
- *del = DELIM;
- }
-
- nfsNodeDestroy(node);
-
-#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr,
- "Re-evaluating '%s'\n",
- part);
-#endif
+ rv = nfscall(
+ nfs->server,
+ NFSPROC_LOOKUP,
+ (xdrproc_t) xdr_diropargs, &SERP_FILE(node),
+ (xdrproc_t) xdr_serporid, &node->serporid
+ );
- if (forMake)
- rval = pathloc->ops->evalformake_h(part, pathloc, arg->c);
- else
- rval = pathloc->ops->evalpath_h(part, strlen(part), arg->i, pathloc);
+ if (rv == 0 && node->serporid.status == NFS_OK) {
+ int force_update = 1;
- free(p);
- return rval;
+ rv = updateAttr(node, force_update);
+ if (rv != 0) {
+ node = NULL;
}
+ } else {
+ node = NULL;
+ }
- /* lookup one element */
- SERP_ARGS(node).diroparg.name = part;
-
- /* remember args / directory fh */
- memcpy( &node->args, &SERP_FILE(node), sizeof(node->args));
-
- /* don't lookup the item we want to create */
- if ( forMake && (!del || !*del) )
- break;
+ return node;
+}
-#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr,"Looking up '%s'\n",part);
-#endif
+static void nfs_follow_link(rtems_filesystem_eval_path_context_t *ctx)
+{
+ const size_t len = NFS_MAXPATHLEN + 1;
+ char *link = malloc(len);
- if ( nfscall(server,
- NFSPROC_LOOKUP,
- (xdrproc_t)xdr_diropargs, &SERP_FILE(node),
- (xdrproc_t)xdr_serporid, &node->serporid) ||
- NFS_OK != (errno=node->serporid.status) ) {
- e = errno;
- goto cleanup;
- }
- node->age = nowSeconds();
+ if (link != NULL) {
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ ssize_t rv = nfs_readlink(currentloc, link, len);
-#if DEBUG & DEBUG_EVALPATH
- if (NFLNK == SERP_ATTR(node).type && del) {
- fprintf(stderr,
- "Following midpath link '%s'\n",
- part);
+ if (rv >= 0) {
+ rtems_filesystem_eval_path_recursive(ctx, link, (size_t) rv);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, 0);
}
-#endif
+ free(link);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
}
+}
- if (forMake) {
- /* remember the name - do this _before_ copying
- * the name to local storage; the caller expects a
- * pointer into pathloc
- */
- assert( node->args.name );
-
- *(arg->c) = pathname + (node->args.name - p);
-
-#if 0
- /* restore the directory node */
+static bool nfs_update_currentloc(
+ rtems_filesystem_eval_path_context_t *ctx,
+ Nfs nfs,
+ NfsNode node
+)
+{
+ bool ok = true;
+ rtems_filesystem_location_info_t *pathloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir));
+ pathloc->node_access = node;
- if ( (nfscall(nfs->server,
- NFSPROC_GETATTR,
- (xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
- (xdrproc_t)xdr_attrstat, &node->serporid) && !errno && (errno = EIO)) ||
- (NFS_OK != (errno=node->serporid.status) ) ) {
- goto cleanup;
- }
-#endif
+ switch (SERP_ATTR(node).type) {
+ case NFDIR: pathloc->handlers = &nfs_dir_file_handlers; break;
+ case NFREG: pathloc->handlers = &nfs_file_file_handlers; break;
+ case NFLNK: pathloc->handlers = &nfs_link_file_handlers; break;
+ default: pathloc->handlers = &rtems_filesystem_handlers_default; break;
}
- if (locIsRoot(pathloc)) {
-
- /* stupid filesystem code has no 'op' for comparing nodes
- * but just compares the 'node_access' pointers.
- * Luckily, this is only done for comparing the root nodes.
- * Hence, we never give them a copy of the root but always
- * the root itself.
- */
- pathloc->node_access = pathloc->mt_entry->mt_fs_root.node_access;
- /* increment the 'in use' counter since we return one more
- * reference to the root node
- */
- rtems_interrupt_disable(flags);
- nfs->nodesInUse++;
- rtems_interrupt_enable(flags);
- nfsNodeDestroy(node);
-
-
- } else {
- switch (SERP_ATTR(node).type) {
- case NFDIR: pathloc->handlers = &nfs_dir_file_handlers; break;
- case NFREG: pathloc->handlers = &nfs_file_file_handlers; break;
- case NFLNK: pathloc->handlers = &nfs_link_file_handlers; break;
- default: pathloc->handlers = &rtems_filesystem_handlers_default; break;
- }
- pathloc->node_access = node;
-
- /* remember the name of this directory entry */
+ /* remember the name of this directory entry */
- if (node->args.name) {
- if (node->str) {
+ if (node->args.name) {
+ if (node->str) {
#if DEBUG & DEBUG_COUNT_NODES
- rtems_interrupt_disable(flags);
- nfs->stringsInUse--;
- rtems_interrupt_enable(flags);
+ rtems_interrupt_level flags;
+ rtems_interrupt_disable(flags);
+ nfs->stringsInUse--;
+ rtems_interrupt_enable(flags);
#endif
- free(node->str);
- }
- node->args.name = node->str = strdup(node->args.name);
- if (!node->str) {
- e = ENOMEM;
- goto cleanup;
- }
-
+ free(node->str);
+ }
+ node->args.name = node->str = strdup(node->args.name);
+ if (node->str != NULL) {
#if DEBUG & DEBUG_COUNT_NODES
+ rtems_interrupt_level flags;
rtems_interrupt_disable(flags);
nfs->stringsInUse++;
rtems_interrupt_enable(flags);
#endif
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
+ ok = false;
}
-
}
- node = 0;
- e = 0;
+ return ok;
+}
-cleanup:
- free(p);
-#if DEBUG & DEBUG_COUNT_NODES
- /* cache counters; nfs may be unmounted by other thread after the last
- * node is destroyed
- */
- niu = nfs->nodesInUse;
- siu = nfs->stringsInUse;
-#endif
- if (node) {
- nfsNodeDestroy(node);
- pathloc->node_access = 0;
- }
-#if DEBUG & DEBUG_COUNT_NODES
- fprintf(stderr,
- "leaving evalpath, in use count is %i nodes, %i strings\n",
- niu,siu);
-#endif
- if (e) {
-#if DEBUG & DEBUG_EVALPATH
- perror("Evalpath");
-#endif
- rtems_set_errno_and_return_minus_one(e);
+static rtems_filesystem_eval_path_generic_status nfs_eval_part(
+ rtems_filesystem_eval_path_context_t *ctx,
+ char *part
+)
+{
+ rtems_filesystem_eval_path_generic_status status =
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc(ctx);
+ Nfs nfs = currentloc->mt_entry->fs_info;
+ NfsNode dir = currentloc->node_access;
+ NfsNode entry = nfs_search_in_directory(nfs, dir, part);
+
+ if (entry != NULL) {
+ rtems_filesystem_eval_path_clear_token(ctx);
+
+ if (nfs_update_currentloc(ctx, nfs, entry)) {
+ int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
+ bool follow_sym_link = (eval_flags & RTEMS_LIBIO_FOLLOW_SYM_LINK) != 0;
+ bool terminal = !rtems_filesystem_eval_path_has_path( ctx );
+
+ if (SERP_ATTR(entry).type == NFLNK && (follow_sym_link || !terminal)) {
+ nfs_follow_link(ctx);
+ } else if (!terminal) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
+ }
+ }
} else {
- return 0;
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
}
+
+ return status;
}
-/* MANDATORY; may set errno=ENOSYS and return -1 */
-static int nfs_evalformake(
- const char *path, /* IN */
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- const char **pname /* OUT */
+static rtems_filesystem_eval_path_generic_status nfs_eval_token(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg,
+ const char *token,
+ size_t tokenlen
)
{
- union nfs_evalpath_arg args;
- args.c = pname;
-
- return nfs_do_evalpath(path, strlen(path), &args, pathloc, 1 /*forMake*/);
+ 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);
+ if (rtems_filesystem_eval_path_has_path(ctx)) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
+ }
+ } else {
+ char *part = nfs_dupname(token, tokenlen);
+
+ if (part != NULL) {
+ status = nfs_eval_part(ctx, part);
+ free(part);
+ } else {
+ rtems_filesystem_eval_path_error(ctx, ENOMEM);
+ }
+ }
+
+ return status;
}
-static int nfs_evalpath(
- const char *path, /* IN */
- size_t pathlen, /* IN */
- int flags, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN/OUT */
-)
+static const rtems_filesystem_eval_path_generic_config nfs_eval_config = {
+ .is_directory = nfs_is_directory,
+ .eval_token = nfs_eval_token
+};
+
+static void nfs_eval_path(rtems_filesystem_eval_path_context_t *ctx)
{
- union nfs_evalpath_arg args;
- args.i = flags;
- return nfs_do_evalpath(path, pathlen, &args, pathloc, 0 /*not forMake*/);
+ rtems_filesystem_eval_path_generic(ctx, NULL, &nfs_eval_config);
}
-
/* create a hard link */
static int nfs_link(
- rtems_filesystem_location_info_t *to_loc, /* IN */
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- const char *name /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen
)
{
+int rv = 0;
NfsNode pNode;
nfsstat status;
-NfsNode tNode = to_loc->node_access;
+NfsNode tNode = targetloc->node_access;
+char *dupname;
+
+ dupname = nfs_dupname(name, namelen);
+ if (dupname == NULL)
+ return -1;
#if DEBUG & DEBUG_SYSCALLS
- fprintf(stderr,"Creating link '%s'\n",name);
+ fprintf(stderr,"Creating link '%s'\n",dupname);
#endif
- if ( !locIsNfs(parent_loc) ) {
- errno = EXDEV;
- return -1;
- }
-
- pNode = parent_loc->node_access;
- if ( tNode->nfs != pNode->nfs ) {
- errno = EXDEV;
- return -1;
- }
memcpy(&SERP_ARGS(tNode).linkarg.to.dir,
&SERP_FILE(pNode),
sizeof(SERP_FILE(pNode)));
@@ -1744,16 +1521,18 @@ NfsNode tNode = to_loc->node_access;
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_link");
#endif
- return -1;
+ rv = -1;
}
- return 0;
+ free(dupname);
+
+ return rv;
}
static int nfs_do_unlink(
- rtems_filesystem_location_info_t *parent_loc,/* IN */
- rtems_filesystem_location_info_t *loc, /* IN */
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc,
int proc
)
{
@@ -1791,18 +1570,10 @@ char *name = NFSPROC_REMOVE == proc ?
return 0;
}
-static int nfs_unlink(
- rtems_filesystem_location_info_t *parent_loc, /* IN */
- rtems_filesystem_location_info_t *loc /* IN */
-)
-{
- return nfs_do_unlink(parent_loc, loc, NFSPROC_REMOVE);
-}
-
static int nfs_chown(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- uid_t owner, /* IN */
- gid_t group /* IN */
+ const rtems_filesystem_location_info_t *pathloc, /* IN */
+ uid_t owner, /* IN */
+ gid_t group /* IN */
)
{
sattr arg;
@@ -1814,14 +1585,27 @@ sattr arg;
}
+static int nfs_clonenode(rtems_filesystem_location_info_t *loc)
+{
+ NfsNode node = loc->node_access;
+
+ LOCK(nfsGlob.lock);
+ node = nfsNodeClone(node);
+ UNLOCK(nfsGlob.lock);
+
+ loc->node_access = node;
+
+ return node != NULL ? 0 : -1;
+}
+
/* Cleanup the FS private info attached to pathloc->node_access */
-static int nfs_freenode(
- rtems_filesystem_location_info_t *pathloc /* IN */
+static void nfs_freenode(
+ const rtems_filesystem_location_info_t *pathloc /* IN */
)
{
+#if DEBUG & DEBUG_COUNT_NODES
Nfs nfs = ((NfsNode)pathloc->node_access)->nfs;
-#if DEBUG & DEBUG_COUNT_NODES
/* print counts at entry where they are > 0 so 'nfs' is safe from being destroyed
* and there's no race condition
*/
@@ -1831,22 +1615,7 @@ Nfs nfs = ((NfsNode)pathloc->node_access)->nfs;
nfs->stringsInUse);
#endif
- /* never destroy the root node; it is released by the unmount
- * code
- */
- if (locIsRoot(pathloc)) {
- unsigned long flags;
- /* just adjust the references to the root node but
- * don't really release it
- */
- rtems_interrupt_disable(flags);
- nfs->nodesInUse--;
- rtems_interrupt_enable(flags);
- } else {
- nfsNodeDestroy(pathloc->node_access);
- pathloc->node_access = 0;
- }
- return 0;
+ nfsNodeDestroy(pathloc->node_access);
}
/* NOTE/TODO: mounting on top of NFS is not currently supported
@@ -1982,12 +1751,12 @@ char *path = mt_entry->dev;
/* looks good so far */
- mt_entry->mt_fs_root.node_access = rootNode;
+ mt_entry->mt_fs_root->location.node_access = rootNode;
rootNode = 0;
- mt_entry->mt_fs_root.ops = &nfs_fs_ops;
- mt_entry->mt_fs_root.handlers = &nfs_dir_file_handlers;
+ mt_entry->mt_fs_root->location.ops = &nfs_fs_ops;
+ mt_entry->mt_fs_root->location.handlers = &nfs_dir_file_handlers;
mt_entry->pathconf_limits_and_options = nfs_limits_and_options;
LOCK(nfsGlob.llock);
@@ -2016,7 +1785,7 @@ cleanup:
}
/* This op is called when they try to unmount THIS fs */
-STATIC int nfs_fsunmount_me(
+STATIC void nfs_fsunmount_me(
rtems_filesystem_mount_table_entry_t *mt_entry /* in */
)
{
@@ -2035,7 +1804,8 @@ LOCK(nfsGlob.llock);
fprintf(stderr,
"Refuse to unmount; there are still %i nodes in use (1 used by us)\n",
nodesInUse);
- rtems_set_errno_and_return_minus_one(EBUSY);
+ rtems_fatal_error_occurred(0xdeadbeef);
+ return;
}
status = buildIpAddr(&uid, &gid, 0, &saddr, &path);
@@ -2052,20 +1822,17 @@ LOCK(nfsGlob.llock);
if (stat) {
UNLOCK(nfsGlob.llock);
fprintf(stderr,"NFS UMOUNT -- %s\n", clnt_sperrno(stat));
- errno = EIO;
- return -1;
+ return;
}
- nfsNodeDestroy(mt_entry->mt_fs_root.node_access);
- mt_entry->mt_fs_root.node_access = 0;
+ nfsNodeDestroy(mt_entry->mt_fs_root->location.node_access);
+ mt_entry->mt_fs_root->location.node_access = 0;
nfsDestroy(mt_entry->fs_info);
mt_entry->fs_info = 0;
nfsGlob.num_mounted_fs--;
UNLOCK(nfsGlob.llock);
-
- return 0;
}
/* OPTIONAL; may be NULL - BUT: CAUTION; mount() doesn't check
@@ -2073,10 +1840,10 @@ UNLOCK(nfsGlob.llock);
* //NOTE: (10/25/2002) patch submitted and probably applied
*/
static rtems_filesystem_node_types_t nfs_node_type(
- rtems_filesystem_location_info_t *pathloc /* in */
+ const rtems_filesystem_location_info_t *loc
)
{
-NfsNode node = pathloc->node_access;
+NfsNode node = loc->node_access;
if (updateAttr(node, 0 /* only if old */))
return -1;
@@ -2104,28 +1871,35 @@ NfsNode node = pathloc->node_access;
}
static int nfs_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 *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev
)
{
+int rv = 0;
struct timeval now;
diropres res;
-NfsNode node = pathloc->node_access;
+NfsNode node = parentloc->node_access;
mode_t type = S_IFMT & mode;
+char *dupname;
if (type != S_IFDIR && type != S_IFREG)
rtems_set_errno_and_return_minus_one(ENOTSUP);
+ dupname = nfs_dupname(name, namelen);
+ if (dupname == NULL)
+ return -1;
+
#if DEBUG & DEBUG_SYSCALLS
- fprintf(stderr,"nfs_mknod: creating %s\n", path);
+ fprintf(stderr,"nfs_mknod: creating %s\n", dupname);
#endif
rtems_clock_get_tod_timeval(&now);
- SERP_ARGS(node).createarg.name = (filename)path;
+ SERP_ARGS(node).createarg.name = dupname;
SERP_ARGS(node).createarg.attributes.mode = mode;
/* TODO: either use our uid or use the Nfs credentials */
SERP_ARGS(node).createarg.attributes.uid = 0;
@@ -2144,16 +1918,40 @@ mode_t type = S_IFMT & mode;
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_mknod");
#endif
- return -1;
+ rv = -1;
}
- return 0;
+ free(dupname);
+
+ return rv;
+}
+
+static int nfs_rmnod(
+ const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *loc
+)
+{
+ int rv = 0;
+ NfsNode node = loc->node_access;
+ int force_update = 0;
+
+ if (updateAttr(node, force_update) == 0) {
+ int proc = SERP_ATTR(node).type == NFDIR
+ ? NFSPROC_RMDIR
+ : NFSPROC_REMOVE;
+
+ rv = nfs_do_unlink(parentloc, loc, proc);
+ } else {
+ rv = -1;
+ }
+
+ return rv;
}
static int nfs_utime(
- rtems_filesystem_location_info_t *pathloc, /* IN */
- time_t actime, /* IN */
- time_t modtime /* IN */
+ const rtems_filesystem_location_info_t *pathloc, /* IN */
+ time_t actime, /* IN */
+ time_t modtime /* IN */
)
{
sattr arg;
@@ -2168,24 +1966,30 @@ sattr arg;
}
static int nfs_symlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- const char *link_name, /* IN */
- const char *node_name
+ const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ const char *target
)
{
+int rv = 0;
struct timeval now;
nfsstat status;
-NfsNode node = loc->node_access;
+NfsNode node = parentloc->node_access;
+char *dupname;
+ dupname = nfs_dupname(name, namelen);
+ if (dupname == NULL)
+ return -1;
#if DEBUG & DEBUG_SYSCALLS
- fprintf(stderr,"nfs_symlink: creating %s -> %s\n", link_name, node_name);
+ fprintf(stderr,"nfs_symlink: creating %s -> %s\n", dupname, target);
#endif
rtems_clock_get_tod_timeval(&now);
- SERP_ARGS(node).symlinkarg.name = (filename)link_name;
- SERP_ARGS(node).symlinkarg.to = (nfspath) node_name;
+ SERP_ARGS(node).symlinkarg.name = dupname;
+ SERP_ARGS(node).symlinkarg.to = (nfspath) target;
SERP_ARGS(node).symlinkarg.attributes.mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
/* TODO */
@@ -2205,243 +2009,103 @@ NfsNode node = loc->node_access;
#if DEBUG & DEBUG_SYSCALLS
perror("nfs_symlink");
#endif
- return -1;
+ rv = -1;
}
- return 0;
+ free(dupname);
+
+ return rv;
}
-static int nfs_do_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- strbuf *psbuf /* IN/OUT */
+static ssize_t nfs_readlink(
+ const rtems_filesystem_location_info_t *loc,
+ char *buf,
+ size_t len
)
{
-NfsNode node = loc->node_access;
-Nfs nfs = node->nfs;
-readlinkres_strbuf rr;
-int wasAlloced;
-int rval;
-
- rr.strbuf = *psbuf;
+ NfsNode node = loc->node_access;
+ Nfs nfs = node->nfs;
+ readlinkres_strbuf rr;
- wasAlloced = (0 == psbuf->buf);
+ rr.strbuf.buf = buf;
+ rr.strbuf.max = len - 1;
- if ( (rval = nfscall(nfs->server,
+ if ( nfscall(nfs->server,
NFSPROC_READLINK,
(xdrproc_t)xdr_nfs_fh, &SERP_FILE(node),
- (xdrproc_t)xdr_readlinkres_strbuf, &rr)) ) {
- if (wasAlloced)
- xdr_free( (xdrproc_t)xdr_strbuf, (caddr_t)&rr.strbuf );
- }
-
-
- if (NFS_OK != rr.status) {
- if (wasAlloced)
- xdr_free( (xdrproc_t)xdr_strbuf, (caddr_t)&rr.strbuf );
- rtems_set_errno_and_return_minus_one(rr.status);
+ (xdrproc_t)xdr_readlinkres_strbuf, &rr)
+ || (NFS_OK != (errno = rr.status)) ) {
+#if DEBUG & DEBUG_SYSCALLS
+ perror("nfs_readlink");
+#endif
+ return -1;
}
- *psbuf = rr.strbuf;
-
- return 0;
+ return (ssize_t) strlen(rr.strbuf.buf);
}
-static ssize_t nfs_readlink(
- rtems_filesystem_location_info_t *loc, /* IN */
- char *buf, /* OUT */
- size_t len
-)
+static void nfs_lock(rtems_filesystem_mount_table_entry_t *mt_entry)
{
-strbuf sbuf;
- sbuf.buf = buf;
- sbuf.max = len;
-
- return nfs_do_readlink(loc, &sbuf);
}
-/* The semantics of this routine are:
- *
- * The caller submits a valid pathloc, i.e. it has
- * an NfsNode attached to node_access.
- * On return, pathloc points to the target node which
- * may or may not be an NFS node.
- * Hence, the original NFS node is released in either
- * case:
- * - link evaluation fails; pathloc points to no valid node
- * - link evaluation success; pathloc points to a new valid
- * node. If it's an NFS node, a new NfsNode will be attached
- * to node_access...
- */
-
-#define LINKVAL_BUFLEN (MAXPATHLEN+1)
-#define RVAL_ERR_BUT_DONT_FREENODE (-1)
-#define RVAL_ERR_AND_DO_FREENODE ( 1)
-#define RVAL_OK ( 0)
+static void nfs_unlock(rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+}
-static int nfs_eval_link(
- rtems_filesystem_location_info_t *pathloc, /* IN/OUT */
- int flags /* IN */
+static bool nfs_are_nodes_equal(
+ const rtems_filesystem_location_info_t *a,
+ const rtems_filesystem_location_info_t *b
)
{
-rtems_filesystem_node_types_t type;
-char *buf = malloc(LINKVAL_BUFLEN);
-int rval = RVAL_ERR_AND_DO_FREENODE;
+ bool equal = false;
+ NfsNode na = a->node_access;
- if (!buf) {
- errno = ENOMEM;
- goto cleanup;
- }
-
- /* in this loop, we must not use NFS specific ops as we might
- * step out of our FS during the process...
- * This algorithm should actually be performed by the
- * generic's evaluate_path routine :-(
- *
- * Unfortunately, there is no way of finding the
- * directory node who contains 'pathloc', however :-(
- */
- do {
- /* assume the generics have verified 'pathloc' to be
- * a link...
- */
- if ( !pathloc->ops->readlink_h ) {
- errno = ENOTSUP;
- goto cleanup;
- }
-
- if ( pathloc->ops->readlink_h(pathloc, buf, LINKVAL_BUFLEN) ) {
- goto cleanup;
- }
-
-#if DEBUG & DEBUG_EVALPATH
- fprintf(stderr, "link value is '%s'\n", buf);
-#endif
-
- /* is the link value an absolute path ? */
- if ( DELIM != *buf ) {
- /* NO; a relative path */
-
- /* we must backup to the link's directory - we
- * know only how to do that for NFS, however.
- * In this special case, we can avoid recursion.
- * Otherwise (i.e. if the link is on another FS),
- * we must step into its eval_link_h().
- */
- if (locIsNfs(pathloc)) {
- NfsNode node = pathloc->node_access;
- int err;
-
- memcpy( &SERP_FILE(node),
- &node->args.dir,
- sizeof(node->args.dir) );
-
- if (updateAttr(node, 1 /* force */))
- goto cleanup;
-
- if (SERP_ATTR(node).type != NFDIR) {
- errno = ENOTDIR;
- goto cleanup;
- }
-
- pathloc->handlers = &nfs_dir_file_handlers;
-
- err = nfs_evalpath(buf, strlen(buf), flags, pathloc);
-
- /* according to its semantics,
- * nfs_evalpath cloned the node attached
- * to pathloc. Hence we have to
- * release the old one (referring to
- * the link; the new clone has been
- * updated and refers to the link _value_).
- */
- nfsNodeDestroy(node);
-
- if (err) {
- /* nfs_evalpath has set errno;
- * pathloc->node_access has no
- * valid node attached in this case
- */
- rval = RVAL_ERR_BUT_DONT_FREENODE;
- goto cleanup;
- }
-
- } else {
- if ( ! pathloc->ops->eval_link_h ) {
- errno = ENOTSUP;
- goto cleanup;
- }
- if (!pathloc->ops->eval_link_h(pathloc, flags)) {
- /* FS is responsible for freeing its pathloc->node_access
- * if necessary
- */
- rval = RVAL_ERR_BUT_DONT_FREENODE;
- goto cleanup;
- }
- }
- } else {
- /* link points to an absolute path '/xxx' */
-
- /* release this node; filesystem_evaluate_path() will
- * lookup a new one.
- */
- rtems_filesystem_freenode(pathloc);
-
- if (rtems_filesystem_evaluate_path(buf, strlen(buf), flags, pathloc, 1)) {
- /* If evalpath fails then there is no valid node
- * attached to pathloc; hence we must not attempt
- * to free the node
- */
- rval = RVAL_ERR_BUT_DONT_FREENODE;
- goto cleanup;
- }
- }
+ if (updateAttr(na, 0) == 0) {
+ NfsNode nb = b->node_access;
- if ( !pathloc->ops->node_type_h ) {
- errno = ENOTSUP;
- goto cleanup;
+ if (updateAttr(nb, 0) == 0) {
+ equal = SERP_ATTR(na).fileid == SERP_ATTR(nb).fileid
+ && SERP_ATTR(na).fsid == SERP_ATTR(nb).fsid;
}
-
- type = pathloc->ops->node_type_h(pathloc);
-
-
- /* I dont know what to do about hard links */
- } while ( RTEMS_FILESYSTEM_SYM_LINK == type );
-
- rval = RVAL_OK;
-
-cleanup:
-
- free(buf);
-
- if (RVAL_ERR_AND_DO_FREENODE == rval) {
- rtems_filesystem_freenode(pathloc);
- return -1;
}
- return rval;
+ return equal;
}
+static int nfs_fchmod(
+ const rtems_filesystem_location_info_t *loc,
+ mode_t mode
+)
+{
+sattr arg;
+
+ arg.mode = mode;
+ return nfs_sattr(loc->node_access, &arg, SATTR_MODE);
-struct _rtems_filesystem_operations_table nfs_fs_ops = {
- nfs_evalpath, /* MANDATORY */
- nfs_evalformake, /* MANDATORY; may set errno=ENOSYS and return -1 */
- nfs_link, /* OPTIONAL; may be defaulted */
- nfs_unlink, /* OPTIONAL; may be defaulted */
- nfs_node_type, /* OPTIONAL; may be defaulted; BUG in mount - no test!! */
- nfs_mknod, /* OPTIONAL; may be defaulted */
- nfs_chown, /* OPTIONAL; may be defaulted */
- nfs_freenode, /* OPTIONAL; may be defaulted; (release node_access) */
- rtems_filesystem_default_mount,
- rtems_nfs_initialize, /* OPTIONAL; may be defaulted -- not used anymore */
- rtems_filesystem_default_unmount,
- nfs_fsunmount_me, /* OPTIONAL; may be defaulted */
- nfs_utime, /* OPTIONAL; may be defaulted */
- nfs_eval_link, /* OPTIONAL; may be defaulted */
- nfs_symlink, /* OPTIONAL; may be defaulted */
- nfs_readlink, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_rename, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_statvfs /* OPTIONAL; may be defaulted */
+}
+const struct _rtems_filesystem_operations_table nfs_fs_ops = {
+ .lock_h = nfs_lock,
+ .unlock_h = nfs_unlock,
+ .eval_path_h = nfs_eval_path,
+ .link_h = nfs_link,
+ .are_nodes_equal_h = nfs_are_nodes_equal,
+ .node_type_h = nfs_node_type,
+ .mknod_h = nfs_mknod,
+ .rmnod_h = nfs_rmnod,
+ .fchmod_h = nfs_fchmod,
+ .chown_h = nfs_chown,
+ .clonenod_h = nfs_clonenode,
+ .freenod_h = nfs_freenode,
+ .mount_h = rtems_filesystem_default_mount,
+ .fsmount_me_h = rtems_nfs_initialize,
+ .unmount_h = rtems_filesystem_default_unmount,
+ .fsunmount_me_h = nfs_fsunmount_me,
+ .utime_h = nfs_utime,
+ .symlink_h = nfs_symlink,
+ .readlink_h = nfs_readlink,
+ .rename_h = rtems_filesystem_default_rename,
+ .statvfs_h = rtems_filesystem_default_statvfs
};
/*****************************************
@@ -2472,8 +2136,8 @@ struct _rtems_filesystem_operations_table nfs_fs_ops = {
static int nfs_file_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
return 0;
@@ -2487,8 +2151,8 @@ static int nfs_file_open(
static int nfs_dir_open(
rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode
+ int oflag,
+ mode_t mode
)
{
NfsNode node = iop->pathinfo.node_access;
@@ -2796,8 +2460,8 @@ struct stat
/* common for file/dir/link */
static int nfs_fstat(
- rtems_filesystem_location_info_t *loc,
- struct stat *buf
+ const rtems_filesystem_location_info_t *loc,
+ struct stat *buf
)
{
NfsNode node = loc->node_access;
@@ -2939,20 +2603,6 @@ u_int mode;
return 0;
}
-
-/* common for file/dir/link */
-static int nfs_fchmod(
- rtems_filesystem_location_info_t *loc,
- mode_t mode
-)
-{
-sattr arg;
-
- arg.mode = mode;
- return nfs_sattr(loc->node_access, &arg, SATTR_MODE);
-
-}
-
/* just set the size attribute to 'length'
* the server will take care of the rest :-)
*/
@@ -2973,71 +2623,52 @@ sattr arg;
SATTR_SIZE);
}
-/* files and symlinks are removed
- * by the common nfs_unlink() routine.
- * NFS has a different NFSPROC_RMDIR
- * call, though...
- */
-static int nfs_dir_rmnod(
- rtems_filesystem_location_info_t *parentpathloc, /* IN */
- rtems_filesystem_location_info_t *pathloc /* IN */
-)
-{
- return nfs_do_unlink(parentpathloc, pathloc, NFSPROC_RMDIR);
-}
-
/* the file handlers table */
-static
+static const
struct _rtems_filesystem_file_handlers_r nfs_file_file_handlers = {
- nfs_file_open, /* OPTIONAL; may be defaulted */
- nfs_file_close, /* OPTIONAL; may be defaulted */
- nfs_file_read, /* OPTIONAL; may be defaulted */
- nfs_file_write, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_ioctl,
- nfs_file_lseek, /* OPTIONAL; may be defaulted */
- nfs_fstat, /* OPTIONAL; may be defaulted */
- nfs_fchmod, /* OPTIONAL; may be defaulted */
- nfs_file_ftruncate, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- nfs_unlink, /* OPTIONAL; may be defaulted */
+ .open_h = nfs_file_open,
+ .close_h = nfs_file_close,
+ .read_h = nfs_file_read,
+ .write_h = nfs_file_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = nfs_file_lseek,
+ .fstat_h = nfs_fstat,
+ .ftruncate_h = nfs_file_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/* the directory handlers table */
-static
+static const
struct _rtems_filesystem_file_handlers_r nfs_dir_file_handlers = {
- nfs_dir_open, /* OPTIONAL; may be defaulted */
- nfs_dir_close, /* OPTIONAL; may be defaulted */
- nfs_dir_read, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_write,
- rtems_filesystem_default_ioctl,
- nfs_dir_lseek, /* OPTIONAL; may be defaulted */
- nfs_fstat, /* OPTIONAL; may be defaulted */
- nfs_fchmod, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_ftruncate,
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- nfs_dir_rmnod, /* OPTIONAL; may be defaulted */
+ .open_h = nfs_dir_open,
+ .close_h = nfs_dir_close,
+ .read_h = nfs_dir_read,
+ .write_h = rtems_filesystem_default_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = nfs_dir_lseek,
+ .fstat_h = nfs_fstat,
+ .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/* the link handlers table */
-static
+static const
struct _rtems_filesystem_file_handlers_r nfs_link_file_handlers = {
- rtems_filesystem_default_open,
- rtems_filesystem_default_close,
- rtems_filesystem_default_read,
- rtems_filesystem_default_write,
- rtems_filesystem_default_ioctl,
- rtems_filesystem_default_lseek,
- nfs_fstat, /* OPTIONAL; may be defaulted */
- nfs_fchmod, /* OPTIONAL; may be defaulted */
- rtems_filesystem_default_ftruncate,
- rtems_filesystem_default_fsync,
- rtems_filesystem_default_fdatasync,
- rtems_filesystem_default_fcntl,
- nfs_unlink, /* OPTIONAL; may be defaulted */
+ .open_h = rtems_filesystem_default_open,
+ .close_h = rtems_filesystem_default_close,
+ .read_h = rtems_filesystem_default_read,
+ .write_h = rtems_filesystem_default_write,
+ .ioctl_h = rtems_filesystem_default_ioctl,
+ .lseek_h = rtems_filesystem_default_lseek,
+ .fstat_h = nfs_fstat,
+ .ftruncate_h = rtems_filesystem_default_ftruncate,
+ .fsync_h = rtems_filesystem_default_fsync,
+ .fdatasync_h = rtems_filesystem_default_fdatasync,
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/* we need a dummy driver entry table to get a
@@ -3096,7 +2727,7 @@ Nfs nfs;
for (nfs = nfsGlob.mounted_fs; nfs; nfs=nfs->next) {
fprintf(f,"%s on ", nfs->mt_entry->dev);
- if (rtems_filesystem_resolve_location(mntpt, MAXPATHLEN, &nfs->mt_entry->mt_fs_root))
+ if (rtems_filesystem_resolve_location(mntpt, MAXPATHLEN, &nfs->mt_entry->mt_fs_root->location))
fprintf(f,"<UNABLE TO LOOKUP MOUNTPOINT>\n");
else
fprintf(f,"%s\n",mntpt);
@@ -3236,15 +2867,15 @@ rtems_filesystem_location_info_t old;
/* IMPORTANT: let the helper task have its own libio environment (i.e. cwd) */
if (RTEMS_SUCCESSFUL == (rpa->status = rtems_libio_set_private_env())) {
- old = rtems_filesystem_current;
+ old = rtems_filesystem_current->location;
- rtems_filesystem_current = *(rpa->loc);
+ rtems_filesystem_current->location = *(rpa->loc);
if ( !getcwd(rpa->buf, rpa->len) )
rpa->status = RTEMS_UNSATISFIED;
/* must restore the cwd because 'freenode' will be called on it */
- rtems_filesystem_current = old;
+ rtems_filesystem_current->location = old;
}
rtems_semaphore_release(rpa->sync);
rtems_task_delete(RTEMS_SELF);
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-dir.h b/cpukit/libfs/src/rfs/rtems-rfs-dir.h
index 6bbe6d6e18..3b8e7c4f06 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-dir.h
+++ b/cpukit/libfs/src/rfs/rtems-rfs-dir.h
@@ -29,47 +29,6 @@
#include <rtems/rfs/rtems-rfs-inode.h>
/**
- * The current directory string as held in directory lists.
- */
-#define RTEMS_RFS_CURRENT_DIR_STR "."
-
-/**
- * The size of the current directory.
- */
-#define RTEMS_RFS_CURRENT_DIR_SIZE (1)
-
-/**
- * Test if the path provided is a current directory.
- *
- * @param _p Pointer to the path string.
- * @return bool True if the path is a current directory.
- */
-#define rtems_rfs_current_dir(_p) \
- ((_p[0] == RTEMS_RFS_CURRENT_DIR_STR[0]) && \
- ((_p[1] == '\0') || rtems_filesystem_is_separator (_p[1])))
-
-/**
- * The parent directory string as held in directory lists.
- */
-#define RTEMS_RFS_PARENT_DIR_STR ".."
-
-/**
- * The size of the parent directory.
- */
-#define RTEMS_RFS_PARENT_DIR_SIZE (2)
-
-/**
- * Test if the path provided is a parent directory.
- *
- * @param _p Pointer to the path string.
- * @return bool True if the path is a parent directory.
- */
-#define rtems_rfs_parent_dir(_p) \
- ((_p[0] == RTEMS_RFS_PARENT_DIR_STR[0]) && \
- (_p[1] == RTEMS_RFS_PARENT_DIR_STR[1]) && \
- ((_p[2] == '\0') || rtems_filesystem_is_separator (_p[2])))
-
-/**
* Define the offsets of the fields of a directory entry.
*/
#define RTEMS_RFS_DIR_ENTRY_INO (0) /**< The ino offset in a directory
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-file.c b/cpukit/libfs/src/rfs/rtems-rfs-file.c
index d8a7335ea4..abd123da1b 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-file.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-file.c
@@ -31,7 +31,7 @@
int
rtems_rfs_file_open (rtems_rfs_file_system* fs,
rtems_rfs_ino ino,
- uint32_t flags,
+ int oflag,
rtems_rfs_file_handle** file)
{
rtems_rfs_file_handle* handle;
@@ -132,7 +132,7 @@ rtems_rfs_file_open (rtems_rfs_file_system* fs,
printf ("rtems-rfs: file-open: ino=%" PRId32 " share created\n", ino);
}
- handle->flags = flags;
+ handle->flags = oflag;
handle->shared = shared;
*file = handle;
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-file.h b/cpukit/libfs/src/rfs/rtems-rfs-file.h
index 284e6273d8..ecadb359bc 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-file.h
+++ b/cpukit/libfs/src/rfs/rtems-rfs-file.h
@@ -180,7 +180,7 @@ typedef struct _rtems_rfs_file_handle
/**
* Special flags that can be controlled by the fctrl call.
*/
- uint32_t flags;
+ int flags;
/**
* The buffer of data at the file's position.
@@ -298,7 +298,7 @@ typedef struct _rtems_rfs_file_handle
*/
int rtems_rfs_file_open (rtems_rfs_file_system* fs,
rtems_rfs_ino ino,
- uint32_t flags,
+ int oflag,
rtems_rfs_file_handle** handle);
/**
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-link.c b/cpukit/libfs/src/rfs/rtems-rfs-link.c
index 392a7520d6..2dcdf8a67a 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-link.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-link.c
@@ -385,8 +385,7 @@ rtems_rfs_symlink_read (rtems_rfs_file_system* fs,
if (size < *length)
{
- rtems_rfs_inode_close (fs, &inode);
- return EINVAL;
+ *length = size;
}
if (rtems_rfs_inode_get_block_count (&inode) == 0)
@@ -450,8 +449,6 @@ rtems_rfs_symlink_read (rtems_rfs_file_system* fs,
}
}
- path[*length] = '\0';
-
rc = rtems_rfs_inode_close (fs, &inode);
return rc;
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
index d5a5a3fcf7..9ca829e168 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.c
@@ -38,8 +38,8 @@
static int
rtems_rfs_rtems_device_open ( rtems_libio_t *iop,
const char *pathname,
- uint32_t flag,
- uint32_t mode)
+ int oflag,
+ mode_t mode)
{
rtems_libio_open_close_args_t args;
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
@@ -257,10 +257,8 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_device_handlers = {
.ioctl_h = rtems_rfs_rtems_device_ioctl,
.lseek_h = rtems_rfs_rtems_device_lseek,
.fstat_h = rtems_rfs_rtems_fstat,
- .fchmod_h = rtems_rfs_rtems_fchmod,
.ftruncate_h = rtems_rfs_rtems_device_ftruncate,
.fsync_h = rtems_filesystem_default_fsync,
.fdatasync_h = rtems_filesystem_default_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .rmnod_h = rtems_rfs_rtems_rmnod
+ .fcntl_h = rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
index 8f9b363336..77eeeba9fa 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c
@@ -36,18 +36,12 @@
* This rountine will verify that the node being opened as a directory is in
* fact a directory node. If it is then the offset into the directory will be
* set to 0 to position to the first directory entry.
- *
- * @param iop
- * @param pathname
- * @param flag
- * @param mode
- * @@return int
*/
static int
rtems_rfs_rtems_dir_open (rtems_libio_t* iop,
const char* pathname,
- uint32_t flag,
- uint32_t mode)
+ int oflag,
+ mode_t mode)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
rtems_rfs_ino ino = rtems_rfs_rtems_get_iop_ino (iop);
@@ -193,36 +187,6 @@ rtems_rfs_rtems_dir_lseek (rtems_libio_t* iop,
return 0;
}
-static int
-rtems_rfs_rtems_dir_rmnod (rtems_filesystem_location_info_t* parent_pathloc,
- rtems_filesystem_location_info_t* pathloc)
-{
- rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
- rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc);
- rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
- uint32_t doff = rtems_rfs_rtems_get_pathloc_doff (pathloc);
- int rc;
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_DIR_RMNOD))
- printf ("rtems-rfs: dir-rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n",
- parent, doff, ino);
-
- if (ino == RTEMS_RFS_ROOT_INO)
- return rtems_rfs_rtems_error ("dir_rmnod: root inode", EBUSY);
-
- rtems_rfs_rtems_lock (fs);
-
- rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty);
- if (rc)
- {
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("dir_rmnod: unlinking", rc);
- }
-
- rtems_rfs_rtems_unlock (fs);
- return 0;
-}
-
/*
* Set of operations handlers for operations on directories.
*/
@@ -235,10 +199,8 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = {
.ioctl_h = rtems_filesystem_default_ioctl,
.lseek_h = rtems_rfs_rtems_dir_lseek,
.fstat_h = rtems_rfs_rtems_fstat,
- .fchmod_h = rtems_rfs_rtems_fchmod,
- .ftruncate_h = rtems_filesystem_default_ftruncate,
+ .ftruncate_h = rtems_filesystem_default_ftruncate_directory,
.fsync_h = rtems_filesystem_default_fsync,
.fdatasync_h = rtems_rfs_rtems_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .rmnod_h = rtems_rfs_rtems_dir_rmnod
+ .fcntl_h = rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
index 346ae54ff5..0a15652dfc 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c
@@ -38,30 +38,24 @@
/**
* This routine processes the open() system call. Note that there is nothing
* special to be done at open() time.
- *
- * @param iop
- * @param pathname
- * @param flag
- * @param mode
- * @return int
*/
static int
rtems_rfs_rtems_file_open (rtems_libio_t* iop,
const char* pathname,
- uint32_t flag,
- uint32_t mode)
+ int oflag,
+ mode_t mode)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
rtems_rfs_ino ino;
rtems_rfs_file_handle* file;
- uint32_t flags;
+ int flags;
int rc;
flags = 0;
if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN))
- printf("rtems-rfs: file-open: path:%s ino:%" PRId32 " flags:%04" PRIx32 " mode:%04" PRIx32 "\n",
+ printf("rtems-rfs: file-open: path:%s ino:%" PRId32 " flags:%04i mode:%04" PRIu32 "\n",
pathname, ino, flags, mode);
rtems_rfs_rtems_lock (fs);
@@ -352,10 +346,8 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
.ioctl_h = rtems_rfs_rtems_file_ioctl,
.lseek_h = rtems_rfs_rtems_file_lseek,
.fstat_h = rtems_rfs_rtems_fstat,
- .fchmod_h = rtems_rfs_rtems_fchmod,
.ftruncate_h = rtems_rfs_rtems_file_ftruncate,
.fsync_h = rtems_rfs_rtems_fdatasync,
.fdatasync_h = rtems_rfs_rtems_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .rmnod_h = rtems_rfs_rtems_rmnod
+ .fcntl_h = rtems_filesystem_default_fcntl
};
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c
index 44c8885bbe..e77ffddaf8 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems-utils.c
@@ -25,60 +25,6 @@
#include "rtems-rfs-rtems.h"
-bool
-rtems_rfs_rtems_eval_perms (rtems_rfs_inode_handle* inode, int flags)
-{
- uid_t st_uid;
- gid_t st_gid;
- uint16_t uid;
- uint16_t gid;
- uint16_t mode;
- int flags_to_test;
-
- uid = rtems_rfs_inode_get_uid (inode);
- gid = rtems_rfs_inode_get_gid (inode);
- mode = rtems_rfs_inode_get_mode (inode);
-
-#if defined (RTEMS_POSIX_API)
- st_uid = geteuid ();
- st_gid = getegid ();
-#else
- st_uid = uid;
- st_gid = gid;
-#endif
-
- /*
- * Check if I am owner or a group member or someone else.
- */
- flags_to_test = flags;
-
- if ((st_uid == 0) || (st_uid == uid))
- flags_to_test |= flags << 6;
- if ((st_uid == 0) || (st_gid == gid))
- flags_to_test |= flags << 3;
- else
- /* must be other - already set above */;
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PERMS))
- printf ("rtems-rfs: eval-perms: uid=%d gid=%d iuid=%d igid=%d " \
- "flags=%o flags_to_test=%o mode=%o (%o)\n",
- st_uid, st_gid, uid, gid,
- flags, flags_to_test, mode & 0777,
- flags_to_test & (mode & 0777));
-
- /*
- * If all of the flags are set we have permission
- * to do this.
- */
- if ((flags_to_test & (mode & 0777)) != 0)
- return true;
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PERMS))
- printf("rtems-rfs: eval-perms: perms failed\n");
-
- return false;
-}
-
/*
* The following sets the handlers based on the type of inode.
*/
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
index 7c92a09a3c..e6006a8970 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems.c
@@ -1,6 +1,9 @@
/*
* COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
*
+ * 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.
@@ -35,522 +38,245 @@
#include <rtems/rfs/rtems-rfs-link.h>
#include "rtems-rfs-rtems.h"
-/**
- * The libio permissions for read/execute.
- */
-#define RTEMS_LIBIO_PERMS_RX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_READ)
-/**
- * The libio permissions for write/execute.
- */
-#define RTEMS_LIBIO_PERMS_WX (RTEMS_LIBIO_PERMS_SEARCH | RTEMS_LIBIO_PERMS_WRITE)
-
-/**
- * Evaluate the path to a node that wishes to be accessed. The pathloc is
- * returned with the ino to the node to be accessed.
- *
- * The routine starts from the root stripping away any leading path separators
- * breaking the path up into the node names and checking an inode exists for
- * that node name. Permissions are checked to insure access to the node is
- * allowed. A path to a node must be accessable all the way even if the end
- * result is directly accessable. As a user on Linux try "ls /root/../tmp" and
- * you will see if fails.
- *
- * The whole process is complicated by crossmount paths where we head down into
- * this file system only to return to the top and out to a another mounted file
- * system. For example we are mounted on '/e' and the user enters "ls
- * /e/a/b/../../dev". We need to head down then back up.
- *
- * @param path
- * @param pathlen
- * @param flags
- * @param pathloc
- */
-static int
-rtems_rfs_rtems_eval_path (const char* path,
- size_t pathlen,
- int flags,
- rtems_filesystem_location_info_t* pathloc)
+static bool
+rtems_rfs_rtems_eval_perms (rtems_filesystem_eval_path_context_t *ctx,
+ int eval_flags,
+ rtems_rfs_inode_handle* inode)
{
- rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
- rtems_rfs_inode_handle inode;
- rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
- uint32_t doff = 0;
- const char* node;
- size_t node_len;
- int stripped;
- int rc;
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PATH))
- printf ("rtems-rfs-rtems: eval-path: in: path:%s pathlen:%zi ino:%" PRId32 "\n",
- path, pathlen, ino);
+ return rtems_filesystem_eval_path_check_access(
+ ctx,
+ eval_flags,
+ rtems_rfs_inode_get_mode (inode),
+ rtems_rfs_inode_get_uid (inode),
+ rtems_rfs_inode_get_gid (inode)
+ );
+}
+static rtems_filesystem_node_types_t
+rtems_rfs_rtems_node_type_by_inode (rtems_rfs_inode_handle* inode)
+{
/*
- * Eat any separators at the start of the path.
+ * Do not return RTEMS_FILESYSTEM_HARD_LINK because this would result in an
+ * eval link which does not make sense in the case of the RFS file
+ * system. All directory entries are links to an inode. A link such as a HARD
+ * link is actually the normal path to a regular file, directory, device
+ * etc's inode. Links to inodes can be considered "the real" one, yet they
+ * are all links.
*/
- stripped = rtems_filesystem_prefix_separators (path, pathlen);
- path += stripped;
- pathlen -= stripped;
-
- rtems_rfs_rtems_lock (fs);
-
- while (true)
- {
- /*
- * Open and load the inode.
- */
- rc = rtems_rfs_inode_open (fs, ino, &inode, true);
- if (rc > 0)
- {
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_path: opening inode", rc);
- }
-
- /*
- * Is this the end of the pathname we were given ?
- */
- if ((*path == '\0') || (pathlen == 0))
- break;
-
- /*
- * If a directory the execute bit must be set for us to enter.
- */
- if (RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)) &&
- !rtems_rfs_rtems_eval_perms (&inode, RTEMS_LIBIO_PERMS_SEARCH))
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_path: eval perms", EACCES);
- }
-
- /*
- * Extract the node name we will look for this time around.
- */
- node = path;
- node_len = 0;
- while (!rtems_filesystem_is_separator (*path) &&
- (*path != '\0') && pathlen &&
- ((node_len + 1) < rtems_rfs_fs_max_name (fs)))
- {
- path++;
- pathlen--;
- node_len++;
- }
-
- /*
- * Eat any separators at the start of the path.
- */
- stripped = rtems_filesystem_prefix_separators (path, pathlen);
- path += stripped;
- pathlen -= stripped;
- node_len += stripped;
-
- /*
- * If the node is the current directory and there is more path to come move
- * on to it otherwise we are at the inode we want.
- */
- if (rtems_rfs_current_dir (node))
- {
- if (*path)
- {
- rtems_rfs_inode_close (fs, &inode);
- continue;
- }
- break;
- }
-
- /*
- * If the node is a parent we must move up one directory. If the location
- * is on another file system we have a crossmount so we call that file
- * system to handle the remainder of the path.
- */
- if (rtems_rfs_parent_dir (node))
- {
- /*
- * If we are at the root inode of the file system we have a crossmount
- * path.
- */
- if (ino == RTEMS_RFS_ROOT_INO)
- {
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PATH))
- printf("rtems-rfs-rtems: eval-path: crossmount: path:%s (%zd)\n",
- path - node_len, pathlen + node_len);
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- *pathloc = pathloc->mt_entry->mt_point_node;
- return (*pathloc->ops->evalpath_h)(path - node_len, pathlen + node_len,
- flags, pathloc);
- }
-
- /*
- * We need to find the parent of this node.
- */
- rc = rtems_rfs_dir_lookup_ino (fs, &inode,
- RTEMS_RFS_PARENT_DIR_STR,
- RTEMS_RFS_PARENT_DIR_SIZE, &ino, &doff);
- if (rc > 0)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_path: read parent inode", rc);
- }
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PATH))
- printf("rtems-rfs-rtems: eval-path: parent: ino:%" PRId32 "\n", ino);
- }
- else
- {
- /*
- * Look up the node name in this directory. If found drop through, close
- * the current inode and let the loop open the inode so the mode can be
- * read and handlers set.
- */
- rc = rtems_rfs_dir_lookup_ino (fs, &inode,
- node, node_len - stripped, &ino, &doff);
- if (rc > 0)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return ((errno = rc) == 0) ? 0 : -1;
- }
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PATH))
- printf("rtems-rfs-rtems: eval-path: down: path:%s ino:%" PRId32 "\n", node, ino);
- }
+ uint16_t mode = rtems_rfs_inode_get_mode (inode);
+ if (RTEMS_RFS_S_ISDIR (mode))
+ return RTEMS_FILESYSTEM_DIRECTORY;
+ else if (RTEMS_RFS_S_ISLNK (mode))
+ return RTEMS_FILESYSTEM_SYM_LINK;
+ else if (RTEMS_RFS_S_ISBLK (mode) || RTEMS_RFS_S_ISCHR (mode))
+ return RTEMS_FILESYSTEM_DEVICE;
+ else
+ return RTEMS_FILESYSTEM_MEMORY_FILE;
+}
- rc = rtems_rfs_inode_close (fs, &inode);
- if (rc > 0)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_path: closing node", rc);
- }
- }
+static void
+rtems_rfs_rtems_lock_by_mt_entry (rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+ rtems_rfs_file_system* fs = mt_entry->fs_info;
- rtems_rfs_rtems_set_pathloc_ino (pathloc, ino);
- rtems_rfs_rtems_set_pathloc_doff (pathloc, doff);
+ rtems_rfs_rtems_lock (fs);
+}
- rc = rtems_rfs_rtems_set_handlers (pathloc, &inode) ? 0 : EIO;
+static void
+rtems_rfs_rtems_unlock_by_mt_entry (rtems_filesystem_mount_table_entry_t *mt_entry)
+{
+ rtems_rfs_file_system* fs = mt_entry->fs_info;
- rtems_rfs_inode_close (fs, &inode);
rtems_rfs_rtems_unlock (fs);
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_PATH))
- printf("rtems-rfs-rtems: eval-path: ino:%" PRId32 "\n", ino);
-
- return rc;
}
-/**
- * The following routine evaluates a path for a new node to be created. The
- * pathloc is returned with a pointer to the parent of the new node. The name
- * is returned with a pointer to the first character in the new node name. The
- * parent node is verified to be a directory.
- *
- * @param path
- * @param pathloc
- * @param name
- * @return int
- */
-static int
-rtems_rfs_rtems_eval_for_make (const char* path,
- rtems_filesystem_location_info_t* pathloc,
- const char** name)
+static bool
+rtems_rfs_rtems_is_directory(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg
+)
{
- rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
- rtems_rfs_inode_handle inode;
- rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
- rtems_rfs_ino node_ino;
- uint32_t doff = 0;
- const char* node;
- int node_len;
- int stripped;
- int rc;
+ rtems_rfs_inode_handle* inode = arg;
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_FOR_MAKE))
- printf ("rtems-rfs-rtems: eval-for-make: path:%s ino:%" PRId32 "\n", path, ino);
-
- *name = path + strlen (path);
-
- while (*name != path)
- {
- (*name)--;
- if (rtems_filesystem_is_separator (**name))
- {
- (*name)++;
- break;
- }
- }
-
- /*
- * Eat any separators at start of the path.
- */
- stripped = rtems_filesystem_prefix_separators (path, strlen(path));
- path += stripped;
-
- rtems_rfs_rtems_lock (fs);
-
- while (true)
- {
- /*
- * Open and load the inode.
- */
- rc = rtems_rfs_inode_open (fs, ino, &inode, true);
- if (rc > 0)
- {
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: read ino", rc);
- }
+ return rtems_rfs_rtems_node_type_by_inode (inode)
+ == RTEMS_FILESYSTEM_DIRECTORY;
+}
- /*
- * If a directory the execute bit must be set for us to enter.
- */
- if (RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)) &&
- !rtems_rfs_rtems_eval_perms (&inode, RTEMS_LIBIO_PERMS_SEARCH))
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: eval perms", EACCES);
- }
+static void rtems_rfs_rtems_follow_link(
+ rtems_filesystem_eval_path_context_t* ctx,
+ rtems_rfs_file_system* fs,
+ rtems_rfs_ino ino
+)
+{
+ size_t len = MAXPATHLEN;
+ char *link = malloc(len + 1);
- /*
- * Is this the end of the pathname we were given ?
- */
- if (path == *name)
- break;
-
- /*
- * Extract the node name we will look for this time around.
- */
- node = path;
- node_len = 0;
- while (!rtems_filesystem_is_separator(*path) &&
- (*path != '\0') &&
- (node_len < (rtems_rfs_fs_max_name (fs) - 1)))
- {
- node_len++;
- path++;
- }
+ if (link != NULL) {
+ int rc = rtems_rfs_symlink_read (fs, ino, link, len, &len);
- /*
- * Eat any separators at start of the new path.
- */
- stripped = rtems_filesystem_prefix_separators (path, strlen (path));
- path += stripped;
- node_len += stripped;
-
- /*
- * If the node is the current directory and there is more path to come move
- * on to it otherwise we are at the inode we want.
- */
- if (rtems_rfs_current_dir (node))
- {
- if (*path)
- {
- rtems_rfs_inode_close (fs, &inode);
- continue;
- }
- break;
+ if (rc == 0) {
+ rtems_filesystem_eval_path_recursive (ctx, link, len);
+ } else {
+ rtems_filesystem_eval_path_error (ctx, 0);
}
- /*
- * If the node is a parent we must move up one directory. If the location
- * is on another file system we have a crossmount so we call that file
- * system to handle the remainder of the path.
- */
- if (rtems_rfs_parent_dir (path))
- {
- /*
- * If we are at the root inode of the file system we have a crossmount
- * path.
- */
- if (ino == RTEMS_RFS_ROOT_INO)
- {
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_FOR_MAKE))
- printf("rtems-rfs-rtems: eval-for-make: crossmount: path:%s\n",
- path - node_len);
-
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- *pathloc = pathloc->mt_entry->mt_point_node;
- return (*pathloc->ops->evalformake_h)(path + 2, pathloc, name);
- }
+ free(link);
+ } else {
+ rtems_filesystem_eval_path_error (ctx, ENOMEM);
+ }
+}
- /*
- * If not a directory give and up return. We cannot change dir from a
- * regular file or device node.
- */
- if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)))
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: not dir", ENOTSUP);
+static rtems_filesystem_eval_path_generic_status
+rtems_rfs_rtems_eval_token(
+ rtems_filesystem_eval_path_context_t *ctx,
+ void *arg,
+ const char *token,
+ size_t tokenlen
+)
+{
+ rtems_filesystem_eval_path_generic_status status =
+ RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
+ rtems_rfs_inode_handle* inode = arg;
+ bool access_ok = rtems_rfs_rtems_eval_perms (ctx, RTEMS_LIBIO_PERMS_SEARCH, inode);
+
+ if (access_ok) {
+ if (rtems_filesystem_is_current_directory (token, tokenlen)) {
+ rtems_filesystem_eval_path_clear_token (ctx);
+ } else {
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc( ctx );
+ rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc);
+ rtems_rfs_ino entry_ino;
+ uint32_t entry_doff;
+ int rc = rtems_rfs_dir_lookup_ino (
+ fs,
+ inode,
+ token,
+ tokenlen,
+ &entry_ino,
+ &entry_doff
+ );
+
+ if (rc == 0) {
+ rc = rtems_rfs_inode_close (fs, inode);
+ if (rc == 0) {
+ rc = rtems_rfs_inode_open (fs, entry_ino, inode, true);
+ }
+
+ if (rc != 0) {
+ /*
+ * This prevents the rtems_rfs_inode_close() from doing something in
+ * rtems_rfs_rtems_eval_path().
+ */
+ memset (inode, 0, sizeof(*inode));
+ }
+ } else {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY;
+ rc = -1;
}
- /*
- * We need to find the parent of this node.
- */
- rc = rtems_rfs_dir_lookup_ino (fs, &inode,
- RTEMS_RFS_PARENT_DIR_STR,
- RTEMS_RFS_PARENT_DIR_SIZE, &ino, &doff);
- if (rc > 0)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: read parent inode", rc);
- }
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_FOR_MAKE))
- printf ("rtems-rfs-rtems: eval-for-make: parent: ino:%" PRId32 "\n", ino);
- }
- else
- {
- /*
- * Read the inode so we know it exists and what type it is.
- */
- rc = rtems_rfs_dir_lookup_ino (fs, &inode,
- node, node_len - stripped, &ino, &doff);
- if (rc > 0)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: reading inode", rc);
+ if (rc == 0) {
+ bool is_sym_link = rtems_rfs_rtems_node_type_by_inode (inode)
+ == RTEMS_FILESYSTEM_SYM_LINK;
+ int eval_flags = rtems_filesystem_eval_path_get_flags (ctx);
+ bool follow_sym_link = (eval_flags & RTEMS_LIBIO_FOLLOW_SYM_LINK) != 0;
+ bool terminal = !rtems_filesystem_eval_path_has_path (ctx);
+
+ rtems_filesystem_eval_path_clear_token (ctx);
+
+ if (is_sym_link && (follow_sym_link || !terminal)) {
+ rtems_rfs_rtems_follow_link (ctx, fs, entry_ino);
+ } else {
+ rc = rtems_rfs_rtems_set_handlers (currentloc, inode) ? 0 : EIO;
+ if (rc == 0) {
+ rtems_rfs_rtems_set_pathloc_ino (currentloc, entry_ino);
+ rtems_rfs_rtems_set_pathloc_doff (currentloc, entry_doff);
+
+ if (!terminal) {
+ status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
+ }
+ } else {
+ rtems_filesystem_eval_path_error (
+ ctx,
+ rtems_rfs_rtems_error ("eval_path: set handlers", rc)
+ );
+ }
+ }
}
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_FOR_MAKE))
- printf("rtems-rfs-rtems: eval-for-make: down: path:%s ino:%" PRId32 "\n",
- node, ino);
- }
-
- rc = rtems_rfs_inode_close (fs, &inode);
- if (rc > 0)
- {
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: closing node", rc);
}
}
- if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)))
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: not dir", ENOTDIR);
- }
+ return status;
+}
- if (!rtems_rfs_rtems_eval_perms (&inode, RTEMS_LIBIO_PERMS_WX))
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: cannot write", EACCES);
- }
+static const rtems_filesystem_eval_path_generic_config
+rtems_rfs_rtems_eval_config = {
+ .is_directory = rtems_rfs_rtems_is_directory,
+ .eval_token = rtems_rfs_rtems_eval_token
+};
- /*
- * Make sure the name does not already exists in the directory.
- */
- rc = rtems_rfs_dir_lookup_ino (fs, &inode, *name, strlen (*name),
- &node_ino, &doff);
- if (rc == 0)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: found name", EEXIST);
- }
+static void
+rtems_rfs_rtems_eval_path (rtems_filesystem_eval_path_context_t *ctx)
+{
+ rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_get_currentloc (ctx);
+ rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (currentloc);
+ rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (currentloc);
+ rtems_rfs_inode_handle inode;
+ int rc;
- if (rc != ENOENT)
- {
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("eval_for_make: look up", rc);
+ rc = rtems_rfs_inode_open (fs, ino, &inode, true);
+ if (rc == 0) {
+ rtems_filesystem_eval_path_generic (
+ ctx,
+ &inode,
+ &rtems_rfs_rtems_eval_config
+ );
+ rc = rtems_rfs_inode_close (fs, &inode);
+ if (rc != 0) {
+ rtems_filesystem_eval_path_error (
+ ctx,
+ rtems_rfs_rtems_error ("eval_path: closing inode", rc)
+ );
+ }
+ } else {
+ rtems_filesystem_eval_path_error (
+ ctx,
+ rtems_rfs_rtems_error ("eval_path: opening inode", rc)
+ );
}
-
- /*
- * Set the parent ino in the path location.
- */
-
- rtems_rfs_rtems_set_pathloc_ino (pathloc, ino);
- rtems_rfs_rtems_set_pathloc_doff (pathloc, doff);
-
- rc = rtems_rfs_rtems_set_handlers (pathloc, &inode) ? 0 : EIO;
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_EVAL_FOR_MAKE))
- printf("rtems-rfs-rtems: eval-for-make: parent ino:%" PRId32 " name:%s\n",
- ino, *name);
-
- rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
-
- return rc;
}
/**
* The following rouine creates a new link node under parent with the name
- * given in name. The link node is set to point to the node at to_loc.
- *
- * @param to_loc
- * @param parent_loc
- * @param name
- * @return int
+ * given in name. The link node is set to point to the node at targetloc.
*/
static int
-rtems_rfs_rtems_link (rtems_filesystem_location_info_t* to_loc,
- rtems_filesystem_location_info_t* parent_loc,
- const char* name)
+rtems_rfs_rtems_link (const rtems_filesystem_location_info_t *parentloc,
+ const rtems_filesystem_location_info_t *targetloc,
+ const char *name,
+ size_t namelen)
{
- rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (to_loc);
- rtems_rfs_ino target = rtems_rfs_rtems_get_pathloc_ino (to_loc);
- rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc);
+ rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (targetloc);
+ rtems_rfs_ino target = rtems_rfs_rtems_get_pathloc_ino (targetloc);
+ rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc);
int rc;
if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_LINK))
printf ("rtems-rfs-rtems: link: in: parent:%" PRId32 " target:%" PRId32 "\n",
parent, target);
- rtems_rfs_rtems_lock (fs);
-
- rc = rtems_rfs_link (fs, name, strlen (name), parent, target, false);
+ rc = rtems_rfs_link (fs, name, namelen, parent, target, false);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("link: linking", rc);
}
- rtems_rfs_rtems_unlock (fs);
return 0;
}
/**
- * Routine to remove a link node from the file system.
- *
- * @param parent_loc
- * @param loc
- * @return int
- */
-
-static int
-rtems_rfs_rtems_unlink (rtems_filesystem_location_info_t* parent_loc,
- rtems_filesystem_location_info_t* loc)
-{
- rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parent_loc);
- rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc);
- rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (loc);
- uint32_t doff = rtems_rfs_rtems_get_pathloc_doff (loc);
- int rc;
-
- rtems_rfs_rtems_lock (fs);
-
- if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_UNLINK))
- printf("rtems-rfs-rtems: unlink: parent:%" PRId32 " doff:%" PRIu32 " ino:%" PRId32 "\n",
- parent, doff, ino);
-
- rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_denied);
- if (rc)
- {
- rtems_rfs_rtems_unlock (fs);
- return rtems_rfs_rtems_error ("unlink: unlink inode", rc);
- }
-
- rtems_rfs_rtems_unlock (fs);
-
- return 0;
-}
-
-/**
* The following verifies that and returns the type of node that the loc refers
* to.
*
@@ -559,51 +285,28 @@ rtems_rfs_rtems_unlink (rtems_filesystem_location_info_t* parent_loc,
*/
static rtems_filesystem_node_types_t
-rtems_rfs_rtems_node_type (rtems_filesystem_location_info_t* pathloc)
+rtems_rfs_rtems_node_type (const rtems_filesystem_location_info_t* pathloc)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
rtems_filesystem_node_types_t type;
rtems_rfs_inode_handle inode;
- uint16_t mode;
int rc;
- rtems_rfs_rtems_lock (fs);
-
rc = rtems_rfs_inode_open (fs, ino, &inode, true);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("node_type: opening inode", rc);
}
- /*
- * Do not return RTEMS_FILESYSTEM_HARD_LINK because this would result in an
- * eval link which does not make sense in the case of the RFS file
- * system. All directory entries are links to an inode. A link such as a HARD
- * link is actually the normal path to a regular file, directory, device
- * etc's inode. Links to inodes can be considered "the real" one, yet they
- * are all links.
- */
- mode = rtems_rfs_inode_get_mode (&inode);
- if (RTEMS_RFS_S_ISDIR (mode))
- type = RTEMS_FILESYSTEM_DIRECTORY;
- else if (RTEMS_RFS_S_ISLNK (mode))
- type = RTEMS_FILESYSTEM_SYM_LINK;
- else if (RTEMS_RFS_S_ISBLK (mode) || RTEMS_RFS_S_ISCHR (mode))
- type = RTEMS_FILESYSTEM_DEVICE;
- else
- type = RTEMS_FILESYSTEM_MEMORY_FILE;
+ type = rtems_rfs_rtems_node_type_by_inode (&inode);
rc = rtems_rfs_inode_close (fs, &inode);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("node_type: closing inode", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
return type;
}
@@ -618,9 +321,9 @@ rtems_rfs_rtems_node_type (rtems_filesystem_location_info_t* pathloc)
*/
static int
-rtems_rfs_rtems_chown (rtems_filesystem_location_info_t *pathloc,
- uid_t owner,
- gid_t group)
+rtems_rfs_rtems_chown (const rtems_filesystem_location_info_t *pathloc,
+ uid_t owner,
+ gid_t group)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
@@ -634,12 +337,9 @@ rtems_rfs_rtems_chown (rtems_filesystem_location_info_t *pathloc,
printf ("rtems-rfs-rtems: chown: in: ino:%" PRId32 " uid:%d gid:%d\n",
ino, owner, group);
- rtems_rfs_rtems_lock (fs);
-
rc = rtems_rfs_inode_open (fs, ino, &inode, true);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("chown: opening inode", rc);
}
@@ -653,7 +353,6 @@ rtems_rfs_rtems_chown (rtems_filesystem_location_info_t *pathloc,
if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
{
rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("chown: not able", EPERM);
}
#endif
@@ -663,12 +362,9 @@ rtems_rfs_rtems_chown (rtems_filesystem_location_info_t *pathloc,
rc = rtems_rfs_inode_close (fs, &inode);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("chown: closing inode", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
return 0;
}
@@ -683,21 +379,18 @@ rtems_rfs_rtems_chown (rtems_filesystem_location_info_t *pathloc,
*/
static int
-rtems_rfs_rtems_utime(rtems_filesystem_location_info_t* pathloc,
- time_t atime,
- time_t mtime)
+rtems_rfs_rtems_utime(const rtems_filesystem_location_info_t* pathloc,
+ time_t atime,
+ time_t mtime)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
rtems_rfs_inode_handle inode;
int rc;
- rtems_rfs_rtems_lock (fs);
-
rc = rtems_rfs_inode_open (fs, ino, &inode, true);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("utime: read inode", rc);
}
@@ -707,73 +400,46 @@ rtems_rfs_rtems_utime(rtems_filesystem_location_info_t* pathloc,
rc = rtems_rfs_inode_close (fs, &inode);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("utime: closing inode", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
return 0;
}
/**
- * The following rouine creates a new symbolic link node under parent with the
- * name given in name. The node is set to point to the node at to_loc.
- *
- * @param parent_loc
- * @param link_name
- * @param node_name
- * return int
+ * The following routine creates a new symbolic link node under parent with the
+ * name given in node_name.
*/
static int
-rtems_rfs_rtems_symlink (rtems_filesystem_location_info_t* parent_loc,
- const char* link_name,
- const char* node_name)
+rtems_rfs_rtems_symlink (const rtems_filesystem_location_info_t* parent_loc,
+ const char* node_name,
+ size_t node_name_len,
+ const char* target)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parent_loc);
rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_loc);
- uid_t uid;
- gid_t gid;
int rc;
-#if defined(RTEMS_POSIX_API)
- uid = geteuid ();
- gid = getegid ();
-#else
- uid = 0;
- gid = 0;
-#endif
-
- rtems_rfs_rtems_lock (fs);
-
- rc = rtems_rfs_symlink (fs, node_name, strlen (node_name),
- link_name, strlen (link_name),
- uid, gid, parent);
+ rc = rtems_rfs_symlink (fs, node_name, node_name_len,
+ target, strlen (target),
+ geteuid(), getegid(), parent);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("symlink: linking", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
return 0;
}
/**
* The following rouine puts the symblic links destination name into buf.
- *
- * @param loc
- * @param buf
- * @param bufsize
- * @return int
*/
static ssize_t
-rtems_rfs_rtems_readlink (rtems_filesystem_location_info_t* pathloc,
- char* buf,
- size_t bufsize)
+rtems_rfs_rtems_readlink (const rtems_filesystem_location_info_t* pathloc,
+ char* buf,
+ size_t bufsize)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
@@ -783,23 +449,18 @@ rtems_rfs_rtems_readlink (rtems_filesystem_location_info_t* pathloc,
if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_READLINK))
printf ("rtems-rfs-rtems: readlink: in: ino:%" PRId32 "\n", ino);
- rtems_rfs_rtems_lock (fs);
-
rc = rtems_rfs_symlink_read (fs, ino, buf, bufsize, &length);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("readlink: reading link", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
- return (int) length;
+ return (ssize_t) length;
}
-int
-rtems_rfs_rtems_fchmod (rtems_filesystem_location_info_t* pathloc,
- mode_t mode)
+static int
+rtems_rfs_rtems_fchmod (const rtems_filesystem_location_info_t* pathloc,
+ mode_t mode)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
@@ -814,12 +475,9 @@ rtems_rfs_rtems_fchmod (rtems_filesystem_location_info_t* pathloc,
printf ("rtems-rfs-rtems: fchmod: in: ino:%" PRId32 " mode:%06" PRIomode_t "\n",
ino, mode);
- rtems_rfs_rtems_lock (fs);
-
rc = rtems_rfs_inode_open (fs, ino, &inode, true);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("fchmod: opening inode", rc);
}
@@ -834,7 +492,6 @@ rtems_rfs_rtems_fchmod (rtems_filesystem_location_info_t* pathloc,
if ((uid != rtems_rfs_inode_get_uid (&inode)) && (uid != 0))
{
rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("fchmod: checking uid", EPERM);
}
#endif
@@ -847,18 +504,15 @@ rtems_rfs_rtems_fchmod (rtems_filesystem_location_info_t* pathloc,
rc = rtems_rfs_inode_close (fs, &inode);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("fchmod: closing inode", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
return 0;
}
int
-rtems_rfs_rtems_fstat (rtems_filesystem_location_info_t* pathloc,
- struct stat* buf)
+rtems_rfs_rtems_fstat (const rtems_filesystem_location_info_t* pathloc,
+ struct stat* buf)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
@@ -870,12 +524,9 @@ rtems_rfs_rtems_fstat (rtems_filesystem_location_info_t* pathloc,
if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_STAT))
printf ("rtems-rfs-rtems: stat: in: ino:%" PRId32 "\n", ino);
- rtems_rfs_rtems_lock (fs);
-
rc = rtems_rfs_inode_open (fs, ino, &inode, true);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("stat: opening inode", rc);
}
@@ -931,32 +582,25 @@ rtems_rfs_rtems_fstat (rtems_filesystem_location_info_t* pathloc,
rc = rtems_rfs_inode_close (fs, &inode);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("stat: closing inode", rc);
}
- rtems_rfs_rtems_unlock (fs);
return 0;
}
/**
* Routine to create a node in the RFS file system.
- *
- * @param name
- * @param mode
- * @param dev
- * @param pathloc
- * @return int
*/
static int
-rtems_rfs_rtems_mknod (const char *name,
- mode_t mode,
- dev_t dev,
- rtems_filesystem_location_info_t *pathloc)
+rtems_rfs_rtems_mknod (const rtems_filesystem_location_info_t *parentloc,
+ const char *name,
+ size_t namelen,
+ mode_t mode,
+ dev_t dev)
{
- rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
- rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (pathloc);
+ rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (parentloc);
+ rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parentloc);
rtems_rfs_ino ino;
rtems_rfs_inode_handle inode;
uid_t uid;
@@ -971,21 +615,17 @@ rtems_rfs_rtems_mknod (const char *name,
gid = 0;
#endif
- rtems_rfs_rtems_lock (fs);
-
- rc = rtems_rfs_inode_create (fs, parent, name, strlen (name),
+ rc = rtems_rfs_inode_create (fs, parent, name, namelen,
rtems_rfs_rtems_imode (mode),
1, uid, gid, &ino);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("mknod: inode create", rc);
}
rc = rtems_rfs_inode_open (fs, ino, &inode, true);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("mknod: inode open", rc);
}
@@ -1003,18 +643,15 @@ rtems_rfs_rtems_mknod (const char *name,
else
{
rtems_rfs_inode_close (fs, &inode);
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("mknod: bad mode", EINVAL);
}
rc = rtems_rfs_inode_close (fs, &inode);
if (rc > 0)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("mknod: closing inode", rc);
}
- rtems_rfs_rtems_unlock (fs);
return 0;
}
@@ -1026,8 +663,8 @@ rtems_rfs_rtems_mknod (const char *name,
* @return int
*/
int
-rtems_rfs_rtems_rmnod (rtems_filesystem_location_info_t* parent_pathloc,
- rtems_filesystem_location_info_t* pathloc)
+rtems_rfs_rtems_rmnod (const rtems_filesystem_location_info_t* parent_pathloc,
+ const rtems_filesystem_location_info_t* pathloc)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
rtems_rfs_ino parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc);
@@ -1039,16 +676,15 @@ rtems_rfs_rtems_rmnod (rtems_filesystem_location_info_t* parent_pathloc,
printf ("rtems-rfs: rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n",
parent, doff, ino);
- rtems_rfs_rtems_lock (fs);
+ if (ino == RTEMS_RFS_ROOT_INO)
+ return rtems_rfs_rtems_error ("rmnod: root inode", EBUSY);
- rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_denied);
+ rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("rmnod: unlinking", rc);
}
- rtems_rfs_rtems_unlock (fs);
return 0;
}
@@ -1073,18 +709,13 @@ rtems_rfs_rtems_fdatasync (rtems_libio_t* iop)
/**
* Rename the node.
- *
- * @param old_parent_loc The old name's parent location.
- * @param old_loc The old name's location.
- * @param new_parent_loc The new name's parent location.
- * @param new_name The new name.
- * @return int
*/
static int
-rtems_rfs_rtems_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)
+rtems_rfs_rtems_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_name_len)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (old_loc);
rtems_rfs_ino old_parent;
@@ -1100,19 +731,16 @@ rtems_rfs_rtems_rename(rtems_filesystem_location_info_t* old_parent_loc,
doff = rtems_rfs_rtems_get_pathloc_doff (old_loc);
if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_RENAME))
- printf ("rtems-rfs: rename: ino:%" PRId32 " doff:%" PRIu32 ", new parent:%" PRId32 " new name:%s\n",
- ino, doff, new_parent, new_name);
-
- rtems_rfs_rtems_lock (fs);
+ printf ("rtems-rfs: rename: ino:%" PRId32 " doff:%" PRIu32 ", new parent:%" PRId32 "\n",
+ ino, doff, new_parent);
/*
* Link to the inode before unlinking so the inode is not erased when
* unlinked.
*/
- rc = rtems_rfs_link (fs, new_name, strlen (new_name), new_parent, ino, true);
+ rc = rtems_rfs_link (fs, new_name, new_name_len, new_parent, ino, true);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("rename: linking", rc);
}
@@ -1124,12 +752,9 @@ rtems_rfs_rtems_rename(rtems_filesystem_location_info_t* old_parent_loc,
rtems_rfs_unlink_dir_allowed);
if (rc)
{
- rtems_rfs_rtems_unlock (fs);
return rtems_rfs_rtems_error ("rename: unlinking", rc);
}
- rtems_rfs_rtems_unlock (fs);
-
return 0;
}
@@ -1141,8 +766,8 @@ rtems_rfs_rtems_rename(rtems_filesystem_location_info_t* old_parent_loc,
* @return int
*/
static int
-rtems_rfs_rtems_statvfs (rtems_filesystem_location_info_t* pathloc,
- struct statvfs* sb)
+rtems_rfs_rtems_statvfs (const rtems_filesystem_location_info_t* pathloc,
+ struct statvfs* sb)
{
rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
size_t blocks;
@@ -1177,12 +802,10 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers =
.ioctl_h = rtems_filesystem_default_ioctl,
.lseek_h = rtems_filesystem_default_lseek,
.fstat_h = rtems_rfs_rtems_fstat,
- .fchmod_h = rtems_filesystem_default_fchmod,
.ftruncate_h = rtems_filesystem_default_ftruncate,
.fsync_h = rtems_filesystem_default_fsync,
.fdatasync_h = rtems_filesystem_default_fdatasync,
- .fcntl_h = rtems_filesystem_default_fcntl,
- .rmnod_h = rtems_rfs_rtems_rmnod
+ .fcntl_h = rtems_filesystem_default_fcntl
};
/**
@@ -1191,27 +814,30 @@ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers =
int rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t *mt_entry,
const void *data);
-int rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t *mt_entry);
+void rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t *mt_entry);
/**
* RFS file system operations table.
*/
const rtems_filesystem_operations_table rtems_rfs_ops =
{
- .evalpath_h = rtems_rfs_rtems_eval_path,
- .evalformake_h = rtems_rfs_rtems_eval_for_make,
+ .lock_h = rtems_rfs_rtems_lock_by_mt_entry,
+ .unlock_h = rtems_rfs_rtems_unlock_by_mt_entry,
+ .are_nodes_equal_h = rtems_filesystem_default_are_nodes_equal,
+ .eval_path_h = rtems_rfs_rtems_eval_path,
.link_h = rtems_rfs_rtems_link,
- .unlink_h = rtems_rfs_rtems_unlink,
.node_type_h = rtems_rfs_rtems_node_type,
+ .fchmod_h = rtems_rfs_rtems_fchmod,
.mknod_h = rtems_rfs_rtems_mknod,
+ .rmnod_h = rtems_rfs_rtems_rmnod,
.chown_h = rtems_rfs_rtems_chown,
+ .clonenod_h = rtems_filesystem_default_clonenode,
.freenod_h = rtems_filesystem_default_freenode,
.mount_h = rtems_filesystem_default_mount,
.fsmount_me_h = rtems_rfs_rtems_initialise,
.unmount_h = rtems_filesystem_default_unmount,
.fsunmount_me_h = rtems_rfs_rtems_shutdown,
.utime_h = rtems_rfs_rtems_utime,
- .eval_link_h = rtems_filesystem_default_evaluate_link, /* never called cause we lie in the node type */
.symlink_h = rtems_rfs_rtems_symlink,
.readlink_h = rtems_rfs_rtems_readlink,
.rename_h = rtems_rfs_rtems_rename,
@@ -1292,9 +918,9 @@ rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t* mt_entry,
mt_entry->fs_info = fs;
- mt_entry->mt_fs_root.node_access = (void*) RTEMS_RFS_ROOT_INO;
- mt_entry->mt_fs_root.handlers = &rtems_rfs_rtems_dir_handlers;
- mt_entry->mt_fs_root.ops = &rtems_rfs_ops;
+ mt_entry->mt_fs_root->location.node_access = (void*) RTEMS_RFS_ROOT_INO;
+ mt_entry->mt_fs_root->location.handlers = &rtems_rfs_rtems_dir_handlers;
+ mt_entry->mt_fs_root->location.ops = &rtems_rfs_ops;
rtems_rfs_rtems_unlock (fs);
@@ -1304,19 +930,17 @@ rtems_rfs_rtems_initialise (rtems_filesystem_mount_table_entry_t* mt_entry,
/**
* Shutdown the file system.
*/
-int
+void
rtems_rfs_rtems_shutdown (rtems_filesystem_mount_table_entry_t* mt_entry)
{
rtems_rfs_file_system* fs = mt_entry->fs_info;
rtems_rfs_rtems_private* rtems;
- int rc;
rtems = rtems_rfs_fs_user (fs);
- rc = rtems_rfs_fs_close(fs);
+ /* FIXME: Return value? */
+ rtems_rfs_fs_close(fs);
rtems_rfs_mutex_destroy (&rtems->access);
free (rtems);
-
- return rtems_rfs_rtems_error ("shutdown: close", rc);
}
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-rtems.h b/cpukit/libfs/src/rfs/rtems-rfs-rtems.h
index a1b0e8556e..c4f8c9a358 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-rtems.h
+++ b/cpukit/libfs/src/rfs/rtems-rfs-rtems.h
@@ -225,16 +225,6 @@ typedef struct rtems_rfs_rtems_private
&rtems_rfs_rtems_ ## _h ## _handlers
/**
- * Evaluate the permissions of the inode's mode against the flags.
- *
- * @param inode The inode handler to check the mode, uid and gid.
- * @param flags The flags to check permissions of.
- * @retval true The permissions allow access to the inode.
- * @retval false Access to the inode is not permitted.
- */
-bool rtems_rfs_rtems_eval_perms (rtems_rfs_inode_handle* inode, int flags);
-
-/**
* Set the handlers in the path location based on the mode of the inode.
*
* @param loc Pointer to the path location to set the handlers in.
@@ -292,23 +282,9 @@ extern const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers;
/**
* The following routine does a stat on a node.
- *
- * @param iop
- * @param buf
- * @return int
- */
-int rtems_rfs_rtems_fstat (rtems_filesystem_location_info_t* pathloc,
- struct stat* buf);
-
-/**
- * File change mode routine.
- *
- * @param iop
- * @param mode
- * @return int
*/
-int rtems_rfs_rtems_fchmod (rtems_filesystem_location_info_t* pathloc,
- mode_t mode);
+int rtems_rfs_rtems_fstat (const rtems_filesystem_location_info_t* pathloc,
+ struct stat* buf);
/**
* Routine to remove a node from the RFS file system.
@@ -316,8 +292,8 @@ int rtems_rfs_rtems_fchmod (rtems_filesystem_location_info_t* pathloc,
* @param parent_pathloc
* @param pathloc
*/
-int rtems_rfs_rtems_rmnod (rtems_filesystem_location_info_t* parent_pathloc,
- rtems_filesystem_location_info_t* pathloc);
+int rtems_rfs_rtems_rmnod (const rtems_filesystem_location_info_t* parent_pathloc,
+ const rtems_filesystem_location_info_t* pathloc);
/**
* The following routine does a sync on an inode node. Currently it flushes
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-shell.c b/cpukit/libfs/src/rfs/rtems-rfs-shell.c
index 6969f1c588..8ef5b76ff5 100644
--- a/cpukit/libfs/src/rfs/rtems-rfs-shell.c
+++ b/cpukit/libfs/src/rfs/rtems-rfs-shell.c
@@ -102,10 +102,12 @@ rtems_rfs_get_fs (const char* path, rtems_rfs_file_system** fs)
* system data.
*/
{
- rtems_filesystem_location_info_t pathloc;
- rc = rtems_filesystem_evaluate_path (path, strlen (path), 0, &pathloc, true);
- *fs = rtems_rfs_rtems_pathloc_dev (&pathloc);
- rtems_filesystem_freenode (&pathloc);
+ rtems_filesystem_eval_path_context_t ctx;
+ int eval_flags = RTEMS_LIBIO_FOLLOW_LINK;
+ const rtems_filesystem_location_info_t *currentloc =
+ rtems_filesystem_eval_path_start (&ctx, path, eval_flags);
+ *fs = rtems_rfs_rtems_pathloc_dev (currentloc);
+ rtems_filesystem_eval_path_cleanup (&ctx);
}
#endif