source: rtems/cpukit/libfs/src/rfs/rtems-rfs-group.c @ 87ff365

4.115
Last change on this file since 87ff365 was 87ff365, checked in by Ralf Corsepius <ralf.corsepius@…>, on 06/17/10 at 02:44:49

2010-06-17 Ralf Corsépius <ralf.corsepius@…>

  • libfs/src/rfs/rtems-rfs-group.c: Various 64bit fixes.
  • Property mode set to 100644
File size: 9.5 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 Group Routines.
16 *
17 * These functions open and close a group as well as manage bit allocations
18 * within a group.
19 */
20
21#if HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <inttypes.h>
26
27#include <rtems/rfs/rtems-rfs-file-system.h>
28#include <rtems/rfs/rtems-rfs-group.h>
29
30int
31rtems_rfs_group_open (rtems_rfs_file_system* fs,
32                      rtems_rfs_buffer_block base,
33                      size_t                 size,
34                      size_t                 inodes,
35                      rtems_rfs_group*       group)
36{
37  int rc;
38 
39  if (base >= rtems_rfs_fs_blocks (fs))
40  {
41    if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
42      printf ("rtems-rfs: group-open: base outside file system range: %d: %s\n",
43              EIO, strerror (EIO));
44    return EIO;
45  }
46
47  if ((base + size) >= rtems_rfs_fs_blocks (fs))
48    size = rtems_rfs_fs_blocks (fs) - base;
49 
50  if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
51    printf ("rtems-rfs: group-open: base=%" PRId32 ", blocks=%zd inodes=%zd\n",
52            base, size, inodes);
53
54  group->base = base;
55  group->size = size;
56 
57  rc = rtems_rfs_buffer_handle_open (fs, &group->block_bitmap_buffer); 
58  if (rc > 0)
59  {
60    if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
61      printf ("rtems-rfs: group-open: could not open block bitmap handle: %d: %s\n",
62              rc, strerror (rc));
63    return rc;
64  }
65
66  rc = rtems_rfs_bitmap_open (&group->block_bitmap, fs,
67                              &group->block_bitmap_buffer, size,
68                              group->base + RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK);
69  if (rc > 0)
70  {
71    rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
72    if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
73      printf ("rtems-rfs: group-open: could not open block bitmap: %d: %s\n",
74              rc, strerror (rc));
75    return rc;
76  }
77
78  rc = rtems_rfs_buffer_handle_open (fs, &group->inode_bitmap_buffer);
79  if (rc > 0)
80  {
81    rtems_rfs_bitmap_close (&group->block_bitmap);
82    rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
83    if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
84      printf ("rtems-rfs: group-open: could not open inode bitmap handle: %d: %s\n",
85              rc, strerror (rc));
86    return rc;
87  }
88
89  rc = rtems_rfs_bitmap_open (&group->inode_bitmap, fs,
90                              &group->inode_bitmap_buffer, inodes,
91                              group->base + RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK);
92  if (rc > 0)
93  {
94    rtems_rfs_buffer_handle_close (fs, &group->inode_bitmap_buffer);
95    rtems_rfs_bitmap_close (&group->block_bitmap);
96    rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
97    if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
98      printf ("rtems-rfs: group-open: could not open inode bitmap: %d: %s\n",
99              rc, strerror (rc));
100    return rc;
101  }
102
103  if (rtems_rfs_fs_release_bitmaps (fs))
104  {
105    rtems_rfs_bitmap_release_buffer (fs, &group->block_bitmap);
106    rtems_rfs_bitmap_release_buffer (fs, &group->inode_bitmap);
107  }
108 
109  return 0;
110}
111
112int
113rtems_rfs_group_close (rtems_rfs_file_system* fs, rtems_rfs_group* group)
114{
115  int result = 0;
116  int rc;
117
118  if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_CLOSE))
119    printf ("rtems-rfs: group-close: base=%" PRId32 "\n", group->base);
120
121  /*
122   * We need to close as much as possible and also return any error if one
123   * occurs but this may result in one even more important error being lost but
124   * we cannot OR the errors together so this is a reasonable compromise.
125   */
126  rc = rtems_rfs_bitmap_close (&group->inode_bitmap);
127  if (rc > 0)
128    result = rc;
129  rc = rtems_rfs_buffer_handle_close (fs, &group->inode_bitmap_buffer);
130  if (rc > 0)
131    result = rc;
132  rc = rtems_rfs_bitmap_close (&group->block_bitmap);
133  if (rc > 0)
134    result = rc;
135  rc = rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
136  if (rc > 0)
137    result = rc;
138 
139  return result;
140}
141
142int
143rtems_rfs_group_bitmap_alloc (rtems_rfs_file_system* fs,
144                              rtems_rfs_bitmap_bit   goal,
145                              bool                   inode,
146                              rtems_rfs_bitmap_bit*  result)
147{
148  int                  group_start;
149  size_t               size;
150  rtems_rfs_bitmap_bit bit;
151  int                  offset;
152  bool                 updown;
153  int                  direction;
154
155  if (inode)
156  {
157    size = fs->group_inodes;
158    goal -= RTEMS_RFS_ROOT_INO;
159  }
160  else
161    size = fs->group_blocks;
162   
163  group_start = goal / size;
164  bit = (rtems_rfs_bitmap_bit) (goal % size);
165  offset = 0;
166  updown = true;
167  direction = 1;
168     
169  /*
170   * Try the goal group first and if that group fails try the groups either
171   * side until the whole file system has be tried.
172   */
173  while (true)
174  {
175    rtems_rfs_bitmap_control* bitmap;
176    int                       group;
177    bool                      allocated = false;
178    int                       rc;
179
180    /*
181     * We can start at any location and we move out from that point in each
182     * direction. The offset grows until we find a free bit or we hit an end.
183     */
184    group = group_start + (direction * offset);
185    if (offset)
186      bit = direction > 0 ? 0 : size - 1;
187   
188    /*
189     * If we are still looking up and down and if the group is out of range we
190     * have reached one end. Stopping looking up and down and just move in the
191     * one direction one group at a time.
192     */
193    if ((group < 0) || (group >= fs->group_count))
194    {
195      if (!updown)
196        break;
197      direction = direction > 0 ? -1 : 1;
198      updown = false;
199      continue;
200    }
201
202   if (inode)
203      bitmap = &fs->groups[group].inode_bitmap;
204    else
205      bitmap = &fs->groups[group].block_bitmap;
206   
207    rc = rtems_rfs_bitmap_map_alloc (bitmap, bit, &allocated, &bit);
208    if (rc > 0)
209      return rc;
210   
211    if (rtems_rfs_fs_release_bitmaps (fs))
212      rtems_rfs_bitmap_release_buffer (fs, bitmap);
213     
214    if (allocated)
215    {
216      if (inode)
217        *result = rtems_rfs_group_inode (fs, group, bit);
218      else
219        *result = rtems_rfs_group_block (&fs->groups[group], bit);
220      if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
221        printf ("rtems-rfs: group-bitmap-alloc: %s allocated: %" PRId32 "\n",
222                inode ? "inode" : "block", *result);
223      return 0;
224    }
225
226    if (updown)
227      direction = direction > 0 ? -1 : 1;
228
229    offset++;
230  }
231 
232  if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
233    printf ("rtems-rfs: group-bitmap-alloc: no blocks available\n");
234
235  return ENOSPC;
236}
237
238int
239rtems_rfs_group_bitmap_free (rtems_rfs_file_system* fs,
240                             bool                   inode,
241                             rtems_rfs_bitmap_bit   no)
242{
243  rtems_rfs_bitmap_control* bitmap;
244  unsigned int              group;
245  rtems_rfs_bitmap_bit      bit;
246  size_t                    size;
247  int                       rc;
248
249  if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
250    printf ("rtems-rfs: group-bitmap-free: %s free: %" PRId32 "\n",
251            inode ? "inode" : "block", no);
252
253  if (inode)
254  {
255    no -= RTEMS_RFS_ROOT_INO;
256    size = fs->group_inodes;
257  }   
258  else
259  {
260    no -= RTEMS_RFS_SUPERBLOCK_SIZE;
261    size = fs->group_blocks;
262  }
263 
264  group = no / size;
265  bit = (rtems_rfs_bitmap_bit) (no % size);
266 
267  if (inode)
268    bitmap = &fs->groups[group].inode_bitmap;
269  else
270    bitmap = &fs->groups[group].block_bitmap;
271
272  rc = rtems_rfs_bitmap_map_clear (bitmap, bit);
273 
274  rtems_rfs_bitmap_release_buffer (fs, bitmap);
275 
276  return rc;
277}
278
279int
280rtems_rfs_group_bitmap_test (rtems_rfs_file_system* fs,
281                             bool                   inode,
282                             rtems_rfs_bitmap_bit   no,
283                             bool*                  state)
284{
285  rtems_rfs_bitmap_control* bitmap;
286  unsigned int              group;
287  rtems_rfs_bitmap_bit      bit;
288  size_t                    size;
289  int                       rc;
290
291  if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
292    printf ("rtems-rfs: group-bitmap-test: %s test: %" PRId32 "\n",
293            inode ? "inode" : "block", no);
294
295  if (inode)
296  {
297    if ((no < RTEMS_RFS_ROOT_INO) || (no > rtems_rfs_fs_inodes (fs)))
298        return EINVAL;
299    no -= RTEMS_RFS_ROOT_INO;
300    size = fs->group_inodes;
301  }   
302  else
303  {
304    if (no >= rtems_rfs_fs_blocks (fs))
305        return EINVAL;
306    size = fs->group_blocks;
307  }
308 
309  group = no / size;
310  bit = (rtems_rfs_bitmap_bit) (no % size);
311 
312  if (inode)
313    bitmap = &fs->groups[group].inode_bitmap;
314  else
315    bitmap = &fs->groups[group].block_bitmap;
316
317  rc = rtems_rfs_bitmap_map_test (bitmap, bit, state);
318 
319  rtems_rfs_bitmap_release_buffer (fs, bitmap);
320 
321  return rc;
322}
323
324int
325rtems_rfs_group_usage (rtems_rfs_file_system* fs,
326                       size_t*                blocks,
327                       size_t*                inodes)
328{
329  int g;
330 
331  *blocks = 0;
332  *inodes = 0;
333 
334  for (g = 0; g < fs->group_count; g++)
335  {
336    rtems_rfs_group* group = &fs->groups[g];
337    *blocks +=
338      rtems_rfs_bitmap_map_size(&group->block_bitmap) -
339      rtems_rfs_bitmap_map_free (&group->block_bitmap);
340    *inodes +=
341      rtems_rfs_bitmap_map_size (&group->inode_bitmap) -
342      rtems_rfs_bitmap_map_free (&group->inode_bitmap);
343  }
344
345  if (*blocks > rtems_rfs_fs_blocks (fs))
346    *blocks = rtems_rfs_fs_blocks (fs);
347  if (*inodes > rtems_rfs_fs_inodes (fs))
348    *inodes = rtems_rfs_fs_inodes (fs);
349 
350  return 0;
351}
352
Note: See TracBrowser for help on using the repository browser.