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

4.104.11
Last change on this file since 3cfa636 was 3cfa636, checked in by Chris Johns <chrisj@…>, on Feb 26, 2010 at 5:54:59 AM

010-02-26 Chris Johns <chrisj@…>

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