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

5
Last change on this file since 0ec9bbc was d8ec270b, checked in by Sebastian Huber <sebastian.huber@…>, on 04/07/16 at 08:29:09

libblock: Drop superfluous <stdlib.h> include

Drop superfluous <stdlib.h> include from <rtems/diskdevs.h> since this
leads to conflicts with the latest Newlib in case this header file is
used in the FreeBSD kernel space, e.g. for USB mass storage support.

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