1 /* 2 This file is part of UFFS, the Ultra-low-cost Flash File System. 3 4 Copyright (C) 2005-2009 Ricky Zheng <[email protected]> 5 6 UFFS is free software; you can redistribute it and/or modify it under 7 the GNU Library General Public License as published by the Free Software 8 Foundation; either version 2 of the License, or (at your option) any 9 later version. 10 11 UFFS is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 or GNU Library General Public License, as applicable, for more details. 15 16 You should have received a copy of the GNU General Public License 17 and GNU Library General Public License along with UFFS; if not, write 18 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20 21 As a special exception, if other files instantiate templates or use 22 macros or inline functions from this file, or you compile this file 23 and link it with other works to produce a work based on this file, 24 this file does not by itself cause the resulting work to be covered 25 by the GNU General Public License. However the source code for this 26 file must still be made available in accordance with section (3) of 27 the GNU General Public License v2. 28 29 This exception does not invalidate any other reasons why a work based 30 on this file might be covered by the GNU General Public License. 31 */ 32 33 /** 34 * \file uffs_buf.h 35 * \brief page buffers 36 * \author Ricky Zheng 37 */ 38 39 #ifndef UFFS_BUF_H 40 #define UFFS_BUF_H 41 42 #include "uffs/uffs_types.h" 43 #include "uffs/uffs_device.h" 44 #include "uffs/uffs_tree.h" 45 #include "uffs/uffs_core.h" 46 47 #ifdef __cplusplus 48 extern "C"{ 49 #endif 50 51 #define CLONE_BUF_MARK 0xffff //!< set uffs_BufSt::ref_count to this for a 'cloned' buffer 52 53 /** for uffs_BufSt::mark */ 54 #define UFFS_BUF_EMPTY 0 //!< buffer is empty 55 #define UFFS_BUF_VALID 1 //!< buffer is holding valid data 56 #define UFFS_BUF_DIRTY 2 //!< buffer data is modified 57 58 /** for uffs_BufSt::ext_mark */ 59 #define UFFS_BUF_EXT_MARK_TRUNC_TAIL 1 //!< the last page of file (when truncating a file) 60 61 /** uffs page buffer */ 62 struct uffs_BufSt{ 63 struct uffs_BufSt *next; //!< link to next buffer 64 struct uffs_BufSt *prev; //!< link to previous buffer 65 struct uffs_BufSt *next_dirty; //!< link to next dirty buffer 66 struct uffs_BufSt *prev_dirty; //!< link to previous dirty buffer 67 u8 type; //!< #UFFS_TYPE_DIR or #UFFS_TYPE_FILE or #UFFS_TYPE_DATA 68 u8 ext_mark; //!< extension mark. 69 u16 parent; //!< parent serial 70 u16 serial; //!< serial 71 u16 page_id; //!< page id 72 u16 mark; //!< #UFFS_BUF_EMPTY or #UFFS_BUF_VALID, or #UFFS_BUF_DIRTY ? 73 u16 ref_count; //!< reference counter, or #CLONE_BUF_MARK for a cloned buffer 74 u16 data_len; //!< length of data 75 u16 check_sum; //!< checksum field 76 u8 * data; //!< data buffer 77 u8 * header; //!< header 78 }; 79 80 #define uffs_BufIsFree(buf) (buf->ref_count == 0 ? U_TRUE : U_FALSE) 81 82 /** initialize page buffers */ 83 URET uffs_BufInit(struct uffs_DeviceSt *dev, int buf_max, int dirty_buf_max); 84 85 /** release page buffers */ 86 URET uffs_BufReleaseAll(struct uffs_DeviceSt *dev); 87 88 /** find the page buffer, move to link list head if found */ 89 uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, u16 parent, u16 serial, u16 page_id); 90 uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, u8 type, TreeNode *node, u16 page_id, int oflag); 91 92 /** alloc a new page buffer */ 93 uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, u8 type, u16 parent, u16 serial, u16 page_id); 94 95 /** find the page buffer (not affect the reference counter) */ 96 uffs_Buf * uffs_BufFind(uffs_Device *dev, u16 parent, u16 serial, u16 page_id); 97 98 /** find the page buffer from #start (not affect the reference counter) */ 99 uffs_Buf * uffs_BufFindFrom(uffs_Device *dev, uffs_Buf *start, 100 u16 parent, u16 serial, u16 page_id); 101 102 /** put page buffer back to pool, called in pair with #uffs_Get,#uffs_GetEx or #uffs_BufNew */ 103 URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf); 104 105 /** increase buffer references */ 106 void uffs_BufIncRef(uffs_Buf *buf); 107 108 /** decrease buffer references */ 109 void uffs_BufDecRef(uffs_Buf *buf); 110 111 /** write data to a page buffer */ 112 URET uffs_BufWrite(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len); 113 114 /** read data from a page buffer */ 115 URET uffs_BufRead(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len); 116 117 /** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, and discard all data it holds */ 118 void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf); 119 120 /** if there is no free dirty group slot, flush the most dirty group */ 121 URET uffs_BufFlush(struct uffs_DeviceSt *dev); 122 URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover); 123 124 /** flush dirty group */ 125 URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial); 126 URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, u16 parent, u16 serial, UBOOL force_block_recover); 127 128 /** find free dirty group slot */ 129 int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev); 130 131 /** find the dirty group slot */ 132 int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial); 133 134 /** lock dirty group */ 135 URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot); 136 137 /** unlock dirty group */ 138 URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot); 139 140 /** flush most dirty group */ 141 URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev); 142 143 /** flush all groups under the same parent number */ 144 URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent); 145 146 /** flush all page buffers */ 147 URET uffs_BufFlushAll(struct uffs_DeviceSt *dev); 148 149 /** no one holding any page buffer ? safe to release page buffers */ 150 UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev); 151 152 /** are all page buffer marked with #UFFS_BUF_EMPTY ? */ 153 UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev); 154 155 /** mark all page buffer as #UFFS_BUF_EMPTY */ 156 URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev); 157 158 /** clone a page buffer */ 159 uffs_Buf * uffs_BufClone(struct uffs_DeviceSt *dev, uffs_Buf *buf); 160 161 /** release a cloned page buffer, call in pair with #uffs_BufClone */ 162 URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf); 163 164 /** load physical storage data to page buffer */ 165 URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page); 166 167 /** load physical storage data to page buffer withouth checking ECC */ 168 URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page); 169 170 /** showing page buffers info, for debug only */ 171 void uffs_BufInspect(uffs_Device *dev); 172 173 #ifdef __cplusplus 174 } 175 #endif 176 177 178 #endif 179