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

4.115
Last change on this file since 36f3207 was 36f3207, checked in by Alex Ivanov <alexivanov97@…>, on 12/28/12 at 13:49:39

libfs: Doxygen Enhancement Task #3

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