source: rtems/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c @ 984c4c49

4.11
Last change on this file since 984c4c49 was 984c4c49, checked in by Ralf Corsepius <ralf.corsepius@…>, on Nov 6, 2011 at 12:00:04 PM

2011-11-06 Ralf Corsépius <ralf.corsepius@…>

PR1945/cpukit

  • libfs/src/nfsclient/src/nfs.c, libfs/src/rfs/rtems-rfs-rtems-dev.c, libfs/src/rfs/rtems-rfs-rtems-dir.c, libfs/src/rfs/rtems-rfs-rtems-file.c, libnetworking/lib/ftpfs.c, libnetworking/lib/tftpDriver.c: Replace rtems_off64_t with off_t.
  • Property mode set to 100644
File size: 7.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 Directory Access Routines
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <inttypes.h>
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <unistd.h>
30
31#include <rtems/rfs/rtems-rfs-dir.h>
32#include <rtems/rfs/rtems-rfs-link.h>
33#include "rtems-rfs-rtems.h"
34
35/**
36 * This rountine will verify that the node being opened as a directory is in
37 * fact a directory node. If it is then the offset into the directory will be
38 * set to 0 to position to the first directory entry.
39 *
40 * @param iop
41 * @param pathname
42 * @param flag
43 * @param mode
44 * @@return int
45 */
46static int
47rtems_rfs_rtems_dir_open (rtems_libio_t* iop,
48                          const char*    pathname,
49                          uint32_t       flag,
50                          uint32_t       mode)
51{
52  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
53  rtems_rfs_ino          ino = rtems_rfs_rtems_get_iop_ino (iop);
54  rtems_rfs_inode_handle inode;
55  int                    rc;
56
57  rtems_rfs_rtems_lock (fs);
58 
59  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
60  if (rc)
61  {
62    rtems_rfs_rtems_unlock (fs);
63    return rtems_rfs_rtems_error ("dir_open: opening inode", rc);
64  }
65 
66  if (!RTEMS_RFS_S_ISDIR (rtems_rfs_inode_get_mode (&inode)))
67  {
68    rtems_rfs_inode_close (fs, &inode);
69    rtems_rfs_rtems_unlock (fs);
70    return rtems_rfs_rtems_error ("dir_open: not dir", ENOTDIR);
71  }
72   
73  iop->offset = 0;
74
75  rtems_rfs_inode_close (fs, &inode);
76  rtems_rfs_rtems_unlock (fs);
77  return 0;
78}
79
80/**
81 * This routine will be called by the generic close routine to cleanup any
82 * resources that have been allocated for the management of the file
83 *
84 * @param iop
85 * @retval 0 Always no error.
86 */
87static int
88rtems_rfs_rtems_dir_close (rtems_libio_t* iop)
89{
90  /*
91   * The RFS does not hold any resources. Nothing to do.
92   */
93  return 0;
94}
95
96/**
97 * This routine will read the next directory entry based on the directory
98 * offset. The offset should be equal to -n- time the size of an individual
99 * dirent structure. If n is not an integer multiple of the sizeof a dirent
100 * structure, an integer division will be performed to determine directory
101 * entry that will be returned in the buffer. Count should reflect -m- times
102 * the sizeof dirent bytes to be placed in the buffer.  If there are not -m-
103 * dirent elements from the current directory position to the end of the
104 * exisiting file, the remaining entries will be placed in the buffer and the
105 * returned value will be equal to -m actual- times the size of a directory
106 * entry.
107 */
108static ssize_t
109rtems_rfs_rtems_dir_read (rtems_libio_t* iop,
110                          void*          buffer,
111                          size_t         count)
112{
113  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (&iop->pathinfo);
114  rtems_rfs_ino          ino = rtems_rfs_rtems_get_iop_ino (iop);
115  rtems_rfs_inode_handle inode;
116  struct dirent*         dirent;
117  ssize_t                bytes_transferred;
118  int                    d;
119  int                    rc;
120
121  count  = count / sizeof (struct dirent);
122  dirent = buffer;
123 
124  rtems_rfs_rtems_lock (fs);
125 
126  rc = rtems_rfs_inode_open (fs, ino, &inode, true);
127  if (rc)
128  {
129    rtems_rfs_rtems_unlock (fs);
130    return rtems_rfs_rtems_error ("dir_read: read inode", rc);
131  }
132
133  bytes_transferred = 0;
134 
135  for (d = 0; d < count; d++, dirent++)
136  {
137    size_t size;
138    rc = rtems_rfs_dir_read (fs, &inode, iop->offset, dirent, &size);
139    if (rc == ENOENT)
140    {
141      rc = 0;
142      break;
143    }
144    if (rc > 0)
145    {
146      bytes_transferred = rtems_rfs_rtems_error ("dir_read: dir read", rc);
147      break;
148    }
149    iop->offset += size;
150    bytes_transferred += sizeof (struct dirent);
151  }
152
153  rtems_rfs_inode_close (fs, &inode);
154  rtems_rfs_rtems_unlock (fs);
155 
156  return bytes_transferred;
157}
158
159/**
160 * This routine will behave in one of three ways based on the state of argument
161 * whence. Based on the state of its value the offset argument will be
162 * interpreted using one of the following methods:
163 *
164 *   SEEK_SET - offset is the absolute byte offset from the start of the
165 *              logical start of the dirent sequence that represents the
166 *              directory
167 *   SEEK_CUR - offset is used as the relative byte offset from the current
168 *              directory position index held in the iop structure
169 *   SEEK_END - N/A --> This will cause an assert.
170 *
171 * @param iop
172 * @param offset
173 * @param whence
174 * return off_t       
175 */
176static off_t       
177rtems_rfs_rtems_dir_lseek (rtems_libio_t* iop,
178                           off_t          offset,
179                           int            whence)
180{
181  switch (whence)
182  {
183    case SEEK_SET:   /* absolute move from the start of the file */
184    case SEEK_CUR:   /* relative move */
185      break;
186
187     case SEEK_END:   /* Movement past the end of the directory via lseek */
188                      /* is not a permitted operation                     */
189    default:
190      return rtems_rfs_rtems_error ("dir_lseek: bad whence", EINVAL);
191      break;
192  }
193  return 0;
194}
195
196static int
197rtems_rfs_rtems_dir_rmnod (rtems_filesystem_location_info_t* parent_pathloc,
198                           rtems_filesystem_location_info_t* pathloc)
199{
200  rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc);
201  rtems_rfs_ino          parent = rtems_rfs_rtems_get_pathloc_ino (parent_pathloc);
202  rtems_rfs_ino          ino = rtems_rfs_rtems_get_pathloc_ino (pathloc);
203  uint32_t               doff = rtems_rfs_rtems_get_pathloc_doff (pathloc);
204  int                    rc;
205
206  if (rtems_rfs_rtems_trace (RTEMS_RFS_RTEMS_DEBUG_DIR_RMNOD))
207    printf ("rtems-rfs: dir-rmnod: parent:%" PRId32 " doff:%" PRIu32 ", ino:%" PRId32 "\n",
208            parent, doff, ino);
209
210  if (ino == RTEMS_RFS_ROOT_INO)
211    return rtems_rfs_rtems_error ("dir_rmnod: root inode", EBUSY);
212
213  rtems_rfs_rtems_lock (fs);
214 
215  rc = rtems_rfs_unlink (fs, parent, ino, doff, rtems_rfs_unlink_dir_if_empty);
216  if (rc)
217  {
218    rtems_rfs_rtems_unlock (fs);
219    return rtems_rfs_rtems_error ("dir_rmnod: unlinking", rc);
220  }
221
222  rtems_rfs_rtems_unlock (fs);
223  return 0;
224}
225
226/*
227 *  Set of operations handlers for operations on directories.
228 */
229
230const rtems_filesystem_file_handlers_r rtems_rfs_rtems_dir_handlers = {
231  .open_h      = rtems_rfs_rtems_dir_open,
232  .close_h     = rtems_rfs_rtems_dir_close,
233  .read_h      = rtems_rfs_rtems_dir_read,
234  .write_h     = rtems_filesystem_default_write,
235  .ioctl_h     = rtems_filesystem_default_ioctl,
236  .lseek_h     = rtems_rfs_rtems_dir_lseek,
237  .fstat_h     = rtems_rfs_rtems_fstat,
238  .fchmod_h    = rtems_rfs_rtems_fchmod,
239  .ftruncate_h = rtems_filesystem_default_ftruncate,
240  .fpathconf_h = rtems_filesystem_default_fpathconf,
241  .fsync_h     = rtems_filesystem_default_fsync,
242  .fdatasync_h = rtems_rfs_rtems_fdatasync,
243  .fcntl_h     = rtems_filesystem_default_fcntl,
244  .rmnod_h     = rtems_rfs_rtems_dir_rmnod
245};
Note: See TracBrowser for help on using the repository browser.