source: rtems/cpukit/libcsupport/src/sup_fs_eval_path_generic.c @ da154e14

4.11
Last change on this file since da154e14 was da154e14, checked in by Sebastian Huber <sebastian.huber@…>, on May 14, 2012 at 2:55:41 PM

Filesystem: Move operations to mount table entry

The scope of the file system operations is the file system instance.
The scope of the file system node handlers is the file location. The
benefit of moving the operations to the mount table entry is a size
reduction of the file location (rtems_filesystem_location_info_t). The
code size is slightly increased due to additional load instructions.

Restructure rtems_filesystem_mount_table_entry_t to improve cache
efficiency.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/libio_.h>
20
21static bool is_fs_root( const rtems_filesystem_location_info_t *loc )
22{
23  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
24  const rtems_filesystem_location_info_t *mt_fs_root =
25    &mt_entry->mt_fs_root->location;
26
27  return (*mt_entry->ops->are_nodes_equal_h)( loc, mt_fs_root );
28}
29
30static bool is_eval_path_root(
31  const rtems_filesystem_eval_path_context_t *ctx,
32  const rtems_filesystem_location_info_t *loc
33)
34{
35  const rtems_filesystem_mount_table_entry_t *mt_entry = loc->mt_entry;
36  const rtems_filesystem_location_info_t *rootloc = &ctx->rootloc->location;
37
38  return mt_entry == rootloc->mt_entry
39    && (*mt_entry->ops->are_nodes_equal_h)( loc, rootloc );
40}
41
42void rtems_filesystem_eval_path_generic(
43  rtems_filesystem_eval_path_context_t *ctx,
44  void *arg,
45  const rtems_filesystem_eval_path_generic_config *config
46)
47{
48  rtems_filesystem_eval_path_generic_status status =
49    RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE;
50
51  while (status == RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_CONTINUE) {
52    const char *token;
53    size_t tokenlen;
54
55    rtems_filesystem_eval_path_get_next_token(ctx, &token, &tokenlen);
56
57    if (tokenlen > 0) {
58      if ((*config->is_directory)(ctx, arg)) {
59        if (rtems_filesystem_is_current_directory(token, tokenlen)) {
60          if (rtems_filesystem_eval_path_has_path(ctx)) {
61            status = (*config->eval_token)(ctx, arg, ".", 1);
62          } else {
63            int eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
64
65            if ((eval_flags & RTEMS_FS_REJECT_TERMINAL_DOT) == 0) {
66              status = (*config->eval_token)(ctx, arg, ".", 1);
67            } else {
68              rtems_filesystem_eval_path_error(ctx, EINVAL);
69              status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
70            }
71          }
72        } else if (rtems_filesystem_is_parent_directory(token, tokenlen)) {
73          rtems_filesystem_location_info_t *currentloc =
74            rtems_filesystem_eval_path_get_currentloc( ctx );
75
76          if (is_eval_path_root(ctx, currentloc)) {
77            /* This prevents the escape from a chroot() environment */
78            status = (*config->eval_token)(ctx, arg, ".", 1);
79          } else if (is_fs_root(currentloc)) {
80            if (currentloc->mt_entry->mt_point_node != NULL) {
81              rtems_filesystem_eval_path_put_back_token(ctx);
82              rtems_filesystem_eval_path_restart(
83                ctx,
84                &currentloc->mt_entry->mt_point_node
85              );
86              status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
87            } else {
88              /* This is the root file system */
89              status = (*config->eval_token)(ctx, arg, ".", 1);
90            }
91          } else {
92            status = (*config->eval_token)(ctx, arg, "..", 2);
93          }
94        } else {
95          status = (*config->eval_token)(ctx, arg, token, tokenlen);
96        }
97
98        if (status == RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_NO_ENTRY) {
99          if (rtems_filesystem_eval_path_has_path(ctx)) {
100            int eval_flags;
101
102            rtems_filesystem_eval_path_eat_delimiter(ctx);
103            eval_flags = rtems_filesystem_eval_path_get_flags(ctx);
104            if (
105              (eval_flags & RTEMS_FS_ACCEPT_RESIDUAL_DELIMITERS) == 0
106                || rtems_filesystem_eval_path_has_path(ctx)
107            ) {
108              rtems_filesystem_eval_path_error(ctx, ENOENT);
109            }
110          }
111        }
112      } else {
113        rtems_filesystem_eval_path_error(ctx, ENOTDIR);
114        status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
115      }
116    } else {
117      status = RTEMS_FILESYSTEM_EVAL_PATH_GENERIC_DONE;
118    }
119  }
120}
Note: See TracBrowser for help on using the repository browser.