xref: /nrf52832-nimble/rt-thread/components/dfs/filesystems/uffs/src/inc/uffs/uffs_buf.h (revision 104654410c56c573564690304ae786df310c91fc)
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