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

4.104.11
Last change on this file since a9fa9b7 was a9fa9b7, checked in by Chris Johns <chrisj@…>, on Feb 18, 2010 at 12:24:25 AM

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

  • libfs/src/rfs/rtems-rfs-bitmaps.c, libfs/src/rfs/rtems-rfs-bitmaps.h, libfs/src/rfs/rtems-rfs-bitmaps-ut.c, libfs/src/rfs/rtems-rfs-block.c, libfs/src/rfs/rtems-rfs-block.h, libfs/src/rfs/rtems-rfs-block-pos.h, libfs/src/rfs/rtems-rfs-buffer-bdbuf.c, libfs/src/rfs/rtems-rfs-buffer.c, libfs/src/rfs/rtems-rfs-buffer-devio.c, libfs/src/rfs/rtems-rfs-buffer.h, libfs/src/rfs/rtems-rfs-data.h, libfs/src/rfs/rtems-rfs-dir.c, libfs/src/rfs/rtems-rfs-dir.h, libfs/src/rfs/rtems-rfs-dir-hash.c, libfs/src/rfs/rtems-rfs-dir-hash.h, libfs/src/rfs/rtems-rfs-file.c, libfs/src/rfs/rtems-rfs-file.h, libfs/src/rfs/rtems-rfs-file-system.c, libfs/src/rfs/rtems-rfs-file-system-fwd.h, libfs/src/rfs/rtems-rfs-file-system.h, libfs/src/rfs/rtems-rfs-format.c, libfs/src/rfs/rtems-rfs-format.h, libfs/src/rfs/rtems-rfs-group.c, libfs/src/rfs/rtems-rfs-group.h, libfs/src/rfs/rtems-rfs.h, libfs/src/rfs/rtems-rfs-inode.c, libfs/src/rfs/rtems-rfs-inode.h, libfs/src/rfs/rtems-rfs-link.c, libfs/src/rfs/rtems-rfs-link.h, libfs/src/rfs/rtems-rfs-mutex.c, libfs/src/rfs/rtems-rfs-mutex.h, libfs/src/rfs/rtems-rfs-rtems.c, libfs/src/rfs/rtems-rfs-rtems-dev.c, libfs/src/rfs/rtems-rfs-rtems-dir.c, libfs/src/rfs/rtems-rfs-rtems-file.c, libfs/src/rfs/rtems-rfs-rtems.h, libfs/src/rfs/rtems-rfs-rtems-utils.c, libfs/src/rfs/rtems-rfs-shell.c, libfs/src/rfs/rtems-rfs-shell.h, libfs/src/rfs/rtems-rfs-trace.c, libfs/src/rfs/rtems-rfs-trace.h: New.
  • Makefile.am, preinstall.am, libfs/Makefile.am, wrapup/Makefile.am: Updated with the RFS support.
  • libfs/README: Updated after 10 years.
  • libblock/src/flashdisk.c, libblock/src/nvdisk.c, libblock/src/ramdisk-driver.c: Updated to the new error reporting in libblock.
  • libmisc/shell/main_ls.c, libmisc/shell/print-ls.c: Fix printing the size in long mode.
  • libnetworking/nfs/bootp_subr.c, libnetworking/rtems/rtems_bootp.c, libnetworking/rtems/rtems_bsdnet_internal.h: Return the BOOTP/DHCP to the forever behaviour of 4.9 with the ability to call BOOTP and control the process if required.
  • Property mode set to 100644
File size: 7.6 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    rtems_rfs_buffer_handle_close (fs, &handle);
58    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
59      printf ("rtems-rfs: read-superblock: invalid superblock, bad magic\n");
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    rtems_rfs_buffer_handle_close (fs, &handle);
69    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
70      printf ("rtems-rfs: read-superblock: invalid superblock block/size count\n");
71    return EIO;
72  }
73
74  fs->bad_blocks      = read_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS);
75  fs->max_name_length = read_sb (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH);
76  fs->group_count     = read_sb (RTEMS_RFS_SB_OFFSET_GROUPS);
77  fs->group_blocks    = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS);
78  fs->group_inodes    = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES);
79
80  fs->blocks_per_block = rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode_block);
81 
82  fs->block_map_singly_blocks =
83    fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
84  fs->block_map_doubly_blocks =
85    fs->blocks_per_block * fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
86
87  fs->inodes = fs->group_count * fs->group_inodes;
88
89  fs->inodes_per_block = fs->block_size / sizeof (rtems_rfs_inode);
90 
91  if (fs->group_blocks >
92      rtems_rfs_bitmap_numof_bits (rtems_rfs_fs_block_size (fs)))
93  {
94    rtems_rfs_buffer_handle_close (fs, &handle);
95    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
96      printf ("rtems-rfs: read-superblock: groups blocks larger than block bits\n");
97    return EIO;
98  }
99
100  rtems_rfs_buffer_handle_close (fs, &handle);
101
102  /*
103   * Change the block size to the value in the superblock.
104   */
105  rc = rtems_rfs_buffer_setblksize (fs, rtems_rfs_fs_block_size (fs));
106  if (rc > 0)
107  {
108    rtems_rfs_buffer_handle_close (fs, &handle);
109    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
110      printf ("rtems-rfs: read-superblock: invalid superblock block size%d: %s\n",
111              rc, strerror (rc));
112    return rc;
113  }
114
115  fs->groups = calloc (fs->group_count, sizeof (rtems_rfs_group));
116
117  if (!fs->groups)
118  {
119    rtems_rfs_buffer_handle_close (fs, &handle);
120    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
121      printf ("rtems-rfs: read-superblock: no memory for group table\n");
122    return ENOMEM;
123  }
124
125  /*
126   * Perform each phase of group initialisation at the same time. This way we
127   * know how far the initialisation has gone if an error occurs and we need to
128   * close everything.
129   */
130  for (group = 0; group < fs->group_count; group++)
131  {
132    rc = rtems_rfs_group_open (fs,
133                               rtems_rfs_fs_block (fs, group, 0),
134                               fs->group_blocks,
135                               fs->group_inodes,
136                               &fs->groups[group]);
137    if (rc > 0)
138    {
139      int g;
140      for (g = 0; g < group; g++)
141        rtems_rfs_group_close (fs, &fs->groups[g]);
142      rtems_rfs_buffer_handle_close (fs, &handle);
143      if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
144        printf ("rtems-rfs: read-superblock: no memory for group table%d: %s\n",
145                rc, strerror (rc));
146      return rc;
147    }
148  }
149
150  return 0;
151}
152
153int
154rtems_rfs_fs_open (const char*             name,
155                   void*                   user,
156                   uint32_t                flags,
157                   rtems_rfs_file_system** fs)
158{
159  rtems_rfs_group*       group;
160  size_t                 group_base;
161  rtems_rfs_inode_handle inode;
162  uint16_t               mode;
163  int                    rc;
164 
165  if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
166    printf ("rtems-rfs: open: %s\n", name);
167 
168  *fs = malloc (sizeof (rtems_rfs_file_system));
169  if (!*fs)
170  {
171    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
172      printf ("rtems-rfs: open: no memory for file system data\n");
173    errno = ENOMEM;
174    return -1;
175  }
176
177  memset (*fs, 0, sizeof (rtems_rfs_file_system));
178
179  (*fs)->user = user;
180  rtems_chain_initialize_empty (&(*fs)->buffers);
181  rtems_chain_initialize_empty (&(*fs)->release);
182  rtems_chain_initialize_empty (&(*fs)->release_modified);
183  rtems_chain_initialize_empty (&(*fs)->file_shares);
184
185  (*fs)->max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS;
186  (*fs)->buffers_count = 0;
187  (*fs)->release_count = 0;
188  (*fs)->release_modified_count = 0;
189  (*fs)->flags = flags;
190
191  group = &(*fs)->groups[0];
192  group_base = 0;
193
194  /*
195   * Open the buffer interface.
196   */
197  rc = rtems_rfs_buffer_open (name, *fs);
198  if (rc > 0)
199  {
200    free (*fs);
201    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
202      printf ("rtems-rfs: open: buffer open failed: %d: %s\n",
203              rc, strerror (rc));
204    errno = rc;
205    return -1;
206  }
207
208  rc = rtems_rfs_fs_read_superblock (*fs);
209  if (rc > 0)
210  {
211    rtems_rfs_buffer_close (*fs);
212    free (*fs);
213    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
214      printf ("rtems-rfs: open: reading superblock: %d: %s\n",
215              rc, strerror (rc));
216    errno = rc;
217    return -1;
218  }
219
220  rc = rtems_rfs_inode_open (*fs, RTEMS_RFS_ROOT_INO, &inode, true);
221  if (rc > 0)
222  {
223    rtems_rfs_buffer_close (*fs);
224    free (*fs);
225    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
226      printf ("rtems-rfs: open: reading root inode: %d: %s\n",
227              rc, strerror (rc));
228    errno = rc;
229    return -1;
230  }
231
232  if (((*fs)->flags & RTEMS_RFS_FS_FORCE_OPEN) == 0)
233  {
234    mode = rtems_rfs_inode_get_mode (&inode);
235
236    if ((mode == 0xffff) || !RTEMS_RFS_S_ISDIR (mode))
237    {
238      rtems_rfs_inode_close (*fs, &inode);
239      rtems_rfs_buffer_close (*fs);
240      free (*fs);
241      if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
242        printf ("rtems-rfs: open: invalid root inode mode\n");
243      errno = EIO;
244      return -1;
245    }
246  }
247 
248  rc = rtems_rfs_inode_close (*fs, &inode);
249  if (rc > 0)
250  {
251    rtems_rfs_buffer_close (*fs);
252    free (*fs);
253    if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
254      printf ("rtems-rfs: open: closing root inode: %d: %s\n", rc, strerror (rc));
255    errno = rc;
256    return -1;
257  }
258   
259  errno = 0;
260  return 0;
261}
262
263int
264rtems_rfs_fs_close (rtems_rfs_file_system* fs)
265{
266  int group;
267 
268  if (rtems_rfs_trace (RTEMS_RFS_TRACE_CLOSE))
269    printf ("rtems-rfs: close\n");
270
271  for (group = 0; group < fs->group_count; group++)
272    rtems_rfs_group_close (fs, &fs->groups[group]);
273
274  rtems_rfs_buffer_close (fs);
275 
276  free (fs);
277  return 0; 
278}
Note: See TracBrowser for help on using the repository browser.