source: rtems/cpukit/libfs/src/rfs/rtems-rfs-rtems-file.c @ df01da67

4.115
Last change on this file since df01da67 was df01da67, checked in by Sebastian Huber <sebastian.huber@…>, on 05/14/12 at 11:16:31

Filesystem: Use ioctl_command_t

  • Property mode set to 100644
File size: 8.5 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/**
9 * @file
10 *
11 * @ingroup rtems-rfs
12 *
13 * RTEMS RFS File Handlers
14 *
15 * This file contains the set of handlers used to process operations on
16 * RFS file nodes.
17 */
18
19#if HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <inttypes.h>
24
25#if SIZEOF_OFF_T == 8
26#define PRIdoff_t PRId64
27#elif SIZEOF_OFF_T == 4
28#define PRIdoff_t PRId32
29#else
30#error "unsupported size of off_t"
31#endif
32
33#include <rtems/rfs/rtems-rfs-file.h>
34#include "rtems-rfs-rtems.h"
35
36/**
37 * This routine processes the open() system call.  Note that there is nothing
38 * special to be done at open() time.
39 */
40
41static int
42rtems_rfs_rtems_file_open (rtems_libio_t* iop,
43                           const char*    pathname,
44                           int            oflag,
45                           mode_t         mode)
46{
47  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
48  rtems_rfs_ino          ino;
49  rtems_rfs_file_handle* file;
50  int                    flags;
51  int                    rc;
52
53  flags = 0;
54
55  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN))
56    printf("rtems-rfs: file-open: path:%s ino:%" PRId32 " flags:%04i mode:%04" PRIu32 "\n",
57           pathname, ino, flags, mode);
58
59  rtems_rfs_rtems_lock (fs);
60
61  ino = rtems_rfs_rtems_get_iop_ino (iop);
62
63  rc = rtems_rfs_file_open (fs, ino, flags, &file);
64  if (rc > 0)
65  {
66    rtems_rfs_rtems_unlock (fs);
67    return rtems_rfs_rtems_error ("file-open: open", rc);
68  }
69
70  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_OPEN))
71    printf("rtems-rfs: file-open: handle:%p\n", file);
72
73  rtems_rfs_rtems_set_iop_file_handle (iop, file);
74
75  rtems_rfs_rtems_unlock (fs);
76  return 0;
77}
78
79/**
80 * This routine processes the close() system call.  Note that there is nothing
81 * to flush at this point.
82 *
83 * @param iop
84 * @return int
85 */
86static int
87rtems_rfs_rtems_file_close (rtems_libio_t* iop)
88{
89  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
90  rtems_rfs_file_system* fs = rtems_rfs_file_fs (file);
91  int                    rc;
92
93  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_CLOSE))
94    printf("rtems-rfs: file-close: handle:%p\n", file);
95
96  rtems_rfs_rtems_lock (fs);
97
98  rc = rtems_rfs_file_close (fs, file);
99  if (rc > 0)
100    rc = rtems_rfs_rtems_error ("file-close: file close", rc);
101
102  rtems_rfs_rtems_unlock (fs);
103  return rc;
104}
105
106/**
107 * This routine processes the read() system call.
108 *
109 * @param iop
110 * @param buffer
111 * @param count
112 * @return int
113 */
114static ssize_t
115rtems_rfs_rtems_file_read (rtems_libio_t* iop,
116                           void*          buffer,
117                           size_t         count)
118{
119  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
120  rtems_rfs_pos          pos;
121  uint8_t*               data = buffer;
122  ssize_t                read = 0;
123  int                    rc;
124
125  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_READ))
126    printf("rtems-rfs: file-read: handle:%p count:%zd\n", file, count);
127
128  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
129
130  pos = iop->offset;
131
132  if (pos < rtems_rfs_file_size (file))
133  {
134    while (count)
135    {
136      size_t size;
137
138      rc = rtems_rfs_file_io_start (file, &size, true);
139      if (rc > 0)
140      {
141        read = rtems_rfs_rtems_error ("file-read: read: io-start", rc);
142        break;
143      }
144
145      if (size == 0)
146        break;
147
148      if (size > count)
149        size = count;
150
151      memcpy (data, rtems_rfs_file_data (file), size);
152
153      data  += size;
154      count -= size;
155      read  += size;
156
157      rc = rtems_rfs_file_io_end (file, size, true);
158      if (rc > 0)
159      {
160        read = rtems_rfs_rtems_error ("file-read: read: io-end", rc);
161        break;
162      }
163    }
164  }
165
166  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
167
168  return read;
169}
170
171/**
172 * This routine processes the write() system call.
173 *
174 * @param iop
175 * @param buffer
176 * @param count
177 * @return ssize_t
178 */
179static ssize_t
180rtems_rfs_rtems_file_write (rtems_libio_t* iop,
181                            const void*    buffer,
182                            size_t         count)
183{
184  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
185  rtems_rfs_pos          pos;
186  rtems_rfs_pos          file_size;
187  const uint8_t*         data = buffer;
188  ssize_t                write = 0;
189  int                    rc;
190
191  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_WRITE))
192    printf("rtems-rfs: file-write: handle:%p count:%zd\n", file, count);
193
194  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
195
196  pos = iop->offset;
197  file_size = rtems_rfs_file_size (file);
198  if (pos > file_size)
199  {
200    /*
201     * If the iop position is past the physical end of the file we need to set
202     * the file size to the new length before writing.  The
203     * rtems_rfs_file_io_end() will grow the file subsequently.
204     */
205    rc = rtems_rfs_file_set_size (file, pos);
206    if (rc)
207    {
208      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
209      return rtems_rfs_rtems_error ("file-write: write extend", rc);
210    }
211
212    rtems_rfs_file_set_bpos (file, pos);
213  }
214  else if (pos < file_size && (iop->flags & LIBIO_FLAGS_APPEND) != 0)
215  {
216    pos = file_size;
217    rc = rtems_rfs_file_seek (file, pos, &pos);
218    if (rc)
219    {
220      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
221      return rtems_rfs_rtems_error ("file-write: write append seek", rc);
222    }
223    iop->offset = pos;
224  }
225
226  while (count)
227  {
228    size_t size = count;
229
230    rc = rtems_rfs_file_io_start (file, &size, false);
231    if (rc)
232    {
233      write = rtems_rfs_rtems_error ("file-write: write open", rc);
234      break;
235    }
236
237    if (size > count)
238      size = count;
239
240    memcpy (rtems_rfs_file_data (file), data, size);
241
242    data  += size;
243    count -= size;
244    write  += size;
245
246    rc = rtems_rfs_file_io_end (file, size, false);
247    if (rc)
248    {
249      write = rtems_rfs_rtems_error ("file-write: write close", rc);
250      break;
251    }
252  }
253
254  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
255
256  return write;
257}
258
259/**
260 * This routine processes the lseek() system call.
261 *
262 * @param iop
263 * @param offset
264 * @param whence
265 * @return off_t
266 */
267static off_t
268rtems_rfs_rtems_file_lseek (rtems_libio_t* iop,
269                            off_t          offset,
270                            int            whence)
271{
272  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
273  off_t                  old_offset;
274  off_t                  new_offset;
275
276  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK))
277    printf("rtems-rfs: file-lseek: handle:%p offset:%" PRIdoff_t "\n", file, offset);
278
279  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
280
281  old_offset = iop->offset;
282  new_offset = rtems_filesystem_default_lseek_file (iop, offset, whence);
283  if (new_offset != -1)
284  {
285    rtems_rfs_pos pos = iop->offset;
286    int           rc = rtems_rfs_file_seek (file, pos, &pos);
287
288    if (rc)
289    {
290      rtems_rfs_rtems_error ("file_lseek: lseek", rc);
291      iop->offset = old_offset;
292      new_offset = -1;
293    }
294  }
295
296  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
297
298  return new_offset;
299}
300
301/**
302 * This routine processes the ftruncate() system call.
303 *
304 * @param iop
305 * @param length
306 * @return int
307 */
308static int
309rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop,
310                                off_t          length)
311{
312  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
313  int                    rc;
314
315  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_FTRUNC))
316    printf("rtems-rfs: file-ftrunc: handle:%p length:%" PRIdoff_t "\n", file, length);
317
318  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
319
320  rc = rtems_rfs_file_set_size (file, length);
321  if (rc)
322    rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc);
323
324  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
325
326  return rc;
327}
328
329/*
330 *  Set of operations handlers for operations on RFS files.
331 */
332
333const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
334  .open_h      = rtems_rfs_rtems_file_open,
335  .close_h     = rtems_rfs_rtems_file_close,
336  .read_h      = rtems_rfs_rtems_file_read,
337  .write_h     = rtems_rfs_rtems_file_write,
338  .ioctl_h     = rtems_filesystem_default_ioctl,
339  .lseek_h     = rtems_rfs_rtems_file_lseek,
340  .fstat_h     = rtems_rfs_rtems_fstat,
341  .ftruncate_h = rtems_rfs_rtems_file_ftruncate,
342  .fsync_h     = rtems_rfs_rtems_fdatasync,
343  .fdatasync_h = rtems_rfs_rtems_fdatasync,
344  .fcntl_h     = rtems_filesystem_default_fcntl
345};
Note: See TracBrowser for help on using the repository browser.