Changeset 657 for trunk/kernel/fs/fatfs.h
- Timestamp:
- Mar 18, 2020, 11:16:59 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/fs/fatfs.h
r656 r657 2 2 * fatfs.h - FATFS file system API definition. 3 3 * 4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017,2018) 4 * Author Alain Greiner (2016,2017,2018,2019,2020) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 27 26 28 27 #include <hal_kernel_types.h> 29 #include <remote_ queuelock.h>28 #include <remote_rwlock.h> 30 29 #include <vfs.h> 31 30 #include <dev_ioc.h> … … 36 35 * 37 36 * The FATFS specific extensions to the generic VFS are the following: 38 * 1) The vfs_ctx_t "extend" field is a void* pointing on the fatfs_ctx_t structure. 39 * This structure contains various general informations such as the total 40 * number of sectors in FAT region, the number of bytes per sector, the number 41 * of sectors per cluster, the lba of FAT region, the lba of data region, or the 42 * cluster index for the root directory. It contains also an extended pointer 43 * on the FAT mapper. 37 * 1) The vfs_ctx_t "extend" field contains a local pointer on the local 38 * fatfs_ctx_t structure. 39 * 44 40 * 2) The vfs_inode_t "extend" contains, for each inode, 45 * the first FAT32 cluster_id (after cast to intptr). 46 * 3) The vfs_dentry_t "extend" field contains, for each dentry, the entry index 47 * in the FATFS directory (32 bytes per FATFS directory entry). 41 * the first FATFS cluster_id (after cast to intptr). 42 * 43 * 3) The vfs_dentry_t "extend" field contains a local pointer on the local 44 * FATFS directory entry (32 bytes) in the directory mapper. 48 45 * 49 46 * In the FAT32 File System, the File Allocation Table is is actually an array … … 57 54 *****************************************************************************************/ 58 55 59 ///////////////////////////////////////////////////////////////////////////////////////////60 61 56 /*************** Partition Boot Sector Format **********************************/ 62 57 // offset | length … … 182 177 * This structure defines a FATFS specific context extension to the VFS context. 183 178 * This fatfs context is replicated in all clusters. 179 * It contains read-only informations such as the total number of sectors in FAT region, 180 * the number of bytes per sector, the number of sectors per cluster, the lba of FAT, 181 * the lba of data region, the cluster_id for the root directory, and an extended 182 * pointer on the FAT mapper. 184 183 * 185 184 * WARNING 1 : All access to the FAT are protected by a remote_rwlock. … … 189 188 * functions to modify the FAT in both the FAT mapper and on IOC device. 190 189 * 191 * WARNING 2 : Most fields are constant values, but the <free_cluster_hint>,192 * < free_clusters>, <lock>, and the <fs_info_buffer> are shared variables,193 * that can be modified by any thread running in any cluster. The <fs_info_buffer>194 * contains a copy of the FS_INFO sector, and is only allocated in the FAT cluster195 * (cluster 0).It is used to synchronously update the free clusters info on IOC device.190 * WARNING 2 : Most fields are constant values, but <free_cluster_hint>, <free_clusters>, 191 * <lock>, and the buffer pointed by the <fs_info_xp> are shared variables, that can 192 * modified by any thread running in any cluster. The <fs_info_buffer> contains 193 * a copy of the FS_INFO sector, and is only allocated in the FAT cluster. 194 * It is used to synchronously update the free clusters info on IOC device. 196 195 * => For all these variables, only the values stored in the FAT cluster must be used. 197 196 ****************************************************************************************/ … … 207 206 uint32_t fs_info_lba; /*! lba of FS_INFO sector */ 208 207 uint32_t root_dir_cluster; /*! cluster index for root directory */ 209 xptr_t fat_mapper_xp; /*! extended pointer on FAT mapper*/208 struct mapper_s * fat_mapper; /*! local pointer on FAT mapper */ 210 209 211 210 /* shared variables (only the copy in FAT cluster must be used) */ 212 uint32_t free_cluster_hint; /*! cluster[hint+1] is the first free*/213 uint32_t free_clusters; /*! free clusters number*/211 uint32_t free_cluster_hint; /*! free_cluster_hint + 1 is first free */ 212 uint32_t free_clusters; /*! number of free clusters */ 214 213 remote_rwlock_t lock; /*! exclusive access to FAT */ 215 214 uint8_t * fs_info_buffer; /*! local pointer on FS_INFO buffer */ … … 224 223 * This debug function display the content of the FATFS context copy in cluster 225 224 * identified by the <cxy> argument. 226 * This function can be called by a thread running in any cluster.225 * This function can be called by any thread running in any cluster. 227 226 ***************************************************************************************** 228 227 * @ cxy : target cluster identifier. … … 232 231 /***************************************************************************************** 233 232 * This debug function access the FAT mapper to display the current FAT state, 234 * as defined by the < page_id>, <min_slot>, and <nb_slots> arguments.235 * It loads the missing pages from IOC to mapper if required.236 * This function can be called by a thread running in any cluster.237 * ****************************************************************************************238 * @ page_id : page index in FAT mapper (one page is 4 Kbytes = 1024 slots).239 * @ min_slot : first slot in page240 * @ nb_slots : number of slots (one slot is 4 bytes).241 * ***************************************************************************************/242 void fatfs_display_fat( uint32_t page_id, 243 233 * as defined by the <min_slot>, and <nb_slots> arguments. 234 * It display as many lines (8 slots par line) as required to display <nb_slots>, 235 * starting from the <min_slot>. The displayed slots can spread on several FAT mapper 236 * pages. It loads the missing pages from IOC to mapper if required. 237 * This function can be called by any thread running in any cluster. 238 ***************************************************************************************** 239 * @ min_slot : first FATFS cluster index. 240 * @ nb_slots : number of slots (one slot is 4 bytes. 241 ****************************************************************************************/ 242 void fatfs_display_fat( uint32_t min_slot, 244 243 uint32_t nb_slots ); 245 244 245 /***************************************************************************************** 246 * This function checks the current values of the "free_clusters" and "free_cluster_hint" 247 * variables in the FS_INFO sector on IOC, versus the values stored in the fatfs context. 248 * As these values are synchronously updated on IOC device at each modification, 249 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device, 250 * and displays a warning message on TXT0 if they are not equal. 251 * This function can be called by any thread running in any cluster. 252 ***************************************************************************************** 253 * @ return 0 if success / return -1 if failure during IOC device access. 254 ****************************************************************************************/ 255 error_t fatfs_check_free_info( void ); 246 256 247 257 ////////////////////////////////////////////////////////////////////////////////////////// … … 251 261 252 262 /***************************************************************************************** 253 * This fuction allocates memory from local cluster for a FATFS context descriptor. 254 ***************************************************************************************** 255 * @ return a pointer on the created context / return NULL if failure. 256 ****************************************************************************************/ 257 fatfs_ctx_t * fatfs_ctx_alloc( void ); 258 259 /***************************************************************************************** 260 * This function access the boot device, and initialises the local FATFS context, 261 * from informations contained in the boot record. This initialisation includes the 262 * creation of the FAT mapper in cluster 0. 263 ***************************************************************************************** 264 * @ vfs_ctx : local pointer on VFS context for FATFS. 265 ****************************************************************************************/ 266 void fatfs_ctx_init( fatfs_ctx_t * fatfs_ctx ); 267 268 /***************************************************************************************** 269 * This function releases memory dynamically allocated for the FATFS context extension. 270 ***************************************************************************************** 271 * @ vfs_ctx : local pointer on VFS context. 272 ****************************************************************************************/ 273 void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx ); 263 * This fuction allocates memory for a FATFS context descriptor in a cluster 264 * identified by the <cxy> argument. 265 ***************************************************************************************** 266 * @ cxy : target cluster identifier. 267 * @ return an extended pointer on the created context / return XPTR_NULL if failure. 268 ****************************************************************************************/ 269 xptr_t fatfs_ctx_alloc( cxy_t cxy ); 270 271 /***************************************************************************************** 272 * This fuction initialize a fatfs context identified by the <fatfs_ctx_xp> argument 273 * from informations found in the IOC device boot record. This initialisation includes 274 * allocation of the FS_INFO buffer and creation of the FAT mapper in the same cluster. 275 ***************************************************************************************** 276 * @ fatfs_ctx_xp : extended pointer on fatfs context. 277 * @ return 0 if success / return -1 if failure. 278 ****************************************************************************************/ 279 error_t fatfs_ctx_init( xptr_t fatfs_ctx_xp ); 280 281 /***************************************************************************************** 282 * This function releases memory dynamically allocated for the FATFS context. 283 ***************************************************************************************** 284 * @ vfs_ctx_xp : extended pointer on FATFS context. 285 ****************************************************************************************/ 286 void fatfs_ctx_destroy( xptr_t fatfs_ctx_xp ); 274 287 275 288 /***************************************************************************************** 276 289 * This function implements the generic vfs_fs_add_dentry() function for the FATFS. 277 290 ***************************************************************************************** 278 * This function updates a directory mapper identified by the <inode> argument 279 * to add a new directory entry identified by the <dentry> argument. 291 * This function introduces in a directory mapper identified by the <parent_inode_xp> 292 * argument a new directory entry identified by the <dentry_ptr> argument. 293 * The dentry descriptor and the associated inode descriptor must have been previously 294 * allocated, initialized, and registered in the Inode Tree. 295 * The dentry descriptor defines the "name" field. 296 * The inode descriptor defines the "type", "size", and "cluster_id" fields. 297 * The "extension field" in dentry descriptor is set : index in the FAT32 directory. 280 298 * All modified pages in the directory mapper are synchronously updated on IOC device. 281 * It must be called by a thread running in the cluster containing the directory inode.299 * This function can be called by any thread running in any cluster. 282 300 * 283 301 * Implementation note : this function works in two steps: … … 285 303 * to find the end of directory (NO_MORE_ENTRY marker). 286 304 * - Then it writes 3, 4, or 5 directory entries (depending on the name length), using 287 * a 5 steps FSM (one state per entry to be written), updates on IOC device the288 * modified pages , and updates the dentry extension field, that must contain289 * the dentry index in FATFS directory.290 * ****************************************************************************************291 * @ inode : local pointer on directory inode.292 * @ dentry : local pointer on dentry.293 * @ return 0 if success / return ENOENT if not found, or EIO if no access to IOC device.294 ****************************************************************************************/ 295 error_t fatfs_add_dentry( struct vfs_inode_s * inode,296 struct vfs_dentry_s * dentry );305 * a 5 steps FSM (one state per entry to be written), and updates on IOC device the 306 * modified pages. 307 ***************************************************************************************** 308 * @ parent_inode_xp : [in] extended pointer on parent directory inode. 309 * @ dentry_ptr : [in] local pointer on dentry (in parent directory cluster). 310 * @ index : [out] index of the new entry in the FAT32 directory. 311 * @ return 0 if success / return -1 if failure. 312 ****************************************************************************************/ 313 error_t fatfs_add_dentry( xptr_t parent_inode_xp, 314 struct vfs_dentry_s * dentry_ptr ); 297 315 298 316 /***************************************************************************************** 299 317 * This function implements the generic vfs_fs_remove_dentry() function for the FATFS. 300 318 ***************************************************************************************** 301 * This function updates a directory identified by the < inode> argument302 * to remove a directory entry identified by the <dentry > argument.319 * This function updates a directory identified by the <parent_inode_xp> argument 320 * to remove a directory entry identified by the <dentry_ptr> argument. 303 321 * All modified pages in directory mapper are synchronously updated on IOC device. 304 * It must be called by a thread running in the cluster containing the inode.322 * This function can be called by any thread running in any cluster. 305 323 * 306 324 * Implementation note: this function uses the dentry extension to directly access … … 308 326 * updates the modified pages on IOC device. 309 327 ***************************************************************************************** 310 * @ inode : local pointer on directory inode. 311 * @ dentry : local pointer on dentry. 312 * @ return 0 if success / return ENOENT if not found, or EIO if no access to IOC device. 313 ****************************************************************************************/ 314 error_t fatfs_remove_dentry( struct vfs_inode_s * inode, 315 struct vfs_dentry_s * dentry ); 316 317 /***************************************************************************************** 318 * This function implements the generic vfs_fs_new_dentry() function for the FATFS. 319 ***************************************************************************************** 320 * It scan a parent directory mapper, identified by the <parent_inode> argument to find 321 * a directory entry identified by the <name> argument. In case of success, it completes 322 * initialization the inode/dentry couple, identified by the <child_inode_xp> argument. 323 * The child inode descriptor, and the associated dentry descriptor must have been 324 * previously allocated by the caller. 328 * @ parent_inode_xp : [in] extended pointer on parent directory inode. 329 * @ dentry_ptr : [in] local pointer on dentry (in parent directory cluster). 330 * @ return 0 if success / return -1 if failure. 331 ****************************************************************************************/ 332 error_t fatfs_remove_dentry( xptr_t parent_inode_xp, 333 struct vfs_dentry_s * dentry_ptr ); 334 335 /***************************************************************************************** 336 * This function implements the generic vfs_fs_new_dentry_from_mapper() for the FATFS. 337 ***************************************************************************************** 338 * It scan a parent directory mapper, identified by the <parent_inode_xp> argument 339 * to find a directory entry name defined by the <dentry_ptr> argument, and completes 340 * the initialization of the dentry and the associated child_inode descriptors, 341 * from informations found in the parent directory mapper : 325 342 * - It set the "type", "size", and "extend" fields in the child inode descriptor. 326 343 * - It set the " extend" field in the dentry descriptor. 327 * It must be called by a thread running in the cluster containing the parent inode. 328 ***************************************************************************************** 329 * @ parent_inode : local pointer on parent inode (directory). 330 * @ name : child name. 331 * @ child_inode_xp : extended pointer on remote child inode (file or directory). 344 * The child inode descriptor, and the dentry descriptor must have been previously 345 * allocated and introduced in the Inode Tree. 346 * This function can be called by any thread running in any cluster. 347 ***************************************************************************************** 348 * @ parent_inode_xp : extended pointer on parent inode (directory). 349 * @ dentry_ptr : local pointer on new dentry (in parent inode cluster). 350 * @ return 0 if success / return -1 if failure. 351 ****************************************************************************************/ 352 error_t fatfs_new_dentry_from_mapper( xptr_t parent_inode_xp, 353 struct vfs_dentry_s * dentry_ptr ); 354 355 /***************************************************************************************** 356 * This function implements the generic vfs_fs_new_dentry_to_mapper() for the FATFS. 357 ***************************************************************************************** 358 * This function introduces a brand new dentry identified by the <dentry_ptr> argument 359 * in the mapper of a directory identified by the <parent_inode_xp> argument. 360 * It is called by the vfs_lookup() function. 361 * The child inode descriptor, and the dentry descriptor must have been previously 362 * allocated and introduced in the Inode Tree. The dentry descriptor contains the name. 363 * 1. It allocates a new FATFS cluster_id, 364 * 2. It registers the allocated cluster_id in the child inode extension, 365 * 3. It add a new entry (32 bytes) in the directory mapper, 366 * This function can be called by any thread running in any cluster. 367 ***************************************************************************************** 368 * @ parent_inode_xp : [in] extended pointer on parent inode (directory). 369 * @ dentry_ptr : [in] local pointer on dentry (in parent inode cluster). 370 * @ return 0 if success / return -1 if failure. 371 ****************************************************************************************/ 372 error_t fatfs_new_dentry_to_mapper( xptr_t parent_inode_xp, 373 struct vfs_dentry_s * dentry_ptr ); 374 375 /***************************************************************************************** 376 * This function implements the generic vfs_fs_update_dentry() function for the FATFS. 377 ***************************************************************************************** 378 * It update the "size" of a directory entry identified by the <dentry_ptr> argument in 379 * the mapper of a directory identified by the <parent_inode_xp> argument, from the 380 * value registered in the inode descriptor. 381 * It scan the directory mapper to find the entry such as name == dentry_ptr->name. 382 * It set the "size" field in the directory mapper, and updates the modified directory 383 * page on the IOC device. 384 * This function can be called by any thread running in any cluster. 385 * 386 * TODO the current implementation uses the fatfs_scan_directory to access the 387 * FAT32 directory by name. We can access directly this directory entry if we use 388 * the dentry "extend" field... 389 ***************************************************************************************** 390 * @ parent_inode_xp : extended pointer on inode (directory). 391 * @ dentry_ptr : local pointer on dentry (in parent directory cluster). 332 392 * @ return 0 if success / return -1 if child not found. 333 393 ****************************************************************************************/ 334 error_t fatfs_new_dentry( struct vfs_inode_s * parent_inode, 335 char * name, 336 xptr_t child_inode_xp ); 337 338 /***************************************************************************************** 339 * This function implements the generic vfs_fs_update_dentry() function for the FATFS. 340 ***************************************************************************************** 341 * It update the size of a directory entry identified by the <dentry> argument in 342 * the mapper of a directory identified by the <inode> argument, as defined by the 343 * <size> argument. 344 * It scan the mapper to find the entry identified by the dentry "name" field. 345 * It set the "size" field in the in the directory mapper AND marks the page as DIRTY. 346 * It must be called by a thread running in the cluster containing the directory inode. 347 ***************************************************************************************** 348 * @ inode : local pointer on inode (directory). 349 * @ dentry : local pointer on dentry (for name). 350 * @ size : new size value. 351 * @ return 0 if success / return ENOENT if child not found. 352 ****************************************************************************************/ 353 error_t fatfs_update_dentry( struct vfs_inode_s * inode, 354 struct vfs_dentry_s * dentry, 355 uint32_t size ); 394 error_t fatfs_update_dentry( xptr_t parent_inode_xp, 395 struct vfs_dentry_s * dentry_ptr ); 356 396 357 397 /***************************************************************************************** … … 367 407 * the Inode Tree is dynamically created, and all dirent fields are documented in the 368 408 * dirent array. Otherwise, only the dentry name is documented. 369 * It must be called by a thread running in the cluster containing the directory inode. 370 ***************************************************************************************** 371 * @ inode : [in] local pointer on directory inode. 409 * 410 * WARNING : It must be called by a thread running in the cluster containing the 411 * target directory inode. 412 ***************************************************************************************** 413 * @ parent_inode_xp : [in] extended pointer on directory inode. 372 414 * @ array : [in] local pointer on array of dirents. 373 415 * @ max_dirent : [in] max number of slots in dirent array. … … 390 432 ***************************************************************************************** 391 433 * It updates the FATFS on the IOC device for a given inode identified by 392 * the <inode > argument. It scan all pages registered in the associated mapper,434 * the <inode_xp> argument. It scan all pages registered in the associated mapper, 393 435 * and copies from mapper to device each page marked as dirty. 394 436 * WARNING : The target <inode> cannot be a directory, because all modifications in a 395 437 * directory are synchronously done on the IOC device by the two fatfs_add_dentry() 396 438 * and fatfs_remove_dentry() functions. 397 ***************************************************************************************** 398 * @ inode : local pointer on inode. 399 * @ return 0 if success / return -1 if failure during IOC device access. 400 ****************************************************************************************/ 401 error_t fatfs_sync_inode( struct vfs_inode_s * inode ); 439 * This function can be called by any thread running in any cluster. 440 ***************************************************************************************** 441 * @ inode_xp : extended pointer on inode. 442 * @ return 0 if success / return -1 if failure. 443 ****************************************************************************************/ 444 error_t fatfs_sync_inode( xptr_t inode_xp ); 402 445 403 446 /***************************************************************************************** … … 407 450 * It scan all clusters registered in the FAT mapper, and copies from mapper to device 408 451 * each page marked as dirty. 409 * 410 * TODO : the current implementation check ALL pages in the FAT region, even if most 411 * pages are empty, and not copied in mapper. It is sub-optimal. 412 * A solution is to maintain in the FAT context two "dirty_min" and "dirty_max" 413 * variables defining the smallest/largest dirty page index in FAT mapper... 452 * This function can be called by any thread running in any cluster. 453 * 454 * Implementation note : this function uses the grdxt_remote_get_first() function 455 * to test only the pages actually registered in the FAT mapper. 414 456 ***************************************************************************************** 415 457 * @ return 0 if success / return -1 if failure during IOC device access. … … 418 460 419 461 /***************************************************************************************** 420 * This function implements the generic vfs_fs_sync_fsinfo() function for the FATFS.421 *****************************************************************************************422 * It checks the current values of the "free_clusters" and "free_cluster_hint" variables423 * in the FS_INFO sector on IOC, versus the values stored in the fatfs context.424 * As these values are synchronously updated on IOC device at each modification,425 * it does nothing if the values are equal. It updates the FS_INFO sector on IOC device,426 * and displays a warning message on TXT0 if they are not equal.427 * This function can be called by any thread running in any cluster.428 *****************************************************************************************429 * @ return 0 if success / return -1 if failure during IOC device access.430 ****************************************************************************************/431 error_t fatfs_sync_free_info( void );432 433 /*****************************************************************************************434 * This function implements the generic vfs_fs_cluster_alloc() function for the FATFS.435 *****************************************************************************************436 * It access the FAT (File allocation table), stored in the FAT mapper, and returns437 * in <searched_cluster> the FATFS cluster index of a free cluster.438 * It can be called by a thread running in any cluster, as it uses remote access439 * primitives when the FAT mapper is remote. It takes the rwlock stored in the FATFS440 * context located in the same cluster as the FAT mapper itself, to get exclusive441 * access to the FAT. It uses and updates the <free_cluster_hint> and <free_clusters>442 * variables stored in this FATFS context.443 * - it updates the <free_cluster_hint> and <free_clusters> variables in FATFS context.444 * - it updates the FAT mapper (handling miss from IOC device if required).445 * - it synchronously updates the FAT region on IOC device.446 * - it returns the allocated cluster index.447 *****************************************************************************************448 * @ searched_cluster_id : [out] allocated FATFS cluster index.449 * @ return 0 if success / return -1 if no more free clusters on IOC device.450 ****************************************************************************************/451 error_t fatfs_cluster_alloc( uint32_t * searched_cluster_id );452 453 /*****************************************************************************************454 462 * This function implements the generic vfs_fs_release_inode() function for the FATFS. 455 463 ***************************************************************************************** 456 * This function is used to remove a given file or directory from FATFS thefile system.464 * This function is used to remove a given file or directory from the FATFS file system. 457 465 * It releases all clusters allocated to a file/directory identified by the <inode_xp> 458 466 * argument. All released clusters are marked FREE_CLUSTER in the FAT mapper. … … 462 470 * synchronously update all modified pages in the FAT mapper to the IOC device. 463 471 * Finally the FS-INFO sector on the IOC device is updated. 472 * This function can be called by any thread running in any cluster. 464 473 ***************************************************************************************** 465 474 * @ inode_xp : extended pointer on inode. … … 478 487 * - For a regular file, it scan the FAT mapper to get the cluster_id on IOC device, 479 488 * and read/write this cluster. 480 * Itcan be called by any thread running in any cluster.489 * This function can be called by any thread running in any cluster. 481 490 * 482 491 * WARNING : For the FAT mapper, the inode field in the mapper MUST be NULL, as this 483 492 * is used to indicate that the corresponding mapper is the FAT mapper. 484 *485 * TODO : In this first implementation, the entry point in the FAT to get the cluster_id486 * is always the cluster_id of the first page, registered in the inode extension.487 * This can introduce a quadratic cost when trying of acessing all pages of a488 * big file. An optimisation would be to introduce in the inode extension two489 * new fields <other_page_id> & <other_cluster_id>, defining a second entry point490 * in the FAT.491 493 ***************************************************************************************** 492 494 * @ page_xp : extended pointer on page descriptor. … … 494 496 * @ return 0 if success / return EIO if error during device access. 495 497 ****************************************************************************************/ 496 error_t fatfs_move_page( xptr_t page_xp,497 cmd_type_t cmd_type );498 error_t fatfs_move_page( xptr_t page_xp, 499 ioc_cmd_type_t cmd_type ); 498 500 499 501
Note: See TracChangeset
for help on using the changeset viewer.