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

4.104.11
Last change on this file since 1d539c0 was 1d539c0, checked in by Chris Johns <chrisj@…>, on Apr 12, 2010 at 5:29:25 AM

2010-04-12 Chris Johns <chrisj@…>

libfs/src/rfs/rtems-rfs-buffer-bdbuf.c,
libfs/src/rfs/rtems-rfs-buffer.c, libfs/src/rfs/rtems-rfs-data.h,
libfs/src/rfs/rtems-rfs-dir.c,
libfs/src/rfs/rtems-rfs-file-system.c,
libfs/src/rfs/rtems-rfs-format.c, libfs/src/rfs/rtems-rfs-inode.h,
libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-rtems.h,
libfs/src/rfs/rtems-rfs-shell.c: Fix for PR1502. Clean up problems
on 16bit targets.

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