yaffsfs.c: Fix NULL dereference in yaffs_unmount2_reldev()
[yaffs2.git] / direct / test-framework / yaffs_osglue.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2018 Aleph One Ltd.
5  *
6  * Created by Charles Manning <charles@aleph1.co.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 /*
14  * Example OS glue functions for running on a Linux/POSIX system.
15  */
16
17 #include "yaffscfg.h"
18 #include "yaffs_guts.h"
19 #include "yaffsfs.h"
20 #include "yaffs_trace.h"
21 #include <assert.h>
22
23 #include <errno.h>
24 #include <unistd.h>
25
26 /*
27  * yaffsfs_SetError() and yaffsfs_GetError()
28  * Do whatever to set the system error.
29  * yaffsfs_GetError() just fetches the last error.
30  */
31
32 static int yaffsfs_lastError;
33
34 void yaffsfs_SetError(int err)
35 {
36         //Do whatever to set error
37         yaffsfs_lastError = err;
38         errno = err;
39 }
40
41 int yaffsfs_GetLastError(void)
42 {
43         return yaffsfs_lastError;
44 }
45
46 /*
47  * yaffsfs_CheckMemRegion()
48  * Check that access to an address is valid.
49  * This can check memory is in bounds and is writable etc.
50  *
51  * Returns 0 if ok, negative if not.
52  */
53 int yaffsfs_CheckMemRegion(const void *addr, size_t size, int write_request)
54 {
55         (void) size;
56         (void) write_request;
57
58         if(!addr)
59                 return -1;
60         return 0;
61 }
62
63 /*
64  * yaffsfs_Lock()
65  * yaffsfs_Unlock()
66  * A single mechanism to lock and unlock yaffs. Hook up to a mutex or whatever.
67  * Here are two examples, one using POSIX pthreads, the other doing nothing.
68  *
69  * If we use pthreads then we also start a background gc thread.
70  */
71
72 #if 1
73
74 #include <pthread.h>
75
76 static pthread_mutex_t mutex1;
77 static pthread_t bc_gc_thread;
78
79 void yaffsfs_Lock(void)
80 {
81         pthread_mutex_lock( &mutex1 );
82 }
83
84 void yaffsfs_Unlock(void)
85 {
86         pthread_mutex_unlock( &mutex1 );
87 }
88
89 static void *bg_gc_func(void *dummy)
90 {
91         struct yaffs_dev *dev;
92         int urgent = 0;
93         int result;
94         int next_urgent;
95
96         (void)dummy;
97
98         /* Sleep for a bit to allow start up */
99         sleep(2);
100
101
102         while (1) {
103                 /* Iterate through devices, do bg gc updating ungency */
104                 yaffs_dev_rewind();
105                 next_urgent = 0;
106
107                 while ((dev = yaffs_next_dev()) != NULL) {
108                         result = yaffs_do_background_gc_reldev(dev, urgent);
109
110                         /* result is 1 if more than half the free space is
111                          * erased.
112                          * If less than half the free space is erased then it is
113                          * worth doing another background_gc operation sooner.
114                          */
115                         if (result == 0)
116                                 next_urgent = 1;
117                 }
118
119                 urgent = next_urgent;
120
121                 if (next_urgent)
122                         sleep(1);
123                 else
124                         sleep(5);
125         }
126
127         /* Don't ever return. */
128         return NULL;
129 }
130
131 void yaffsfs_LockInit(void)
132 {
133         /* Initialise lock */
134         pthread_mutex_init(&mutex1, NULL);
135
136         /* Sneak in starting a background gc thread too */
137         pthread_create(&bc_gc_thread, NULL, bg_gc_func, NULL);
138 }
139
140 #else
141
142 void yaffsfs_Lock(void)
143 {
144 }
145
146 void yaffsfs_Unlock(void)
147 {
148 }
149
150 void yaffsfs_LockInit(void)
151 {
152 }
153 #endif
154
155 /*
156  * yaffsfs_CurrentTime() retrns a 32-bit timestamp.
157  *
158  * Can return 0 if your system does not care about time.
159  */
160
161 u32 yaffsfs_CurrentTime(void)
162 {
163         return time(NULL);
164 }
165
166
167 /*
168  * yaffsfs_malloc()
169  * yaffsfs_free()
170  *
171  * Functions to allocate and free memory.
172  */
173
174
175 static unsigned malloc_high_water;
176 static unsigned malloc_currently_allocated;
177
178 #ifdef CONFIG_YAFFS_MONITOR_MALLOC
179
180 #include <malloc.h>
181 static void yaffsfs_malloc_add(void *ptr)
182 {
183         unsigned this_size = malloc_usable_size(ptr);
184         malloc_currently_allocated += this_size;
185
186         if (malloc_currently_allocated > malloc_high_water)
187                 malloc_high_water = malloc_currently_allocated;
188 }
189
190 static void yaffsfs_malloc_remove(void *ptr)
191 {
192         unsigned this_size = malloc_usable_size(ptr);
193         malloc_currently_allocated -= this_size;
194 }
195 #else
196 static void yaffsfs_malloc_add(void *ptr)
197 {
198         (void)ptr;
199 }
200
201 static void yaffsfs_malloc_remove(void *ptr)
202 {
203         (void)ptr;
204 }
205 #endif
206
207 void yaffsfs_get_malloc_values(unsigned *current, unsigned *high_water)
208 {
209         if (current)
210                 *current = malloc_currently_allocated;
211         if(high_water)
212                 *high_water = malloc_high_water;
213 }
214
215
216 #ifdef CONFIG_YAFFS_TEST_MALLOC
217
218 static int yaffs_kill_alloc = 0;
219 static size_t total_malloced = 0;
220 static size_t malloc_limit = 0 & 6000000;
221
222 void *yaffsfs_malloc(size_t size)
223 {
224         void * this;
225         if(yaffs_kill_alloc)
226                 return NULL;
227         if(malloc_limit && malloc_limit <(total_malloced + size) )
228                 return NULL;
229
230         this = malloc(size);
231         if(this)
232                 total_malloced += size;
233         yaffsfs_malloc_add(this);
234         return this;
235 }
236
237 #else
238
239 void *yaffsfs_malloc(size_t size)
240 {
241         void *this = malloc(size);
242         yaffsfs_malloc_add(this);
243         return this;
244 }
245
246 #endif
247
248
249
250
251 void yaffsfs_free(void *ptr)
252 {
253         yaffsfs_malloc_remove(ptr);
254         free(ptr);
255 }
256
257 void yaffsfs_OSInitialisation(void)
258 {
259         yaffsfs_LockInit();
260 }
261
262 /*
263  * yaffs_bug_fn()
264  * Function to report a bug.
265  */
266
267 void yaffs_bug_fn(const char *file_name, int line_no)
268 {
269         printf("yaffs bug detected %s:%d\n",
270                 file_name, line_no);
271         assert(0);
272 }