patch-2.4.19 linux-2.4.19/fs/jffs2/scan.c
Next file: linux-2.4.19/fs/jffs2/super.c
Previous file: linux-2.4.19/fs/jffs2/readinode.c
Back to the patch index
Back to the overall index
- Lines: 115
- Date:
Fri Aug 2 17:39:45 2002
- Orig file:
linux-2.4.18/fs/jffs2/scan.c
- Orig date:
Thu Oct 4 15:13:18 2001
diff -urN linux-2.4.18/fs/jffs2/scan.c linux-2.4.19/fs/jffs2/scan.c
@@ -31,7 +31,7 @@
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
- * $Id: scan.c,v 1.51 2001/09/19 00:06:35 dwmw2 Exp $
+ * $Id: scan.c,v 1.51.2.2 2002/02/23 13:34:31 dwmw2 Exp $
*
*/
#include <linux/kernel.h>
@@ -62,6 +62,9 @@
} \
} while(0)
+static uint32_t pseudo_random;
+static void jffs2_rotate_lists(struct jffs2_sb_info *c);
+
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
@@ -142,6 +145,9 @@
c->nr_erasing_blocks++;
}
}
+ /* Rotate the lists by some number to ensure wear levelling */
+ jffs2_rotate_lists(c);
+
if (c->nr_erasing_blocks) {
if (!c->used_size && empty_blocks != c->nr_blocks) {
printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
@@ -444,6 +450,12 @@
*ofs += 4;
return 0;
}
+ /* There was a bug where we wrote hole nodes out with csize/dsize
+ swapped. Deal with it */
+ if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {
+ ri.dsize = ri.csize;
+ ri.csize = 0;
+ }
if (ri.csize) {
/* Check data CRC too */
@@ -474,7 +486,7 @@
*ofs, ri.data_crc, crc);
DIRTY_SPACE(PAD(ri.totlen));
*ofs += PAD(ri.totlen);
- return -0;
+ return 0;
}
}
@@ -518,6 +530,8 @@
D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));
+ pseudo_random += ri.version;
+
for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {
if ((*tn_list)->version < ri.version)
continue;
@@ -613,6 +627,8 @@
return 0;
}
+ pseudo_random += rd.version;
+
fd = jffs2_alloc_full_dirent(rd.nsize+1);
if (!fd) {
return -ENOMEM;
@@ -686,3 +702,45 @@
*ofs += PAD(rd.totlen);
return 0;
}
+
+static int count_list(struct list_head *l)
+{
+ uint32_t count = 0;
+ struct list_head *tmp;
+
+ list_for_each(tmp, l) {
+ count++;
+ }
+ return count;
+}
+
+/* Note: This breaks if list_empty(head). I don't care. You
+ might, if you copy this code and use it elsewhere :) */
+static void rotate_list(struct list_head *head, uint32_t count)
+{
+ struct list_head *n = head->next;
+
+ list_del(head);
+ while(count--)
+ n = n->next;
+ list_add(head, n);
+}
+
+static void jffs2_rotate_lists(struct jffs2_sb_info *c)
+{
+ uint32_t x;
+
+ x = count_list(&c->clean_list);
+ if (x)
+ rotate_list((&c->clean_list), pseudo_random % x);
+
+ x = count_list(&c->dirty_list);
+ if (x)
+ rotate_list((&c->dirty_list), pseudo_random % x);
+
+ if (c->nr_erasing_blocks)
+ rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);
+
+ if (c->nr_free_blocks) /* Not that it should ever be zero */
+ rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)