yaffs_guts.h
上传用户:wealth48
上传日期:2022-06-24
资源大小:1701k
文件大小:15k
源码类别:

uCOS

开发平台:

C/C++

  1. /*
  2.  * YAFFS: Yet another FFS. A NAND-flash specific file system. 
  3.  * yaffs_guts.h: Configuration etc for yaffs_guts
  4.  *
  5.  * Copyright (C) 2002 Aleph One Ltd.
  6.  *   for Toby Churchill Ltd and Brightstar Engineering
  7.  *
  8.  * Created by Charles Manning <charles@aleph1.co.uk>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU Lesser General Public License version 2.1 as
  12.  * published by the Free Software Foundation.
  13.  *
  14.  *
  15.  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  16.  *
  17.  * $Id: yaffs_guts.h,v 1.18 2004/10/20 20:12:43 charles Exp $
  18.  */
  19. #ifndef __YAFFS_GUTS_H__
  20. #define __YAFFS_GUTS_H__
  21. #include "yportenv.h"
  22. #define YAFFS_OK 1
  23. #define YAFFS_FAIL  0
  24. // Give us a Y=0x59, 
  25. // Give us an A=0x41, 
  26. // Give us an FF=0xFF 
  27. // Give us an S=0x53
  28. // And what have we got... 
  29. #define YAFFS_MAGIC 0x5941FF53
  30. #define YAFFS_NTNODES_LEVEL0    16
  31. #define YAFFS_TNODES_LEVEL0_BITS 4
  32. #define YAFFS_TNODES_LEVEL0_MASK 0xf
  33. #define YAFFS_NTNODES_INTERNAL  (YAFFS_NTNODES_LEVEL0 / 2)
  34. #define YAFFS_TNODES_INTERNAL_BITS  (YAFFS_TNODES_LEVEL0_BITS - 1)
  35. #define YAFFS_TNODES_INTERNAL_MASK 0x7
  36. #define YAFFS_TNODES_MAX_LEVEL 6
  37. #define YAFFS_BYTES_PER_SPARE 16
  38. #define YAFFS_BYTES_PER_CHUNK 512
  39. //#define YAFFS_CHUNK_SIZE_SHIFT 9
  40. #define YAFFS_CHUNKS_PER_BLOCK 32
  41. #define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
  42. #define YAFFS_MAX_CHUNK_ID 0x000FFFFF
  43. #define YAFFS_UNUSED_OBJECT_ID 0x0003FFFF
  44. #define YAFFS_ALLOCATION_NOBJECTS 100
  45. #define YAFFS_ALLOCATION_NTNODES 100
  46. #define YAFFS_ALLOCATION_NLINKS 100
  47. #define YAFFS_NOBJECT_BUCKETS 256
  48. #define YAFFS_OBJECT_SPACE 0x40000
  49. #define YAFFS_MAX_NAME_LENGTH 255
  50. #define YAFFS_SHORT_NAME_LENGTH 15
  51. #define YAFFS_MAX_ALIAS_LENGTH 159
  52. #define YAFFS_OBJECTID_ROOT 1
  53. #define YAFFS_OBJECTID_LOSTNFOUND 2
  54. #define YAFFS_OBJECTID_UNLINKED 3
  55. #define YAFFS_MAX_SHORT_OP_CACHES 20
  56. // ChunkCache is used for short read/write operations.
  57. typedef struct
  58. {
  59. struct yaffs_ObjectStruct *object;
  60. int chunkId;
  61. int lastUse;
  62. int dirty;
  63. int nBytes; // Only valid if the cache is dirty
  64. __u8 data[YAFFS_BYTES_PER_CHUNK];
  65. } yaffs_ChunkCache;
  66. // Tags structures in RAM
  67. // NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise
  68. // the structure size will get blown out.
  69. typedef struct
  70. {
  71.     unsigned chunkId:20;
  72.     unsigned serialNumber:2;
  73.     unsigned byteCount:10;
  74.     unsigned objectId:18;
  75.     unsigned ecc:12;
  76.     unsigned unusedStuff:2;
  77. } yaffs_Tags;
  78. typedef union
  79. {
  80.     yaffs_Tags asTags;
  81.     __u8       asBytes[8];
  82. } yaffs_TagsUnion;
  83. // Spare structure
  84. typedef struct
  85. {
  86.     __u8  tagByte0;
  87.     __u8  tagByte1;
  88.     __u8  tagByte2;
  89.     __u8  tagByte3;
  90.     __u8  pageStatus;  // set to 0 to delete the chunk
  91.     __u8  blockStatus;
  92.     __u8  tagByte4;
  93.     __u8  tagByte5;
  94.     __u8  ecc1[3];
  95.     __u8  tagByte6;
  96.     __u8  tagByte7;
  97.     __u8  ecc2[3];
  98. } yaffs_Spare;
  99. //Special structure for passing through to mtd
  100. struct yaffs_NANDSpare {
  101. yaffs_Spare spare;
  102. int eccres1;
  103. int eccres2;
  104. };
  105. // Block data in RAM
  106. typedef enum {
  107. YAFFS_BLOCK_STATE_UNKNOWN = 0,
  108. YAFFS_BLOCK_STATE_SCANNING, // Used while the block is being scanned.
  109. // NB Don't erase blocks while they're being scanned
  110. YAFFS_BLOCK_STATE_EMPTY, // This block is empty
  111. YAFFS_BLOCK_STATE_ALLOCATING, // This block is partially allocated. 
  112. // This is the one currently being used for page
  113. // allocation. Should never be more than one of these
  114. YAFFS_BLOCK_STATE_FULL, // All the pages in this block have been allocated.
  115. // At least one page holds valid data.
  116.  
  117. YAFFS_BLOCK_STATE_DIRTY, // All pages have been allocated and deleted. 
  118. // Erase me, reuse me.
  119. YAFFS_BLOCK_STATE_DEAD  // This block has failed and is not in use
  120. } yaffs_BlockState;
  121. typedef struct
  122. {
  123. #ifndef CONFIG_YAFFS_NO_YAFFS2
  124. __u32 sequenceNumber; // block sequence number for yaffs2
  125. #endif
  126. int   softDeletions:8;  // number of soft deleted pages
  127.     int   pagesInUse:8; // number of pages in use
  128.     __u32 blockState:4;  // One of the above block states
  129.     __u32 needsRetiring:1; // Data has failed on this block, need to get valid data off
  130.      // and retire the block.
  131. } yaffs_BlockInfo;
  132. //////////////////// Object structure ///////////////////////////
  133. // This is the object structure as stored on NAND
  134. typedef enum
  135. {
  136. YAFFS_OBJECT_TYPE_UNKNOWN,
  137. YAFFS_OBJECT_TYPE_FILE,
  138. YAFFS_OBJECT_TYPE_SYMLINK,
  139. YAFFS_OBJECT_TYPE_DIRECTORY,
  140. YAFFS_OBJECT_TYPE_HARDLINK,
  141. YAFFS_OBJECT_TYPE_SPECIAL
  142. } yaffs_ObjectType;
  143. typedef struct
  144. {
  145. yaffs_ObjectType type;
  146. // Apply to everything
  147. int   parentObjectId;
  148. __u16 sum__NoLongerUsed; // checksum of name. Calc this off the name to prevent inconsistencies
  149. char  name[YAFFS_MAX_NAME_LENGTH + 1];
  150. // Thes following apply to directories, files, symlinks - not hard links
  151. __u32 st_mode;  // protection
  152. #ifdef CONFIG_YAFFS_WINCE
  153. __u32 notForWinCE[5];
  154. #else
  155. __u32 st_uid;   // user ID of owner
  156. __u32 st_gid;    // group ID of owner 
  157. __u32 st_atime; // time of last access
  158. __u32 st_mtime; // time of last modification
  159. __u32 st_ctime; // time of last change
  160. #endif
  161. // File size  applies to files only
  162. int fileSize; 
  163. // Equivalent object id applies to hard links only.
  164. int  equivalentObjectId;
  165. // Alias is for symlinks only.
  166. char alias[YAFFS_MAX_ALIAS_LENGTH + 1];
  167. __u32 st_rdev;  // device stuff for block and char devices (maj/min)
  168. #ifdef CONFIG_YAFFS_WINCE
  169. __u32 win_ctime[2];
  170. __u32 win_atime[2];
  171. __u32 win_mtime[2];
  172. __u32 roomToGrow[6];
  173. #else
  174. __u32 roomToGrow[12];
  175. #endif
  176. } yaffs_ObjectHeader;
  177. ////////////////////  Tnode ///////////////////////////
  178. union yaffs_Tnode_union
  179. {
  180. #ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
  181. union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL+1];
  182. #else
  183. union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL];
  184. #endif
  185. __u16 level0[YAFFS_NTNODES_LEVEL0];
  186. };
  187. typedef union yaffs_Tnode_union yaffs_Tnode;
  188. struct yaffs_TnodeList_struct
  189. {
  190. struct yaffs_TnodeList_struct *next;
  191. yaffs_Tnode *tnodes;
  192. };
  193. typedef struct yaffs_TnodeList_struct yaffs_TnodeList;
  194. ///////////////////  Object ////////////////////////////////
  195. // An object can be one of:
  196. // - a directory (no data, has children links
  197. // - a regular file (data.... not prunes :->).
  198. // - a symlink [symbolic link] (the alias).
  199. // - a hard link
  200. typedef struct 
  201. {
  202. __u32 fileSize;
  203. __u32 scannedFileSize;
  204. int   topLevel;
  205. yaffs_Tnode *top;
  206. } yaffs_FileStructure;
  207. typedef struct
  208. {
  209. struct list_head children; // list of child links
  210. } yaffs_DirectoryStructure;
  211. typedef struct
  212. {
  213. char *alias;
  214. } yaffs_SymLinkStructure;
  215. typedef struct
  216. {
  217. struct yaffs_ObjectStruct *equivalentObject;
  218. __u32 equivalentObjectId;
  219. } yaffs_HardLinkStructure;
  220. typedef union
  221. {
  222. yaffs_FileStructure fileVariant;
  223. yaffs_DirectoryStructure directoryVariant;
  224. yaffs_SymLinkStructure symLinkVariant;
  225. yaffs_HardLinkStructure hardLinkVariant;
  226. } yaffs_ObjectVariant;
  227. struct  yaffs_ObjectStruct
  228. {
  229. __u8 deleted: 1; // This should only apply to unlinked files.
  230. __u8 softDeleted: 1; // it has also been soft deleted
  231. __u8 unlinked: 1; // An unlinked file. The file should be in the unlinked pseudo directory.
  232. __u8 fake:1; // A fake object has no presence on NAND.
  233. __u8 renameAllowed:1;
  234. __u8 unlinkAllowed:1;
  235. __u8 dirty:1; // the object needs to be written to flash
  236. __u8 valid:1; // When the file system is being loaded up, this 
  237. // object might be created before the data
  238. // is available (ie. file data records appear before the header).
  239. __u8 serial; // serial number of chunk in NAND. Store here so we don't have to
  240. // read back the old one to update.
  241. __u16 sum; // sum of the name to speed searching
  242. struct yaffs_DeviceStruct *myDev; // The device I'm on
  243. struct list_head hashLink; // list of objects in this hash bucket
  244. struct list_head hardLinks; // all the equivalent hard linked objects
  245. // live on this list
  246. // directory structure stuff
  247. struct yaffs_ObjectStruct  *parent; //my parent directory
  248. struct list_head siblings; // siblings in a directory
  249. // also used for linking up the free list
  250. // Where's my data in NAND?
  251. int chunkId; // where it lives
  252. int nDataChunks;
  253. __u32 objectId; // the object id value
  254. __u32 st_mode;   // protection
  255. #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
  256. char shortName[YAFFS_SHORT_NAME_LENGTH+1];
  257. #endif
  258. #ifndef __KERNEL__
  259. __u32 inUse;
  260. #endif
  261. #ifdef CONFIG_YAFFS_WINCE
  262. __u32 win_ctime[2];
  263. __u32 win_mtime[2];
  264. __u32 win_atime[2];
  265. #else
  266. __u32 st_uid;    // user ID of owner
  267. __u32 st_gid;     // group ID of owner 
  268. __u32 st_atime;  // time of last access
  269. __u32 st_mtime;  // time of last modification
  270. __u32 st_ctime;  // time of last change
  271. #endif
  272. __u32 st_rdev;      // device stuff for block and char devices
  273. #ifdef __KERNEL__
  274. struct inode *myInode;
  275. __u8  deferedFree;   // YAFFS has removed the object from NAND, but it is being kept
  276.      // Alive until the inode is cleared to prevent inode inconsistencies.
  277. #endif
  278. yaffs_ObjectType variantType;
  279. yaffs_ObjectVariant variant;
  280. };
  281. typedef struct yaffs_ObjectStruct yaffs_Object;
  282. struct yaffs_ObjectList_struct
  283. {
  284. yaffs_Object *objects;
  285. struct yaffs_ObjectList_struct *next;
  286. };
  287. typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
  288. typedef struct
  289. {
  290. struct list_head list;
  291. int count;
  292. } yaffs_ObjectBucket;
  293. //////////////////// Device ////////////////////////////////
  294. struct yaffs_DeviceStruct
  295. {
  296. // Entry parameters set up way early. Yaffs sets up the rest.
  297. int   nBytesPerChunk;   // Should be a power of 2 >= 512
  298. int   nChunksPerBlock;  // does not need to be a power of 2
  299. int   startBlock;  // Start block we're allowed to use
  300. int   endBlock;  // End block we're allowed to use
  301. int   nReservedBlocks;  // We want this tuneable so that we can reduce
  302.  // reserved blocks on NOR and RAM.
  303. int   useNANDECC; // Flag to decide whether or not to use NANDECC
  304. int   nShortOpCaches; // If <= 0, then short op caching is disabled, else
  305. // the number of short op caches (don't use too many).
  306. void *genericDevice; // Pointer to device context
  307.  // On an mtd this holds the mtd pointer.
  308. // NAND access functions (Must be set before calling YAFFS)
  309. int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare);
  310. int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare);
  311. int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND);
  312. int (*initialiseNAND)(struct yaffs_DeviceStruct *dev);
  313. // Runtime parameters. Set up by YAFFS.
  314. __u16 chunkGroupBits; // 0 for devices <= 32MB. else log2(nchunks) - 16
  315. __u16 chunkGroupSize; // == 2^^chunkGroupBits
  316. #ifdef __KERNEL__
  317. struct semaphore sem;// Semaphore for waiting on erasure.
  318. struct semaphore grossLock; // Gross locking semaphore
  319. #endif
  320. #ifdef __KERNEL__
  321. void (*putSuperFunc)(struct super_block *sb);
  322. #endif
  323. int isMounted;
  324. // Block Info
  325. yaffs_BlockInfo *blockInfo;
  326. __u8 *chunkBits;   // bitmap of chunks in use
  327. int   chunkBitmapStride; // Number of bytes of chunkBits per block. 
  328.  // Must be consistent with nChunksPerBlock.
  329. int   nErasedBlocks;
  330. int   allocationBlock; // Current block being allocated off
  331. __u32 allocationPage;
  332. int   allocationBlockFinder; // Used to search for next allocation block
  333. // Runtime state
  334. int   nTnodesCreated;
  335. yaffs_Tnode *freeTnodes;
  336. int  nFreeTnodes;
  337. yaffs_TnodeList *allocatedTnodeList;
  338. int   nObjectsCreated;
  339. yaffs_Object *freeObjects;
  340. int   nFreeObjects;
  341. yaffs_ObjectList *allocatedObjectList;
  342. yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS];
  343. int   nFreeChunks;
  344. int   currentDirtyChecker; // Used to find current dirtiest block
  345. // Operations since mount
  346. int nPageWrites;
  347. int nPageReads;
  348. int nBlockErasures;
  349. int nGCCopies;
  350. int garbageCollections;
  351. int passiveGarbageCollections;
  352. int nRetriedWrites;
  353. int nRetiredBlocks;
  354. int eccFixed;
  355. int eccUnfixed;
  356. int tagsEccFixed;
  357. int tagsEccUnfixed;
  358. int nDeletions;
  359. int nUnmarkedDeletions;
  360. yaffs_Object *rootDir;
  361. yaffs_Object *lostNFoundDir;
  362. // Buffer areas for storing data to recover from write failures
  363. // __u8  bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
  364. // yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK];
  365. int bufferedBlock; // Which block is buffered here?
  366. int doingBufferedBlockRewrite;
  367. yaffs_ChunkCache *srCache;
  368. int srLastUse;
  369. int cacheHits;
  370. // Stuff for background deletion and unlinked files.
  371. yaffs_Object *unlinkedDir; // Directory where unlinked and deleted files live.
  372. yaffs_Object *unlinkedDeletion; // Current file being background deleted.
  373. int nDeletedFiles; // Count of files awaiting deletion;
  374. int nUnlinkedFiles; // Count of unlinked files. 
  375. int nBackgroundDeletions; // Count of background deletions.
  376. __u8 *localBuffer;
  377. };
  378. typedef struct yaffs_DeviceStruct yaffs_Device;
  379. //////////// YAFFS Functions //////////////////
  380. int yaffs_GutsInitialise(yaffs_Device *dev);
  381. void yaffs_Deinitialise(yaffs_Device *dev);
  382. int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev);
  383. // Rename
  384. int yaffs_RenameObject(yaffs_Object *oldDir, const char *oldName, yaffs_Object *newDir, const char *newName);
  385. // generic Object functions
  386. int yaffs_Unlink(yaffs_Object *dir, const char *name);
  387. int yaffs_DeleteFile(yaffs_Object *obj);
  388. // Object access functions.
  389. int yaffs_GetObjectName(yaffs_Object *obj,char *name,int buffSize);
  390. int yaffs_GetObjectFileLength(yaffs_Object *obj);
  391. int yaffs_GetObjectInode(yaffs_Object *obj);
  392. unsigned yaffs_GetObjectType(yaffs_Object *obj);
  393. int yaffs_GetObjectLinkCount(yaffs_Object *obj);
  394. // Change inode attributes
  395. int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr);
  396. int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr);
  397. // File operations
  398. int yaffs_ReadDataFromFile(yaffs_Object *obj, __u8 *buffer, __u32 offset, int nBytes);
  399. int yaffs_WriteDataToFile(yaffs_Object *obj, const __u8 *buffer, __u32 offset, int nBytes);
  400. int yaffs_ResizeFile(yaffs_Object *obj, int newSize);
  401. yaffs_Object *yaffs_MknodFile(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid);
  402. int yaffs_FlushFile(yaffs_Object *obj,int updateTime);
  403. // Directory operations
  404. yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid);
  405. yaffs_Object *yaffs_FindObjectByName(yaffs_Object *theDir,const char *name);
  406. int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,int (*fn)(yaffs_Object *));
  407. yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev,__u32 number);
  408. // Link operations
  409. yaffs_Object *yaffs_Link(yaffs_Object *parent, const char *name, yaffs_Object *equivalentObject);
  410. yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj);
  411. // Symlink operations
  412. yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const char *name, __u32 mode,  __u32 uid, __u32 gid, const char *alias);
  413. char *yaffs_GetSymlinkAlias(yaffs_Object *obj);
  414. // Special inodes (fifos, sockets and devices)
  415. yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid,__u32 rdev);
  416. // Special directories
  417. yaffs_Object *yaffs_Root(yaffs_Device *dev);
  418. yaffs_Object *yaffs_LostNFound(yaffs_Device *dev);
  419. #ifdef CONFIG_YAFFS_WINCE
  420. // CONFIG_YAFFS_WINCE special stuff
  421. void  yfsd_WinFileTimeNow(__u32 target[2]);
  422. #endif
  423. #ifdef __KERNEL__
  424. void yaffs_HandleDeferedFree(yaffs_Object *obj);
  425. #endif
  426. // Debug dump 
  427. int yaffs_DumpObject(yaffs_Object *obj);
  428. void yaffs_GutsTest(yaffs_Device *dev);
  429. #endif