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

4.115
Last change on this file since ca8c50de was ca8c50de, checked in by Chris Johns <chrisj@…>, on Jun 17, 2010 at 10:00:47 PM

2010-06-18 Chris Johns <chrisj@…>

  • libfs/src/rfs/rtems-rfs-file-system.h, libfs/src/rfs/rtems-rfs-file-system.c: Move questionable macros to C functions.
  • Property mode set to 100644
File size: 8.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 File Systems Open
16 *
17 * Open the file system by reading the superblock and then the group data.
18 */
19
20#if HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <inttypes.h>
25
26#include <rtems/rfs/rtems-rfs-data.h>
27#include <rtems/rfs/rtems-rfs-file-system.h>
28#include <rtems/rfs/rtems-rfs-inode.h>
29#include <rtems/rfs/rtems-rfs-trace.h>
30
31uint64_t
32rtems_rfs_fs_size (rtems_rfs_file_system* fs)
33{
34  uint64_t blocks = rtems_rfs_fs_blocks (fs);
35  uint64_t block_size = rtems_rfs_fs_block_size (fs);
36  return blocks * block_size;
37}
38
39uint64_t
40rtems_rfs_fs_media_size (rtems_rfs_file_system* fs)
41{
42  uint64_t media_blocks = (uint64_t) rtems_rfs_fs_media_blocks (fs);
43  uint64_t media_block_size = (uint64_t) rtems_rfs_fs_media_block_size (fs);
44  return media_blocks * media_block_size;
45}
46
47static int
48rtems_rfs_fs_read_superblock (rtems_rfs_file_system* fs)
49{
50  rtems_rfs_buffer_handle handle;
51  uint8_t*                sb;
52  int                     group;
53  int                     rc;
54
55  rc = rtems_rfs_buffer_handle_open (fs, &handle);
56  if (rc > 0)
57  {
58    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
59      printf ("rtems-rfs: read-superblock: handle open failed: %d: %s\n",
60              rc, strerror (rc));
61    return rc;
62  }
63
64  rc = rtems_rfs_buffer_handle_request (fs, &handle, 0, true);
65  if (rc > 0)
66  {
67    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
68      printf ("rtems-rfs: read-superblock: request failed%d: %s\n",
69              rc, strerror (rc));
70    return rc;
71  }
72
73  sb = rtems_rfs_buffer_data (&handle);
74 
75#define read_sb(_o) rtems_rfs_read_u32 (sb + (_o))
76 
77  if (read_sb (RTEMS_RFS_SB_OFFSET_MAGIC) != RTEMS_RFS_SB_MAGIC)
78  {
79    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
80      printf ("rtems-rfs: read-superblock: invalid superblock, bad magic\n");
81    rtems_rfs_buffer_handle_close (fs, &handle);
82    return EIO;
83  }
84
85  fs->blocks     = read_sb (RTEMS_RFS_SB_OFFSET_BLOCKS);
86  fs->block_size = read_sb (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE);
87
88  if (rtems_rfs_fs_size(fs) > rtems_rfs_fs_media_size (fs))
89  {
90    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
91      printf ("rtems-rfs: read-superblock: invalid superblock block/size count\n");
92    rtems_rfs_buffer_handle_close (fs, &handle);
93    return EIO;
94  }
95
96  if ((read_sb (RTEMS_RFS_SB_OFFSET_VERSION) & RTEMS_RFS_VERSION_MASK) !=
97      (RTEMS_RFS_VERSION * RTEMS_RFS_VERSION_MASK))
98  {
99    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
100      printf ("rtems-rfs: read-superblock: incompatible version: %08" PRIx32 " (%08" PRIx32 ")\n",
101              read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
102    rtems_rfs_buffer_handle_close (fs, &handle);
103    return EIO;
104  }
105     
106  if (read_sb (RTEMS_RFS_SB_OFFSET_INODE_SIZE) != RTEMS_RFS_INODE_SIZE)
107  {
108    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
109      printf ("rtems-rfs: read-superblock: inode size mismatch: fs:%" PRId32 " target:%" PRId32 "\n",
110              read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
111    rtems_rfs_buffer_handle_close (fs, &handle);
112    return EIO;
113  }
114     
115  fs->bad_blocks      = read_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS);
116  fs->max_name_length = read_sb (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH);
117  fs->group_count     = read_sb (RTEMS_RFS_SB_OFFSET_GROUPS);
118  fs->group_blocks    = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS);
119  fs->group_inodes    = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES);
120
121  fs->blocks_per_block =
122    rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode_block);
123 
124  fs->block_map_singly_blocks =
125    fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
126  fs->block_map_doubly_blocks =
127    fs->blocks_per_block * fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
128
129  fs->inodes = fs->group_count * fs->group_inodes;
130
131  fs->inodes_per_block = fs->block_size / RTEMS_RFS_INODE_SIZE;
132 
133  if (fs->group_blocks >
134      rtems_rfs_bitmap_numof_bits (rtems_rfs_fs_block_size (fs)))
135  {
136    rtems_rfs_buffer_handle_close (fs, &handle);
137    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
138      printf ("rtems-rfs: read-superblock: groups blocks larger than block bits\n");
139    return EIO;
140  }
141
142  rtems_rfs_buffer_handle_close (fs, &handle);
143
144  /*
145   * Change the block size to the value in the superblock.
146   */
147  rc = rtems_rfs_buffer_setblksize (fs, rtems_rfs_fs_block_size (fs));
148  if (rc > 0)
149  {
150    rtems_rfs_buffer_handle_close (fs, &handle);
151    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
152      printf ("rtems-rfs: read-superblock: invalid superblock block size%d: %s\n",
153              rc, strerror (rc));
154    return rc;
155  }
156
157  fs->groups = calloc (fs->group_count, sizeof (rtems_rfs_group));
158
159  if (!fs->groups)
160  {
161    rtems_rfs_buffer_handle_close (fs, &handle);
162    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
163      printf ("rtems-rfs: read-superblock: no memory for group table\n");
164    return ENOMEM;
165  }
166
167  /*
168   * Perform each phase of group initialisation at the same time. This way we
169   * know how far the initialisation has gone if an error occurs and we need to
170   * close everything.
171   */
172  for (group = 0; group < fs->group_count; group++)
173  {
174    rc = rtems_rfs_group_open (fs,
175                               rtems_rfs_fs_block (fs, group, 0),
176                               fs->group_blocks,
177                               fs->group_inodes,
178                               &fs->groups[group]);
179    if (rc > 0)
180    {
181      int g;
182      for (g = 0; g < group; g++)
183        rtems_rfs_group_close (fs, &fs->groups[g]);
184      rtems_rfs_buffer_handle_close (fs, &handle);
185      if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
186        printf ("rtems-rfs: read-superblock: no memory for group table%d: %s\n",
187                rc, strerror (rc));
188      return rc;
189    }
190  }
191
192  return 0;
193}
194
195int
196rtems_rfs_fs_open (const char*             name,
197                   void*                   user,
198                   uint32_t                flags,
199                   rtems_rfs_file_system** fs)
200{
201  rtems_rfs_group*       group;
202  size_t                 group_base;
203  rtems_rfs_inode_handle inode;
204  uint16_t               mode;
205  int                    rc;
206 
207  if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
208    printf ("rtems-rfs: open: %s\n", name);
209 
210  *fs = malloc (sizeof (rtems_rfs_file_system));
211  if (!*fs)
212  {
213    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
214      printf ("rtems-rfs: open: no memory for file system data\n");
215    errno = ENOMEM;
216    return -1;
217  }
218
219  memset (*fs, 0, sizeof (rtems_rfs_file_system));
220
221  (*fs)->user = user;
222  rtems_chain_initialize_empty (&(*fs)->buffers);
223  rtems_chain_initialize_empty (&(*fs)->release);
224  rtems_chain_initialize_empty (&(*fs)->release_modified);
225  rtems_chain_initialize_empty (&(*fs)->file_shares);
226
227  (*fs)->max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS;
228  (*fs)->buffers_count = 0;
229  (*fs)->release_count = 0;
230  (*fs)->release_modified_count = 0;
231  (*fs)->flags = flags;
232
233  group = &(*fs)->groups[0];
234  group_base = 0;
235
236  /*
237   * Open the buffer interface.
238   */
239  rc = rtems_rfs_buffer_open (name, *fs);
240  if (rc > 0)
241  {
242    free (*fs);
243    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
244      printf ("rtems-rfs: open: buffer open failed: %d: %s\n",
245              rc, strerror (rc));
246    errno = rc;
247    return -1;
248  }
249
250  rc = rtems_rfs_fs_read_superblock (*fs);
251  if (rc > 0)
252  {
253    rtems_rfs_buffer_close (*fs);
254    free (*fs);
255    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
256      printf ("rtems-rfs: open: reading superblock: %d: %s\n",
257              rc, strerror (rc));
258    errno = rc;
259    return -1;
260  }
261
262  rc = rtems_rfs_inode_open (*fs, RTEMS_RFS_ROOT_INO, &inode, true);
263  if (rc > 0)
264  {
265    rtems_rfs_buffer_close (*fs);
266    free (*fs);
267    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
268      printf ("rtems-rfs: open: reading root inode: %d: %s\n",
269              rc, strerror (rc));
270    errno = rc;
271    return -1;
272  }
273
274  if (((*fs)->flags & RTEMS_RFS_FS_FORCE_OPEN) == 0)
275  {
276    mode = rtems_rfs_inode_get_mode (&inode);
277
278    if ((mode == 0xffff) || !RTEMS_RFS_S_ISDIR (mode))
279    {
280      rtems_rfs_inode_close (*fs, &inode);
281      rtems_rfs_buffer_close (*fs);
282      free (*fs);
283      if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
284        printf ("rtems-rfs: open: invalid root inode mode\n");
285      errno = EIO;
286      return -1;
287    }
288  }
289 
290  rc = rtems_rfs_inode_close (*fs, &inode);
291  if (rc > 0)
292  {
293    rtems_rfs_buffer_close (*fs);
294    free (*fs);
295    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
296      printf ("rtems-rfs: open: closing root inode: %d: %s\n", rc, strerror (rc));
297    errno = rc;
298    return -1;
299  }
300   
301  errno = 0;
302  return 0;
303}
304
305int
306rtems_rfs_fs_close (rtems_rfs_file_system* fs)
307{
308  int group;
309 
310  if (rtems_rfs_trace (RTEMS_RFS_TRACE_CLOSE))
311    printf ("rtems-rfs: close\n");
312
313  for (group = 0; group < fs->group_count; group++)
314    rtems_rfs_group_close (fs, &fs->groups[group]);
315
316  rtems_rfs_buffer_close (fs);
317 
318  free (fs);
319  return 0; 
320}
Note: See TracBrowser for help on using the repository browser.