Changeset 602 for trunk/kernel/fs/fatfs.h
- Timestamp:
- Dec 3, 2018, 12:15:53 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/fatfs.h
r484 r602 3 3 * 4 4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017 )5 * Alain Greiner (2016,2017,2018) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 27 27 28 28 #include <hal_kernel_types.h> 29 #include <r wlock.h>29 #include <remote_queuelock.h> 30 30 #include <vfs.h> 31 31 … … 35 35 // 36 36 // The FATFS extensions to the generic VFS are the following: 37 // 37 38 // 1) The vfs_ctx_t "extend" field is a void* pointing on the fatfs_ctx_t structure. 38 39 // This structure contains various general informations such as the total … … 41 42 // cluster index for the root directory. It contains also an extended pointer 42 43 // on the FAT mapper. 43 // 2) The vfs_inode_t "extend" field is a void*, but contains for each inode, 44 // 45 // 2) The vfs_inode_t "extend" contains, for each inode, 44 46 // the first FAT cluster index (after cast to intptr). 47 // 48 // 3) The vfs_dentry_t "extend" field contains, for each dentry, the entry index 49 // in the FATFS directory (32 bytes per FATFS entry). 45 50 /////////////////////////////////////////////////////////////////////////////////////////// 46 51 … … 163 168 struct vfs_ctx_s; 164 169 struct vfs_inode_s; 165 166 /***************************************************************************************** 167 * This structure defines a FATFS specific context (extension to VFS context). 170 struct vfs_dentry_s; 171 172 /***************************************************************************************** 173 * This structure defines a FATFS specific context (extension to VFS context). 174 * This extension is replicated in all clusters. 175 * 176 * WARNING : Almost all fields are constant values, but the <free_cluster_hint> and 177 * <free_clusters> are shared variables. All kernel instances use the variables 178 * in cluster 0, using the <free_lock> remote busy_lock for exclusive access. 168 179 ****************************************************************************************/ 169 180 170 181 typedef struct fatfs_ctx_s 171 182 { 172 uint32_t fat_sectors_count; /*! number of sectors in FAT region */ 173 uint32_t bytes_per_sector; /*! number of bytes per sector */ 174 uint32_t sectors_per_cluster; /*! number of sectors per cluster */ 175 uint32_t fat_begin_lba; /*! lba of FAT region */ 176 uint32_t cluster_begin_lba; /*! lba of data region */ 177 uint32_t root_dir_cluster; /*! cluster index for the root directory */ 178 uint32_t last_allocated_sector; /*! TODO ??? */ 179 uint32_t last_allocated_index; /*! TODO ??? */ 180 xptr_t fat_mapper_xp; /*! FAT mapper (in IO cluster) */ 183 uint32_t fat_sectors_count; /*! number of sectors in FAT region */ 184 uint32_t bytes_per_sector; /*! number of bytes per sector */ 185 uint32_t sectors_per_cluster; /*! number of sectors per cluster */ 186 uint32_t fat_begin_lba; /*! lba of FAT region */ 187 uint32_t cluster_begin_lba; /*! lba of data region */ 188 uint32_t fs_info_lba; /*! lba of FS_INFO sector */ 189 uint32_t root_dir_cluster; /*! cluster index for root directory */ 190 xptr_t fat_mapper_xp; /*! extended pointer on FAT mapper */ 191 uint32_t free_cluster_hint; /*! start point to search free cluster */ 192 uint32_t free_clusters; /*! free clusters number */ 193 remote_queuelock_t free_lock; /*! exclusive access to hint & number */ 181 194 } 182 195 fatfs_ctx_t; … … 186 199 ////////////////////////////////////////////////////////////////////////////////////////// 187 200 188 /****************************************************************************************** 189 * This function scan the FAT (File Allocation Table), stored in the FAT mapper, 190 * and returns the FATFS cluster index for a given page of a given file. 191 * It must be called by a thread running in the cluster containing the FAT mapper. 192 * We can use a RPC to scan the remote FAT mapper, because the RPC_FIFO will avoid 193 * contention in the cluster containing the FAT mapper, and the RPC latency is not 194 * critical compared to the device access latency. 201 /***************************************************************************************** 202 * This function access the FAT (File Allocation Table), stored in the FAT mapper, and 203 * returns in <searched_cluster> the FATFS cluster index for a given page of a given 204 * inode identified by the <first_cluster> and <page_id> arguments. 205 * It can be called by a thread running in any cluster, as it uses remote access 206 * primitives when the FAT mapper is remote. 195 207 * The FAT is actually an array of uint32_t slots. Each slot in this array contains the 196 208 * index of another slot in this array, to form one linked list for each file stored on … … 198 210 * FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page. 199 211 * For a given file, the entry point in the FAT is simply the index of the FATFS cluster 200 * containing the first page of the file. The mapper being a cache, this function 201 * automatically updates the FAT mapper from informations stored on device in case of miss. 202 ****************************************************************************************** 203 * @ mapper : local pointer on the FAT mapper. 204 * @ first_cluster : index of the first FATFS cluster allocated to the file. 205 * @ page_index : index of searched page in file. 206 * @ searched_cluster_id : [out] found FATFS cluster index. 207 * @ return 0 if success / return EIO if a FAT mapper miss cannot be solved. 208 *****************************************************************************************/ 209 error_t fatfs_get_cluster( struct mapper_s * mapper, 210 uint32_t first_cluster, 211 uint32_t page_index, 212 uint32_t * searched_cluster_id ); 213 214 /****************************************************************************************** 212 * containing the first page of the file. The FAT mapper being a cache, this function 213 * updates the FAT mapper from informations stored on IOC device in case of miss. 214 ***************************************************************************************** 215 * @ first_cluster : [in] index of first FATFS cluster allocated to the file. 216 * @ page_id : [in] index of searched page in file. 217 * @ searched_cluster : [out] found FATFS cluster index. 218 * @ return 0 if success / return -1 if a FAT mapper miss cannot be solved. 219 ****************************************************************************************/ 220 error_t fatfs_get_cluster( uint32_t first_cluster, 221 uint32_t page_id, 222 uint32_t * searched_cluster ); 223 224 /***************************************************************************************** 215 225 * This function display the content of the FATFS context. 216 **************************************************************************************** */226 ****************************************************************************************/ 217 227 void fatfs_ctx_display( void ); 218 228 229 /***************************************************************************************** 230 * This function displays the content of a part of the File Allocation Table. 231 * It loads the requested page fom device to mapper if required. 232 ***************************************************************************************** 233 * @ page_id : page index in FAT mapper (one page is 4 Kbytes). 234 * @ nentries : number of entries (one entry is 4 bytes). 235 ****************************************************************************************/ 236 void fatfs_display_fat( uint32_t page_id, 237 uint32_t nentries ); 238 239 219 240 220 241 ////////////////////////////////////////////////////////////////////////////////////////// 221 // Generic API: These functions are called by the kernel ,242 // Generic API: These functions are called by the kernel VFS, 222 243 // and must be implemented by all File Systems. 223 244 ////////////////////////////////////////////////////////////////////////////////////////// 224 245 225 /***************************************************************************************** *246 /***************************************************************************************** 226 247 * This fuction allocates memory from local cluster for a FATFS context descriptor. 227 ***************************************************************************************** *248 ***************************************************************************************** 228 249 * @ return a pointer on the created context / return NULL if failure. 229 **************************************************************************************** */250 ****************************************************************************************/ 230 251 fatfs_ctx_t * fatfs_ctx_alloc( void ); 231 252 232 253 /***************************************************************************************** 233 * This function access the boot device, and initialises the FATFS context254 * This function access the boot device, and initialises the local FATFS context 234 255 * from informations contained in the boot record. 235 256 ***************************************************************************************** … … 246 267 247 268 /***************************************************************************************** 248 * This function moves a page from/to the mapper to/from the FATFS file system on device. 249 * It must be called by a thread running in cluster containing the mapper. 250 * The pointer on the mapper and the page index in file are found in the page descriptor. 251 * WARNING : The inode field in the mapper MUST be NULL for the FAT mapper, as this 252 * is used to implement a specific behaviour to access the FAT zone on device. 253 ***************************************************************************************** 254 * @ page : local pointer on page descriptor. 255 * @ to_mapper : transfer direction 256 * @ return 0 if success / return EIO if error. 257 ****************************************************************************************/ 258 error_t fatfs_mapper_move_page( struct page_s * page, 259 bool_t to_mapper ); 260 261 /***************************************************************************************** 262 * This function scan an existing parent directory, identified by the <parent> argument, 263 * to find a directory entry identified by the <name> argument and update the remote 264 * child inode descriptor, identified by the <child_xp> argument. 265 * It set the "type", "size", and "extend" (FAT cluster index) fields in child inode. 269 * This function implements the generic vfs_fs_add_dentry() function for the FATFS. 270 ***************************************************************************************** 271 * This function updates a directory identified by the <inode> argument 272 * to add a new directory entry identified by the <dentry> argument. 273 * All modified pages in directory mapper are synchronously updated on IOC device. 274 * It must be called by a thread running in the cluster containing the inode. 275 * 276 * Implementation note : this function works in two steps: 277 * - It scan the set of 32 bytes FATFS directry entries, using two embedded loops 278 * to find the end of directory (NO_MORE_ENTRY marker). 279 * - Then it writes 3, 4, or 5 directory entries (depending on the name length), using 280 * a 5 steps FSM (one state per entry to be written), updates on IOC device the 281 * modified pages, and updates the dentry extension field, that must contain 282 * the dentry index in FATFS directory. 283 ***************************************************************************************** 284 * @ inode : local pointer on directory inode. 285 * @ dentry : local pointer on dentry. 286 * @ return 0 if success / return ENOENT if not found, or EIO if no access to IOC device. 287 ****************************************************************************************/ 288 error_t fatfs_add_dentry( struct vfs_inode_s * inode, 289 struct vfs_dentry_s * dentry ); 290 291 /***************************************************************************************** 292 * This function implements the generic vfs_fs_remove_dentry() function for the FATFS. 293 ***************************************************************************************** 294 * This function updates a directory identified by the <inode> argument 295 * to remove a directory entry identified by the <dentry> argument. 296 * All modified pages in directory mapper are synchronously updated on IOC device. 297 * It must be called by a thread running in the cluster containing the inode. 298 * 299 * Implementation note: this function uses the dentry extension to directly access 300 * the NORMAL directory entry and invalidate all involved LFN entries. Then it 301 * updates the modified pages on IOC device. 302 ***************************************************************************************** 303 * @ inode : local pointer on directory inode. 304 * @ dentry : local pointer on dentry. 305 * @ return 0 if success / return ENOENT if not found, or EIO if no access to IOC device. 306 ****************************************************************************************/ 307 error_t fatfs_remove_dentry( struct vfs_inode_s * inode, 308 struct vfs_dentry_s * dentry ); 309 310 /***************************************************************************************** 311 * This function implements the generic vfs_fs_child_init() function for the FATFS. 312 ***************************************************************************************** 313 * It scan the mapper of an existing parent directory, identified by the <parent> 314 * argument, to find a directory entry identified by the <name> argument. 315 * It updates the existing remote child inode, identified by the <child_xp> argument, 316 * - it set the "type", "size", and "extend" fields in inode descriptor. 317 * - it set the " extend" field in dentry descriptor. 266 318 * It must be called by a thread running in the cluster containing the parent inode. 267 319 ***************************************************************************************** … … 271 323 * @ return 0 if success / return ENOENT if child not found. 272 324 ****************************************************************************************/ 273 error_t fatfs_ inode_load( struct vfs_inode_s * parent_inode,325 error_t fatfs_child_init( struct vfs_inode_s * parent_inode, 274 326 char * name, 275 327 xptr_t child_inode_xp ); 276 328 329 /***************************************************************************************** 330 * This function implements the generic vfs_fs_sync_inode() function for the FATFS. 331 ***************************************************************************************** 332 * It updates the FATFS on the IOC device for a given inode identified by 333 * the <inode> argument. It scan all pages registered in the associated mapper, 334 * and copies from mapper to device each page marked as dirty. 335 * WARNING : The target <inode> cannot be a directory, because all modifications in a 336 * directory * are synchronously done on the IOC device by the two fatfs_add_dentry() 337 * and fatfs_remove_dentry() functions. 338 ***************************************************************************************** 339 * @ inode : local pointer on inode. 340 * @ return 0 if success / return EIO if failure during device access. 341 ****************************************************************************************/ 342 error_t fatfs_sync_inode( struct vfs_inode_s * inode ); 343 344 /***************************************************************************************** 345 * This function implements the generic vfs_fs_sync_fat() function for the FATFS. 346 ***************************************************************************************** 347 * It updates the FATFS on the IOC device for the FAT itself. 348 * It scan all clusters registered in the FAT mapper, and copies from mapper to device 349 * each page marked as dirty. 350 * 351 * TODO : the current implementation check ALL pages in the FAT region, even if most 352 * pages are empty, and not copied in mapper. It is sub-optimal. 353 * - A first solution is to maintain in the FAT context two "dirty_min" and "dirty_max" 354 * variables defining the smallest/largest dirty page index in FAT mapper... 355 ***************************************************************************************** 356 * @ return 0 if success / return EIO if failure during device access. 357 ****************************************************************************************/ 358 error_t fatfs_sync_fat( void ); 359 360 /***************************************************************************************** 361 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS. 362 ***************************************************************************************** 363 * It updates the FS_INFO sector on the IOC device. 364 * It copies the <free_cluster_hint> and <free_clusters> variables from 365 * the FATFS context in cluster 0 to the FS_INFO sector on device. 366 ***************************************************************************************** 367 * @ return 0 if success / return EIO if failure during device access. 368 ****************************************************************************************/ 369 error_t fatfs_sync_free_info( void ); 370 371 /***************************************************************************************** 372 * This function implements the generic vfs_fs_cluster_alloc() function for the FATFS. 373 ***************************************************************************************** 374 * It access the FAT (File allocation table), stored in the FAT mapper, and returns 375 * in <searched_cluster> the FATFS cluster index of a free cluster. 376 * It can be called by a thread running in any cluster, as it uses remote access 377 * primitives when the FAT mapper is remote. It takes the "free_lock" stored in the 378 * FATFS context located in the same cluster as the FAT mapper itself, to get exclusive 379 * access to the FAT. It uses (and updates) the <free_cluster_hint> and <free_clusters> 380 * shared variables in this FATFS context. 381 * It updates the FAT mapper, and synchronously updates the FAT region on IOC device. 382 * The FAT mapper being a cache, this function updates the FAT mapper from informations 383 * stored on IOC device in case of miss. 384 ***************************************************************************************** 385 * @ searched_cluster : [out] found FATFS cluster index. 386 * @ return 0 if success / return -1 if no more free clusters on IOC device. 387 ****************************************************************************************/ 388 error_t fatfs_cluster_alloc( uint32_t * searched_cluster ); 389 390 /***************************************************************************************** 391 * This function implements the generic vfs_fs_release_inode() function for the FATFS. 392 ***************************************************************************************** 393 * It releases all clusters allocated to a file/directory identified by the <inode_xp> 394 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper. 395 * This function calls the recursive function fatfs_cluster_release() to release 396 * the clusters in reverse order of the linked list (from last to first). 397 * When the FAT mapper has been updated, it calls the fatfs_sync_fat() function to 398 * synchronously update all dirty pages in the FAT mapper to the IOC device. 399 * Finally the FS-INFO sector on the IOC device is updated. 400 ***************************************************************************************** 401 * @ inode_xp : extended pointer on inode. 402 * @ return 0 if success / return EIO if failure during device access. 403 ****************************************************************************************/ 404 error_t fatfs_release_inode( xptr_t inode_xp ); 405 406 /***************************************************************************************** 407 * This function implements the generic vfs_fs_move_page() function for the FATFS. 408 ***************************************************************************************** 409 * This function moves a page from/to the mapper to/from the FATFS file system on device. 410 * The page must have been previously allocated and registered in the mapper, but the 411 * page - and the mapper - can be located in another cluster than the calling thread. 412 * The pointer on the mapper and the page index in file are found in the page descriptor. 413 * It is used both for the regular file/directory mappers, and for the FAT mapper. 414 * For the FAT mapper, it access the FATFS to get the location on IOC device. 415 * For a regular file, it access the FAT mapper to get the cluster index on IOC device. 416 * It can be called by any thread running in any cluster. 417 * 418 * WARNING : For the FAT mapper, the inode field in the mapper MUST be NULL, as this 419 * is used to indicate that the corresponding mapper is the FAT mapper. 420 ***************************************************************************************** 421 * @ page_xp : extended pointer on page descriptor. 422 * @ to_mapper : true for device->mapper / false for mapper->device 423 * @ return 0 if success / return EIO if error during device access. 424 ****************************************************************************************/ 425 error_t fatfs_move_page( xptr_t page_xp, 426 bool_t to_mapper ); 427 428 429 430 431 432 277 433 #endif /* _FATFS_H_ */
Note: See TracChangeset
for help on using the changeset viewer.