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

4.115
Last change on this file since d0fcd0b was d0fcd0b, checked in by Chris Johns <chrisj@…>, on 03/15/11 at 05:02:34

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

PR 1763/shell

  • libmisc/shell/hexdump-conv.c: Remove debug hacks.

PR 1757/filesystem

  • libfs/src/rfs/rtems-rfs-block-pos.h, libfs/src/rfs/rtems-rfs-block.h, libfs/src/rfs/rtems-rfs-file.c, libfs/src/rfs/rtems-rfs-rtems-file.c: Set the file size in iop-size when a file is open. Fix lseek to end of file then write for sizes less than half the file system block size.
  • libfs/src/rfs/rtems-rfs-rtems-dev.c, libfs/src/rfs/rtems-rfs-rtems-dir.c, libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-rtems.h: Fix the fstat and fchmod calls due to the change in the iop struct where pathinfo went away. The node_access field in pathinfo was overloaded.
  • Property mode set to 100644
File size: 9.9 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  iop->pathinfo.node_access = 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 = iop->pathinfo.node_access;
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 = iop->pathinfo.node_access;
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 = iop->pathinfo.node_access;
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 = iop->pathinfo.node_access;
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 * Stat the file.
307 *
308 * @param iop
309 * @param buf
310 * @return int
311 */
312static int
313rtems_rfs_rtems_file_fstat (rtems_filesystem_location_info_t* pathloc,
314                            struct stat*                      buf)
315{
316  rtems_rfs_file_handle* file = pathloc->node_access;
317  int                    rc;
318
319  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_STAT))
320    printf ("rtems-rfs: file-fstat: handle:%p\n", file);
321
322  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
323
324  rc = rtems_rfs_rtems_stat_inode (rtems_rfs_file_fs (file),
325                                   rtems_rfs_file_inode (file),
326                                   buf);
327
328  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
329
330  return rc;
331}
332
333/**
334 * File change mode routine.
335 *
336 * @param iop
337 * @param mode
338 * @return int
339 */
340static int
341rtems_rfs_rtems_file_fchmod (rtems_filesystem_location_info_t* pathloc,
342                             mode_t                            mode)
343{
344  rtems_rfs_file_handle* file = pathloc->node_access;
345  int                    rc;
346
347  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FCHMOD))
348    printf ("rtems-rfs: file-fchmod: handle:%p\n", file);
349
350  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
351
352  rc = rtems_rfs_rtems_fchmod_inode (rtems_rfs_file_fs (file),
353                                     rtems_rfs_file_inode (file),
354                                     mode);
355
356  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
357
358  return rc;
359}
360
361/**
362 * This routine processes the ftruncate() system call.
363 *
364 * @param iop
365 * @param length
366 * @return int
367 */
368static int
369rtems_rfs_rtems_file_ftruncate (rtems_libio_t* iop,
370                                rtems_off64_t  length)
371{
372  rtems_rfs_file_handle* file = iop->pathinfo.node_access;
373  int                    rc;
374
375  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_FILE_FTRUNC))
376    printf("rtems-rfs: file-ftrunc: handle:%p length:%Ld\n", file, length);
377 
378  rtems_rfs_rtems_lock (rtems_rfs_file_fs (file));
379 
380  rc = rtems_rfs_file_set_size (file, length);
381  if (rc)
382    rc = rtems_rfs_rtems_error ("file_ftruncate: set size", rc);
383
384  iop->size = rtems_rfs_file_size (file);
385 
386  rtems_rfs_rtems_unlock (rtems_rfs_file_fs (file));
387
388  return rc;
389}
390
391/*
392 *  Set of operations handlers for operations on RFS files.
393 */
394
395const rtems_filesystem_file_handlers_r rtems_rfs_rtems_file_handlers = {
396  .open_h      = rtems_rfs_rtems_file_open,
397  .close_h     = rtems_rfs_rtems_file_close,
398  .read_h      = rtems_rfs_rtems_file_read,
399  .write_h     = rtems_rfs_rtems_file_write,
400  .ioctl_h     = rtems_rfs_rtems_file_ioctl,
401  .lseek_h     = rtems_rfs_rtems_file_lseek,
402  .fstat_h     = rtems_rfs_rtems_file_fstat,
403  .fchmod_h    = rtems_rfs_rtems_file_fchmod,
404  .ftruncate_h = rtems_rfs_rtems_file_ftruncate,
405  .fpathconf_h = rtems_filesystem_default_fpathconf,
406  .fsync_h     = rtems_rfs_rtems_fdatasync,
407  .fdatasync_h = rtems_rfs_rtems_fdatasync,
408  .fcntl_h     = rtems_filesystem_default_fcntl,
409  .rmnod_h     = rtems_rfs_rtems_rmnod
410};
Note: See TracBrowser for help on using the repository browser.