1 /*
2  * JFFS2 -- Journalling Flash File System, Version 2.
3  *
4  * Copyright (C) 2001 Red Hat, Inc.
5  *
6  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
7  *
8  * The original JFFS, from which the design for JFFS2 was derived,
9  * was designed and implemented by Axis Communications AB.
10  *
11  * The contents of this file are subject to the Red Hat eCos Public
12  * License Version 1.1 (the "Licence"); you may not use this file
13  * except in compliance with the Licence.  You may obtain a copy of
14  * the Licence at http://www.redhat.com/
15  *
16  * Software distributed under the Licence is distributed on an "AS IS"
17  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
18  * See the Licence for the specific language governing rights and
19  * limitations under the Licence.
20  *
21  * The Original Code is JFFS2 - Journalling Flash File System, version 2
22  *
23  * Alternatively, the contents of this file may be used under the
24  * terms of the GNU General Public License version 2 (the "GPL"), in
25  * which case the provisions of the GPL are applicable instead of the
26  * above.  If you wish to allow the use of your version of this file
27  * only under the terms of the GPL and not to allow others to use your
28  * version of this file under the RHEPL, indicate your decision by
29  * deleting the provisions above and replace them with the notice and
30  * other provisions required by the GPL.  If you do not delete the
31  * provisions above, a recipient may use your version of this file
32  * under either the RHEPL or the GPL.
33  *
34  * $Id: nodemgmt.c,v 1.45.2.1 2002/02/23 14:13:34 dwmw2 Exp $
35  *
36  */
37 
38 #include <linux/kernel.h>
39 #include <linux/slab.h>
40 #include <linux/jffs2.h>
41 #include <linux/mtd/mtd.h>
42 #include <linux/interrupt.h>
43 #include "nodelist.h"
44 
45 /**
46  *	jffs2_reserve_space - request physical space to write nodes to flash
47  *	@c: superblock info
48  *	@minsize: Minimum acceptable size of allocation
49  *	@ofs: Returned value of node offset
50  *	@len: Returned value of allocation length
51  *	@prio: Allocation type - ALLOC_{NORMAL,DELETION}
52  *
53  *	Requests a block of physical space on the flash. Returns zero for success
54  *	and puts 'ofs' and 'len' into the appriopriate place, or returns -ENOSPC
55  *	or other error if appropriate.
56  *
57  *	If it returns zero, jffs2_reserve_space() also downs the per-filesystem
58  *	allocation semaphore, to prevent more than one allocation from being
59  *	active at any time. The semaphore is later released by jffs2_commit_allocation()
60  *
61  *	jffs2_reserve_space() may trigger garbage collection in order to make room
62  *	for the requested allocation.
63  */
64 
65 static int jffs2_do_reserve_space(struct jffs2_sb_info *c,  __u32 minsize, __u32 *ofs, __u32 *len);
66 
jffs2_reserve_space(struct jffs2_sb_info * c,__u32 minsize,__u32 * ofs,__u32 * len,int prio)67 int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio)
68 {
69 	int ret = -EAGAIN;
70 	int blocksneeded = JFFS2_RESERVED_BLOCKS_WRITE;
71 	/* align it */
72 	minsize = PAD(minsize);
73 
74 	if (prio == ALLOC_DELETION)
75 		blocksneeded = JFFS2_RESERVED_BLOCKS_DELETION;
76 
77 	D1(printk(KERN_DEBUG "jffs2_reserve_space(): Requested 0x%x bytes\n", minsize));
78 	down(&c->alloc_sem);
79 
80 	D1(printk(KERN_DEBUG "jffs2_reserve_space(): alloc sem got\n"));
81 
82 	spin_lock_bh(&c->erase_completion_lock);
83 
84 	/* this needs a little more thought */
85 	while(ret == -EAGAIN) {
86 		while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) {
87 			int ret;
88 
89 			up(&c->alloc_sem);
90 			if (c->dirty_size < c->sector_size) {
91 				D1(printk(KERN_DEBUG "Short on space, but total dirty size 0x%08x < sector size 0x%08x, so -ENOSPC\n", c->dirty_size, c->sector_size));
92 				spin_unlock_bh(&c->erase_completion_lock);
93 				return -ENOSPC;
94 			}
95 			D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
96 				  c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
97 				  c->free_size + c->dirty_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
98 			spin_unlock_bh(&c->erase_completion_lock);
99 
100 			ret = jffs2_garbage_collect_pass(c);
101 			if (ret)
102 				return ret;
103 
104 			if (current->need_resched)
105 				schedule();
106 
107 			if (signal_pending(current))
108 				return -EINTR;
109 
110 			down(&c->alloc_sem);
111 			spin_lock_bh(&c->erase_completion_lock);
112 		}
113 
114 		ret = jffs2_do_reserve_space(c, minsize, ofs, len);
115 		if (ret) {
116 			D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
117 		}
118 	}
119 	spin_unlock_bh(&c->erase_completion_lock);
120 	if (ret)
121 		up(&c->alloc_sem);
122 	return ret;
123 }
124 
jffs2_reserve_space_gc(struct jffs2_sb_info * c,__u32 minsize,__u32 * ofs,__u32 * len)125 int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len)
126 {
127 	int ret = -EAGAIN;
128 	minsize = PAD(minsize);
129 
130 	D1(printk(KERN_DEBUG "jffs2_reserve_space_gc(): Requested 0x%x bytes\n", minsize));
131 
132 	spin_lock_bh(&c->erase_completion_lock);
133 	while(ret == -EAGAIN) {
134 		ret = jffs2_do_reserve_space(c, minsize, ofs, len);
135 		if (ret) {
136 		        D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
137 		}
138 	}
139 	spin_unlock_bh(&c->erase_completion_lock);
140 	return ret;
141 }
142 
143 /* Called with alloc sem _and_ erase_completion_lock */
jffs2_do_reserve_space(struct jffs2_sb_info * c,__u32 minsize,__u32 * ofs,__u32 * len)144 static int jffs2_do_reserve_space(struct jffs2_sb_info *c,  __u32 minsize, __u32 *ofs, __u32 *len)
145 {
146 	struct jffs2_eraseblock *jeb = c->nextblock;
147 
148  restart:
149 	if (jeb && minsize > jeb->free_size) {
150 		/* Skip the end of this block and file it as having some dirty space */
151 		c->dirty_size += jeb->free_size;
152 		c->free_size -= jeb->free_size;
153 		jeb->dirty_size += jeb->free_size;
154 		jeb->free_size = 0;
155 		D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
156 			  jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
157 		list_add_tail(&jeb->list, &c->dirty_list);
158 		c->nextblock = jeb = NULL;
159 	}
160 
161 	if (!jeb) {
162 		struct list_head *next;
163 		/* Take the next block off the 'free' list */
164 
165 		if (list_empty(&c->free_list)) {
166 
167 			DECLARE_WAITQUEUE(wait, current);
168 
169 			if (!c->nr_erasing_blocks) {
170 //			if (list_empty(&c->erasing_list) && list_empty(&c->erase_pending_list) && list_empty(c->erase_complete_list)) {
171 				/* Ouch. We're in GC, or we wouldn't have got here.
172 				   And there's no space left. At all. */
173 				printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n",
174 				       c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
175 				return -ENOSPC;
176 			}
177 			/* Make sure this can't deadlock. Someone has to start the erases
178 			   of erase_pending blocks */
179 			set_current_state(TASK_INTERRUPTIBLE);
180 			add_wait_queue(&c->erase_wait, &wait);
181 			D1(printk(KERN_DEBUG "Waiting for erases to complete. erasing_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n",
182 				  c->nr_erasing_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"));
183 			if (!list_empty(&c->erase_pending_list)) {
184 				D1(printk(KERN_DEBUG "Triggering pending erases\n"));
185 				jffs2_erase_pending_trigger(c);
186 			}
187 			spin_unlock_bh(&c->erase_completion_lock);
188 			schedule();
189 			remove_wait_queue(&c->erase_wait, &wait);
190 			spin_lock_bh(&c->erase_completion_lock);
191 			if (signal_pending(current)) {
192 				return -EINTR;
193 			}
194 			/* An erase may have failed, decreasing the
195 			   amount of free space available. So we must
196 			   restart from the beginning */
197 			return -EAGAIN;
198 		}
199 
200 		next = c->free_list.next;
201 		list_del(next);
202 		c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list);
203 		c->nr_free_blocks--;
204 		if (jeb->free_size != c->sector_size - sizeof(struct jffs2_unknown_node)) {
205 			printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size);
206 			goto restart;
207 		}
208 	}
209 	/* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
210 	   enough space */
211 	*ofs = jeb->offset + (c->sector_size - jeb->free_size);
212 	*len = jeb->free_size;
213 	D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs));
214 	return 0;
215 }
216 
217 /**
218  *	jffs2_add_physical_node_ref - add a physical node reference to the list
219  *	@c: superblock info
220  *	@ofs: physical location of this physical node
221  *	@len: length of this physical node
222  *	@ino: inode number with which this physical node is associated
223  *
224  *	Should only be used to report nodes for which space has been allocated
225  *	by jffs2_reserve_space.
226  *
227  *	Must be called with the alloc_sem held.
228  */
229 
jffs2_add_physical_node_ref(struct jffs2_sb_info * c,struct jffs2_raw_node_ref * new,__u32 len,int dirty)230 int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty)
231 {
232 	struct jffs2_eraseblock *jeb;
233 
234 	len = PAD(len);
235 	jeb = &c->blocks[(new->flash_offset & ~3) / c->sector_size];
236 	D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x, size 0x%x\n", new->flash_offset & ~3, len));
237 #if 1
238 	if (jeb != c->nextblock || (new->flash_offset & ~3) != jeb->offset + (c->sector_size - jeb->free_size)) {
239 		printk(KERN_WARNING "argh. node added in wrong place\n");
240 		jffs2_free_raw_node_ref(new);
241 		return -EINVAL;
242 	}
243 #endif
244 	if (!jeb->first_node)
245 		jeb->first_node = new;
246 	if (jeb->last_node)
247 		jeb->last_node->next_phys = new;
248 	jeb->last_node = new;
249 
250 	spin_lock_bh(&c->erase_completion_lock);
251 	jeb->free_size -= len;
252 	c->free_size -= len;
253 	if (dirty) {
254 		new->flash_offset |= 1;
255 		jeb->dirty_size += len;
256 		c->dirty_size += len;
257 	} else {
258 		jeb->used_size += len;
259 		c->used_size += len;
260 	}
261 	spin_unlock_bh(&c->erase_completion_lock);
262 	if (!jeb->free_size && !jeb->dirty_size) {
263 		/* If it lives on the dirty_list, jffs2_reserve_space will put it there */
264 		D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
265 			  jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
266 		list_add_tail(&jeb->list, &c->clean_list);
267 		c->nextblock = NULL;
268 	}
269 	ACCT_SANITY_CHECK(c,jeb);
270 	ACCT_PARANOIA_CHECK(jeb);
271 
272 	return 0;
273 }
274 
275 
jffs2_complete_reservation(struct jffs2_sb_info * c)276 void jffs2_complete_reservation(struct jffs2_sb_info *c)
277 {
278 	D1(printk(KERN_DEBUG "jffs2_complete_reservation()\n"));
279 	jffs2_garbage_collect_trigger(c);
280 	up(&c->alloc_sem);
281 }
282 
jffs2_mark_node_obsolete(struct jffs2_sb_info * c,struct jffs2_raw_node_ref * ref)283 void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref)
284 {
285 	struct jffs2_eraseblock *jeb;
286 	int blocknr;
287 	struct jffs2_unknown_node n;
288 	int ret;
289 	ssize_t retlen;
290 
291 	if(!ref) {
292 		printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
293 		return;
294 	}
295 	if (ref->flash_offset & 1) {
296 		D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref->flash_offset &~3));
297 		return;
298 	}
299 	blocknr = ref->flash_offset / c->sector_size;
300 	if (blocknr >= c->nr_blocks) {
301 		printk(KERN_NOTICE "raw node at 0x%08x is off the end of device!\n", ref->flash_offset);
302 		BUG();
303 	}
304 	jeb = &c->blocks[blocknr];
305 	if (jeb->used_size < ref->totlen) {
306 		printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
307 		       ref->totlen, blocknr, ref->flash_offset, jeb->used_size);
308 		BUG();
309 	}
310 
311 	spin_lock_bh(&c->erase_completion_lock);
312 	jeb->used_size -= ref->totlen;
313 	jeb->dirty_size += ref->totlen;
314 	c->used_size -= ref->totlen;
315 	c->dirty_size += ref->totlen;
316 	ref->flash_offset |= 1;
317 
318 	ACCT_SANITY_CHECK(c, jeb);
319 
320 	ACCT_PARANOIA_CHECK(jeb);
321 
322 	if (c->flags & JFFS2_SB_FLAG_MOUNTING) {
323 		/* Mount in progress. Don't muck about with the block
324 		   lists because they're not ready yet, and don't actually
325 		   obliterate nodes that look obsolete. If they weren't
326 		   marked obsolete on the flash at the time they _became_
327 		   obsolete, there was probably a reason for that. */
328 		spin_unlock_bh(&c->erase_completion_lock);
329 		return;
330 	}
331 	if (jeb == c->nextblock) {
332 		D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
333 	} else if (jeb == c->gcblock) {
334 		D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
335 #if 0 /* We no longer do this here. It can screw the wear levelling. If you have a lot of static
336 	 data and a few blocks free, and you just create new files and keep deleting/overwriting
337 	 them, then you'd keep erasing and reusing those blocks without ever moving stuff around.
338 	 So we leave completely obsoleted blocks on the dirty_list and let the GC delete them
339 	 when it finds them there. That way, we still get the 'once in a while, take a clean block'
340 	 to spread out the flash usage */
341 	} else if (!jeb->used_size) {
342 		D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset));
343 		list_del(&jeb->list);
344 		D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n"));
345 		list_add_tail(&jeb->list, &c->erase_pending_list);
346 		c->nr_erasing_blocks++;
347 		jffs2_erase_pending_trigger(c);
348 		//		OFNI_BS_2SFFJ(c)->s_dirt = 1;
349 		D1(printk(KERN_DEBUG "Done OK\n"));
350 #endif
351 	} else if (jeb->dirty_size == ref->totlen) {
352 		D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset));
353 		list_del(&jeb->list);
354 		D1(printk(KERN_DEBUG "...and adding to dirty_list\n"));
355 		list_add_tail(&jeb->list, &c->dirty_list);
356 	}
357 	spin_unlock_bh(&c->erase_completion_lock);
358 
359 	if (c->mtd->type != MTD_NORFLASH && c->mtd->type != MTD_RAM)
360 		return;
361 	if (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
362 		return;
363 
364 	D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref->flash_offset &~3));
365 	ret = c->mtd->read(c->mtd, ref->flash_offset &~3, sizeof(n), &retlen, (char *)&n);
366 	if (ret) {
367 		printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret);
368 		return;
369 	}
370 	if (retlen != sizeof(n)) {
371 		printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen);
372 		return;
373 	}
374 	if (PAD(n.totlen) != PAD(ref->totlen)) {
375 		printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen in node ref (0x%08x)\n", n.totlen, ref->totlen);
376 		return;
377 	}
378 	if (!(n.nodetype & JFFS2_NODE_ACCURATE)) {
379 		D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x\n", ref->flash_offset &~3, n.nodetype));
380 		return;
381 	}
382 	n.nodetype &= ~JFFS2_NODE_ACCURATE;
383 	ret = c->mtd->write(c->mtd, ref->flash_offset&~3, sizeof(n), &retlen, (char *)&n);
384 	if (ret) {
385 		printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret);
386 		return;
387 	}
388 	if (retlen != sizeof(n)) {
389 		printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen);
390 		return;
391 	}
392 }
393