source: rtems/cpukit/libfs/src/rfs/rtems-rfs-rtems-dev.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: 6.1 KB
Line 
1/*
2 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.com/license/LICENSE.
7 *
8 *  $Id$
9 */
10/**
11 * @file
12 *
13 * @ingroup rtems-rfs
14 *
15 * RTEMS RFS Device Interface.
16 *
17 * This file contains the set of handlers used to map operations on RFS device
18 * nodes onto calls to the RTEMS Classic API IO Manager.
19 *
20 */
21
22#if HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include <rtems/devfs.h>
27#include "rtems-rfs-rtems.h"
28
29/**
30 * This handler maps an open() operation onto rtems_io_open().
31 *
32 * @param iop
33 * @param pathname
34 * @param flag
35 * @param mode
36 * @return int
37 */
38static int
39rtems_rfs_rtems_device_open ( rtems_libio_t *iop,
40                              const char    *pathname,
41                              int            oflag,
42                              mode_t         mode)
43{
44  rtems_libio_open_close_args_t args;
45  rtems_rfs_file_system*        fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
46  rtems_rfs_ino                 ino = rtems_rfs_rtems_get_iop_ino (iop);
47  rtems_rfs_inode_handle        inode;
48  int                           major;
49  int                           minor;
50  rtems_status_code             status;
51  int                           rc;
52
53  rtems_rfs_rtems_lock (fs);
54
55  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
56  if (rc > 0)
57  {
58    rtems_rfs_rtems_unlock (fs);
59    return rtems_rfs_rtems_error ("device_open: opening inode", rc);
60  }
61
62  major = rtems_rfs_inode_get_block (&inode, 0);
63  minor = rtems_rfs_inode_get_block (&inode, 1);
64
65  rc = rtems_rfs_inode_close (fs, &inode);
66  if (rc > 0)
67  {
68    rtems_rfs_rtems_unlock (fs);
69    return rtems_rfs_rtems_error ("device_open: closing inode", rc);
70  }
71
72  rtems_rfs_rtems_unlock (fs);
73
74  iop->data0 = major;
75  iop->data1 = (void*)((intptr_t) minor);
76
77  args.iop   = iop;
78  args.flags = iop->flags;
79  args.mode  = mode;
80
81  status = rtems_io_open (major, minor, (void *) &args);
82
83  return rtems_deviceio_errno (status);
84}
85
86/**
87 * This handler maps a close() operation onto rtems_io_close().
88 *
89 * @param iop
90 * @return int
91 */
92
93static int
94rtems_rfs_rtems_device_close (rtems_libio_t* iop)
95{
96  rtems_libio_open_close_args_t args;
97  rtems_status_code             status;
98  int                           major;
99  int                           minor;
100
101  major = (int) iop->data0;
102  minor = (intptr_t) iop->data1;
103
104  args.iop   = iop;
105  args.flags = 0;
106  args.mode  = 0;
107
108  status = rtems_io_close (major, minor, (void *) &args);
109
110  return rtems_deviceio_errno (status);
111}
112
113/**
114 * This handler maps a read() operation onto rtems_io_read().
115 *
116 * @param iop
117 * @param buffer
118 * @param count
119 * @return ssize_t
120 */
121
122static ssize_t
123rtems_rfs_rtems_device_read (rtems_libio_t* iop, void* buffer, size_t count)
124{
125  rtems_libio_rw_args_t args;
126  rtems_status_code     status;
127  int                   major;
128  int                   minor;
129
130  major = (int) iop->data0;
131  minor = (intptr_t) iop->data1;
132
133  args.iop         = iop;
134  args.offset      = iop->offset;
135  args.buffer      = buffer;
136  args.count       = count;
137  args.flags       = iop->flags;
138  args.bytes_moved = 0;
139
140  status = rtems_io_read (major, minor, (void *) &args);
141  if (status)
142    return rtems_deviceio_errno (status);
143
144  return (ssize_t) args.bytes_moved;
145}
146
147/*
148 * This handler maps a write() operation onto rtems_io_write().
149 *
150 * @param iop
151 * @param buffer
152 * @param count
153 * @return ssize_t
154 */
155
156static ssize_t
157rtems_rfs_rtems_device_write (rtems_libio_t* iop,
158                              const void*    buffer,
159                              size_t         count)
160{
161  rtems_libio_rw_args_t args;
162  rtems_status_code     status;
163  int                   major;
164  int                   minor;
165
166  major = (int) iop->data0;
167  minor = (intptr_t) iop->data1;
168
169  args.iop         = iop;
170  args.offset      = iop->offset;
171  args.buffer      = (void *) buffer;
172  args.count       = count;
173  args.flags       = iop->flags;
174  args.bytes_moved = 0;
175
176  status = rtems_io_write (major, minor, (void *) &args);
177  if (status)
178    return rtems_deviceio_errno (status);
179
180  return (ssize_t) args.bytes_moved;
181}
182
183/**
184 * This handler maps an ioctl() operation onto rtems_io_ioctl().
185 *
186 * @param iop
187 * @param command
188 * @param buffer
189 * @return int
190 */
191
192static int
193rtems_rfs_rtems_device_ioctl (rtems_libio_t* iop,
194                              uint32_t       command,
195                              void*          buffer)
196{
197  rtems_libio_ioctl_args_t args;
198  rtems_status_code        status;
199  int                      major;
200  int                      minor;
201
202  major = (int) iop->data0;
203  minor = (intptr_t) iop->data1;
204
205  args.iop     = iop;
206  args.command = command;
207  args.buffer  = buffer;
208
209  status = rtems_io_control (major, minor, (void *) &args);
210  if (status)
211    return rtems_deviceio_errno (status);
212
213  return args.ioctl_return;
214}
215
216/**
217 * This handler eats all lseek() operations and does not create an error. It
218 * assumes all devices can handle the seek. The writes fail.
219 *
220 * @param iop
221 * @param offset
222 * @param whence
223 * @return off_t
224 */
225
226static off_t
227rtems_rfs_rtems_device_lseek (rtems_libio_t* iop,
228                              off_t          offset,
229                              int            whence)
230{
231  return offset;
232}
233
234/**
235 * The consumes the truncate call. You cannot truncate device files.
236 *
237 * @param iop
238 * @param length
239 * @return int
240 */
241
242static int
243rtems_rfs_rtems_device_ftruncate (rtems_libio_t* iop, off_t length)
244{
245  return 0;
246}
247
248/*
249 *  Handler table for RFS device nodes
250 */
251
252const rtems_filesystem_file_handlers_r rtems_rfs_rtems_device_handlers = {
253  .open_h      = rtems_rfs_rtems_device_open,
254  .close_h     = rtems_rfs_rtems_device_close,
255  .read_h      = rtems_rfs_rtems_device_read,
256  .write_h     = rtems_rfs_rtems_device_write,
257  .ioctl_h     = rtems_rfs_rtems_device_ioctl,
258  .lseek_h     = rtems_rfs_rtems_device_lseek,
259  .fstat_h     = rtems_rfs_rtems_fstat,
260  .ftruncate_h = rtems_rfs_rtems_device_ftruncate,
261  .fsync_h     = rtems_filesystem_default_fsync,
262  .fdatasync_h = rtems_filesystem_default_fdatasync,
263  .fcntl_h     = rtems_filesystem_default_fcntl
264};
Note: See TracBrowser for help on using the repository browser.