source: rtems/cpukit/libfs/src/rfs/rtems-rfs-group.c @ 3c96bee

4.115
Last change on this file since 3c96bee was 7660e8b3, checked in by Sebastian Huber <sebastian.huber@…>, on 07/23/13 at 11:32:58

Include missing <string.h>

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