int rtems_rfs_group_usage (rtems_rfs_file_system* fs, size_t* blocks, size_t* inodes) { int g; *blocks = 0; *inodes = 0; for (g = 0; g < fs->group_count; g++) { rtems_rfs_group* group = &fs->groups[g]; *blocks += rtems_rfs_bitmap_map_size(&group->block_bitmap) - rtems_rfs_bitmap_map_free (&group->block_bitmap); *inodes += rtems_rfs_bitmap_map_size (&group->inode_bitmap) - rtems_rfs_bitmap_map_free (&group->inode_bitmap); } if (*blocks > rtems_rfs_fs_blocks (fs)) *blocks = rtems_rfs_fs_blocks (fs); if (*inodes > rtems_rfs_fs_inodes (fs)) *inodes = rtems_rfs_fs_inodes (fs); return 0; }
/** * Return the inode overhead given a number of inodes. */ static int rtems_rfs_inode_overhead (rtems_rfs_file_system* fs) { int blocks; int bits_per_block; blocks = rtems_rfs_rup_quotient(fs->group_inodes * RTEMS_RFS_INODE_SIZE, rtems_rfs_fs_block_size (fs)); bits_per_block = rtems_rfs_bits_per_block (fs); /* * There could be more bits than blocks, eg 512K disk with 512 blocks. */ if (bits_per_block > (rtems_rfs_fs_blocks (fs) - RTEMS_RFS_SUPERBLOCK_SIZE)) bits_per_block = rtems_rfs_fs_blocks (fs) - RTEMS_RFS_SUPERBLOCK_SIZE; return ((blocks + 1) * 100 * 10) / bits_per_block; }
uint64_t rtems_rfs_fs_size (rtems_rfs_file_system* fs) { uint64_t blocks = rtems_rfs_fs_blocks (fs); uint64_t block_size = rtems_rfs_fs_block_size (fs); return blocks * block_size; }
/** * Find a block indirectly held in a table of block numbers. * * @param fs The file system. * @param buffer The handle to access the block data by. * @param block The block number of the table of block numbers. * @param offset The offset in the table of the block number to return. This is * a block number offset not a byte offset into the table. * @param result Pointer to the result of the search. * @return int The error number (errno). No error if 0. */ static int rtems_rfs_block_find_indirect (rtems_rfs_file_system* fs, rtems_rfs_buffer_handle* buffer, rtems_rfs_block_no block, int offset, rtems_rfs_block_no* result) { int rc; /* * If the handle has a buffer and this request is a different block the current * buffer is released. */ rc = rtems_rfs_buffer_handle_request (fs, buffer, block, true); if (rc > 0) return rc; *result = rtems_rfs_block_get_number (buffer, offset); if ((*result + 1) == 0) *result = 0; if (*result >= rtems_rfs_fs_blocks (fs)) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BLOCK_FIND)) printf ("rtems-rfs: block-find: invalid block in table:" " block=%" PRId32 ", indirect=%" PRId32 "/%d\n", *result, block, offset); *result = 0; rc = EIO; } return 0; }
static int rtems_rfs_shell_data (rtems_rfs_file_system* fs, int argc, char *argv[]) { size_t blocks; size_t inodes; int bpcent; int ipcent; printf ("RFS Filesystem Data\n"); printf (" flags: %08" PRIx32 "\n", fs->flags); #if 0 printf (" device: %08lx\n", rtems_rfs_fs_device (fs)); #endif printf (" blocks: %zu\n", rtems_rfs_fs_blocks (fs)); printf (" block size: %zu\n", rtems_rfs_fs_block_size (fs)); printf (" size: %" PRIu64 "\n", rtems_rfs_fs_size (fs)); printf (" media block size: %" PRIu32 "\n", rtems_rfs_fs_media_block_size (fs)); printf (" media size: %" PRIu64 "\n", rtems_rfs_fs_media_size (fs)); printf (" inodes: %" PRIu32 "\n", rtems_rfs_fs_inodes (fs)); printf (" bad blocks: %" PRIu32 "\n", fs->bad_blocks); printf (" max. name length: %" PRIu32 "\n", rtems_rfs_fs_max_name (fs)); printf (" groups: %d\n", fs->group_count); printf (" group blocks: %zd\n", fs->group_blocks); printf (" group inodes: %zd\n", fs->group_inodes); printf (" inodes per block: %zd\n", fs->inodes_per_block); printf (" blocks per block: %zd\n", fs->blocks_per_block); printf (" singly blocks: %zd\n", fs->block_map_singly_blocks); printf (" doublly blocks: %zd\n", fs->block_map_doubly_blocks); printf (" max. held buffers: %" PRId32 "\n", fs->max_held_buffers); rtems_rfs_shell_lock_rfs (fs); rtems_rfs_group_usage (fs, &blocks, &inodes); rtems_rfs_shell_unlock_rfs (fs); bpcent = (blocks * 1000) / rtems_rfs_fs_blocks (fs); ipcent = (inodes * 1000) / rtems_rfs_fs_inodes (fs); printf (" blocks used: %zd (%d.%d%%)\n", blocks, bpcent / 10, bpcent % 10); printf (" inodes used: %zd (%d.%d%%)\n", inodes, ipcent / 10, ipcent % 10); return 0; }
/** * Return the number of inodes as a percentage of the total number that can fit * in a blocl. */ static int rtems_rfs_inodes_from_percent (rtems_rfs_file_system* fs, int percentage) { int blocks; blocks = ((rtems_rfs_fs_blocks (fs) - RTEMS_RFS_SUPERBLOCK_SIZE) * percentage) / 100; blocks = rtems_rfs_rup_quotient (blocks, fs->group_count); return blocks * (rtems_rfs_fs_block_size (fs) / RTEMS_RFS_INODE_SIZE); }
int rtems_rfs_group_bitmap_test (rtems_rfs_file_system* fs, bool inode, rtems_rfs_bitmap_bit no, bool* state) { rtems_rfs_bitmap_control* bitmap; unsigned int group; rtems_rfs_bitmap_bit bit; size_t size; int rc; if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_BITMAPS)) printf ("rtems-rfs: group-bitmap-test: %s test: %" PRId32 "\n", inode ? "inode" : "block", no); if (inode) { if ((no < RTEMS_RFS_ROOT_INO) || (no > rtems_rfs_fs_inodes (fs))) return EINVAL; no -= RTEMS_RFS_ROOT_INO; size = fs->group_inodes; } else { if (no >= rtems_rfs_fs_blocks (fs)) return EINVAL; size = fs->group_blocks; } group = no / size; bit = (rtems_rfs_bitmap_bit) (no % size); if (inode) bitmap = &fs->groups[group].inode_bitmap; else bitmap = &fs->groups[group].block_bitmap; rc = rtems_rfs_bitmap_map_test (bitmap, bit, state); rtems_rfs_bitmap_release_buffer (fs, bitmap); return rc; }
/** * Return the file system stat data. * * @param pathloc * @param sb * @return int */ static int rtems_rfs_rtems_statvfs (const rtems_filesystem_location_info_t* pathloc, struct statvfs* sb) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); size_t blocks; size_t inodes; rtems_rfs_group_usage (fs, &blocks, &inodes); sb->f_bsize = rtems_rfs_fs_block_size (fs); sb->f_frsize = rtems_rfs_fs_media_block_size (fs); sb->f_blocks = rtems_rfs_fs_media_blocks (fs); sb->f_bfree = rtems_rfs_fs_blocks (fs) - blocks; sb->f_bavail = sb->f_bfree; sb->f_files = rtems_rfs_fs_inodes (fs); sb->f_ffree = rtems_rfs_fs_inodes (fs) - inodes; sb->f_favail = sb->f_ffree; sb->f_fsid = RTEMS_RFS_SB_MAGIC; sb->f_flag = rtems_rfs_fs_flags (fs); sb->f_namemax = rtems_rfs_fs_max_name (fs); return 0; }
int rtems_rfs_group_open (rtems_rfs_file_system* fs, rtems_rfs_buffer_block base, size_t size, size_t inodes, rtems_rfs_group* group) { int rc; if (base >= rtems_rfs_fs_blocks (fs)) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN)) printf ("rtems-rfs: group-open: base outside file system range: %d: %s\n", EIO, strerror (EIO)); return EIO; } if ((base + size) >= rtems_rfs_fs_blocks (fs)) size = rtems_rfs_fs_blocks (fs) - base; /* * Limit the inodes to the same size as the blocks. This is what the * format does and if this is not done the accounting of inodes does * not work. If we are so pushed for inodes that this makes a difference * the format configuration needs reviewing. */ if (inodes > size) inodes = size; if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN)) printf ("rtems-rfs: group-open: base=%" PRId32 ", blocks=%zd inodes=%zd\n", base, size, inodes); group->base = base; group->size = size; rc = rtems_rfs_buffer_handle_open (fs, &group->block_bitmap_buffer); if (rc > 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN)) printf ("rtems-rfs: group-open: could not open block bitmap handle: %d: %s\n", rc, strerror (rc)); return rc; } rc = rtems_rfs_bitmap_open (&group->block_bitmap, fs, &group->block_bitmap_buffer, size, group->base + RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer); if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN)) printf ("rtems-rfs: group-open: could not open block bitmap: %d: %s\n", rc, strerror (rc)); return rc; } rc = rtems_rfs_buffer_handle_open (fs, &group->inode_bitmap_buffer); if (rc > 0) { rtems_rfs_bitmap_close (&group->block_bitmap); rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer); if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN)) printf ("rtems-rfs: group-open: could not open inode bitmap handle: %d: %s\n", rc, strerror (rc)); return rc; } rc = rtems_rfs_bitmap_open (&group->inode_bitmap, fs, &group->inode_bitmap_buffer, inodes, group->base + RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &group->inode_bitmap_buffer); rtems_rfs_bitmap_close (&group->block_bitmap); rtems_rfs_buffer_handle_close (fs, &group->block_bitmap_buffer); if (rtems_rfs_trace (RTEMS_RFS_TRACE_GROUP_OPEN)) printf ("rtems-rfs: group-open: could not open inode bitmap: %d: %s\n", rc, strerror (rc)); return rc; } if (rtems_rfs_fs_release_bitmaps (fs)) { rtems_rfs_bitmap_release_buffer (fs, &group->block_bitmap); rtems_rfs_bitmap_release_buffer (fs, &group->inode_bitmap); } return 0; }
*/ static int rtems_rfs_rtems_statvfs ( const rtems_filesystem_location_info_t *__restrict pathloc, struct statvfs *__restrict sb) { rtems_rfs_file_system* fs = rtems_rfs_rtems_pathloc_dev (pathloc); size_t blocks; size_t inodes; rtems_rfs_group_usage (fs, &blocks, &inodes); sb->f_bsize = rtems_rfs_fs_block_size (fs); sb->f_frsize = rtems_rfs_fs_media_block_size (fs); sb->f_blocks = rtems_rfs_fs_media_blocks (fs); sb->f_bfree = rtems_rfs_fs_blocks (fs) - blocks - 1; /* do not count the superblock */ sb->f_bavail = sb->f_bfree; sb->f_files = rtems_rfs_fs_inodes (fs); sb->f_ffree = rtems_rfs_fs_inodes (fs) - inodes; sb->f_favail = sb->f_ffree; sb->f_fsid = RTEMS_RFS_SB_MAGIC; sb->f_flag = rtems_rfs_fs_flags (fs); sb->f_namemax = rtems_rfs_fs_max_name (fs); return 0; } /** * Handler table for RFS link nodes */ const rtems_filesystem_file_handlers_r rtems_rfs_rtems_link_handlers =
static int rtems_rfs_shell_inode (rtems_rfs_file_system* fs, int argc, char *argv[]) { rtems_rfs_ino start; rtems_rfs_ino end; rtems_rfs_ino total; rtems_rfs_ino ino; bool show_all; bool error_check_only; bool forced; bool have_start; bool have_end; int arg; int b; int rc; total = fs->group_inodes * fs->group_count; start = RTEMS_RFS_ROOT_INO; end = total - 1; show_all = false; error_check_only = false; forced = false; have_start = have_end = false; for (arg = 1; arg < argc; arg++) { if (argv[arg][0] == '-') { switch (argv[arg][1]) { case 'a': show_all = true; break; case 'e': error_check_only = true; break; case 'f': forced = true; break; default: printf ("warning: option ignored: %s\n", argv[arg]); break; } } else { if (have_end && have_start) printf ("warning: option ignored: %s\n", argv[arg]); else if (!have_start) { start = end = strtoul (argv[arg], 0, 0); have_start = true; } else { end = strtoul (argv[arg], 0, 0); have_end = true; } } } if ((start >= total) || (end >= total)) { printf ("error: inode out of range (0->%" PRId32 ").\n", total - 1); return 1; } rtems_rfs_shell_lock_rfs (fs); for (ino = start; ino <= end; ino++) { rtems_rfs_inode_handle inode; bool allocated; rc = rtems_rfs_group_bitmap_test (fs, true, ino, &allocated); if (rc > 0) { rtems_rfs_shell_unlock_rfs (fs); printf ("error: testing inode state: ino=%" PRIu32 ": (%d) %s\n", ino, rc, strerror (rc)); return 1; } if (show_all || allocated) { uint16_t mode; bool error; rc = rtems_rfs_inode_open (fs, ino, &inode, true); if (rc > 0) { rtems_rfs_shell_unlock_rfs (fs); printf ("error: opening inode handle: ino=%" PRIu32 ": (%d) %s\n", ino, rc, strerror (rc)); return 1; } error = false; mode = rtems_rfs_inode_get_mode (&inode); if (error_check_only) { if (!RTEMS_RFS_S_ISDIR (mode) && !RTEMS_RFS_S_ISCHR (mode) && !RTEMS_RFS_S_ISBLK (mode) && !RTEMS_RFS_S_ISREG (mode) && !RTEMS_RFS_S_ISLNK (mode)) error = true; else { #if NEED_TO_HANDLE_DIFFERENT_TYPES int b; for (b = 0; b < RTEMS_RFS_INODE_BLOCKS; b++) { uint32_t block; block = rtems_rfs_inode_get_block (&inode, b); if ((block <= RTEMS_RFS_SUPERBLOCK_SIZE) || (block >= rtems_rfs_fs_blocks (fs))) error = true; } #endif } } if (!error_check_only || error) { printf (" %5" PRIu32 ": pos=%06" PRIu32 ":%04zx %c ", ino, rtems_rfs_buffer_bnum (&inode.buffer), inode.offset * RTEMS_RFS_INODE_SIZE, allocated ? 'A' : 'F'); if (!allocated && !forced) printf (" --\n"); else { const char* type; type = "UKN"; if (RTEMS_RFS_S_ISDIR (mode)) type = "DIR"; else if (RTEMS_RFS_S_ISCHR (mode)) type = "CHR"; else if (RTEMS_RFS_S_ISBLK (mode)) type = "BLK"; else if (RTEMS_RFS_S_ISREG (mode)) type = "REG"; else if (RTEMS_RFS_S_ISLNK (mode)) type = "LNK"; printf ("links=%03i mode=%04x (%s/%03o) bo=%04u bc=%04" PRIu32 " b=[", rtems_rfs_inode_get_links (&inode), mode, type, mode & ((1 << 10) - 1), rtems_rfs_inode_get_block_offset (&inode), rtems_rfs_inode_get_block_count (&inode)); for (b = 0; b < (RTEMS_RFS_INODE_BLOCKS - 1); b++) printf ("%" PRIu32 " ", rtems_rfs_inode_get_block (&inode, b)); printf ("%" PRIu32 "]\n", rtems_rfs_inode_get_block (&inode, b)); } } rc = rtems_rfs_inode_close (fs, &inode); if (rc > 0) { rtems_rfs_shell_unlock_rfs (fs); printf ("error: closing inode handle: ino=%" PRIu32 ": (%d) %s\n", ino, rc, strerror (rc)); return 1; } } } rtems_rfs_shell_unlock_rfs (fs); return 0; }
static bool rtems_rfs_check_config (rtems_rfs_file_system* fs, const rtems_rfs_format_config* config) { fs->block_size = config->block_size; if (!fs->block_size) { uint64_t total_size = rtems_rfs_fs_media_size (fs); if (total_size >= GIGS (1)) { uint32_t gigs = (total_size + GIGS (1)) / GIGS (1); int b; for (b = 31; b > 0; b--) if ((gigs & (1 << b)) != 0) break; fs->block_size = 1 << b; } if (fs->block_size < 512) fs->block_size = 512; if (fs->block_size > (4 * 1024)) fs->block_size = (4 * 1024); } if ((fs->block_size % rtems_rfs_fs_media_block_size (fs)) != 0) { printf ("block size (%zd) is not a multiple of media block size (%" PRId32 ")\n", fs->block_size, rtems_rfs_fs_media_block_size (fs)); return false; } fs->group_blocks = config->group_blocks; if (!fs->group_blocks) { /* * The number of blocks per group is defined by the number of bits in a * block. */ fs->group_blocks = rtems_rfs_bitmap_numof_bits (fs->block_size); } if (fs->group_blocks > rtems_rfs_bitmap_numof_bits (fs->block_size)) { printf ("group block count is higher than bits in block\n"); return false; } fs->blocks = rtems_rfs_fs_media_size (fs) / fs->block_size; /* * The bits per block sets the upper limit for the number of blocks in a * group. The disk will be divided into groups which are the number of bits * per block. */ fs->group_count = rtems_rfs_rup_quotient (rtems_rfs_fs_blocks (fs), rtems_rfs_bits_per_block (fs)); fs->group_inodes = config->group_inodes; if (!fs->group_inodes) { int inode_overhead = RTEMS_RFS_INODE_OVERHEAD_PERCENTAGE; /* * The number of inodes per group is set as a percentage. */ if (config->inode_overhead) inode_overhead = config->inode_overhead; fs->group_inodes = rtems_rfs_inodes_from_percent (fs, inode_overhead); } /* * Round up to fill a block because the minimum allocation unit is a block. */ fs->inodes_per_block = rtems_rfs_fs_block_size (fs) / RTEMS_RFS_INODE_SIZE; fs->group_inodes = rtems_rfs_rup_quotient (fs->group_inodes, fs->inodes_per_block) * fs->inodes_per_block; if (fs->group_inodes > rtems_rfs_bitmap_numof_bits (fs->block_size)) fs->group_inodes = rtems_rfs_bitmap_numof_bits (fs->block_size); fs->max_name_length = config->max_name_length; if (!fs->max_name_length) { fs->max_name_length = 512; } return true; }
int rtems_rfs_format (const char* name, const rtems_rfs_format_config* config) { rtems_rfs_file_system fs; int group; int rc; if (config->verbose) printf ("rtems-rfs: format: %s\n", name); memset (&fs, 0, sizeof (rtems_rfs_file_system)); rtems_chain_initialize_empty (&fs.buffers); rtems_chain_initialize_empty (&fs.release); rtems_chain_initialize_empty (&fs.release_modified); rtems_chain_initialize_empty (&fs.file_shares); fs.max_held_buffers = RTEMS_RFS_FS_MAX_HELD_BUFFERS; fs.release_count = 0; fs.release_modified_count = 0; fs.flags = RTEMS_RFS_FS_NO_LOCAL_CACHE; /* * Open the buffer interface. */ rc = rtems_rfs_buffer_open (name, &fs); if (rc > 0) { printf ("rtems-rfs: format: buffer open failed: %d: %s\n", rc, strerror (rc)); return -1; } /* * Check the media. */ if (rtems_rfs_fs_media_block_size (&fs) == 0) { printf ("rtems-rfs: media block is invalid: %" PRIu32 "\n", rtems_rfs_fs_media_block_size (&fs)); return -1; } /* * Check the configuration data. */ if (!rtems_rfs_check_config (&fs, config)) return -1; if (config->verbose) { printf ("rtems-rfs: format: media size = %" PRIu64 "\n", rtems_rfs_fs_media_size (&fs)); printf ("rtems-rfs: format: media blocks = %" PRIu32 "\n", rtems_rfs_fs_media_blocks (&fs)); printf ("rtems-rfs: format: media block size = %" PRIu32 "\n", rtems_rfs_fs_media_block_size (&fs)); printf ("rtems-rfs: format: size = %" PRIu64 "\n", rtems_rfs_fs_size (&fs)); printf ("rtems-rfs: format: blocks = %zu\n", rtems_rfs_fs_blocks (&fs)); printf ("rtems-rfs: format: block size = %zu\n", rtems_rfs_fs_block_size (&fs)); printf ("rtems-rfs: format: bits per block = %u\n", rtems_rfs_bits_per_block (&fs)); printf ("rtems-rfs: format: inode size = %zu\n", RTEMS_RFS_INODE_SIZE); printf ("rtems-rfs: format: inodes = %zu (%d.%d%%)\n", fs.group_inodes * fs.group_count, rtems_rfs_inode_overhead (&fs) / 10, rtems_rfs_inode_overhead (&fs) % 10); printf ("rtems-rfs: format: groups = %u\n", fs.group_count); printf ("rtems-rfs: format: group blocks = %zu\n", fs.group_blocks); printf ("rtems-rfs: format: group inodes = %zu\n", fs.group_inodes); } rc = rtems_rfs_buffer_setblksize (&fs, rtems_rfs_fs_block_size (&fs)); if (rc > 0) { printf ("rtems-rfs: format: setting block size failed: %d: %s\n", rc, strerror (rc)); return -1; } if (!rtems_rfs_write_superblock (&fs)) { printf ("rtems-rfs: format: superblock write failed\n"); return -1; } for (group = 0; group < fs.group_count; group++) if (!rtems_rfs_write_group (&fs, group, config->initialise_inodes, config->verbose)) return -1; if (config->verbose) printf ("\n"); rc = rtems_rfs_buffer_close (&fs); if (rc > 0) { printf ("rtems-rfs: format: buffer close failed: %d: %s\n", rc, strerror (rc)); return -1; } rc = rtems_rfs_write_root_dir (name); if (rc > 0) { printf ("rtems-rfs: format: writing root dir failed: %d: %s\n", rc, strerror (rc)); return -1; } return 0; }
static bool rtems_rfs_write_superblock (rtems_rfs_file_system* fs) { rtems_rfs_buffer_handle handle; uint8_t* sb; int rc; rc = rtems_rfs_buffer_handle_open (fs, &handle); if (rc > 0) { printf ("rtems-rfs: write-superblock: handle open failed: %d: %s\n", rc, strerror (rc)); return false; } rc = rtems_rfs_buffer_handle_request (fs, &handle, 0, false); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("rtems-rfs: write-superblock: request failed: %d: %s\n", rc, strerror (rc)); return false; } sb = rtems_rfs_buffer_data (&handle); #define write_sb(_o, _d) rtems_rfs_write_u32(sb + (_o), _d) memset (sb, 0xff, rtems_rfs_fs_block_size (fs)); write_sb (RTEMS_RFS_SB_OFFSET_MAGIC, RTEMS_RFS_SB_MAGIC); write_sb (RTEMS_RFS_SB_OFFSET_VERSION, RTEMS_RFS_VERSION); write_sb (RTEMS_RFS_SB_OFFSET_BLOCKS, rtems_rfs_fs_blocks (fs)); write_sb (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE, rtems_rfs_fs_block_size (fs)); write_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS, fs->bad_blocks); write_sb (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH, fs->max_name_length); write_sb (RTEMS_RFS_SB_OFFSET_GROUPS, fs->group_count); write_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS, fs->group_blocks); write_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES, fs->group_inodes); write_sb (RTEMS_RFS_SB_OFFSET_INODE_SIZE, RTEMS_RFS_INODE_SIZE); rtems_rfs_buffer_mark_dirty (&handle); rc = rtems_rfs_buffer_handle_release (fs, &handle); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("rtems-rfs: write-superblock: buffer release failed: %d: %s\n", rc, strerror (rc)); return false; } rc = rtems_rfs_buffer_handle_close (fs, &handle); if (rc > 0) { printf ("rtems-rfs: write-superblock: buffer handle close failed: %d: %s\n", rc, strerror (rc)); return false; } return true; }
static bool rtems_rfs_write_group (rtems_rfs_file_system* fs, int group, bool initialise_inodes, bool verbose) { rtems_rfs_buffer_handle handle; rtems_rfs_bitmap_control bitmap; rtems_rfs_buffer_block group_base; size_t group_size; int blocks; int b; int rc; group_base = rtems_rfs_fs_block (fs, group, 0); if (group_base > rtems_rfs_fs_blocks (fs)) { printf ("rtems-rfs: write-group: group %d base beyond disk limit\n", group); return false; } group_size = fs->group_blocks; /* * Be nice to strange sizes of disks. These are embedded systems after all * and nice numbers do not always work out. Let the last block pick up the * remainder of the blocks. */ if ((group_base + group_size) > rtems_rfs_fs_blocks (fs)) group_size = rtems_rfs_fs_blocks (fs) - group_base; if (verbose) printf ("\rrtems-rfs: format: group %3d: base = %" PRId32 ", size = %zd", group, group_base, group_size); /* * Open a handle and request an empty buffer. */ rc = rtems_rfs_buffer_handle_open (fs, &handle); if (rc > 0) { printf ("\nrtems-rfs: write-group: handle open failed: %d: %s\n", rc, strerror (rc)); return false; } if (verbose) printf (", blocks"); /* * Open the block bitmap using the new buffer. */ rc = rtems_rfs_bitmap_open (&bitmap, fs, &handle, group_size, group_base + RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: open block bitmap failed: %d: %s\n", group, rc, strerror (rc)); return false; } /* * Force the whole buffer to a known state. The bit map may not occupy the * whole block. */ memset (rtems_rfs_buffer_data (&handle), 0xff, rtems_rfs_fs_block_size (fs)); /* * Clear the bitmap. */ rc = rtems_rfs_bitmap_map_clear_all (&bitmap); if (rc > 0) { rtems_rfs_bitmap_close (&bitmap); rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: block bitmap clear all failed: %d: %s\n", group, rc, strerror (rc)); return false; } /* * Forced allocation of the block bitmap. */ rtems_rfs_bitmap_map_set (&bitmap, RTEMS_RFS_GROUP_BLOCK_BITMAP_BLOCK); /* * Forced allocation of the inode bitmap. */ rtems_rfs_bitmap_map_set (&bitmap, RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK); /* * Determine the number of inodes blocks in the group. */ blocks = rtems_rfs_rup_quotient (fs->group_inodes, fs->inodes_per_block); /* * Forced allocation of the inode blocks which follow the block bitmap. */ for (b = 0; b < blocks; b++) rtems_rfs_bitmap_map_set (&bitmap, b + RTEMS_RFS_GROUP_INODE_BLOCK); /* * Close the block bitmap. */ rc = rtems_rfs_bitmap_close (&bitmap); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: close block bitmap failed: %d: %s\n", group, rc, strerror (rc)); return false; } rtems_rfs_buffer_mark_dirty (&handle); if (verbose) printf (", inodes"); /* * Open the inode bitmap using the old buffer. Should release any changes. */ rc = rtems_rfs_bitmap_open (&bitmap, fs, &handle, group_size, group_base + RTEMS_RFS_GROUP_INODE_BITMAP_BLOCK); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: open inode bitmap failed: %d: %s\n", group, rc, strerror (rc)); return false; } /* * Force the whole buffer to a known state. The bit map may not occupy the * whole block. */ memset (rtems_rfs_buffer_data (&handle), 0x00, rtems_rfs_fs_block_size (fs)); /* * Clear the inode bitmap. */ rc = rtems_rfs_bitmap_map_clear_all (&bitmap); if (rc > 0) { rtems_rfs_bitmap_close (&bitmap); rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: inode bitmap" \ " clear all failed: %d: %s\n", group, rc, strerror (rc)); return false; } /* * Close the inode bitmap. */ rc = rtems_rfs_bitmap_close (&bitmap); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: close inode" \ " bitmap failed: %d: %s\n", group, rc, strerror (rc)); return false; } rtems_rfs_buffer_mark_dirty (&handle); /* * Initialise the inode tables if required to do so. */ if (initialise_inodes) { for (b = 0; b < blocks; b++) { rc = rtems_rfs_buffer_handle_request (fs, &handle, group_base + b + RTEMS_RFS_GROUP_INODE_BLOCK, false); if (rc > 0) { rtems_rfs_buffer_handle_close (fs, &handle); printf ("\nrtems-rfs: write-group: group %3d: block %" PRId32 " request failed: %d: %s\n", group, group_base + b + RTEMS_RFS_GROUP_INODE_BLOCK, rc, strerror (rc)); return false; } /* * Force the whole buffer to a known state. The bit map may not occupy the * whole block. */ memset (rtems_rfs_buffer_data (&handle), 0xff, rtems_rfs_fs_block_size (fs)); rtems_rfs_buffer_mark_dirty (&handle); } } rc = rtems_rfs_buffer_handle_close (fs, &handle); if (rc > 0) { printf ("\nrtems-rfs: write-group: buffer handle close failed: %d: %s\n", rc, strerror (rc)); return false; } return true; }