1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 11 #include <stdio_tfs.h> 12 #include <posix.h> 13 #include <fsdriver.h> 14 15 /***********************************************************************/ 16 /* Configuration */ 17 /***********************************************************************/ 18 #ifndef FS_MEM_PROFILE 19 #define FS_MEM_PROFILE FALSE // TRUE to enable FS heap profiling 20 #endif 21 #define INC_FAT_MBR INC_FAT 22 23 /***********************************************************************/ 24 /* Symbol Definitions */ 25 /***********************************************************************/ 26 // FS API input parameter checking 27 #define FS_PARM_CHECK (OS_PARM_CHECK || CIFS_INCLUDED) 28 29 // FSEARCH codes 30 #define FIRST_DIR 0 31 #define CURR_DIR 1 32 #define PARENT_DIR 2 33 #define ACTUAL_DIR 3 34 #define DIR_FILE 4 35 36 // The different types of FileTable entries 37 #define FEMPTY 0 38 #define FDIREN 1 39 #define FCOMMN 2 40 #define FFILEN 3 41 42 // The different types of sectors 43 #define FOTHR 0 44 #define FHEAD 1 45 #define FTAIL 2 46 47 // Number of entries per file table 48 #define FNUM_ENT 20 49 50 // Flag values for writing/skipping control information 51 #define FFLUSH_DO 1 52 #define FFLUSH_DONT 0 53 54 // Flag values for adjusting file pointers in file control blocks 55 #define ADJUST_FCBs TRUE 56 #define DONT_ADJUST_FCBs FALSE 57 58 // Flag values for acquiring exclusive access to volumes 59 #define FS_GRAB_SEM TRUE 60 #define FS_NO_SEM FALSE 61 62 // Flag values for FS sync 63 #define FORCED_SYNC TRUE 64 #define UNFORCED_SYNC FALSE 65 66 // Flag values for the file/directory structure 67 #define F_WRITE (1u << 0) 68 #define F_READ (1u << 1) 69 #define F_EXECUTE (1u << 2) 70 #define F_APPEND (1u << 3) 71 #define F_NONBLOCK (1u << 4) 72 #define F_ASYNC (1u << 5) 73 74 #define FCB_DIR (1u << 6) 75 #define FCB_FILE (1u << 7) 76 #define FCB_TTY (1u << 8) 77 #define FCB_MOD (1u << 9) 78 #define FCB_NO_UPDATE (1u << 10) 79 #define FCB_CLOSE (1u << 11) 80 #define FCB_ESC_HIT (1u << 12) 81 #define FCB_NO_OVERWRITE (1u << 13) 82 #define FSEARCH_NO_SEM (1u << 14) 83 84 // Flag values for FSearchFSUID() 85 #define FILE_NAME 1 86 #define PATH_NAME 2 87 88 // Return values for TFFS recycle function 89 #define RECYCLE_FAILED -1 90 #define RECYCLE_NOT_NEEDED 1 91 #define RECYCLE_OK 0 92 93 #define REMOVED_LINK 0xFFFFFFFF // Value assigned to next and 94 // prev for removed link 95 #define OFF_REMOVED_LINK 0xFFFE 96 97 #define ROOT_DIR_INDEX FOPEN_MAX // index in Files[] for root 98 99 // Maximum allowed number of FFS_VOLS + FAT_VOLS with NAND_FTLS or fixed 100 // This value is used to issue volume ID numbers for the FSUID when a 101 // serial number is not provided 102 #define MAX_FIXED_VOLS 32 103 104 /* 105 ** Number of bits the file ID, volume ID take in the 32 bit FSUID 106 */ 107 #define FID_LEN 20 108 #define VID_LEN 8 109 110 #define FID_MASK 0xFFFFFu // MUST be 2^FID_LEN - 1 111 #define VID_MASK 0xFFu // MUST be 2^VID_LEN - 1 112 #define FSUID_MASK ((VID_MASK << FID_LEN) | FID_MASK) 113 114 // Default block read limits to avoid read-disturb errors 115 #define MLC_NAND_RC_LIMIT 100000 116 #define SLC_NAND_RC_LIMIT 1000000 117 #define NOR_RC_LIMIT 1000000 118 119 // Symbols for excluding/including SLC/MLC-specific code 120 #define INC_NDM_SLC (INC_FTL_NDM_SLC || INC_FFS_NDM_SLC) 121 #define INC_NDM_MLC (INC_FFS_NDM_MLC || INC_FTL_NDM_MLC) 122 123 /***********************************************************************/ 124 /* Macro Definitions */ 125 /***********************************************************************/ 126 // Bitmap accessors 127 #define BITMAP_ON(start, i) (*((ui8*)(start) + (i) / 8) |= (ui8)(1 << ((i) % 8))) 128 #define BITMAP_OFF(start, i) (*((ui8*)(start) + (i) / 8) &= (ui8) ~(1 << ((i) % 8))) 129 #define IS_BITMAP_ON(start, i) (*((ui8*)(start) + (i) / 8) & (1 << ((i) % 8))) 130 131 // Create an FSUID val(ui32) based on volume number and file number 132 #define FSUID(vid, fid) (ui32)((((vid)&VID_MASK) << FID_LEN) | ((fid)&FID_MASK)) 133 134 // Accessor macros for volume ID, file ID from an FSUID 135 #define GET_VID(fsuid) (((fsuid) & (VID_MASK << FID_LEN)) >> FID_LEN) 136 #define GET_FID(fsuid) ((fsuid)&FID_MASK) 137 138 // Determine if an FCB pointer/fid is valid 139 #define IS_VALID_FCB(fcbp) ((fcbp) && (fcbp) >= &Files[0] && (fcbp) < &Files[FOPEN_MAX]) 140 #define IS_VALID_FID(fid) ((fid) >= 0 && (fid) < FOPEN_MAX) 141 142 // Determine if a file system volume is on the mounted list 143 #define IS_MOUNTED(vol) ((vol)->sys.prev || (MountedList.head == &((vol)->sys))) 144 145 /***********************************************************************/ 146 /* Type Definitions */ 147 /***********************************************************************/ 148 typedef struct file_sys FileSys; 149 struct file_sys { 150 FileSys* next; 151 FileSys* prev; 152 ui32 flags; // holds various volume bit flags 153 #define FSYS_FATAL_ERR (1 << 0) 154 #define FSYS_READ_ONLY (1 << 1) 155 #define FSYS_VOL_BUSY (1 << 2) 156 void* (*ioctl)(FILE_TFS* stream, int code, ...); 157 void* volume; 158 #if FILE_AIO_INC 159 int aio_buf_size; // max number of buffered AIO transfers 160 int aio_num_bufs; // number of sectors in each AIO transfer 161 #endif 162 char name[(FILENAME_MAX + 3) & ~3]; // avoid extra padding 163 }; 164 165 typedef struct head_entry { 166 FileSys* head; 167 FileSys* tail; 168 } HeadEntry; 169 170 #if FILE_OFFSETS 171 // An indivual value in the offsets values array 172 typedef struct { 173 ui32 sect_num; // volume sector for offset 174 ui32 sect_off; // sector offset within file for offset 175 } FOff; 176 177 // FCB offsets type 178 typedef struct { 179 FOff values[FILE_OFFSETS]; // recorded file offsets 180 ui32 f_sects; // recorded file size in sectors 181 } FOffs; 182 #endif // FILE_OFFSETS 183 184 // FILE implementation for stdio.h, DIR implementation for posix.h 185 struct file { 186 SEM sem; // internal locking semaphore 187 void (*acquire)(FILE_TFS* fcb, uint access_mode); 188 void (*release)(FILE_TFS* fcb, uint access_mode); 189 void* handle; // self handle to be passed to ioctl 190 void* volume; // file system file/dir belongs to 191 void* pos; // directory position; used for readdir 192 void* (*ioctl)(FILE_TFS* fcb, int code, ...); 193 int (*read_TFS)(FILE_TFS* fcb, ui8* buf, ui32 len); 194 int (*write_TFS)(FILE_TFS* fcb, const ui8* buf, ui32 len); 195 #if FILE_AIO_INC 196 void* aio_ext; // asynchronous I/O control block 197 #endif 198 #if FILE_OFFSETS 199 FOffs* offsets; // file offsets 200 #endif 201 int hold_char; 202 int errcode; 203 struct dirent_TFS dent; // used by readdir() 204 fpos_t_TFS curr_ptr; // current position in file 205 fpos_t_TFS old_ptr; // previous position in file 206 ui32 flags; // file/dir specific flags 207 ui32 parent; // parent directory 208 }; 209 210 // Ioctl() Commands 211 typedef enum { 212 // Begin list of APIs that cause state change. Must be grouped together 213 // numerically because XFS uses range comparisons to test for these. 214 CHMOD = 1, 215 CHOWN, 216 CLOSE_UNLINK, 217 FCLOSE, 218 FFLUSH, 219 FSEEK, 220 FSEEK64, 221 FSTAT_SET, 222 FTRUNCATE, 223 FTRUNCATE64, 224 LINK, 225 MKDIR, 226 OPEN, 227 REMOVE, 228 RENAME, 229 RMDIR, 230 SHRED, 231 SORTDIR, 232 STAT_SET, 233 TRUNCATE, 234 TRUNCATE64, 235 UNLINK_ALL, 236 UTIME, 237 VFS_CREATE, 238 VFS_LINK, 239 VFS_MKDIR, 240 VFS_RENAME, 241 VFS_TRUNCATE, 242 VFS_FTRUNCATE64, 243 VFS_UNLINK, 244 // End list of APIs that cause change of media state 245 ACCESS, 246 ATTRIB, 247 CHDIR, 248 CLOSEDIR, 249 CTIME, 250 DISABLE_SYNC, 251 DUP, 252 ENABLE_SYNC, 253 FEOF, 254 FREOPEN, 255 FSEARCH, 256 FSETPOS, 257 FRSTAT, 258 FSTAT, 259 FTELL, 260 GETCWD, 261 GET_FL, 262 GET_FSUID, 263 GET_FSUID_FID, 264 GET_NAME, 265 GET_QUOTA, 266 GET_QUOTAM, 267 ISOPEN, 268 MMAP, 269 NXT_SECT_CHAIN, 270 OPENDIR, 271 PARAM_DELETE, 272 PARAM_READ, 273 PARAM_SIZE, 274 PARAM_WRITE, 275 READDIR, 276 READDIR_OPEN, 277 READDIR_STAT, 278 REWINDDIR, 279 RSTAT, 280 SECT_FIRST, 281 SECT_NEXT, 282 SETVBUF, 283 SET_FL, 284 STAT, 285 TMPFILE, 286 TMPNAM, 287 UNMOUNT, 288 VCLEAN, 289 VMEMGB, 290 VSTAT, 291 VSYNC, 292 VFS_OPEN 293 } IOCTLS; 294 295 typedef struct f_f_e FFSEnt; 296 typedef struct r_f_e RFSEnt; 297 typedef struct flash_entries FFSEnts; 298 typedef struct ram_entries RFSEnts; 299 300 typedef struct { 301 ui16 sector; 302 ui16 offset; 303 } OffLoc; 304 305 // Represents structure of common info between dir and file in RAM 306 typedef struct { 307 uid_t user_id; // used ID 308 gid_t group_id; // group ID 309 mode_t mode; // file/dir create mode 310 ui16 padding; 311 time_t mod_time; // last modified time for entry 312 time_t ac_time; // last access time for entry 313 ui32 size; // size of file (0 for dirs) 314 ui32 fileno; // file/dir number 315 ui32 attrib; // attribute() field 316 FFSEnt* addr; // entry location in RAM 317 OffLoc one_past_last; // pointer to one past the EOF 318 ui16 frst_sect; // first sector for files (0 for dirs) 319 ui16 last_sect; // last sector for files (0 for dirs) 320 ui8 link_cnt; // number of links from file/dir 321 ui8 open_cnt; // number of file/dir open FCBs 322 ui8 open_mode; // file/dir open mode 323 ui8 opl_offset_hi; // one past last offset overflow byte 324 } FCOM_T; 325 326 // RFS variation of common entry 327 typedef struct { 328 uid_t user_id; // user ID 329 gid_t group_id; // group ID 330 mode_t mode; // file/dir create mode 331 ui16 padding; 332 time_t mod_time; // last modified time for entry 333 time_t ac_time; // last access time for entry 334 ui32 size; // size of file (0 for dirs) 335 ui32 fileno; // file/dir number 336 RFSEnt* addr; // entry location in RAM 337 ui32 one_past_last; // offset within last sector 338 void* first; // first sector(file)/entry(directory) 339 void* last; // last sector(file) 340 ui8 link_cnt; // number of links from file/dir 341 ui8 open_cnt; // number of file/dir open FCBs 342 ui8 open_mode; // file/dir open mode 343 ui8 temp; // indicates temporary file 344 } RCOM_T; 345 346 // Represents structure of a link to a file as used in RAM 347 typedef struct { 348 char* name; // link name 349 FFSEnt* next; // next entry in parent directory 350 FFSEnt* prev; // prev entry in parent directory 351 FCOM_T* comm; // pointer to actual file info 352 FFSEnt* parent_dir; // pointer to parent directory 353 uint open_cnt; // number of file entry opens 354 } FFIL_T; 355 356 // Represents structure of a link to a dir as used in RAM 357 typedef struct { 358 char* name; // directory name 359 FFSEnt* next; // next entry in parent directory 360 FFSEnt* prev; // prev entry in parent directory 361 FCOM_T* comm; // pointer to actual dir info 362 FFSEnt* parent_dir; // pointer to parent directory 363 uint open_cnt; // number of directory entry opens 364 FFSEnt* first; // head of contents list for dir 365 #if QUOTA_ENABLED 366 ui32 max_q; // max quota 367 ui32 min_q; // min quota 368 ui32 used; // used space 369 ui32 free; // free space 370 ui32 free_below; // free space below 371 ui32 res_below; // reserved below 372 #endif 373 } FDIR_T; 374 375 // RFS variation of file entry 376 typedef struct { 377 char* name; // file/directory name 378 RFSEnt* next; // next entry in parent directory 379 RFSEnt* prev; // prev entry in parent directory 380 RCOM_T* comm; // pointer to common entry 381 RFSEnt* parent_dir; // pointer to parent directory 382 uint open_cnt; // number of file entry opens 383 } RFIL_T; 384 385 typedef RFIL_T RDIR_T; 386 387 // Represents the type for an entry in RAM (dir, file or link) 388 union f_file_entry { 389 FDIR_T dir; 390 FCOM_T comm; 391 FFIL_T file; 392 }; 393 394 // Represents the type for an entry for RFS (dif, file or link) 395 union r_file_entry { 396 RDIR_T dir; 397 RCOM_T comm; 398 RFIL_T file; 399 }; 400 401 // An entry in RAM consists of its type and value as a union 402 struct f_f_e { 403 union f_file_entry entry; 404 ui8 type; 405 FFSEnts* tbl; 406 }; 407 408 // An entry in RFS consists of its type and value as a union 409 struct r_f_e { 410 union r_file_entry entry; 411 ui8 type; 412 }; 413 414 // Holds a table full of entries, pointers to next and prev, num free 415 struct flash_entries { 416 FFSEnt tbl[FNUM_ENT]; 417 FFSEnts* next_tbl; 418 FFSEnts* prev_tbl; 419 ui32 free; 420 ui32 num; 421 }; 422 423 struct ram_entries { 424 RFSEnt tbl[FNUM_ENT]; 425 RFSEnts* next_tbl; 426 RFSEnts* prev_tbl; 427 ui32 free; 428 }; 429 430 // Structure to cast all volume structures to, to retrieve ioctl_func 431 typedef struct { 432 CircLink link; /*lint !e601, !e10*/ 433 FileSys sys; 434 } FsVolume; 435 436 #if FS_CRYPT 437 // FS Crypt Type 438 typedef struct fscrypt FSCrypt; 439 struct fscrypt { 440 // Public API 441 void (*delete)(FSCrypt** fs_crypt); 442 int (*decr)(const FSCrypt* fs_crypt, ui8* data, ui32 vpn, int n); 443 int (*rd_decr)(const FSCrypt* fs_crypt, ui8* data, ui32 vpn, int n); 444 int (*encr)(const FSCrypt* fs_crypt, ui8* data, ui32 vpn, int n); 445 int (*encr_wr)(const FSCrypt* fs_crypt, const ui8* data, ui32 vpn, int n); 446 ui32 (*ram_use)(const FSCrypt* fs_crypt); 447 448 ui32 page_sz; // FS read/write page size 449 ui32 buf_pgs; // encryption buffer size in pages 450 ui8* buf; // encryption buffer 451 void* crypt; // encryption/decryption engine 452 void* fs_vol; // parameter passed to FS driver functions 453 454 // FS driver read/write 455 int (*fs_wr)(const void* buf, ui32 frst, int n, void* fs_vol); 456 int (*fs_rd)(void* buf, ui32 frst, int n, void* fs_vol); 457 }; 458 #endif // FS_CRYPT 459 460 /***********************************************************************/ 461 /* Variable Declarations */ 462 /***********************************************************************/ 463 extern int CurrFixedVols; 464 extern FILE_TFS Files[FOPEN_MAX + 1]; 465 extern HeadEntry MountedList; 466 extern FileSys TtySys; 467 extern int FsMaxOpen; // maximum # of concurrently open files 468 extern void* FSIterCurrVol; 469 470 // FS Volumes Lists 471 extern CircLink FatVols; 472 extern CircLink FfsVols; 473 extern CircLink XfsVols; 474 extern CircLink RfsVols; 475 extern CircLink ZfsVols; 476 477 /***********************************************************************/ 478 /* Function Prototypes */ 479 /***********************************************************************/ 480 // File/directory path lookup related functions 481 int FsInvalName(const char* name, int ignore_last); 482 int FsIsLast(const char* name, ui32* lenp, ui32* incp); 483 const char* FsSkipSeparators(const char* path); 484 void* FSearch(void* hndl, const char** path, int dir_lookup, uint flags); 485 char* FSearchFSUID(ui32 fsuid, char* buf, size_t size, int lookup); 486 FileSys* FsResolvePath(const char* path); 487 488 // General system/root level functions 489 int IsFreeFCB(const FILE_TFS* file); 490 void FsInitFCB(FILE_TFS* file, ui32 type); 491 void FsCopyFCB(FILE_TFS* dst, const FILE_TFS* src); 492 int DirFileWrite(FILE_TFS* stream, const ui8* buf, ui32 len); 493 int DirFileRead(FILE_TFS* stream, ui8* buf, ui32 len); 494 void* RootIoctl(DIR_TFS* dir, int code, ...); 495 int FsError(int err_code); 496 int FsIoError(FileSys* file_sys); 497 int FsSetErrno(int flags); 498 499 // Auxiliary functions 500 void QuickSort(RFSEnt** head, RFSEnt** tail, DirEntry* e1, DirEntry* e2, 501 int (*cmp)(const DirEntry*, const DirEntry*)); 502 int FNameEqu(const char* s1, const char* s2); 503 int FNameEquN(const char* s1, const char* s2, size_t n); 504 void DNameCpy(char* dst, const char* src); 505 int DNameEqu(const char* s1, const char* s2); 506 int DNameEquCase(const char* s1, const char* s2); 507 size_t DNameLen(const char* s); 508 void FsAddMount(FileSys* volume); 509 void FsDelMount(FileSys* volume); 510 void* FtlNdmAddFatFTL(FtlNdmVol* ftl_dvr, FatVol* fat_dvr); 511 void* FtlNdmAddXfsFTL(FtlNdmVol* ftl_dvr, XfsVol* xfs_dvr); 512 void FtlnFreeFTL(void* ftl); 513 int FsConvOpenMode(const char* mode); 514 int FsCheckPerm(mode_t mode, uid_t uid, gid_t gid, uint permissions); 515 void FsSetFl(FILE_TFS* fcb, int oflag); 516 void* FsGetFl(const FILE_TFS* fcb); 517 int FsFormatResetWc(const char* name); 518 int FatGetSectSize(const FatVol* fat_vol); 519 ui32 UDiv64(ui64 dividend, ui32 divisor); 520 void FsMemPrn(void); 521 ui32 FsMemPeakRst(void); 522 523 #if FS_CRYPT 524 // FS Crypt Initialization 525 FSCrypt* FsCryptNew(FSCryptDrvr* fs_crypt); 526 int FsCryptSetBufSz(FSCrypt* fs_crypt, ui32 buf_pgs); 527 #endif 528 529 // FCB recorded file offsets interface 530 fpos_t_TFS FOffGet(const FILE_TFS* fcbp, ui32 sect_off, ui32 frst_sect); 531 void FOffSet(FILE_TFS* fcbp, const fpos_t_TFS* new_pos, ui32 f_sects); 532 void FOffUpdate(const FILE_TFS* fcbp, ui32 old_sect, ui32 new_sect); 533 void FOffDel(FILE_TFS* fcbp); 534 535 // Asynchronous I/O 536 void aioInit(void); 537 int aioOpen(FILE_TFS* file, int sect_size); 538 void aioSetIdle(FILE_TFS* file, uint code); 539 void aioVolInit(FileSys* vol); 540 541 // File System Memory Allocation Wrapper Functions 542 void* FsCalloc(size_t nmemb, size_t size); 543 void* FsMalloc(size_t size); 544 void* FsAalloc(size_t size); 545 void FsFreeClear(void* ptr_ptr); 546 void FsAfreeClear(void* ptr_ptr); 547 void FsFree(void* ptr); 548 549 #ifdef __cplusplus 550 } 551 #endif 552