File indexing completed on 2025-05-11 08:24:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 #ifdef HAVE_CONFIG_H
0041 #include "config.h"
0042 #endif
0043
0044 #include <inttypes.h>
0045 #include <string.h>
0046
0047 #include <rtems/rfs/rtems-rfs-file-system.h>
0048 #include <rtems/rfs/rtems-rfs-group.h>
0049
0050 int
0051 rtems_rfs_group_open (rtems_rfs_file_system* fs,
0052 rtems_rfs_buffer_block base,
0053 size_t size,
0054 size_t inodes,
0055 rtems_rfs_group* group)
0056 {
0057 int rc;
0058
0059 if (base >= rtems_rfs_fs_blocks (fs))
0060 {
0061 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
0062 printf ("rtems-rfs: group-open: base outside file system range: %d: %s\n",
0063 EIO, strerror (EIO));
0064 return EIO;
0065 }
0066
0067 if ((base + size) >= rtems_rfs_fs_blocks (fs))
0068 size = rtems_rfs_fs_blocks (fs) - base;
0069
0070
0071
0072
0073
0074
0075
0076 if (inodes > size)
0077 inodes = size;
0078
0079 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
0080 printf ("rtems-rfs: group-open: base=%" PRId32 ", blocks=%zd inodes=%zd\n",
0081 base, size, inodes);
0082
0083 group->base = base;
0084 group->size = size;
0085
0086 rc = rtems_rfs_buffer_handle_open (fs, &group->block_bitmap_buffer);
0087 if (rc > 0)
0088 {
0089 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
0090 printf ("rtems-rfs: group-open: could not open block bitmap handle: %d: %s\n",
0091 rc, strerror (rc));
0092 return rc;
0093 }
0094
0095 rc = rtems_rfs_bitmap_open (&group->block_bitmap, fs,
0096 &group->block_bitmap_buffer, size,
0097 group->base + RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK);
0098 if (rc > 0)
0099 {
0100 rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
0101 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
0102 printf ("rtems-rfs: group-open: could not open block bitmap: %d: %s\n",
0103 rc, strerror (rc));
0104 return rc;
0105 }
0106
0107 rc = rtems_rfs_buffer_handle_open (fs, &group->inode_bitmap_buffer);
0108 if (rc > 0)
0109 {
0110 rtems_rfs_bitmap_close (&group->block_bitmap);
0111 rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
0112 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
0113 printf ("rtems-rfs: group-open: could not open inode bitmap handle: %d: %s\n",
0114 rc, strerror (rc));
0115 return rc;
0116 }
0117
0118 rc = rtems_rfs_bitmap_open (&group->inode_bitmap, fs,
0119 &group->inode_bitmap_buffer, inodes,
0120 group->base + RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK);
0121 if (rc > 0)
0122 {
0123 rtems_rfs_buffer_handle_close (fs, &group->inode_bitmap_buffer);
0124 rtems_rfs_bitmap_close (&group->block_bitmap);
0125 rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
0126 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN))
0127 printf ("rtems-rfs: group-open: could not open inode bitmap: %d: %s\n",
0128 rc, strerror (rc));
0129 return rc;
0130 }
0131
0132 if (rtems_rfs_fs_release_bitmaps (fs))
0133 {
0134 rtems_rfs_bitmap_release_buffer (fs, &group->block_bitmap);
0135 rtems_rfs_bitmap_release_buffer (fs, &group->inode_bitmap);
0136 }
0137
0138 return 0;
0139 }
0140
0141 int
0142 rtems_rfs_group_close (rtems_rfs_file_system* fs, rtems_rfs_group* group)
0143 {
0144 int result = 0;
0145 int rc;
0146
0147 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_CLOSE))
0148 printf ("rtems-rfs: group-close: base=%" PRId32 "\n", group->base);
0149
0150
0151
0152
0153
0154
0155 rc = rtems_rfs_bitmap_close (&group->inode_bitmap);
0156 if (rc > 0)
0157 result = rc;
0158 rc = rtems_rfs_buffer_handle_close (fs, &group->inode_bitmap_buffer);
0159 if (rc > 0)
0160 result = rc;
0161 rc = rtems_rfs_bitmap_close (&group->block_bitmap);
0162 if (rc > 0)
0163 result = rc;
0164 rc = rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer);
0165 if (rc > 0)
0166 result = rc;
0167
0168 return result;
0169 }
0170
0171 int
0172 rtems_rfs_group_bitmap_alloc (rtems_rfs_file_system* fs,
0173 rtems_rfs_bitmap_bit goal,
0174 bool inode,
0175 rtems_rfs_bitmap_bit* result)
0176 {
0177 int group_start;
0178 size_t size;
0179 rtems_rfs_bitmap_bit bit;
0180 int offset;
0181 bool updown;
0182 int direction;
0183
0184 if (inode)
0185 {
0186 size = fs->group_inodes;
0187 goal -= RTEMS_RFS_ROOT_INO;
0188 }
0189 else
0190 {
0191 size = fs->group_blocks;
0192
0193
0194
0195
0196
0197
0198 if (goal >= RTEMS_RFS_ROOT_INO)
0199 goal -= RTEMS_RFS_ROOT_INO;
0200 }
0201
0202 group_start = goal / size;
0203 bit = (rtems_rfs_bitmap_bit) (goal % size);
0204 offset = 0;
0205 updown = true;
0206 direction = 1;
0207
0208
0209
0210
0211
0212 while (true)
0213 {
0214 rtems_rfs_bitmap_control* bitmap;
0215 int group;
0216 bool allocated = false;
0217 int rc;
0218
0219
0220
0221
0222
0223 group = group_start + (direction * offset);
0224 if (offset)
0225 bit = direction > 0 ? 0 : size - 1;
0226
0227
0228
0229
0230
0231
0232 if ((group < 0) || (group >= fs->group_count))
0233 {
0234 if (!updown)
0235 break;
0236 direction = direction > 0 ? -1 : 1;
0237 updown = false;
0238 continue;
0239 }
0240
0241 if (inode)
0242 bitmap = &fs->groups[group].inode_bitmap;
0243 else
0244 bitmap = &fs->groups[group].block_bitmap;
0245
0246 rc = rtems_rfs_bitmap_map_alloc (bitmap, bit, &allocated, &bit);
0247 if (rc > 0)
0248 return rc;
0249
0250 if (rtems_rfs_fs_release_bitmaps (fs))
0251 rtems_rfs_bitmap_release_buffer (fs, bitmap);
0252
0253 if (allocated)
0254 {
0255 if (inode)
0256 *result = rtems_rfs_group_inode (fs, group, bit);
0257 else
0258 *result = rtems_rfs_group_block (&fs->groups[group], bit);
0259 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
0260 printf ("rtems-rfs: group-bitmap-alloc: %s allocated: %" PRId32 "\n",
0261 inode ? "inode" : "block", *result);
0262 return 0;
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272 if (updown)
0273 {
0274 direction = direction > 0 ? -1 : 1;
0275 if ( direction == -1 )
0276 offset++;
0277 }
0278 else
0279 {
0280 offset++;
0281 }
0282
0283 }
0284
0285 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
0286 printf ("rtems-rfs: group-bitmap-alloc: no blocks available\n");
0287
0288 return ENOSPC;
0289 }
0290
0291 int
0292 rtems_rfs_group_bitmap_free (rtems_rfs_file_system* fs,
0293 bool inode,
0294 rtems_rfs_bitmap_bit no)
0295 {
0296 rtems_rfs_bitmap_control* bitmap;
0297 unsigned int group;
0298 rtems_rfs_bitmap_bit bit;
0299 size_t size;
0300 int rc;
0301
0302 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
0303 printf ("rtems-rfs: group-bitmap-free: %s free: %" PRId32 "\n",
0304 inode ? "inode" : "block", no);
0305
0306 if (inode)
0307 {
0308 no -= RTEMS_RFS_ROOT_INO;
0309 size = fs->group_inodes;
0310 }
0311 else
0312 {
0313 no -= RTEMS_RFS_SUPERBLOCK_SIZE;
0314 size = fs->group_blocks;
0315 }
0316
0317 group = no / size;
0318 bit = (rtems_rfs_bitmap_bit) (no % size);
0319
0320 if (inode)
0321 bitmap = &fs->groups[group].inode_bitmap;
0322 else
0323 bitmap = &fs->groups[group].block_bitmap;
0324
0325 rc = rtems_rfs_bitmap_map_clear (bitmap, bit);
0326
0327 rtems_rfs_bitmap_release_buffer (fs, bitmap);
0328
0329 return rc;
0330 }
0331
0332 int
0333 rtems_rfs_group_bitmap_test (rtems_rfs_file_system* fs,
0334 bool inode,
0335 rtems_rfs_bitmap_bit no,
0336 bool* state)
0337 {
0338 rtems_rfs_bitmap_control* bitmap;
0339 unsigned int group;
0340 rtems_rfs_bitmap_bit bit;
0341 size_t size;
0342 int rc;
0343
0344 if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS))
0345 printf ("rtems-rfs: group-bitmap-test: %s test: %" PRId32 "\n",
0346 inode ? "inode" : "block", no);
0347
0348 if (inode)
0349 {
0350 if ((no < RTEMS_RFS_ROOT_INO) || (no > rtems_rfs_fs_inodes (fs)))
0351 return EINVAL;
0352 no -= RTEMS_RFS_ROOT_INO;
0353 size = fs->group_inodes;
0354 }
0355 else
0356 {
0357 if ((no < RTEMS_RFS_ROOT_INO) || (no >= rtems_rfs_fs_blocks (fs)))
0358 return EINVAL;
0359 no -= RTEMS_RFS_ROOT_INO;
0360 size = fs->group_blocks;
0361 }
0362
0363 group = no / size;
0364 bit = (rtems_rfs_bitmap_bit) (no % size);
0365
0366 if (inode)
0367 bitmap = &fs->groups[group].inode_bitmap;
0368 else
0369 bitmap = &fs->groups[group].block_bitmap;
0370
0371 rc = rtems_rfs_bitmap_map_test (bitmap, bit, state);
0372
0373 rtems_rfs_bitmap_release_buffer (fs, bitmap);
0374
0375 return rc;
0376 }
0377
0378 int
0379 rtems_rfs_group_usage (rtems_rfs_file_system* fs,
0380 size_t* blocks,
0381 size_t* inodes)
0382 {
0383 int g;
0384
0385 *blocks = 0;
0386 *inodes = 0;
0387
0388 for (g = 0; g < fs->group_count; g++)
0389 {
0390 rtems_rfs_group* group = &fs->groups[g];
0391 *blocks +=
0392 rtems_rfs_bitmap_map_size(&group->block_bitmap) -
0393 rtems_rfs_bitmap_map_free (&group->block_bitmap);
0394 *inodes +=
0395 rtems_rfs_bitmap_map_size (&group->inode_bitmap) -
0396 rtems_rfs_bitmap_map_free (&group->inode_bitmap);
0397 }
0398
0399 if (*blocks > rtems_rfs_fs_blocks (fs))
0400 *blocks = rtems_rfs_fs_blocks (fs);
0401 if (*inodes > rtems_rfs_fs_inodes (fs))
0402 *inodes = rtems_rfs_fs_inodes (fs);
0403
0404 return 0;
0405 }
0406