int rtems_rfs_inode_open (rtems_rfs_file_system* fs, rtems_rfs_ino ino, rtems_rfs_inode_handle* handle, bool load) { int group; int gino; int index; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_INODE_OPEN)) printf ("rtems-rfs: inode-open: ino: %" PRIu32 "\n", ino); if (ino == RTEMS_RFS_EMPTY_INO) return EINVAL; if ((ino - RTEMS_RFS_ROOT_INO) > rtems_rfs_fs_inodes (fs)) return EINVAL; handle->ino = ino; handle->node = NULL; handle->loads = 0; gino = ino - RTEMS_RFS_ROOT_INO; group = gino / fs->group_inodes; gino = gino % fs->group_inodes; index = (gino / fs->inodes_per_block) + RTEMS_RFS_GROUP_INODE_BLOCK; handle->offset = gino % fs->inodes_per_block; handle->block = rtems_rfs_group_block (&fs->groups[group], index); rc = rtems_rfs_buffer_handle_open (fs, &handle->buffer); if ((rc == 0) && load) rc = rtems_rfs_inode_load (fs, handle); return rc; }
int rtems_rfs_group_bitmap_alloc (rtems_rfs_file_system* fs, rtems_rfs_bitmap_bit goal, bool inode, rtems_rfs_bitmap_bit* result) { int group_start; size_t size; rtems_rfs_bitmap_bit bit; int offset; bool updown; int direction; if (inode) { size = fs->group_inodes; goal -= RTEMS_RFS_ROOT_INO; } else size = fs->group_blocks; group_start = goal / size; bit = (rtems_rfs_bitmap_bit) (goal % size); offset = 0; updown = true; direction = 1; /* * Try the goal group first and if that group fails try the groups either * side until the whole file system has be tried. */ while (true) { rtems_rfs_bitmap_control* bitmap; int group; bool allocated = false; int rc; /* * We can start at any location and we move out from that point in each * direction. The offset grows until we find a free bit or we hit an end. */ group = group_start + (direction * offset); if (offset) bit = direction > 0 ? 0 : size - 1; /* * If we are still looking up and down and if the group is out of range we * have reached one end. Stopping looking up and down and just move in the * one direction one group at a time. */ if ((group < 0) || (group >= fs->group_count)) { if (!updown) break; direction = direction > 0 ? -1 : 1; updown = false; continue; } if (inode) bitmap = &fs->groups[group].inode_bitmap; else bitmap = &fs->groups[group].block_bitmap; rc = rtems_rfs_bitmap_map_alloc (bitmap, bit, &allocated, &bit); if (rc > 0) return rc; if (rtems_rfs_fs_release_bitmaps (fs)) rtems_rfs_bitmap_release_buffer (fs, bitmap); if (allocated) { if (inode) *result = rtems_rfs_group_inode (fs, group, bit); else *result = rtems_rfs_group_block (&fs->groups[group], bit); if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS)) printf ("rtems-rfs: group-bitmap-alloc: %s allocated: %" PRId32 "\n", inode ? "inode" : "block", *result); return 0; } if (updown) direction = direction > 0 ? -1 : 1; offset++; } if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS)) printf ("rtems-rfs: group-bitmap-alloc: no blocks available\n"); return ENOSPC; }