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

4.115
Last change on this file since 6dd4853c was 6dd4853c, checked in by Chris Johns <chrisj@…>, on 10/18/10 at 22:39:35

2010-10-19 Chris Johns <chrisj@…>

  • libfs/src/rfs/rtems-rfs-rtems-file.c: Add missing unlock in write. Return the error code in close.
  • Property mode set to 100644
File size: 8.2 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->pathinfo.node_access = 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 = iop->pathinfo.node_access;
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 */
114ssize_t
115rtems_rfs_rtems_file_read (rtems_libio_t* iop,
116                           void*          buffer,
117                           size_t         count)
118{
119  rtems_rfs_file_handle* file = iop->pathinfo.node_access;
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 */
179ssize_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 = iop->pathinfo.node_access;
185  rtems_rfs_pos          pos;
186  const uint8_t*         data = buffer;
187  ssize_t                write = 0;
188  int                    rc;
189
190  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_WRITE))
191    printf("rtems-rfs: file-write: handle:%p count:%zd\n", file, count);
192
193  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
194
195  pos = iop->offset;
196 
197  /*
198   * If the iop position is past the physical end of the file we need to set the
199   * file size to the new length before writing.
200   */
201 
202  if (pos > rtems_rfs_file_size (file))
203  {
204    rc = rtems_rfs_file_set_size (file, pos);
205    if (rc)
206    {
207      rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
208      return rtems_rfs_rtems_error ("file-write: write extend", rc);
209    }
210    rtems_rfs_file_set_bpos (file, pos);
211  }
212 
213  while (count)
214  {
215    size_t size = count;
216   
217    rc = rtems_rfs_file_io_start (file, &size, false);
218    if (rc)
219    {
220      write = rtems_rfs_rtems_error ("file-write: write open", rc);
221      break;
222    }
223   
224    if (size > count)
225      size = count;
226
227    memcpy (rtems_rfs_file_data (file), data, size);
228
229    data  += size;
230    count -= size;
231    write  += size;
232   
233    rc = rtems_rfs_file_io_end (file, size, false);
234    if (rc)
235    {
236      write = rtems_rfs_rtems_error ("file-write: write close", rc);
237      break;
238    }
239  }
240 
241  iop->size = rtems_rfs_file_size (file);
242 
243  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
244 
245  return write;
246}
247
248/**
249 * This routine processes the ioctl() system call.
250 *
251 * @note  No ioctl()'s are currently supported for RFS files.
252 *
253 * @param iop
254 * @param command
255 * @param buffer
256 */
257
258int
259rtems_rfs_rtems_file_ioctl (rtems_libio_t* iop, uint32_t command, void* buffer)
260{
261  return 0;
262}
263
264/**
265 * This routine processes the lseek() system call.
266 *
267 * @param iop
268 * @param offset
269 * @param whence
270 * @return rtems_off64_t
271 */
272rtems_off64_t
273rtems_rfs_rtems_file_lseek (rtems_libio_t* iop,
274                            rtems_off64_t  offset,
275                            int            whence)
276{
277  rtems_rfs_file_handle* file = iop->pathinfo.node_access;
278  rtems_rfs_pos          pos;
279  int                    rc;
280
281  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_LSEEK))
282    printf("rtems-rfs: file-lseek: handle:%p offset:%Ld\n", file, offset);
283
284  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
285 
286  pos = iop->offset;
287 
288  rc = rtems_rfs_file_seek (file, pos, &pos);
289  if (rc)
290  {
291    rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
292    return rtems_rfs_rtems_error ("file_lseek: lseek", rc);
293  }
294 
295  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
296 
297  return iop->offset;
298}
299
300/**
301 * This routine processes the ftruncate() system call.
302 *
303 * @param iop
304 * @param length
305 * @return int
306 */
307int
308rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop,
309                                rtems_off64_t  length)
310{
311  rtems_rfs_file_handle* file = iop->pathinfo.node_access;
312  int                    rc;
313
314  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_FTRUNC))
315    printf("rtems-rfs: file-ftrunc: handle:%p length:%Ld\n", file, length);
316 
317  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
318 
319  rc = rtems_rfs_file_set_size (file, length);
320  if (rc)
321    rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc);
322
323  iop->size = rtems_rfs_file_size (file);
324 
325  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
326
327  return rc;
328}
329
330/*
331 *  Set of operations handlers for operations on RFS files.
332 */
333
334const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
335  .open_h      = rtems_rfs_rtems_file_open,
336  .close_h     = rtems_rfs_rtems_file_close,
337  .read_h      = rtems_rfs_rtems_file_read,
338  .write_h     = rtems_rfs_rtems_file_write,
339  .ioctl_h     = rtems_rfs_rtems_file_ioctl,
340  .lseek_h     = rtems_rfs_rtems_file_lseek,
341  .fstat_h     = rtems_rfs_rtems_stat,
342  .fchmod_h    = rtems_rfs_rtems_fchmod,
343  .ftruncate_h = rtems_rfs_rtems_file_ftruncate,
344  .fpathconf_h = rtems_filesystem_default_fpathconf,
345  .fsync_h     = rtems_rfs_rtems_fdatasync,
346  .fdatasync_h = rtems_rfs_rtems_fdatasync,
347  .fcntl_h     = rtems_filesystem_default_fcntl,
348  .rmnod_h     = rtems_rfs_rtems_rmnod
349};
Note: See TracBrowser for help on using the repository browser.