source: rtems/testsuites/fstests/fsnofs01/init.c @ 3b7c123

4.115
Last change on this file since 3b7c123 was 3b7c123, checked in by Sebastian Huber <sebastian.huber@…>, on 03/13/12 at 10:33:51

Filesystem: Reference counting for locations

o A new data structure rtems_filesystem_global_location_t was

introduced to be used for

o the mount point location in the mount table entry,
o the file system root location in the mount table entry,
o the root directory location in the user environment, and
o the current directory location in the user environment.

During the path evaluation global start locations are obtained to
ensure that the current file system instance will be not unmounted in
the meantime.

o The user environment uses now reference counting and is protected

from concurrent access.

o The path evaluation process was completely rewritten and simplified.

The IMFS, RFS, NFS, and DOSFS use now a generic path evaluation
method. Recursive calls in the path evaluation have been replaced
with iteration to avoid stack overflows. Only the evaluation of
symbolic links is recursive. No dynamic memory allocations and
intermediate buffers are used in the high level path evaluation. No
global locks are held during the file system instance specific path
evaluation process.

o Recursive symbolic link evaluation is now limited by

RTEMS_FILESYSTEM_SYMLOOP_MAX. Applications can retrieve this value
via sysconf().

o The device file system (devFS) uses now no global variables and

allocation from the workspace. Node names are allocated from the
heap.

o The upper layer lseek() performs now some parameter checks.
o The upper layer ftruncate() performs now some parameter checks.
o unmask() is now restricted to the RWX flags and protected from

concurrent access.

o The fchmod_h and rmnod_h file system node handlers are now a file

system operation.

o The unlink_h operation has been removed. All nodes are now destroyed

with the rmnod_h operation.

o New lock_h, unlock_h, clonenod_h, and are_nodes_equal_h file system

operations.

o The path evaluation and file system operations are now protected by

per file system instance lock and unlock operations.

o Fix and test file descriptor duplicate in fcntl().
o New test fstests/fsnofs01.

  • Property mode set to 100644
File size: 10.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#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "tmacros.h"
20
21#include <sys/stat.h>
22#include <sys/statvfs.h>
23#include <errno.h>
24#include <fcntl.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <utime.h>
28
29#include <rtems/libio_.h>
30
31static int node_count(const rtems_chain_control *chain)
32{
33  int count = 0;
34  const rtems_chain_node *current = rtems_chain_immutable_first(chain);
35  const rtems_chain_node *tail = rtems_chain_immutable_tail(chain);
36
37  while (current != tail) {
38    ++count;
39
40    current = rtems_chain_immutable_next(current);
41  }
42
43  return count;
44}
45
46static void rtems_test_assert_equal_to_null_loc(
47  const rtems_filesystem_location_info_t *local_loc
48)
49{
50  rtems_filesystem_global_location_t *null_loc =
51    &rtems_filesystem_global_location_null;
52
53  rtems_test_assert(null_loc->location.node_access == local_loc->node_access);
54  rtems_test_assert(null_loc->location.node_access_2 == local_loc->node_access_2);
55  rtems_test_assert(null_loc->location.handlers == local_loc->handlers);
56  rtems_test_assert(null_loc->location.ops == local_loc->ops);
57  rtems_test_assert(null_loc->location.mt_entry == local_loc->mt_entry);
58}
59
60static void test_initial_values(void)
61{
62  rtems_filesystem_global_location_t *null_loc =
63    &rtems_filesystem_global_location_null;
64  rtems_filesystem_mount_table_entry_t *null_mt = null_loc->location.mt_entry;
65  rtems_chain_control *loc_chain = &null_mt->location_chain;
66  rtems_chain_node *loc_node = &null_loc->location.mt_entry_node;
67
68  rtems_test_assert(node_count(loc_chain) == 1);
69  rtems_test_assert(rtems_chain_previous(loc_node) == rtems_chain_head(loc_chain));
70  rtems_test_assert(rtems_chain_next(loc_node) == rtems_chain_tail(loc_chain));
71  rtems_test_assert(null_mt->mt_point_node == null_loc);
72  rtems_test_assert(null_mt->mt_fs_root == null_loc);
73  rtems_test_assert(!null_mt->mounted);
74  rtems_test_assert(!null_mt->writeable);
75  rtems_test_assert(null_loc->reference_count == 4);
76}
77
78static void test_location_obtain(void)
79{
80  rtems_filesystem_global_location_t *global_loc = NULL;
81  rtems_filesystem_global_location_t *null_loc =
82    rtems_filesystem_global_location_obtain(&global_loc);
83  rtems_filesystem_mount_table_entry_t *null_mt = null_loc->location.mt_entry;
84  rtems_chain_control *loc_chain = &null_mt->location_chain;
85
86  rtems_test_assert(node_count(loc_chain) == 1);
87  rtems_test_assert(null_loc->reference_count == 5);
88
89  rtems_filesystem_global_location_release(null_loc);
90
91  rtems_test_assert(node_count(loc_chain) == 1);
92  rtems_test_assert(null_loc->reference_count == 4);
93}
94
95static void test_null_location_obtain(void)
96{
97  rtems_filesystem_global_location_t *null_loc =
98    rtems_filesystem_global_location_obtain_null();
99  rtems_filesystem_mount_table_entry_t *null_mt = null_loc->location.mt_entry;
100  rtems_chain_control *loc_chain = &null_mt->location_chain;
101
102  rtems_test_assert(node_count(loc_chain) == 1);
103  rtems_test_assert(null_loc->reference_count == 5);
104
105  rtems_filesystem_global_location_release(null_loc);
106
107  rtems_test_assert(node_count(loc_chain) == 1);
108  rtems_test_assert(null_loc->reference_count == 4);
109}
110
111static void test_null_location_replace(void)
112{
113  rtems_filesystem_global_location_t *null_loc =
114    &rtems_filesystem_global_location_null;
115  rtems_filesystem_mount_table_entry_t *null_mt = null_loc->location.mt_entry;
116  rtems_chain_control *loc_chain = &null_mt->location_chain;
117  rtems_filesystem_location_info_t local_loc;
118
119  rtems_test_assert(node_count(loc_chain) == 1);
120  rtems_test_assert(null_loc->reference_count == 4);
121  rtems_test_assert(rtems_filesystem_global_location_is_null(null_loc));
122
123  rtems_filesystem_location_copy(&local_loc, &null_loc->location);
124
125  rtems_test_assert(node_count(loc_chain) == 2);
126  rtems_test_assert(null_loc->reference_count == 4);
127
128  rtems_filesystem_location_detach(&local_loc);
129
130  rtems_test_assert(node_count(loc_chain) == 2);
131  rtems_test_assert(null_loc->reference_count == 4);
132  rtems_test_assert(rtems_filesystem_location_is_null(&local_loc));
133  rtems_test_assert_equal_to_null_loc(&local_loc);
134
135  rtems_filesystem_location_free(&local_loc);
136
137  rtems_test_assert(node_count(loc_chain) == 1);
138  rtems_test_assert(null_loc->reference_count == 4);
139}
140
141static void test_null_location_get_and_replace(void)
142{
143  rtems_filesystem_global_location_t *null_loc =
144    &rtems_filesystem_global_location_null;
145  rtems_filesystem_mount_table_entry_t *null_mt = null_loc->location.mt_entry;
146  rtems_chain_control *loc_chain = &null_mt->location_chain;
147  rtems_filesystem_location_info_t local_loc_0;
148  rtems_filesystem_location_info_t local_loc_1;
149
150  rtems_test_assert(node_count(loc_chain) == 1);
151  rtems_test_assert(null_loc->reference_count == 4);
152
153  rtems_filesystem_location_copy(&local_loc_0, &null_loc->location);
154
155  rtems_test_assert(node_count(loc_chain) == 2);
156  rtems_test_assert(null_loc->reference_count == 4);
157  rtems_test_assert_equal_to_null_loc(&local_loc_0);
158
159  rtems_filesystem_location_copy_and_detach(&local_loc_1, &local_loc_0);
160
161  rtems_test_assert(node_count(loc_chain) == 3);
162  rtems_test_assert(null_loc->reference_count == 4);
163  rtems_test_assert_equal_to_null_loc(&local_loc_0);
164  rtems_test_assert_equal_to_null_loc(&local_loc_1);
165
166  rtems_filesystem_location_free(&local_loc_0);
167
168  rtems_test_assert(node_count(loc_chain) == 2);
169  rtems_test_assert(null_loc->reference_count == 4);
170  rtems_test_assert_equal_to_null_loc(&local_loc_1);
171
172  rtems_filesystem_location_free(&local_loc_1);
173
174  rtems_test_assert(node_count(loc_chain) == 1);
175  rtems_test_assert(null_loc->reference_count == 4);
176}
177
178static void test_path_ops(void)
179{
180  int rv = 0;
181  long lrv = 0;
182  struct stat st;
183  struct statvfs stvfs;
184  char buf [32];
185  ssize_t n = 0;
186  const char *path = "/";
187  const struct utimbuf times;
188
189  errno = 0;
190  rv = open(path, O_RDONLY);
191  rtems_test_assert(rv == -1);
192  rtems_test_assert(errno == ENXIO);
193
194  errno = 0;
195  rv = chdir(path);
196  rtems_test_assert(rv == -1);
197  rtems_test_assert(errno == ENXIO);
198
199  errno = 0;
200  rv = chroot(path);
201  rtems_test_assert(rv == -1);
202  rtems_test_assert(errno == ENXIO);
203
204  errno = 0;
205  rv = mknod(path, S_IFREG, 0);
206  rtems_test_assert(rv == -1);
207  rtems_test_assert(errno == ENXIO);
208
209  errno = 0;
210  rv = mkdir(path, 0);
211  rtems_test_assert(rv == -1);
212  rtems_test_assert(errno == ENXIO);
213
214  errno = 0;
215  rv = mkfifo(path, 0);
216  rtems_test_assert(rv == -1);
217  rtems_test_assert(errno == ENXIO);
218
219  errno = 0;
220  rv = stat(path, &st);
221  rtems_test_assert(rv == -1);
222  rtems_test_assert(errno == ENXIO);
223
224  errno = 0;
225  rv = lstat(path, &st);
226  rtems_test_assert(rv == -1);
227  rtems_test_assert(errno == ENXIO);
228
229  errno = 0;
230  rv = statvfs(path, &stvfs);
231  rtems_test_assert(rv == -1);
232  rtems_test_assert(errno == ENXIO);
233
234  errno = 0;
235  n = readlink(path, buf, sizeof(buf));
236  rtems_test_assert(n == -1);
237  rtems_test_assert(errno == ENXIO);
238
239  errno = 0;
240  rv = chmod(path, 0);
241  rtems_test_assert(rv == -1);
242  rtems_test_assert(errno == ENXIO);
243
244  errno = 0;
245  rv = chown(path, 0, 0);
246  rtems_test_assert(rv == -1);
247  rtems_test_assert(errno == ENXIO);
248
249  errno = 0;
250  rv = lchown(path, 0, 0);
251  rtems_test_assert(rv == -1);
252  rtems_test_assert(errno == ENXIO);
253
254  errno = 0;
255  rv = rmdir(path);
256  rtems_test_assert(rv == -1);
257  rtems_test_assert(errno == ENXIO);
258
259  errno = 0;
260  rv = unlink(path);
261  rtems_test_assert(rv == -1);
262  rtems_test_assert(errno == ENXIO);
263
264  errno = 0;
265  rv = truncate(path, 0);
266  rtems_test_assert(rv == -1);
267  rtems_test_assert(errno == ENXIO);
268
269  errno = 0;
270  rv = access(path, 0);
271  rtems_test_assert(rv == -1);
272  rtems_test_assert(errno == ENXIO);
273
274  errno = 0;
275  lrv = pathconf(path, _PC_LINK_MAX);
276  rtems_test_assert(lrv == -1);
277  rtems_test_assert(errno == ENXIO);
278
279  errno = 0;
280  rv = link(path, path);
281  rtems_test_assert(rv == -1);
282  rtems_test_assert(errno == ENXIO);
283
284  errno = 0;
285  rv = symlink(path, path);
286  rtems_test_assert(rv == -1);
287  rtems_test_assert(errno == ENXIO);
288
289  errno = 0;
290  rv = rename(path, path);
291  rtems_test_assert(rv == -1);
292  rtems_test_assert(errno == ENXIO);
293
294  errno = 0;
295  rv = utime(path, &times);
296  rtems_test_assert(rv == -1);
297  rtems_test_assert(errno == ENXIO);
298}
299
300static void test_user_env(void)
301{
302  rtems_status_code sc = RTEMS_SUCCESSFUL;
303  rtems_filesystem_global_location_t *null_loc =
304    &rtems_filesystem_global_location_null;
305  rtems_filesystem_mount_table_entry_t *null_mt = null_loc->location.mt_entry;
306  rtems_chain_control *loc_chain = &null_mt->location_chain;
307
308  rtems_test_assert(node_count(loc_chain) == 1);
309  rtems_test_assert(null_loc->reference_count == 4);
310
311  sc = rtems_libio_set_private_env();
312  rtems_test_assert(sc == RTEMS_UNSATISFIED);
313
314  rtems_test_assert(node_count(loc_chain) == 1);
315  rtems_test_assert(null_loc->reference_count == 4);
316
317  sc = rtems_libio_share_private_env(RTEMS_SELF);
318  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
319
320  rtems_test_assert(node_count(loc_chain) == 1);
321  rtems_test_assert(null_loc->reference_count == 4);
322
323  sc = rtems_libio_share_private_env(rtems_task_self());
324  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
325
326  rtems_test_assert(node_count(loc_chain) == 1);
327  rtems_test_assert(null_loc->reference_count == 4);
328
329  rtems_libio_use_global_env();
330
331  rtems_test_assert(node_count(loc_chain) == 1);
332  rtems_test_assert(null_loc->reference_count == 4);
333}
334
335static void Init(rtems_task_argument arg)
336{
337  printk("\n\n*** TEST FSNOFS 1 ***\n");
338
339  rtems_libio_init();
340
341  test_initial_values();
342  test_location_obtain();
343  test_null_location_obtain();
344  test_null_location_replace();
345  test_null_location_get_and_replace();
346  test_path_ops();
347  test_user_env();
348
349  printk("*** END OF TEST FSNOFS 1 ***\n");
350
351  exit(0);
352}
353
354#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
355
356#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
357
358#define CONFIGURE_MAXIMUM_TASKS 1
359
360#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
361
362#define CONFIGURE_INIT
363
364#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.