source: rtems/testsuites/fstests/fsimfsgeneric01/init.c @ c17d0b3

4.11
Last change on this file since c17d0b3 was c17d0b3, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 2, 2012 at 1:44:59 PM

Filesystem: Reject removal of root nodes

Reject the removal of file system instance root nodes in rmdir() and
unlink() and return the EBUSY error status. File system instances can
be removed with unmount(). Remove root node special cases in IMFS,
DOSFS, and RFS.

  • Property mode set to 100644
File size: 7.7 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/ioctl.h>
23#include <fcntl.h>
24#include <unistd.h>
25#include <errno.h>
26
27#include <rtems/imfs.h>
28#include <rtems/malloc.h>
29
30typedef enum {
31  TEST_NEW,
32  TEST_INITIALIZED,
33  TEST_FSTAT_OPEN,
34  TEST_OPEN,
35  TEST_READ,
36  TEST_WRITE,
37  TEST_IOCTL,
38  TEST_LSEEK,
39  TEST_FTRUNCATE,
40  TEST_FSYNC,
41  TEST_FDATASYNC,
42  TEST_FCNTL,
43  TEST_CLOSED,
44  TEST_FSTAT_UNLINK,
45  TEST_REMOVED,
46  TEST_DESTROYED
47} test_state;
48
49static test_state global_state = TEST_NEW;
50
51static int handler_open(
52  rtems_libio_t *iop,
53  const char *path,
54  int oflag,
55  mode_t mode
56)
57{
58  test_state *state = IMFS_generic_get_context_by_iop(iop);
59
60  rtems_test_assert(*state == TEST_FSTAT_OPEN);
61  *state = TEST_OPEN;
62
63  return 0;
64}
65
66static int handler_close(
67  rtems_libio_t *iop
68)
69{
70  test_state *state = IMFS_generic_get_context_by_iop(iop);
71
72  rtems_test_assert(*state == TEST_FCNTL);
73  *state = TEST_CLOSED;
74
75  return 0;
76}
77
78static ssize_t handler_read(
79  rtems_libio_t *iop,
80  void *buffer,
81  size_t count
82)
83{
84  test_state *state = IMFS_generic_get_context_by_iop(iop);
85
86  rtems_test_assert(*state == TEST_OPEN);
87  *state = TEST_READ;
88
89  return 0;
90}
91
92static ssize_t handler_write(
93  rtems_libio_t *iop,
94  const void *buffer,
95  size_t count
96)
97{
98  test_state *state = IMFS_generic_get_context_by_iop(iop);
99
100  rtems_test_assert(*state == TEST_READ);
101  *state = TEST_WRITE;
102
103  return 0;
104}
105
106static int handler_ioctl(
107  rtems_libio_t *iop,
108  uint32_t request,
109  void *buffer
110)
111{
112  test_state *state = IMFS_generic_get_context_by_iop(iop);
113
114  rtems_test_assert(*state == TEST_WRITE);
115  *state = TEST_IOCTL;
116
117  return 0;
118}
119
120static off_t handler_lseek(
121  rtems_libio_t *iop,
122  off_t length,
123  int whence
124)
125{
126  test_state *state = IMFS_generic_get_context_by_iop(iop);
127
128  rtems_test_assert(*state == TEST_IOCTL);
129  *state = TEST_LSEEK;
130
131  return 0;
132}
133
134static int handler_fstat(
135  const rtems_filesystem_location_info_t *loc,
136  struct stat *buf
137)
138{
139  test_state *state = IMFS_generic_get_context_by_location(loc);
140
141  switch (*state) {
142    case TEST_INITIALIZED:
143      *state = TEST_FSTAT_OPEN;
144      break;
145    case TEST_CLOSED:
146      *state = TEST_FSTAT_UNLINK;
147      break;
148    default:
149      rtems_test_assert(0);
150      break;
151  }
152
153  return rtems_filesystem_default_fstat(loc, buf);
154}
155
156static int handler_ftruncate(
157  rtems_libio_t *iop,
158  off_t length
159)
160{
161  test_state *state = IMFS_generic_get_context_by_iop(iop);
162
163  rtems_test_assert(*state == TEST_LSEEK);
164  *state = TEST_FTRUNCATE;
165
166  return 0;
167}
168
169static int handler_fsync(
170  rtems_libio_t *iop
171)
172{
173  test_state *state = IMFS_generic_get_context_by_iop(iop);
174
175  rtems_test_assert(*state == TEST_FTRUNCATE);
176  *state = TEST_FSYNC;
177
178  return 0;
179}
180
181static int handler_fdatasync(
182  rtems_libio_t *iop
183)
184{
185  test_state *state = IMFS_generic_get_context_by_iop(iop);
186
187  rtems_test_assert(*state == TEST_FSYNC);
188  *state = TEST_FDATASYNC;
189
190  return 0;
191}
192
193static int handler_fcntl(
194  rtems_libio_t *iop,
195  int cmd
196)
197{
198  test_state *state = IMFS_generic_get_context_by_iop(iop);
199
200  rtems_test_assert(*state == TEST_FDATASYNC);
201  *state = TEST_FCNTL;
202
203  return 0;
204}
205
206static const rtems_filesystem_file_handlers_r node_handlers = {
207  .open_h = handler_open,
208  .close_h = handler_close,
209  .read_h = handler_read,
210  .write_h = handler_write,
211  .ioctl_h = handler_ioctl,
212  .lseek_h = handler_lseek,
213  .fstat_h = handler_fstat,
214  .ftruncate_h = handler_ftruncate,
215  .fsync_h = handler_fsync,
216  .fdatasync_h = handler_fdatasync,
217  .fcntl_h = handler_fcntl
218};
219
220static IMFS_jnode_t *node_initialize(
221  IMFS_jnode_t *node,
222  const IMFS_types_union *info
223)
224{
225  test_state *state = NULL;
226
227  node = IMFS_node_initialize_generic(node, info);
228  state = IMFS_generic_get_context_by_node(node);
229
230  rtems_test_assert(*state == TEST_NEW);
231  *state = TEST_INITIALIZED;
232
233  return node;
234}
235
236static IMFS_jnode_t *node_remove(IMFS_jnode_t *node)
237{
238  test_state *state = IMFS_generic_get_context_by_node(node);
239
240  rtems_test_assert(*state == TEST_FSTAT_UNLINK);
241  *state = TEST_REMOVED;
242
243  return node;
244}
245
246static IMFS_jnode_t *node_destroy(IMFS_jnode_t *node)
247{
248  test_state *state = IMFS_generic_get_context_by_node(node);
249
250  rtems_test_assert(*state == TEST_REMOVED);
251  *state = TEST_DESTROYED;
252
253  return node;
254}
255
256static const IMFS_node_control node_control = {
257  .imfs_type = IMFS_GENERIC,
258  .handlers = &node_handlers,
259  .node_initialize = node_initialize,
260  .node_remove = node_remove,
261  .node_destroy = node_destroy
262};
263
264static void test_imfs_make_generic_node(void)
265{
266  int rv = 0;
267  int fd = 0;
268  const char *path = "generic";
269  char buf [1];
270  ssize_t n = 0;
271  off_t off = 0;
272
273  rv = IMFS_make_generic_node(
274    path,
275    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
276    &node_control,
277    &global_state
278  );
279  rtems_test_assert(rv == 0);
280
281  fd = open(path, O_RDWR);
282  rtems_test_assert(fd >= 0);
283
284  n = read(fd, buf, sizeof(buf));
285  rtems_test_assert(n == 0);
286
287  n = write(fd, buf, sizeof(buf));
288  rtems_test_assert(n == 0);
289
290  rv = ioctl(fd, 0);
291  rtems_test_assert(rv == 0);
292
293  off = lseek(fd, off, SEEK_SET);
294  rtems_test_assert(off == 0);
295
296  rv = ftruncate(fd, 0);
297  rtems_test_assert(rv == 0);
298
299  rv = fsync(fd);
300  rtems_test_assert(rv == 0);
301
302  rv = fdatasync(fd);
303  rtems_test_assert(rv == 0);
304
305  rv = fcntl(fd, F_GETFD);
306  rtems_test_assert(rv >= 0);
307
308  rv = close(fd);
309  rtems_test_assert(rv == 0);
310
311  rv = unlink(path);
312  rtems_test_assert(rv == 0);
313
314  rtems_test_assert(global_state == TEST_DESTROYED);
315}
316
317static const IMFS_node_control node_invalid_control = {
318  .imfs_type = IMFS_DIRECTORY,
319  .handlers = &node_handlers,
320  .node_initialize = node_initialize,
321  .node_remove = node_remove,
322  .node_destroy = node_destroy
323};
324
325static void test_imfs_make_generic_node_errors(void)
326{
327  int rv = 0;
328  const char *path = "generic";
329  rtems_chain_control *chain = &rtems_filesystem_mount_table;
330  rtems_filesystem_mount_table_entry_t *mt_entry =
331    (rtems_filesystem_mount_table_entry_t *) rtems_chain_first(chain);
332  const char *type = mt_entry->type;
333  void *opaque = NULL;
334
335  errno = 0;
336  rv = IMFS_make_generic_node(
337    path,
338    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
339    &node_invalid_control,
340    NULL
341  );
342  rtems_test_assert(rv == -1);
343  rtems_test_assert(errno == EINVAL);
344
345  errno = 0;
346  rv = IMFS_make_generic_node(
347    path,
348    S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO,
349    &node_control,
350    NULL
351  );
352  rtems_test_assert(rv == -1);
353  rtems_test_assert(errno == EINVAL);
354
355  mt_entry->type = "XXX";
356  errno = 0;
357  rv = IMFS_make_generic_node(
358    path,
359    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
360    &node_control,
361    NULL
362  );
363  rtems_test_assert(rv == -1);
364  rtems_test_assert(errno == ENOTSUP);
365  mt_entry->type = type;
366
367  opaque = rtems_heap_greedy_allocate(NULL, 0);
368  errno = 0;
369  rv = IMFS_make_generic_node(
370    path,
371    S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
372    &node_control,
373    NULL
374  );
375  rtems_test_assert(rv == -1);
376  rtems_test_assert(errno == ENOMEM);
377  rtems_heap_greedy_free(opaque);
378}
379
380static void Init(rtems_task_argument arg)
381{
382  printf("\n\n*** TEST FSIMFSGENERIC 1 ***\n");
383
384  test_imfs_make_generic_node();
385  test_imfs_make_generic_node_errors();
386
387  printf("*** END OF TEST FSIMFSGENERIC 1 ***\n");
388
389  rtems_test_exit(0);
390}
391
392#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
393#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
394
395#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
396
397#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
398
399#define CONFIGURE_MAXIMUM_TASKS 1
400
401#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
402
403#define CONFIGURE_INIT
404
405#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.