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

4.11
Last change on this file since 59762469 was 59762469, checked in by Chris Johns <chrisj@…>, on Mar 15, 2011 at 7:32:39 AM

2011-03-15 Chris Johns <chrisj@…>

  • libfs/src/rfs/rtems-rfs-rtems-file.c, libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-rtems.h: The fix to the removal of file_info from iop was broken. The node_access field must be the inode number in the RFS because the file system ops provides no way to tell is a stat call is the result of stat, fstat, or lstat. The solution is to move the file handle to node_access_2 which is also shared with doff but these do not overlap.
  • Property mode set to 100644
File size: 8.6 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 File Handlers
16 *
17 * This file contains the set of handlers used to process operations on
18 * RFS file nodes.
19 */
20
21#if HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <inttypes.h>
26
27#include <rtems/rfs/rtems-rfs-file.h>
28#include "rtems-rfs-rtems.h"
29
30/**
31 * This routine processes the open() system call.  Note that there is nothing
32 * special to be done at open() time.
33 *
34 * @param iop
35 * @param pathname
36 * @param flag
37 * @param mode
38 * @return int
39 */
40
41static int
42rtems_rfs_rtems_file_open (rtems_libio_t* iop,
43                           const char*    pathname,
44                           uint32_t       flag,
45                           uint32_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  uint32_t               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:%04" PRIx32 " mode:%04" PRIx32 "\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  iop->size = rtems_rfs_file_size (file);
74  rtems_rfs_rtems_set_iop_file_handle (iop, file);
75 
76  rtems_rfs_rtems_unlock (fs);
77  return 0;
78}
79
80/**
81 * This routine processes the close() system call.  Note that there is nothing
82 * to flush at this point.
83 *
84 * @param iop
85 * @return int
86 */
87static int
88rtems_rfs_rtems_file_close (rtems_libio_t* iop)
89{
90  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
91  rtems_rfs_file_system* fs = rtems_rfs_file_fs (file);
92  int                    rc;
93
94  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_CLOSE))
95    printf("rtems-rfs: file-close: handle:%p\n", file);
96
97  rtems_rfs_rtems_lock (fs);
98 
99  rc = rtems_rfs_file_close (fs, file);
100  if (rc > 0)
101    rc = rtems_rfs_rtems_error ("file-close: file close", rc);
102 
103  rtems_rfs_rtems_unlock (fs);
104  return rc;
105}
106
107/**
108 * This routine processes the read() system call.
109 *
110 * @param iop
111 * @param buffer
112 * @param count
113 * @return int
114 */
115static ssize_t
116rtems_rfs_rtems_file_read (rtems_libio_t* iop,
117                           void*          buffer,
118                           size_t         count)
119{
120  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
121  rtems_rfs_pos          pos;
122  uint8_t*               data = buffer;
123  ssize_t                read = 0;
124  int                    rc;
125
126  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_READ))
127    printf("rtems-rfs: file-read: handle:%p count:%zd\n", file, count);
128
129  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
130
131  pos = iop->offset;
132 
133  if (pos < rtems_rfs_file_size (file))
134  {
135    while (count)
136    {
137      size_t size;
138
139      rc = rtems_rfs_file_io_start (file, &size, true);
140      if (rc > 0)
141      {
142        read = rtems_rfs_rtems_error ("file-read: read: io-start", rc);
143        break;
144      }
145
146      if (size == 0)
147        break;
148   
149      if (size > count)
150        size = count;
151   
152      memcpy (data, rtems_rfs_file_data (file), size);
153
154      data  += size;
155      count -= size;
156      read  += size;
157
158      rc = rtems_rfs_file_io_end (file, size, true);
159      if (rc > 0)
160      {
161        read = rtems_rfs_rtems_error ("file-read: read: io-end", rc);
162        break;
163      }
164    }
165  }
166 
167  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
168 
169  return read;
170}
171
172/**
173 * This routine processes the write() system call.
174 *
175 * @param iop
176 * @param buffer
177 * @param count
178 * @return ssize_t
179 */
180static ssize_t
181rtems_rfs_rtems_file_write (rtems_libio_t* iop,
182                            const void*    buffer,
183                            size_t         count)
184{
185  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
186  rtems_rfs_pos          pos;
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 
198  /*
199   * If the iop position is past the physical end of the file we need to set
200   * the file size to the new length before writing. If the position equals the
201   * size of file we are still past the end of the file as positions number
202   * from 0. For a specific position we need a file that has a length of one
203   * more.
204   */
205 
206  if (pos >= rtems_rfs_file_size (file))
207  {
208    rc = rtems_rfs_file_set_size (file, pos + 1);
209    if (rc)
210    {
211      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
212      return rtems_rfs_rtems_error ("file-write: write extend", rc);
213    }
214  }
215 
216  rtems_rfs_file_set_bpos (file, pos);
217 
218  while (count)
219  {
220    size_t size = count;
221   
222    rc = rtems_rfs_file_io_start (file, &size, false);
223    if (rc)
224    {
225      write = rtems_rfs_rtems_error ("file-write: write open", rc);
226      break;
227    }
228   
229    if (size > count)
230      size = count;
231
232    memcpy (rtems_rfs_file_data (file), data, size);
233
234    data  += size;
235    count -= size;
236    write  += size;
237   
238    rc = rtems_rfs_file_io_end (file, size, false);
239    if (rc)
240    {
241      write = rtems_rfs_rtems_error ("file-write: write close", rc);
242      break;
243    }
244  }
245 
246  iop->size = rtems_rfs_file_size (file);
247 
248  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
249 
250  return write;
251}
252
253/**
254 * This routine processes the ioctl() system call.
255 *
256 * @note  No ioctl()'s are currently supported for RFS files.
257 *
258 * @param iop
259 * @param command
260 * @param buffer
261 */
262
263static int
264rtems_rfs_rtems_file_ioctl (rtems_libio_t* iop, uint32_t command, void* buffer)
265{
266  return 0;
267}
268
269/**
270 * This routine processes the lseek() system call.
271 *
272 * @param iop
273 * @param offset
274 * @param whence
275 * @return rtems_off64_t
276 */
277static rtems_off64_t
278rtems_rfs_rtems_file_lseek (rtems_libio_t* iop,
279                            rtems_off64_t  offset,
280                            int            whence)
281{
282  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
283  rtems_rfs_pos          pos;
284  int                    rc;
285
286  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK))
287    printf("rtems-rfs: file-lseek: handle:%p offset:%Ld\n", file, offset);
288
289  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
290 
291  pos = iop->offset;
292 
293  rc = rtems_rfs_file_seek (file, pos, &pos);
294  if (rc)
295  {
296    rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
297    return rtems_rfs_rtems_error ("file_lseek: lseek", rc);
298  }
299 
300  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
301 
302  return iop->offset;
303}
304
305/**
306 * This routine processes the ftruncate() system call.
307 *
308 * @param iop
309 * @param length
310 * @return int
311 */
312static int
313rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop,
314                                rtems_off64_t  length)
315{
316  rtems_rfs_file_handle* file = rtems_rfs_rtems_get_iop_file_handle (iop);
317  int                    rc;
318
319  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_FTRUNC))
320    printf("rtems-rfs: file-ftrunc: handle:%p length:%Ld\n", file, length);
321 
322  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
323 
324  rc = rtems_rfs_file_set_size (file, length);
325  if (rc)
326    rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc);
327
328  iop->size = rtems_rfs_file_size (file);
329 
330  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
331
332  return rc;
333}
334
335/*
336 *  Set of operations handlers for operations on RFS files.
337 */
338
339const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
340  .open_h      = rtems_rfs_rtems_file_open,
341  .close_h     = rtems_rfs_rtems_file_close,
342  .read_h      = rtems_rfs_rtems_file_read,
343  .write_h     = rtems_rfs_rtems_file_write,
344  .ioctl_h     = rtems_rfs_rtems_file_ioctl,
345  .lseek_h     = rtems_rfs_rtems_file_lseek,
346  .fstat_h     = rtems_rfs_rtems_fstat,
347  .fchmod_h    = rtems_rfs_rtems_fchmod,
348  .ftruncate_h = rtems_rfs_rtems_file_ftruncate,
349  .fpathconf_h = rtems_filesystem_default_fpathconf,
350  .fsync_h     = rtems_rfs_rtems_fdatasync,
351  .fdatasync_h = rtems_rfs_rtems_fdatasync,
352  .fcntl_h     = rtems_filesystem_default_fcntl,
353  .rmnod_h     = rtems_rfs_rtems_rmnod
354};
Note: See TracBrowser for help on using the repository browser.