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 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include <inttypes.h>
0042 #include <stdlib.h>
0043 #include <string.h>
0044
0045 #include <rtems/rfs/rtems-rfs-data.h>
0046 #include <rtems/rfs/rtems-rfs-file-system.h>
0047 #include <rtems/rfs/rtems-rfs-inode.h>
0048 #include <rtems/rfs/rtems-rfs-trace.h>
0049
0050 uint64_t
0051 rtems_rfs_fs_size (rtems_rfs_file_system* fs)
0052 {
0053 uint64_t blocks = rtems_rfs_fs_blocks (fs);
0054 uint64_t block_size = rtems_rfs_fs_block_size (fs);
0055 return blocks * block_size;
0056 }
0057
0058 uint64_t
0059 rtems_rfs_fs_media_size (rtems_rfs_file_system* fs)
0060 {
0061 uint64_t media_blocks = (uint64_t) rtems_rfs_fs_media_blocks (fs);
0062 uint64_t media_block_size = (uint64_t) rtems_rfs_fs_media_block_size (fs);
0063 return media_blocks * media_block_size;
0064 }
0065
0066 static int
0067 rtems_rfs_fs_read_superblock (rtems_rfs_file_system* fs)
0068 {
0069 rtems_rfs_buffer_handle handle;
0070 uint8_t* sb;
0071 int group;
0072 int rc;
0073
0074 rc = rtems_rfs_buffer_handle_open (fs, &handle);
0075 if (rc > 0)
0076 {
0077 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0078 printf ("rtems-rfs: read-superblock: handle open failed: %d: %s\n",
0079 rc, strerror (rc));
0080 return rc;
0081 }
0082
0083 rc = rtems_rfs_buffer_handle_request (fs, &handle, 0, true);
0084 if (rc > 0)
0085 {
0086 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0087 printf ("rtems-rfs: read-superblock: request failed%d: %s\n",
0088 rc, strerror (rc));
0089 return rc;
0090 }
0091
0092 sb = rtems_rfs_buffer_data (&handle);
0093
0094 #define read_sb(_o) rtems_rfs_read_u32 (sb + (_o))
0095
0096 if (read_sb (RTEMS_RFS_SB_OFFSET_MAGIC) != RTEMS_RFS_SB_MAGIC)
0097 {
0098 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0099 printf ("rtems-rfs: read-superblock: invalid superblock, bad magic\n");
0100 rtems_rfs_buffer_handle_close (fs, &handle);
0101 return EIO;
0102 }
0103
0104 fs->blocks = read_sb (RTEMS_RFS_SB_OFFSET_BLOCKS);
0105 fs->block_size = read_sb (RTEMS_RFS_SB_OFFSET_BLOCK_SIZE);
0106
0107 if (rtems_rfs_fs_size(fs) > rtems_rfs_fs_media_size (fs))
0108 {
0109 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0110 printf ("rtems-rfs: read-superblock: invalid superblock block/size count\n");
0111 rtems_rfs_buffer_handle_close (fs, &handle);
0112 return EIO;
0113 }
0114
0115 if ((read_sb (RTEMS_RFS_SB_OFFSET_VERSION) & RTEMS_RFS_VERSION_MASK) !=
0116 (RTEMS_RFS_VERSION * RTEMS_RFS_VERSION_MASK))
0117 {
0118 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0119 printf ("rtems-rfs: read-superblock: incompatible version: %08" PRIx32 " (%08" PRIx32 ")\n",
0120 read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
0121 rtems_rfs_buffer_handle_close (fs, &handle);
0122 return EIO;
0123 }
0124
0125 if (read_sb (RTEMS_RFS_SB_OFFSET_INODE_SIZE) != RTEMS_RFS_INODE_SIZE)
0126 {
0127 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0128 printf ("rtems-rfs: read-superblock: inode size mismatch: fs:%" PRId32 " target:%" PRId32 "\n",
0129 read_sb (RTEMS_RFS_SB_OFFSET_VERSION), RTEMS_RFS_VERSION_MASK);
0130 rtems_rfs_buffer_handle_close (fs, &handle);
0131 return EIO;
0132 }
0133
0134 fs->bad_blocks = read_sb (RTEMS_RFS_SB_OFFSET_BAD_BLOCKS);
0135 fs->max_name_length = read_sb (RTEMS_RFS_SB_OFFSET_MAX_NAME_LENGTH);
0136 fs->group_count = read_sb (RTEMS_RFS_SB_OFFSET_GROUPS);
0137 fs->group_blocks = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_BLOCKS);
0138 fs->group_inodes = read_sb (RTEMS_RFS_SB_OFFSET_GROUP_INODES);
0139
0140 fs->blocks_per_block =
0141 rtems_rfs_fs_block_size (fs) / sizeof (rtems_rfs_inode_block);
0142
0143 fs->block_map_singly_blocks =
0144 fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
0145 fs->block_map_doubly_blocks =
0146 fs->blocks_per_block * fs->blocks_per_block * RTEMS_RFS_INODE_BLOCKS;
0147
0148 fs->inodes = fs->group_count * fs->group_inodes;
0149
0150 fs->inodes_per_block = fs->block_size / RTEMS_RFS_INODE_SIZE;
0151
0152 if (fs->group_blocks >
0153 rtems_rfs_bitmap_numof_bits (rtems_rfs_fs_block_size (fs)))
0154 {
0155 rtems_rfs_buffer_handle_close (fs, &handle);
0156 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0157 printf ("rtems-rfs: read-superblock: groups blocks larger than block bits\n");
0158 return EIO;
0159 }
0160
0161 rtems_rfs_buffer_handle_close (fs, &handle);
0162
0163
0164
0165
0166 rc = rtems_rfs_buffer_setblksize (fs, rtems_rfs_fs_block_size (fs));
0167 if (rc > 0)
0168 {
0169 rtems_rfs_buffer_handle_close (fs, &handle);
0170 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0171 printf ("rtems-rfs: read-superblock: invalid superblock block size%d: %s\n",
0172 rc, strerror (rc));
0173 return rc;
0174 }
0175
0176 fs->groups = calloc (fs->group_count, sizeof (rtems_rfs_group));
0177
0178 if (!fs->groups)
0179 {
0180 rtems_rfs_buffer_handle_close (fs, &handle);
0181 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0182 printf ("rtems-rfs: read-superblock: no memory for group table\n");
0183 return ENOMEM;
0184 }
0185
0186
0187
0188
0189
0190
0191 for (group = 0; group < fs->group_count; group++)
0192 {
0193 rc = rtems_rfs_group_open (fs,
0194 rtems_rfs_fs_block (fs, group, 0),
0195 fs->group_blocks,
0196 fs->group_inodes,
0197 &fs->groups[group]);
0198 if (rc > 0)
0199 {
0200 int g;
0201 for (g = 0; g < group; g++)
0202 rtems_rfs_group_close (fs, &fs->groups[g]);
0203 rtems_rfs_buffer_handle_close (fs, &handle);
0204 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0205 printf ("rtems-rfs: read-superblock: no memory for group table%d: %s\n",
0206 rc, strerror (rc));
0207 return rc;
0208 }
0209 }
0210
0211 return 0;
0212 }
0213
0214 int
0215 rtems_rfs_fs_open (const char* name,
0216 void* user,
0217 uint32_t flags,
0218 uint32_t max_held_buffers,
0219 rtems_rfs_file_system** fs)
0220 {
0221 #if UNUSED
0222 rtems_rfs_group* group;
0223 size_t group_base;
0224 #endif
0225 rtems_rfs_inode_handle inode;
0226 uint16_t mode;
0227 int rc;
0228
0229 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0230 printf ("rtems-rfs: open: %s\n", name);
0231
0232 *fs = malloc (sizeof (rtems_rfs_file_system));
0233 if (!*fs)
0234 {
0235 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0236 printf ("rtems-rfs: open: no memory for file system data\n");
0237 errno = ENOMEM;
0238 return -1;
0239 }
0240
0241 memset (*fs, 0, sizeof (rtems_rfs_file_system));
0242
0243 (*fs)->user = user;
0244 rtems_chain_initialize_empty (&(*fs)->buffers);
0245 rtems_chain_initialize_empty (&(*fs)->release);
0246 rtems_chain_initialize_empty (&(*fs)->release_modified);
0247 rtems_chain_initialize_empty (&(*fs)->file_shares);
0248
0249 (*fs)->max_held_buffers = max_held_buffers;
0250 (*fs)->buffers_count = 0;
0251 (*fs)->release_count = 0;
0252 (*fs)->release_modified_count = 0;
0253 (*fs)->flags = flags;
0254
0255 #if UNUSED
0256 group = &(*fs)->groups[0];
0257 group_base = 0;
0258 #endif
0259
0260
0261
0262
0263 rc = rtems_rfs_buffer_open (name, *fs);
0264 if (rc > 0)
0265 {
0266 free (*fs);
0267 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0268 printf ("rtems-rfs: open: buffer open failed: %d: %s\n",
0269 rc, strerror (rc));
0270 errno = rc;
0271 return -1;
0272 }
0273
0274 rc = rtems_rfs_fs_read_superblock (*fs);
0275 if (rc > 0)
0276 {
0277 rtems_rfs_buffer_close (*fs);
0278 free (*fs);
0279 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0280 printf ("rtems-rfs: open: reading superblock: %d: %s\n",
0281 rc, strerror (rc));
0282 errno = rc;
0283 return -1;
0284 }
0285
0286 rc = rtems_rfs_inode_open (*fs, RTEMS_RFS_ROOT_INO, &inode, true);
0287 if (rc > 0)
0288 {
0289 rtems_rfs_buffer_close (*fs);
0290 free (*fs);
0291 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0292 printf ("rtems-rfs: open: reading root inode: %d: %s\n",
0293 rc, strerror (rc));
0294 errno = rc;
0295 return -1;
0296 }
0297
0298 if (((*fs)->flags & RTEMS_RFS_FS_FORCE_OPEN) == 0)
0299 {
0300 mode = rtems_rfs_inode_get_mode (&inode);
0301
0302 if ((mode == 0xffff) || !RTEMS_RFS_S_ISDIR (mode))
0303 {
0304 rtems_rfs_inode_close (*fs, &inode);
0305 rtems_rfs_buffer_close (*fs);
0306 free (*fs);
0307 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0308 printf ("rtems-rfs: open: invalid root inode mode\n");
0309 errno = EIO;
0310 return -1;
0311 }
0312 }
0313
0314 rc = rtems_rfs_inode_close (*fs, &inode);
0315 if (rc > 0)
0316 {
0317 rtems_rfs_buffer_close (*fs);
0318 free (*fs);
0319 if (rtems_rfs_trace (RTEMS_RFS_TRACE_OPEN))
0320 printf ("rtems-rfs: open: closing root inode: %d: %s\n", rc, strerror (rc));
0321 errno = rc;
0322 return -1;
0323 }
0324
0325 return 0;
0326 }
0327
0328 int
0329 rtems_rfs_fs_close (rtems_rfs_file_system* fs)
0330 {
0331 int group;
0332
0333 if (rtems_rfs_trace (RTEMS_RFS_TRACE_CLOSE))
0334 printf ("rtems-rfs: close\n");
0335
0336 for (group = 0; group < fs->group_count; group++)
0337 rtems_rfs_group_close (fs, &fs->groups[group]);
0338
0339 rtems_rfs_buffer_close (fs);
0340
0341 free (fs);
0342 return 0;
0343 }