int rtems_rfs_buffer_close (rtems_rfs_file_system* fs) { int rc = 0; if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_CLOSE)) printf ("rtems-rfs: buffer-close: closing\n"); /* * Change the block size to the media device size. It will release and sync * all buffers. */ rc = rtems_rfs_buffer_setblksize (fs, rtems_rfs_fs_media_block_size (fs)); if ((rc > 0) && rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_CLOSE)) printf ("rtems-rfs: buffer-close: set media block size failed: %d: %s\n", rc, strerror (rc)); if (close (fs->device) < 0) { rc = errno; if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_CLOSE)) printf ("rtems-rfs: buffer-close: file close failed: %d: %s\n", rc, strerror (rc)); } return rc; }
uint64_t rtems_rfs_fs_media_size (rtems_rfs_file_system* fs) { uint64_t media_blocks = (uint64_t) rtems_rfs_fs_media_blocks (fs); uint64_t media_block_size = (uint64_t) rtems_rfs_fs_media_block_size (fs); return media_blocks * media_block_size; }
int rtems_rfs_buffer_open (const char* name, rtems_rfs_file_system* fs) { struct stat st; #if RTEMS_RFS_USE_LIBBLOCK int rv; #endif if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_SYNC)) printf ("rtems-rfs: buffer-open: opening: %s\n", name); fs->device = open (name, O_RDWR); if (fs->device < 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: cannot open file\n"); return ENXIO; } if (fstat (fs->device, &st) < 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: stat '%s' failed: %s\n", name, strerror (errno)); return ENXIO; } #if RTEMS_RFS_USE_LIBBLOCK /* * Is the device a block device ? */ if (!S_ISBLK (st.st_mode)) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: '%s' is not a block device\n", name); return ENXIO; } /* * Check that device is registred as a block device and lock it. */ rv = rtems_disk_fd_get_disk_device (fs->device, &fs->disk); if (rv != 0) { if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_OPEN)) printf ("rtems-rfs: buffer-open: cannot obtain the disk\n"); return ENXIO; } #else fs->media_size = st.st_size; strcat (fs->name, name); #endif if (rtems_rfs_trace (RTEMS_RFS_TRACE_BUFFER_SYNC)) printf ("rtems-rfs: buffer-open: blks=%" PRId32 ", blk-size=%" PRId32 "\n", rtems_rfs_fs_media_blocks (fs), rtems_rfs_fs_media_block_size (fs)); 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 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; }
* @param sb * @return int */ 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
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; }