source: rtems/cpukit/libfs/src/rfs/rtems-rfs-rtems-dir.c @ 355b0544

4.104.115
Last change on this file since 355b0544 was 355b0544, checked in by Chris Johns <chrisj@…>, on 03/27/10 at 04:04:40

2010-03-27 Chris Johns <chrisj@…>

libfs/src/nfsclient/src/cexphelp.c,
libfs/src/nfsclient/src/dirutils.c,
libfs/src/nfsclient/src/nfs.modini.c,
libfs/src/nfsclient/src/nfsTest.c,
libfs/src/nfsclient/src/rpcio.c,
libfs/src/nfsclient/src/rpcio.modini.c,
libfs/src/nfsclient/src/sock_mbuf.c,
libfs/src/nfsclient/src/xdr_mbuf.c,
libfs/src/rfs/rtems-rfs-bitmaps-ut.c,
libfs/src/rfs/rtems-rfs-bitmaps.c,
libfs/src/rfs/rtems-rfs-block.c,
libfs/src/rfs/rtems-rfs-buffer-bdbuf.c,
libfs/src/rfs/rtems-rfs-buffer-devio.c,
libfs/src/rfs/rtems-rfs-buffer.c,
libfs/src/rfs/rtems-rfs-dir-hash.c, libfs/src/rfs/rtems-rfs-dir.c,
libfs/src/rfs/rtems-rfs-file-system.c,
libfs/src/rfs/rtems-rfs-file.c, libfs/src/rfs/rtems-rfs-format.c,
libfs/src/rfs/rtems-rfs-group.c, libfs/src/rfs/rtems-rfs-inode.c,
libfs/src/rfs/rtems-rfs-link.c, libfs/src/rfs/rtems-rfs-mutex.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,
libfs/src/rfs/rtems-rfs-rtems-utils.c,
libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-shell.c,
libfs/src/rfs/rtems-rfs-trace.c: Add HAVE_CONFIG_H support to let
files receive configure defines.

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