summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libfs')
-rw-r--r--cpukit/libfs/Makefile.am20
-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
105 files changed, 2093 insertions, 4582 deletions
diff --git a/cpukit/libfs/Makefile.am b/cpukit/libfs/Makefile.am
index 20a974c33e..ad103482ef 100644
--- a/cpukit/libfs/Makefile.am
+++ b/cpukit/libfs/Makefile.am
@@ -11,22 +11,27 @@ EXTRA_DIST = README
noinst_LIBRARIES = libdefaultfs.a
libdefaultfs_a_SOURCES = \
+ src/defaults/default_clone.c \
+ src/defaults/default_are_nodes_equal.c \
+ src/defaults/default_lock_and_unlock.c \
+ src/defaults/default_eval_path.c \
src/defaults/default_fchmod.c src/defaults/default_freenode.c \
src/defaults/default_fsync.c src/defaults/default_link.c \
src/defaults/default_read.c src/defaults/default_rmnod.c \
- src/defaults/default_unlink.c src/defaults/default_chown.c \
+ src/defaults/default_chown.c \
src/defaults/default_fcntl.c src/defaults/default_fsmount.c \
src/defaults/default_ftruncate.c src/defaults/default_lseek.c \
src/defaults/default_readlink.c src/defaults/default_statvfs.c \
- src/defaults/default_utime.c src/defaults/default_evalpath.c \
+ src/defaults/default_utime.c \
src/defaults/default_fdatasync.c src/defaults/default_fstat.c \
src/defaults/default_ioctl.c src/defaults/default_mount.c \
src/defaults/default_rename.c src/defaults/default_symlink.c \
src/defaults/default_write.c \
- src/defaults/default_unmount.c src/defaults/default_evaluate_link.c \
+ src/defaults/default_unmount.c \
src/defaults/default_open.c src/defaults/default_close.c \
src/defaults/default_fsunmount.c src/defaults/default_mknod.c \
- src/defaults/default_node_type.c src/defaults/default_evalformake.c \
+ src/defaults/default_node_type.c \
+ src/defaults/default_ftruncate_directory.c \
src/defaults/default_handlers.c src/defaults/default_ops.c
noinst_LIBRARIES += libimfs.a
@@ -37,14 +42,14 @@ libimfs_a_SOURCES += src/imfs/deviceerrno.c src/imfs/deviceio.c \
src/imfs/imfs_creat.c src/imfs/imfs_debug.c src/imfs/imfs_directory.c \
src/imfs/imfs_eval.c src/imfs/imfs_fchmod.c \
src/imfs/imfs_fdatasync.c src/imfs/imfs_fifo.c \
- src/imfs/imfs_fsunmount.c src/imfs/imfs_getchild.c \
- src/imfs/imfs_gtkn.c src/imfs/imfs_handlers_device.c \
+ src/imfs/imfs_fsunmount.c \
+ src/imfs/imfs_handlers_device.c \
src/imfs/imfs_handlers_directory.c src/imfs/imfs_handlers_link.c \
src/imfs/imfs_handlers_memfile.c src/imfs/imfs_init.c \
src/imfs/imfs_initsupp.c src/imfs/imfs_link.c src/imfs/imfs_load_tar.c \
src/imfs/imfs_mknod.c src/imfs/imfs_mount.c src/imfs/imfs_ntype.c \
src/imfs/imfs_readlink.c src/imfs/imfs_rename.c src/imfs/imfs_rmnod.c \
- src/imfs/imfs_stat.c src/imfs/imfs_symlink.c src/imfs/imfs_unlink.c \
+ src/imfs/imfs_stat.c src/imfs/imfs_symlink.c \
src/imfs/imfs_unmount.c src/imfs/imfs_utime.c src/imfs/ioman.c \
src/imfs/memfile.c src/imfs/miniimfs_init.c src/imfs/imfs.h
@@ -74,6 +79,7 @@ libdosfs_a_SOURCES += src/dosfs/msdos_create.c src/dosfs/msdos_dir.c \
src/dosfs/msdos_handlers_file.c src/dosfs/msdos_init.c \
src/dosfs/msdos_initsupp.c src/dosfs/msdos_misc.c \
src/dosfs/msdos_mknod.c src/dosfs/msdos_node_type.c \
+ src/dosfs/msdos_rmnod.c \
src/dosfs/msdos_conv.c src/dosfs/msdos.h src/dosfs/msdos_format.c \
src/dosfs/dosfs.h src/dosfs/msdos_rename.c
endif
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