diff options
Diffstat (limited to 'fs/jffs2')
46 files changed, 880 insertions, 1386 deletions
diff --git a/fs/jffs2/LICENCE b/fs/jffs2/LICENCE index cd81d83e4ad2..562885908135 100644 --- a/fs/jffs2/LICENCE +++ b/fs/jffs2/LICENCE | |||
@@ -1,7 +1,7 @@ | |||
1 | The files in this directory and elsewhere which refer to this LICENCE | 1 | The files in this directory and elsewhere which refer to this LICENCE |
2 | file are part of JFFS2, the Journalling Flash File System v2. | 2 | file are part of JFFS2, the Journalling Flash File System v2. |
3 | 3 | ||
4 | Copyright (C) 2001, 2002 Red Hat, Inc. | 4 | Copyright © 2001-2007 Red Hat, Inc. and others |
5 | 5 | ||
6 | JFFS2 is free software; you can redistribute it and/or modify it under | 6 | JFFS2 is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free | 7 | the terms of the GNU General Public License as published by the Free |
@@ -28,8 +28,3 @@ of the GNU General Public License. | |||
28 | This exception does not invalidate any other reasons why a work based on | 28 | This exception does not invalidate any other reasons why a work based on |
29 | this file might be covered by the GNU General Public License. | 29 | this file might be covered by the GNU General Public License. |
30 | 30 | ||
31 | For information on obtaining alternative licences for JFFS2, see | ||
32 | http://sources.redhat.com/jffs2/jffs2-licence.html | ||
33 | |||
34 | |||
35 | $Id: LICENCE,v 1.1 2002/05/20 14:56:37 dwmw2 Exp $ | ||
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile index 7f28ee0bd132..c32b241e3d91 100644 --- a/fs/jffs2/Makefile +++ b/fs/jffs2/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the Linux Journalling Flash File System v2 (JFFS2) | 2 | # Makefile for the Linux Journalling Flash File System v2 (JFFS2) |
3 | # | 3 | # |
4 | # $Id: Makefile.common,v 1.11 2005/09/07 08:34:53 havasi Exp $ | ||
5 | # | 4 | # |
6 | 5 | ||
7 | obj-$(CONFIG_JFFS2_FS) += jffs2.o | 6 | obj-$(CONFIG_JFFS2_FS) += jffs2.o |
diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking index c8f0bd64e53e..d14d5a4dc5ac 100644 --- a/fs/jffs2/README.Locking +++ b/fs/jffs2/README.Locking | |||
@@ -1,4 +1,3 @@ | |||
1 | $Id: README.Locking,v 1.12 2005/04/13 13:22:35 dwmw2 Exp $ | ||
2 | 1 | ||
3 | JFFS2 LOCKING DOCUMENTATION | 2 | JFFS2 LOCKING DOCUMENTATION |
4 | --------------------------- | 3 | --------------------------- |
diff --git a/fs/jffs2/TODO b/fs/jffs2/TODO index d0e23b26fa50..5d3ea4070f01 100644 --- a/fs/jffs2/TODO +++ b/fs/jffs2/TODO | |||
@@ -1,4 +1,3 @@ | |||
1 | $Id: TODO,v 1.18 2005/09/22 11:24:56 dedekind Exp $ | ||
2 | 1 | ||
3 | - support asynchronous operation -- add a per-fs 'reserved_space' count, | 2 | - support asynchronous operation -- add a per-fs 'reserved_space' count, |
4 | let each outstanding write reserve the _maximum_ amount of physical | 3 | let each outstanding write reserve the _maximum_ amount of physical |
@@ -30,8 +29,6 @@ $Id: TODO,v 1.18 2005/09/22 11:24:56 dedekind Exp $ | |||
30 | the full dirent, we only need to go to the flash in lookup() when we think we've | 29 | the full dirent, we only need to go to the flash in lookup() when we think we've |
31 | got a match, and in readdir(). | 30 | got a match, and in readdir(). |
32 | - Doubly-linked next_in_ino list to allow us to free obsoleted raw_node_refs immediately? | 31 | - Doubly-linked next_in_ino list to allow us to free obsoleted raw_node_refs immediately? |
33 | - Remove totlen from jffs2_raw_node_ref? Need to have totlen passed into | ||
34 | jffs2_mark_node_obsolete(). Can all callers work it out? | ||
35 | - Remove size from jffs2_raw_node_frag. | 32 | - Remove size from jffs2_raw_node_frag. |
36 | 33 | ||
37 | dedekind: | 34 | dedekind: |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 73f0d60f73a5..a46101ee867a 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
13 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index fa327dbd3171..c84378cee82a 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | struct jffs2_acl_entry { | 12 | struct jffs2_acl_entry { |
12 | jint16_t e_tag; | 13 | jint16_t e_tag; |
13 | jint16_t e_perm; | 14 | jint16_t e_perm; |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 888f236e5494..0c82dfcfd246 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: background.c,v 1.54 2005/05/20 21:37:12 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c index 07119c42a861..0ca2fff2617f 100644 --- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: build.c,v 1.85 2005/11/07 11:14:38 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c index 7001ba26c067..485d065de41f 100644 --- a/fs/jffs2/compr.c +++ b/fs/jffs2/compr.c | |||
@@ -1,16 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * Created by Arjan van de Ven <arjanv@redhat.com> | 5 | * Created by Arjan van de Ven <arjanv@redhat.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, | 7 | * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, |
8 | * University of Szeged, Hungary | 8 | * University of Szeged, Hungary |
9 | * | 9 | * |
10 | * For licensing information, see the file 'LICENCE' in this directory. | 10 | * For licensing information, see the file 'LICENCE' in this directory. |
11 | * | 11 | * |
12 | * $Id: compr.c,v 1.46 2005/11/07 11:14:38 gleixner Exp $ | ||
13 | * | ||
14 | */ | 12 | */ |
15 | 13 | ||
16 | #include "compr.h" | 14 | #include "compr.h" |
@@ -268,144 +266,6 @@ int jffs2_unregister_compressor(struct jffs2_compressor *comp) | |||
268 | return 0; | 266 | return 0; |
269 | } | 267 | } |
270 | 268 | ||
271 | #ifdef CONFIG_JFFS2_PROC | ||
272 | |||
273 | #define JFFS2_STAT_BUF_SIZE 16000 | ||
274 | |||
275 | char *jffs2_list_compressors(void) | ||
276 | { | ||
277 | struct jffs2_compressor *this; | ||
278 | char *buf, *act_buf; | ||
279 | |||
280 | act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL); | ||
281 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
282 | act_buf += sprintf(act_buf, "%10s priority:%d ", this->name, this->priority); | ||
283 | if ((this->disabled)||(!this->compress)) | ||
284 | act_buf += sprintf(act_buf,"disabled"); | ||
285 | else | ||
286 | act_buf += sprintf(act_buf,"enabled"); | ||
287 | act_buf += sprintf(act_buf,"\n"); | ||
288 | } | ||
289 | return buf; | ||
290 | } | ||
291 | |||
292 | char *jffs2_stats(void) | ||
293 | { | ||
294 | struct jffs2_compressor *this; | ||
295 | char *buf, *act_buf; | ||
296 | |||
297 | act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL); | ||
298 | |||
299 | act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n"); | ||
300 | act_buf += sprintf(act_buf,"%10s ","none"); | ||
301 | act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks, | ||
302 | none_stat_compr_size, none_stat_decompr_blocks); | ||
303 | spin_lock(&jffs2_compressor_list_lock); | ||
304 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
305 | act_buf += sprintf(act_buf,"%10s ",this->name); | ||
306 | if ((this->disabled)||(!this->compress)) | ||
307 | act_buf += sprintf(act_buf,"- "); | ||
308 | else | ||
309 | act_buf += sprintf(act_buf,"+ "); | ||
310 | act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks, | ||
311 | this->stat_compr_new_size, this->stat_compr_orig_size, | ||
312 | this->stat_decompr_blocks); | ||
313 | act_buf += sprintf(act_buf,"\n"); | ||
314 | } | ||
315 | spin_unlock(&jffs2_compressor_list_lock); | ||
316 | |||
317 | return buf; | ||
318 | } | ||
319 | |||
320 | char *jffs2_get_compression_mode_name(void) | ||
321 | { | ||
322 | switch (jffs2_compression_mode) { | ||
323 | case JFFS2_COMPR_MODE_NONE: | ||
324 | return "none"; | ||
325 | case JFFS2_COMPR_MODE_PRIORITY: | ||
326 | return "priority"; | ||
327 | case JFFS2_COMPR_MODE_SIZE: | ||
328 | return "size"; | ||
329 | } | ||
330 | return "unkown"; | ||
331 | } | ||
332 | |||
333 | int jffs2_set_compression_mode_name(const char *name) | ||
334 | { | ||
335 | if (!strcmp("none",name)) { | ||
336 | jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; | ||
337 | return 0; | ||
338 | } | ||
339 | if (!strcmp("priority",name)) { | ||
340 | jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; | ||
341 | return 0; | ||
342 | } | ||
343 | if (!strcmp("size",name)) { | ||
344 | jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; | ||
345 | return 0; | ||
346 | } | ||
347 | return 1; | ||
348 | } | ||
349 | |||
350 | static int jffs2_compressor_Xable(const char *name, int disabled) | ||
351 | { | ||
352 | struct jffs2_compressor *this; | ||
353 | spin_lock(&jffs2_compressor_list_lock); | ||
354 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
355 | if (!strcmp(this->name, name)) { | ||
356 | this->disabled = disabled; | ||
357 | spin_unlock(&jffs2_compressor_list_lock); | ||
358 | return 0; | ||
359 | } | ||
360 | } | ||
361 | spin_unlock(&jffs2_compressor_list_lock); | ||
362 | printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); | ||
363 | return 1; | ||
364 | } | ||
365 | |||
366 | int jffs2_enable_compressor_name(const char *name) | ||
367 | { | ||
368 | return jffs2_compressor_Xable(name, 0); | ||
369 | } | ||
370 | |||
371 | int jffs2_disable_compressor_name(const char *name) | ||
372 | { | ||
373 | return jffs2_compressor_Xable(name, 1); | ||
374 | } | ||
375 | |||
376 | int jffs2_set_compressor_priority(const char *name, int priority) | ||
377 | { | ||
378 | struct jffs2_compressor *this,*comp; | ||
379 | spin_lock(&jffs2_compressor_list_lock); | ||
380 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
381 | if (!strcmp(this->name, name)) { | ||
382 | this->priority = priority; | ||
383 | comp = this; | ||
384 | goto reinsert; | ||
385 | } | ||
386 | } | ||
387 | spin_unlock(&jffs2_compressor_list_lock); | ||
388 | printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); | ||
389 | return 1; | ||
390 | reinsert: | ||
391 | /* list is sorted in the order of priority, so if | ||
392 | we change it we have to reinsert it into the | ||
393 | good place */ | ||
394 | list_del(&comp->list); | ||
395 | list_for_each_entry(this, &jffs2_compressor_list, list) { | ||
396 | if (this->priority < comp->priority) { | ||
397 | list_add(&comp->list, this->list.prev); | ||
398 | spin_unlock(&jffs2_compressor_list_lock); | ||
399 | return 0; | ||
400 | } | ||
401 | } | ||
402 | list_add_tail(&comp->list, &jffs2_compressor_list); | ||
403 | spin_unlock(&jffs2_compressor_list_lock); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | #endif | ||
408 | |||
409 | void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) | 269 | void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) |
410 | { | 270 | { |
411 | if (orig != comprbuf) | 271 | if (orig != comprbuf) |
diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h index 509b8b1c0811..68cc7010dbdf 100644 --- a/fs/jffs2/compr.h +++ b/fs/jffs2/compr.h | |||
@@ -1,13 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, | 4 | * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, |
5 | * University of Szeged, Hungary | 5 | * University of Szeged, Hungary |
6 | * | 6 | * |
7 | * For licensing information, see the file 'LICENCE' in the | 7 | * For licensing information, see the file 'LICENCE' in this directory. |
8 | * jffs2 directory. | ||
9 | * | ||
10 | * $Id: compr.h,v 1.9 2005/11/07 11:14:38 gleixner Exp $ | ||
11 | * | 8 | * |
12 | */ | 9 | */ |
13 | 10 | ||
@@ -76,16 +73,6 @@ int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
76 | 73 | ||
77 | void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig); | 74 | void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig); |
78 | 75 | ||
79 | #ifdef CONFIG_JFFS2_PROC | ||
80 | int jffs2_enable_compressor_name(const char *name); | ||
81 | int jffs2_disable_compressor_name(const char *name); | ||
82 | int jffs2_set_compression_mode_name(const char *mode_name); | ||
83 | char *jffs2_get_compression_mode_name(void); | ||
84 | int jffs2_set_compressor_priority(const char *mode_name, int priority); | ||
85 | char *jffs2_list_compressors(void); | ||
86 | char *jffs2_stats(void); | ||
87 | #endif | ||
88 | |||
89 | /* Compressor modules */ | 76 | /* Compressor modules */ |
90 | /* These functions will be called by jffs2_compressors_init/exit */ | 77 | /* These functions will be called by jffs2_compressors_init/exit */ |
91 | 78 | ||
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c index 2eb1b7428d16..0d0bfd2e4e0d 100644 --- a/fs/jffs2/compr_rtime.c +++ b/fs/jffs2/compr_rtime.c | |||
@@ -1,13 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by Arjan van de Ven <arjanv@redhat.com> | 6 | * Created by Arjan van de Ven <arjanv@redhat.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: compr_rtime.c,v 1.14 2004/06/23 16:34:40 havasi Exp $ | ||
11 | * | 10 | * |
12 | * | 11 | * |
13 | * Very simple lz77-ish encoder. | 12 | * Very simple lz77-ish encoder. |
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c index e792e675d624..ea0431e047d5 100644 --- a/fs/jffs2/compr_rubin.c +++ b/fs/jffs2/compr_rubin.c | |||
@@ -1,23 +1,94 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001, 2002 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by Arjan van de Ven <arjanv@redhat.com> | 6 | * Created by Arjan van de Ven <arjanv@redhat.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: compr_rubin.c,v 1.20 2004/06/23 16:34:40 havasi Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/string.h> | 12 | #include <linux/string.h> |
15 | #include <linux/types.h> | 13 | #include <linux/types.h> |
16 | #include <linux/jffs2.h> | 14 | #include <linux/jffs2.h> |
17 | #include "compr_rubin.h" | 15 | #include <linux/errno.h> |
18 | #include "histo_mips.h" | ||
19 | #include "compr.h" | 16 | #include "compr.h" |
20 | 17 | ||
18 | |||
19 | #define RUBIN_REG_SIZE 16 | ||
20 | #define UPPER_BIT_RUBIN (((long) 1)<<(RUBIN_REG_SIZE-1)) | ||
21 | #define LOWER_BITS_RUBIN ((((long) 1)<<(RUBIN_REG_SIZE-1))-1) | ||
22 | |||
23 | |||
24 | #define BIT_DIVIDER_MIPS 1043 | ||
25 | static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */ | ||
26 | |||
27 | #include <linux/errno.h> | ||
28 | |||
29 | struct pushpull { | ||
30 | unsigned char *buf; | ||
31 | unsigned int buflen; | ||
32 | unsigned int ofs; | ||
33 | unsigned int reserve; | ||
34 | }; | ||
35 | |||
36 | struct rubin_state { | ||
37 | unsigned long p; | ||
38 | unsigned long q; | ||
39 | unsigned long rec_q; | ||
40 | long bit_number; | ||
41 | struct pushpull pp; | ||
42 | int bit_divider; | ||
43 | int bits[8]; | ||
44 | }; | ||
45 | |||
46 | static inline void init_pushpull(struct pushpull *pp, char *buf, unsigned buflen, unsigned ofs, unsigned reserve) | ||
47 | { | ||
48 | pp->buf = buf; | ||
49 | pp->buflen = buflen; | ||
50 | pp->ofs = ofs; | ||
51 | pp->reserve = reserve; | ||
52 | } | ||
53 | |||
54 | static inline int pushbit(struct pushpull *pp, int bit, int use_reserved) | ||
55 | { | ||
56 | if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) { | ||
57 | return -ENOSPC; | ||
58 | } | ||
59 | |||
60 | if (bit) { | ||
61 | pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs &7))); | ||
62 | } | ||
63 | else { | ||
64 | pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs &7))); | ||
65 | } | ||
66 | pp->ofs++; | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static inline int pushedbits(struct pushpull *pp) | ||
72 | { | ||
73 | return pp->ofs; | ||
74 | } | ||
75 | |||
76 | static inline int pullbit(struct pushpull *pp) | ||
77 | { | ||
78 | int bit; | ||
79 | |||
80 | bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1; | ||
81 | |||
82 | pp->ofs++; | ||
83 | return bit; | ||
84 | } | ||
85 | |||
86 | static inline int pulledbits(struct pushpull *pp) | ||
87 | { | ||
88 | return pp->ofs; | ||
89 | } | ||
90 | |||
91 | |||
21 | static void init_rubin(struct rubin_state *rs, int div, int *bits) | 92 | static void init_rubin(struct rubin_state *rs, int div, int *bits) |
22 | { | 93 | { |
23 | int c; | 94 | int c; |
diff --git a/fs/jffs2/compr_rubin.h b/fs/jffs2/compr_rubin.h deleted file mode 100644 index bf1a93451621..000000000000 --- a/fs/jffs2/compr_rubin.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* Rubin encoder/decoder header */ | ||
2 | /* work started at : aug 3, 1994 */ | ||
3 | /* last modification : aug 15, 1994 */ | ||
4 | /* $Id: compr_rubin.h,v 1.7 2005/11/07 11:14:38 gleixner Exp $ */ | ||
5 | |||
6 | #include "pushpull.h" | ||
7 | |||
8 | #define RUBIN_REG_SIZE 16 | ||
9 | #define UPPER_BIT_RUBIN (((long) 1)<<(RUBIN_REG_SIZE-1)) | ||
10 | #define LOWER_BITS_RUBIN ((((long) 1)<<(RUBIN_REG_SIZE-1))-1) | ||
11 | |||
12 | |||
13 | struct rubin_state { | ||
14 | unsigned long p; | ||
15 | unsigned long q; | ||
16 | unsigned long rec_q; | ||
17 | long bit_number; | ||
18 | struct pushpull pp; | ||
19 | int bit_divider; | ||
20 | int bits[8]; | ||
21 | }; | ||
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c index 0c1fc6e20b43..2b87fccc1557 100644 --- a/fs/jffs2/compr_zlib.c +++ b/fs/jffs2/compr_zlib.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: compr_zlib.c,v 1.32 2005/11/07 11:14:38 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #if !defined(__KERNEL__) && !defined(__ECOS) | 12 | #if !defined(__KERNEL__) && !defined(__ECOS) |
diff --git a/fs/jffs2/comprtest.c b/fs/jffs2/comprtest.c deleted file mode 100644 index f0fb8be7740c..000000000000 --- a/fs/jffs2/comprtest.c +++ /dev/null | |||
@@ -1,307 +0,0 @@ | |||
1 | /* $Id: comprtest.c,v 1.6 2005/11/07 11:14:38 gleixner Exp $ */ | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/string.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <asm/types.h> | ||
7 | #if 0 | ||
8 | #define TESTDATA_LEN 512 | ||
9 | static unsigned char testdata[TESTDATA_LEN] = { | ||
10 | 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
11 | 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x83, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, | ||
12 | 0xb0, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x06, 0x00, 0x28, 0x00, | ||
13 | 0x1e, 0x00, 0x1b, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x80, 0x04, 0x08, | ||
14 | 0x34, 0x80, 0x04, 0x08, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, | ||
15 | 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xf4, 0x80, 0x04, 0x08, | ||
16 | 0xf4, 0x80, 0x04, 0x08, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
17 | 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x08, | ||
18 | 0x00, 0x80, 0x04, 0x08, 0x0d, 0x05, 0x00, 0x00, 0x0d, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, | ||
19 | 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x10, 0x95, 0x04, 0x08, | ||
20 | 0x10, 0x95, 0x04, 0x08, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
21 | 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x58, 0x05, 0x00, 0x00, 0x58, 0x95, 0x04, 0x08, | ||
22 | 0x58, 0x95, 0x04, 0x08, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, | ||
23 | 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x08, 0x81, 0x04, 0x08, | ||
24 | 0x08, 0x81, 0x04, 0x08, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, | ||
25 | 0x04, 0x00, 0x00, 0x00, 0x2f, 0x6c, 0x69, 0x62, 0x2f, 0x6c, 0x64, 0x2d, 0x6c, 0x69, 0x6e, 0x75, | ||
26 | 0x78, 0x2e, 0x73, 0x6f, 0x2e, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, | ||
27 | 0x01, 0x00, 0x00, 0x00, 0x47, 0x4e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, | ||
28 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, | ||
29 | 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
30 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
31 | 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
32 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, | ||
33 | 0x0c, 0x83, 0x04, 0x08, 0x81, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, | ||
34 | 0x1c, 0x83, 0x04, 0x08, 0xac, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, | ||
35 | 0x2c, 0x83, 0x04, 0x08, 0xdd, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, | ||
36 | 0x3c, 0x83, 0x04, 0x08, 0x2e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, | ||
37 | 0x4c, 0x83, 0x04, 0x08, 0x7d, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, | ||
38 | 0x00, 0x85, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x67, | ||
40 | 0x6d, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x00, 0x6c, 0x69, 0x62, 0x63, | ||
41 | 0x2e, 0x73, 0x6f, 0x2e, 0x36, 0x00, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x00, 0x5f, 0x5f, 0x63}; | ||
42 | #else | ||
43 | #define TESTDATA_LEN 3481 | ||
44 | static unsigned char testdata[TESTDATA_LEN] = { | ||
45 | 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x64, 0x62, 0x65, 0x6e, 0x63, 0x68, | ||
46 | 0x2e, 0x68, 0x22, 0x0a, 0x0a, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x4d, 0x41, 0x58, | ||
47 | 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x20, 0x31, 0x30, 0x30, 0x30, 0x0a, 0x0a, 0x73, 0x74, 0x61, | ||
48 | 0x74, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x62, 0x75, 0x66, 0x5b, 0x37, 0x30, 0x30, | ||
49 | 0x30, 0x30, 0x5d, 0x3b, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x74, 0x20, | ||
50 | 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x61, | ||
51 | 0x74, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x09, 0x69, 0x6e, | ||
52 | 0x74, 0x20, 0x66, 0x64, 0x3b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, | ||
53 | 0x65, 0x3b, 0x0a, 0x7d, 0x20, 0x66, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5b, 0x4d, 0x41, 0x58, 0x5f, | ||
54 | 0x46, 0x49, 0x4c, 0x45, 0x53, 0x5d, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, | ||
55 | 0x5f, 0x75, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x28, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x66, 0x6e, | ||
56 | 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x75, 0x70, 0x70, 0x65, 0x72, | ||
57 | 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x75, | ||
58 | 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x21, 0x3d, 0x20, | ||
59 | 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x28, | ||
60 | 0x25, 0x64, 0x29, 0x20, 0x75, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x20, 0x25, 0x73, 0x20, 0x66, 0x61, | ||
61 | 0x69, 0x6c, 0x65, 0x64, 0x20, 0x28, 0x25, 0x73, 0x29, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, | ||
62 | 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, | ||
63 | 0x6e, 0x74, 0x2c, 0x20, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x65, 0x72, | ||
64 | 0x72, 0x6f, 0x72, 0x28, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, | ||
65 | 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x5f, 0x66, | ||
66 | 0x69, 0x6c, 0x65, 0x28, 0x69, 0x6e, 0x74, 0x20, 0x66, 0x64, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, | ||
67 | 0x73, 0x69, 0x7a, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x73, 0x3b, 0x0a, | ||
68 | 0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x20, 0x7b, 0x0a, | ||
69 | 0x09, 0x09, 0x73, 0x20, 0x3d, 0x20, 0x4d, 0x49, 0x4e, 0x28, 0x73, 0x69, 0x7a, 0x65, 0x6f, 0x66, | ||
70 | 0x28, 0x62, 0x75, 0x66, 0x29, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, | ||
71 | 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x66, 0x64, 0x2c, 0x20, 0x62, 0x75, 0x66, 0x2c, 0x20, 0x73, | ||
72 | 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x2d, 0x3d, 0x20, 0x73, 0x3b, 0x0a, | ||
73 | 0x09, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x6f, 0x70, | ||
74 | 0x65, 0x6e, 0x28, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, | ||
75 | 0x69, 0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, | ||
76 | 0x73, 0x69, 0x7a, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x66, 0x64, 0x2c, | ||
77 | 0x20, 0x69, 0x3b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x20, 0x3d, | ||
78 | 0x20, 0x4f, 0x5f, 0x52, 0x44, 0x57, 0x52, 0x7c, 0x4f, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x3b, | ||
79 | 0x0a, 0x09, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x73, 0x74, 0x61, 0x74, 0x20, 0x73, 0x74, | ||
80 | 0x3b, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x63, 0x6f, | ||
81 | 0x75, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, | ||
82 | 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x69, | ||
83 | 0x7a, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x20, 0x7c, | ||
84 | 0x3d, 0x20, 0x4f, 0x5f, 0x54, 0x52, 0x55, 0x4e, 0x43, 0x3b, 0x0a, 0x0a, 0x09, 0x66, 0x64, 0x20, | ||
85 | 0x3d, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x66, 0x6c, | ||
86 | 0x61, 0x67, 0x73, 0x2c, 0x20, 0x30, 0x36, 0x30, 0x30, 0x29, 0x3b, 0x0a, 0x09, 0x69, 0x66, 0x20, | ||
87 | 0x28, 0x66, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x2d, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, | ||
88 | 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x28, 0x25, 0x64, 0x29, 0x20, 0x6f, 0x70, 0x65, 0x6e, | ||
89 | 0x20, 0x25, 0x73, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x68, | ||
90 | 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x25, 0x64, 0x20, 0x28, 0x25, 0x73, 0x29, 0x5c, 0x6e, 0x22, | ||
91 | 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, | ||
92 | 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x68, | ||
93 | 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, | ||
94 | 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, | ||
95 | 0x6e, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x66, 0x73, 0x74, 0x61, 0x74, 0x28, 0x66, 0x64, 0x2c, | ||
96 | 0x20, 0x26, 0x73, 0x74, 0x29, 0x3b, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x73, 0x69, 0x7a, 0x65, | ||
97 | 0x20, 0x3e, 0x20, 0x73, 0x74, 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x20, 0x7b, | ||
98 | 0x0a, 0x23, 0x69, 0x66, 0x20, 0x44, 0x45, 0x42, 0x55, 0x47, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, | ||
99 | 0x6e, 0x74, 0x66, 0x28, 0x22, 0x28, 0x25, 0x64, 0x29, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, | ||
100 | 0x69, 0x6e, 0x67, 0x20, 0x25, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x25, 0x64, 0x20, 0x66, 0x72, 0x6f, | ||
101 | 0x6d, 0x20, 0x25, 0x64, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, | ||
102 | 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, 0x66, | ||
103 | 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0x20, 0x28, 0x69, 0x6e, 0x74, | ||
104 | 0x29, 0x73, 0x74, 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x23, 0x65, | ||
105 | 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x09, 0x09, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x5f, 0x66, 0x69, | ||
106 | 0x6c, 0x65, 0x28, 0x66, 0x64, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x2d, 0x20, 0x73, 0x74, | ||
107 | 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x20, 0x65, 0x6c, | ||
108 | 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3c, 0x20, 0x73, 0x74, | ||
109 | 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, | ||
110 | 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x69, 0x6e, 0x67, | ||
111 | 0x20, 0x25, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x25, 0x64, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x25, | ||
112 | 0x64, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
113 | 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0x20, 0x28, 0x69, 0x6e, | ||
114 | 0x74, 0x29, 0x73, 0x74, 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, | ||
115 | 0x09, 0x66, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x28, 0x66, 0x64, 0x2c, 0x20, 0x73, | ||
116 | 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x69, | ||
117 | 0x3d, 0x30, 0x3b, 0x69, 0x3c, 0x4d, 0x41, 0x58, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x3b, 0x69, | ||
118 | 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x66, 0x74, 0x61, 0x62, | ||
119 | 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x3d, 0x3d, 0x20, | ||
120 | 0x30, 0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x69, 0x66, | ||
121 | 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x4d, 0x41, 0x58, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, | ||
122 | 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x66, 0x69, | ||
123 | 0x6c, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x66, 0x6f, | ||
124 | 0x72, 0x20, 0x25, 0x73, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x3b, | ||
125 | 0x0a, 0x09, 0x09, 0x65, 0x78, 0x69, 0x74, 0x28, 0x31, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, | ||
126 | 0x66, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, | ||
127 | 0x20, 0x3d, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x3b, 0x0a, 0x09, 0x66, 0x74, 0x61, 0x62, | ||
128 | 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x66, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x64, 0x3b, 0x0a, 0x09, | ||
129 | 0x69, 0x66, 0x20, 0x28, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2b, 0x2b, 0x20, 0x25, 0x20, 0x31, 0x30, | ||
130 | 0x30, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, | ||
131 | 0x74, 0x66, 0x28, 0x22, 0x2e, 0x22, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x76, | ||
132 | 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x69, 0x6e, 0x74, | ||
133 | 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x7a, | ||
134 | 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x29, 0x0a, 0x7b, | ||
135 | 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x62, | ||
136 | 0x75, 0x66, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x6d, 0x65, 0x6d, 0x73, | ||
137 | 0x65, 0x74, 0x28, 0x62, 0x75, 0x66, 0x2c, 0x20, 0x31, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x6f, | ||
138 | 0x66, 0x28, 0x62, 0x75, 0x66, 0x29, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, | ||
139 | 0x69, 0x3d, 0x30, 0x3b, 0x69, 0x3c, 0x4d, 0x41, 0x58, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x3b, | ||
140 | 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x66, 0x74, 0x61, | ||
141 | 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x3d, 0x3d, | ||
142 | 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, | ||
143 | 0x09, 0x7d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x4d, 0x41, 0x58, | ||
144 | 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x29, 0x20, 0x7b, 0x0a, 0x23, 0x69, 0x66, 0x20, 0x31, 0x0a, | ||
145 | 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x28, 0x25, 0x64, 0x29, 0x20, 0x64, | ||
146 | 0x6f, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x3a, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, | ||
147 | 0x25, 0x64, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, | ||
148 | 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x25, 0x64, 0x20, 0x6f, 0x66, 0x73, 0x3d, 0x25, 0x64, 0x5c, 0x6e, | ||
149 | 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, | ||
150 | 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x2c, | ||
151 | 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x29, 0x3b, 0x0a, | ||
152 | 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, | ||
153 | 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x6c, 0x73, 0x65, 0x65, 0x6b, 0x28, 0x66, 0x74, 0x61, 0x62, 0x6c, | ||
154 | 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x66, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, | ||
155 | 0x20, 0x53, 0x45, 0x45, 0x4b, 0x5f, 0x53, 0x45, 0x54, 0x29, 0x3b, 0x0a, 0x09, 0x69, 0x66, 0x20, | ||
156 | 0x28, 0x77, 0x72, 0x69, 0x74, 0x65, 0x28, 0x66, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, | ||
157 | 0x2e, 0x66, 0x64, 0x2c, 0x20, 0x62, 0x75, 0x66, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x20, | ||
158 | 0x21, 0x3d, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, | ||
159 | 0x6e, 0x74, 0x66, 0x28, 0x22, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, | ||
160 | 0x64, 0x20, 0x6f, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x25, 0x64, 0x5c, 0x6e, | ||
161 | 0x22, 0x2c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, | ||
162 | 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x28, 0x69, | ||
163 | 0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x73, | ||
164 | 0x69, 0x7a, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x29, | ||
165 | 0x0a, 0x7b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, | ||
166 | 0x28, 0x69, 0x3d, 0x30, 0x3b, 0x69, 0x3c, 0x4d, 0x41, 0x58, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, | ||
167 | 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x66, 0x74, | ||
168 | 0x61, 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x3d, | ||
169 | 0x3d, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, | ||
170 | 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x4d, 0x41, | ||
171 | 0x58, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, | ||
172 | 0x6e, 0x74, 0x66, 0x28, 0x22, 0x28, 0x25, 0x64, 0x29, 0x20, 0x64, 0x6f, 0x5f, 0x72, 0x65, 0x61, | ||
173 | 0x64, 0x3a, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x25, 0x64, 0x20, 0x77, 0x61, 0x73, | ||
174 | 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x25, | ||
175 | 0x64, 0x20, 0x6f, 0x66, 0x73, 0x3d, 0x25, 0x64, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, | ||
176 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, | ||
177 | 0x74, 0x2c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2c, | ||
178 | 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, | ||
179 | 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x6c, 0x73, 0x65, 0x65, 0x6b, 0x28, 0x66, 0x74, | ||
180 | 0x61, 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x66, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, | ||
181 | 0x65, 0x74, 0x2c, 0x20, 0x53, 0x45, 0x45, 0x4b, 0x5f, 0x53, 0x45, 0x54, 0x29, 0x3b, 0x0a, 0x09, | ||
182 | 0x72, 0x65, 0x61, 0x64, 0x28, 0x66, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x66, | ||
183 | 0x64, 0x2c, 0x20, 0x62, 0x75, 0x66, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x7d, | ||
184 | 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, | ||
185 | 0x69, 0x6e, 0x74, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x69, | ||
186 | 0x6e, 0x74, 0x20, 0x69, 0x3b, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x69, 0x3d, 0x30, 0x3b, | ||
187 | 0x69, 0x3c, 0x4d, 0x41, 0x58, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x3b, 0x69, 0x2b, 0x2b, 0x29, | ||
188 | 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x69, 0x66, 0x20, 0x28, 0x66, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5b, | ||
189 | 0x69, 0x5d, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x68, 0x61, 0x6e, | ||
190 | 0x64, 0x6c, 0x65, 0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, | ||
191 | 0x69, 0x66, 0x20, 0x28, 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x4d, 0x41, 0x58, 0x5f, 0x46, 0x49, 0x4c, | ||
192 | 0x45, 0x53, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, | ||
193 | 0x28, 0x25, 0x64, 0x29, 0x20, 0x64, 0x6f, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x3a, 0x20, 0x68, | ||
194 | 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x25, 0x64, 0x20, 0x77, 0x61, 0x73, 0x20, 0x6e, 0x6f, 0x74, | ||
195 | 0x20, 0x6f, 0x70, 0x65, 0x6e, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, | ||
196 | 0x20, 0x20, 0x20, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, | ||
197 | 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, | ||
198 | 0x6e, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x66, 0x74, 0x61, | ||
199 | 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x66, 0x64, 0x29, 0x3b, 0x0a, 0x09, 0x66, 0x74, 0x61, | ||
200 | 0x62, 0x6c, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x3d, 0x20, | ||
201 | 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x6d, 0x6b, | ||
202 | 0x64, 0x69, 0x72, 0x28, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, | ||
203 | 0x0a, 0x7b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, 0x66, 0x6e, 0x61, | ||
204 | 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x6d, 0x6b, 0x64, 0x69, 0x72, | ||
205 | 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x30, 0x37, 0x30, 0x30, 0x29, 0x20, 0x21, 0x3d, | ||
206 | 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x23, 0x69, 0x66, 0x20, 0x44, 0x45, 0x42, 0x55, 0x47, 0x0a, | ||
207 | 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x6d, 0x6b, 0x64, 0x69, 0x72, 0x20, | ||
208 | 0x25, 0x73, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x28, 0x25, 0x73, 0x29, 0x5c, 0x6e, | ||
209 | 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6e, 0x61, | ||
210 | 0x6d, 0x65, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x65, 0x72, 0x72, | ||
211 | 0x6e, 0x6f, 0x29, 0x29, 0x3b, 0x0a, 0x23, 0x65, 0x6e, 0x64, 0x69, 0x66, 0x0a, 0x09, 0x7d, 0x0a, | ||
212 | 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x72, 0x6d, 0x64, 0x69, 0x72, | ||
213 | 0x28, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x7b, 0x0a, | ||
214 | 0x09, 0x73, 0x74, 0x72, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, | ||
215 | 0x3b, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x72, 0x6d, 0x64, 0x69, 0x72, 0x28, 0x66, 0x6e, | ||
216 | 0x61, 0x6d, 0x65, 0x29, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, | ||
217 | 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x72, 0x6d, 0x64, 0x69, 0x72, 0x20, 0x25, 0x73, 0x20, | ||
218 | 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x28, 0x25, 0x73, 0x29, 0x5c, 0x6e, 0x22, 0x2c, 0x20, | ||
219 | 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, | ||
220 | 0x20, 0x73, 0x74, 0x72, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x29, | ||
221 | 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, | ||
222 | 0x5f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x6f, 0x6c, | ||
223 | 0x64, 0x2c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x6e, 0x65, 0x77, 0x29, 0x0a, 0x7b, 0x0a, | ||
224 | 0x09, 0x73, 0x74, 0x72, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, 0x6f, 0x6c, 0x64, 0x29, 0x3b, 0x0a, | ||
225 | 0x09, 0x73, 0x74, 0x72, 0x75, 0x70, 0x70, 0x65, 0x72, 0x28, 0x6e, 0x65, 0x77, 0x29, 0x3b, 0x0a, | ||
226 | 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x28, 0x6f, 0x6c, 0x64, | ||
227 | 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x29, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x09, | ||
228 | 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x20, | ||
229 | 0x25, 0x73, 0x20, 0x25, 0x73, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x28, 0x25, 0x73, | ||
230 | 0x29, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
231 | 0x6f, 0x6c, 0x64, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x65, 0x72, 0x72, | ||
232 | 0x6f, 0x72, 0x28, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, | ||
233 | 0x0a, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x28, | ||
234 | 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, | ||
235 | 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, | ||
236 | 0x20, 0x73, 0x74, 0x61, 0x74, 0x20, 0x73, 0x74, 0x3b, 0x0a, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x75, | ||
237 | 0x70, 0x70, 0x65, 0x72, 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x3b, 0x0a, 0x0a, 0x09, 0x69, | ||
238 | 0x66, 0x20, 0x28, 0x73, 0x74, 0x61, 0x74, 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x26, | ||
239 | 0x73, 0x74, 0x29, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, | ||
240 | 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x28, 0x25, 0x64, 0x29, 0x20, 0x64, 0x6f, 0x5f, 0x73, 0x74, | ||
241 | 0x61, 0x74, 0x3a, 0x20, 0x25, 0x73, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x25, 0x64, 0x20, 0x25, | ||
242 | 0x73, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
243 | 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, 0x66, 0x6e, 0x61, 0x6d, | ||
244 | 0x65, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0x20, 0x73, 0x74, 0x72, 0x65, 0x72, 0x72, 0x6f, | ||
245 | 0x72, 0x28, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x29, 0x29, 0x3b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, | ||
246 | 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, 0x53, 0x5f, 0x49, | ||
247 | 0x53, 0x44, 0x49, 0x52, 0x28, 0x73, 0x74, 0x2e, 0x73, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x29, | ||
248 | 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x0a, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x28, | ||
249 | 0x73, 0x74, 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x73, 0x69, | ||
250 | 0x7a, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, | ||
251 | 0x28, 0x25, 0x64, 0x29, 0x20, 0x64, 0x6f, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x3a, 0x20, 0x25, 0x73, | ||
252 | 0x20, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x25, 0x64, 0x20, 0x25, | ||
253 | 0x64, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x0a, 0x09, 0x09, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | ||
254 | 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x20, 0x66, 0x6e, 0x61, 0x6d, | ||
255 | 0x65, 0x2c, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x29, 0x73, 0x74, 0x2e, 0x73, 0x74, 0x5f, 0x73, 0x69, | ||
256 | 0x7a, 0x65, 0x2c, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, 0x0a, | ||
257 | 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x64, 0x6f, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, | ||
258 | 0x63, 0x68, 0x61, 0x72, 0x20, 0x2a, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x74, | ||
259 | 0x20, 0x73, 0x69, 0x7a, 0x65, 0x29, 0x0a, 0x7b, 0x0a, 0x09, 0x64, 0x6f, 0x5f, 0x6f, 0x70, 0x65, | ||
260 | 0x6e, 0x28, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x35, 0x30, 0x30, 0x30, 0x2c, 0x20, 0x73, | ||
261 | 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x0a, 0x09, 0x64, 0x6f, 0x5f, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, | ||
262 | 0x35, 0x30, 0x30, 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a | ||
263 | }; | ||
264 | #endif | ||
265 | static unsigned char comprbuf[TESTDATA_LEN]; | ||
266 | static unsigned char decomprbuf[TESTDATA_LEN]; | ||
267 | |||
268 | int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in, | ||
269 | unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); | ||
270 | unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out, | ||
271 | uint32_t *datalen, uint32_t *cdatalen); | ||
272 | |||
273 | int init_module(void ) { | ||
274 | unsigned char comprtype; | ||
275 | uint32_t c, d; | ||
276 | int ret; | ||
277 | |||
278 | printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
279 | testdata[0],testdata[1],testdata[2],testdata[3], | ||
280 | testdata[4],testdata[5],testdata[6],testdata[7], | ||
281 | testdata[8],testdata[9],testdata[10],testdata[11], | ||
282 | testdata[12],testdata[13],testdata[14],testdata[15]); | ||
283 | d = TESTDATA_LEN; | ||
284 | c = TESTDATA_LEN; | ||
285 | comprtype = jffs2_compress(testdata, comprbuf, &d, &c); | ||
286 | |||
287 | printk("jffs2_compress used compression type %d. Compressed size %d, uncompressed size %d\n", | ||
288 | comprtype, c, d); | ||
289 | printk("Compressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
290 | comprbuf[0],comprbuf[1],comprbuf[2],comprbuf[3], | ||
291 | comprbuf[4],comprbuf[5],comprbuf[6],comprbuf[7], | ||
292 | comprbuf[8],comprbuf[9],comprbuf[10],comprbuf[11], | ||
293 | comprbuf[12],comprbuf[13],comprbuf[14],comprbuf[15]); | ||
294 | |||
295 | ret = jffs2_decompress(comprtype, comprbuf, decomprbuf, c, d); | ||
296 | printk("jffs2_decompress returned %d\n", ret); | ||
297 | printk("Decompressed data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
298 | decomprbuf[0],decomprbuf[1],decomprbuf[2],decomprbuf[3], | ||
299 | decomprbuf[4],decomprbuf[5],decomprbuf[6],decomprbuf[7], | ||
300 | decomprbuf[8],decomprbuf[9],decomprbuf[10],decomprbuf[11], | ||
301 | decomprbuf[12],decomprbuf[13],decomprbuf[14],decomprbuf[15]); | ||
302 | if (memcmp(decomprbuf, testdata, d)) | ||
303 | printk("Compression and decompression corrupted data\n"); | ||
304 | else | ||
305 | printk("Compression good for %d bytes\n", d); | ||
306 | return 1; | ||
307 | } | ||
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c index 4189e4a36050..3a32c64ed497 100644 --- a/fs/jffs2/debug.c +++ b/fs/jffs2/debug.c | |||
@@ -1,15 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: debug.c,v 1.12 2005/11/07 11:14:39 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
11 | |||
13 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
14 | #include <linux/types.h> | 13 | #include <linux/types.h> |
15 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h index f89c85d5a3f8..2a49f2c51a9f 100644 --- a/fs/jffs2/debug.h +++ b/fs/jffs2/debug.h | |||
@@ -1,15 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: debug.h,v 1.21 2005/11/07 11:14:39 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
11 | |||
13 | #ifndef _JFFS2_DEBUG_H_ | 12 | #ifndef _JFFS2_DEBUG_H_ |
14 | #define _JFFS2_DEBUG_H_ | 13 | #define _JFFS2_DEBUG_H_ |
15 | 14 | ||
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c index 9fa2e27f0641..c1dfca310dd6 100644 --- a/fs/jffs2/dir.c +++ b/fs/jffs2/dir.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: dir.c,v 1.90 2005/11/07 11:14:39 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index ad0121088dde..66e7c2f1e644 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: erase.c,v 1.85 2005/09/20 14:53:15 dedekind Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -333,7 +331,7 @@ static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_erasebl | |||
333 | 331 | ||
334 | *bad_offset = ofs; | 332 | *bad_offset = ofs; |
335 | 333 | ||
336 | ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); | 334 | ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf); |
337 | if (ret) { | 335 | if (ret) { |
338 | printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); | 336 | printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); |
339 | goto fail; | 337 | goto fail; |
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index e82eeaf7590d..99871279a1ed 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: file.c,v 1.104 2005/10/18 23:29:35 tpoynor Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 8a649f602767..1d3b7a9fc828 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: fs.c,v 1.66 2005/09/27 13:17:29 dedekind Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c index 3a3cf225981f..2d99e06ab223 100644 --- a/fs/jffs2/gc.c +++ b/fs/jffs2/gc.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: gc.c,v 1.155 2005/11/07 11:14:39 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -144,7 +142,8 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) | |||
144 | c->unchecked_size); | 142 | c->unchecked_size); |
145 | jffs2_dbg_dump_block_lists_nolock(c); | 143 | jffs2_dbg_dump_block_lists_nolock(c); |
146 | spin_unlock(&c->erase_completion_lock); | 144 | spin_unlock(&c->erase_completion_lock); |
147 | BUG(); | 145 | up(&c->alloc_sem); |
146 | return -ENOSPC; | ||
148 | } | 147 | } |
149 | 148 | ||
150 | spin_unlock(&c->erase_completion_lock); | 149 | spin_unlock(&c->erase_completion_lock); |
diff --git a/fs/jffs2/ioctl.c b/fs/jffs2/ioctl.c index 69099835de1c..f4d525b0ea53 100644 --- a/fs/jffs2/ioctl.c +++ b/fs/jffs2/ioctl.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: ioctl.c,v 1.10 2005/11/07 11:14:40 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
diff --git a/fs/jffs2/jffs2_fs_i.h b/fs/jffs2/jffs2_fs_i.h index 3a566077ac95..0b78fdc9773b 100644 --- a/fs/jffs2/jffs2_fs_i.h +++ b/fs/jffs2/jffs2_fs_i.h | |||
@@ -1,4 +1,13 @@ | |||
1 | /* $Id: jffs2_fs_i.h,v 1.19 2005/11/07 11:14:52 gleixner Exp $ */ | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | ||
3 | * | ||
4 | * Copyright © 2001-2007 Red Hat, Inc. | ||
5 | * | ||
6 | * Created by David Woodhouse <dwmw2@infradead.org> | ||
7 | * | ||
8 | * For licensing information, see the file 'LICENCE' in this directory. | ||
9 | * | ||
10 | */ | ||
2 | 11 | ||
3 | #ifndef _JFFS2_FS_I | 12 | #ifndef _JFFS2_FS_I |
4 | #define _JFFS2_FS_I | 13 | #define _JFFS2_FS_I |
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index ea88f69af130..b13298a824ed 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h | |||
@@ -1,4 +1,13 @@ | |||
1 | /* $Id: jffs2_fs_sb.h,v 1.54 2005/09/21 13:37:34 dedekind Exp $ */ | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | ||
3 | * | ||
4 | * Copyright © 2001-2007 Red Hat, Inc. | ||
5 | * | ||
6 | * Created by David Woodhouse <dwmw2@infradead.org> | ||
7 | * | ||
8 | * For licensing information, see the file 'LICENCE' in this directory. | ||
9 | * | ||
10 | */ | ||
2 | 11 | ||
3 | #ifndef _JFFS2_FS_SB | 12 | #ifndef _JFFS2_FS_SB |
4 | #define _JFFS2_FS_SB | 13 | #define _JFFS2_FS_SB |
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index 83f9881ec4cc..35c1a5e30ba1 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: malloc.c,v 1.31 2005/11/07 11:14:40 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index 5a6b4d64206c..4bf86088b3ae 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: nodelist.c,v 1.115 2005/11/07 11:14:40 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -54,7 +52,7 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new | |||
54 | *prev = new; | 52 | *prev = new; |
55 | } | 53 | } |
56 | 54 | ||
57 | void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size) | 55 | uint32_t jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint32_t size) |
58 | { | 56 | { |
59 | struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size); | 57 | struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size); |
60 | 58 | ||
@@ -76,18 +74,24 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint | |||
76 | } | 74 | } |
77 | 75 | ||
78 | if (size == 0) | 76 | if (size == 0) |
79 | return; | 77 | return 0; |
80 | 78 | ||
81 | /* | ||
82 | * If the last fragment starts at the RAM page boundary, it is | ||
83 | * REF_PRISTINE irrespective of its size. | ||
84 | */ | ||
85 | frag = frag_last(list); | 79 | frag = frag_last(list); |
80 | |||
81 | /* Sanity check for truncation to longer than we started with... */ | ||
82 | if (!frag) | ||
83 | return 0; | ||
84 | if (frag->ofs + frag->size < size) | ||
85 | return frag->ofs + frag->size; | ||
86 | |||
87 | /* If the last fragment starts at the RAM page boundary, it is | ||
88 | * REF_PRISTINE irrespective of its size. */ | ||
86 | if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) { | 89 | if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) { |
87 | dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n", | 90 | dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n", |
88 | frag->ofs, frag->ofs + frag->size); | 91 | frag->ofs, frag->ofs + frag->size); |
89 | frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE; | 92 | frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE; |
90 | } | 93 | } |
94 | return size; | ||
91 | } | 95 | } |
92 | 96 | ||
93 | static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, | 97 | static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, |
@@ -397,466 +401,6 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in | |||
397 | return 0; | 401 | return 0; |
398 | } | 402 | } |
399 | 403 | ||
400 | /* | ||
401 | * Check the data CRC of the node. | ||
402 | * | ||
403 | * Returns: 0 if the data CRC is correct; | ||
404 | * 1 - if incorrect; | ||
405 | * error code if an error occured. | ||
406 | */ | ||
407 | static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) | ||
408 | { | ||
409 | struct jffs2_raw_node_ref *ref = tn->fn->raw; | ||
410 | int err = 0, pointed = 0; | ||
411 | struct jffs2_eraseblock *jeb; | ||
412 | unsigned char *buffer; | ||
413 | uint32_t crc, ofs, len; | ||
414 | size_t retlen; | ||
415 | |||
416 | BUG_ON(tn->csize == 0); | ||
417 | |||
418 | if (!jffs2_is_writebuffered(c)) | ||
419 | goto adj_acc; | ||
420 | |||
421 | /* Calculate how many bytes were already checked */ | ||
422 | ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); | ||
423 | len = ofs % c->wbuf_pagesize; | ||
424 | if (likely(len)) | ||
425 | len = c->wbuf_pagesize - len; | ||
426 | |||
427 | if (len >= tn->csize) { | ||
428 | dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", | ||
429 | ref_offset(ref), tn->csize, ofs); | ||
430 | goto adj_acc; | ||
431 | } | ||
432 | |||
433 | ofs += len; | ||
434 | len = tn->csize - len; | ||
435 | |||
436 | dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", | ||
437 | ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); | ||
438 | |||
439 | #ifndef __ECOS | ||
440 | /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), | ||
441 | * adding and jffs2_flash_read_end() interface. */ | ||
442 | if (c->mtd->point) { | ||
443 | err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); | ||
444 | if (!err && retlen < tn->csize) { | ||
445 | JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); | ||
446 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | ||
447 | } else if (err) | ||
448 | JFFS2_WARNING("MTD point failed: error code %d.\n", err); | ||
449 | else | ||
450 | pointed = 1; /* succefully pointed to device */ | ||
451 | } | ||
452 | #endif | ||
453 | |||
454 | if (!pointed) { | ||
455 | buffer = kmalloc(len, GFP_KERNEL); | ||
456 | if (unlikely(!buffer)) | ||
457 | return -ENOMEM; | ||
458 | |||
459 | /* TODO: this is very frequent pattern, make it a separate | ||
460 | * routine */ | ||
461 | err = jffs2_flash_read(c, ofs, len, &retlen, buffer); | ||
462 | if (err) { | ||
463 | JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err); | ||
464 | goto free_out; | ||
465 | } | ||
466 | |||
467 | if (retlen != len) { | ||
468 | JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len); | ||
469 | err = -EIO; | ||
470 | goto free_out; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | /* Continue calculating CRC */ | ||
475 | crc = crc32(tn->partial_crc, buffer, len); | ||
476 | if(!pointed) | ||
477 | kfree(buffer); | ||
478 | #ifndef __ECOS | ||
479 | else | ||
480 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | ||
481 | #endif | ||
482 | |||
483 | if (crc != tn->data_crc) { | ||
484 | JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", | ||
485 | ofs, tn->data_crc, crc); | ||
486 | return 1; | ||
487 | } | ||
488 | |||
489 | adj_acc: | ||
490 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; | ||
491 | len = ref_totlen(c, jeb, ref); | ||
492 | |||
493 | /* | ||
494 | * Mark the node as having been checked and fix the | ||
495 | * accounting accordingly. | ||
496 | */ | ||
497 | spin_lock(&c->erase_completion_lock); | ||
498 | jeb->used_size += len; | ||
499 | jeb->unchecked_size -= len; | ||
500 | c->used_size += len; | ||
501 | c->unchecked_size -= len; | ||
502 | spin_unlock(&c->erase_completion_lock); | ||
503 | |||
504 | return 0; | ||
505 | |||
506 | free_out: | ||
507 | if(!pointed) | ||
508 | kfree(buffer); | ||
509 | #ifndef __ECOS | ||
510 | else | ||
511 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | ||
512 | #endif | ||
513 | return err; | ||
514 | } | ||
515 | |||
516 | /* | ||
517 | * Helper function for jffs2_add_older_frag_to_fragtree(). | ||
518 | * | ||
519 | * Checks the node if we are in the checking stage. | ||
520 | */ | ||
521 | static int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn) | ||
522 | { | ||
523 | int ret; | ||
524 | |||
525 | BUG_ON(ref_obsolete(tn->fn->raw)); | ||
526 | |||
527 | /* We only check the data CRC of unchecked nodes */ | ||
528 | if (ref_flags(tn->fn->raw) != REF_UNCHECKED) | ||
529 | return 0; | ||
530 | |||
531 | dbg_fragtree2("check node %#04x-%#04x, phys offs %#08x.\n", | ||
532 | tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw)); | ||
533 | |||
534 | ret = check_node_data(c, tn); | ||
535 | if (unlikely(ret < 0)) { | ||
536 | JFFS2_ERROR("check_node_data() returned error: %d.\n", | ||
537 | ret); | ||
538 | } else if (unlikely(ret > 0)) { | ||
539 | dbg_fragtree2("CRC error, mark it obsolete.\n"); | ||
540 | jffs2_mark_node_obsolete(c, tn->fn->raw); | ||
541 | } | ||
542 | |||
543 | return ret; | ||
544 | } | ||
545 | |||
546 | /* | ||
547 | * Helper function for jffs2_add_older_frag_to_fragtree(). | ||
548 | * | ||
549 | * Called when the new fragment that is being inserted | ||
550 | * splits a hole fragment. | ||
551 | */ | ||
552 | static int split_hole(struct jffs2_sb_info *c, struct rb_root *root, | ||
553 | struct jffs2_node_frag *newfrag, struct jffs2_node_frag *hole) | ||
554 | { | ||
555 | dbg_fragtree2("fragment %#04x-%#04x splits the hole %#04x-%#04x\n", | ||
556 | newfrag->ofs, newfrag->ofs + newfrag->size, hole->ofs, hole->ofs + hole->size); | ||
557 | |||
558 | if (hole->ofs == newfrag->ofs) { | ||
559 | /* | ||
560 | * Well, the new fragment actually starts at the same offset as | ||
561 | * the hole. | ||
562 | */ | ||
563 | if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) { | ||
564 | /* | ||
565 | * We replace the overlapped left part of the hole by | ||
566 | * the new node. | ||
567 | */ | ||
568 | |||
569 | dbg_fragtree2("insert fragment %#04x-%#04x and cut the left part of the hole\n", | ||
570 | newfrag->ofs, newfrag->ofs + newfrag->size); | ||
571 | rb_replace_node(&hole->rb, &newfrag->rb, root); | ||
572 | |||
573 | hole->ofs += newfrag->size; | ||
574 | hole->size -= newfrag->size; | ||
575 | |||
576 | /* | ||
577 | * We know that 'hole' should be the right hand | ||
578 | * fragment. | ||
579 | */ | ||
580 | jffs2_fragtree_insert(hole, newfrag); | ||
581 | rb_insert_color(&hole->rb, root); | ||
582 | } else { | ||
583 | /* | ||
584 | * Ah, the new fragment is of the same size as the hole. | ||
585 | * Relace the hole by it. | ||
586 | */ | ||
587 | dbg_fragtree2("insert fragment %#04x-%#04x and overwrite hole\n", | ||
588 | newfrag->ofs, newfrag->ofs + newfrag->size); | ||
589 | rb_replace_node(&hole->rb, &newfrag->rb, root); | ||
590 | jffs2_free_node_frag(hole); | ||
591 | } | ||
592 | } else { | ||
593 | /* The new fragment lefts some hole space at the left */ | ||
594 | |||
595 | struct jffs2_node_frag * newfrag2 = NULL; | ||
596 | |||
597 | if (hole->ofs + hole->size > newfrag->ofs + newfrag->size) { | ||
598 | /* The new frag also lefts some space at the right */ | ||
599 | newfrag2 = new_fragment(NULL, newfrag->ofs + | ||
600 | newfrag->size, hole->ofs + hole->size | ||
601 | - newfrag->ofs - newfrag->size); | ||
602 | if (unlikely(!newfrag2)) { | ||
603 | jffs2_free_node_frag(newfrag); | ||
604 | return -ENOMEM; | ||
605 | } | ||
606 | } | ||
607 | |||
608 | hole->size = newfrag->ofs - hole->ofs; | ||
609 | dbg_fragtree2("left the hole %#04x-%#04x at the left and inserd fragment %#04x-%#04x\n", | ||
610 | hole->ofs, hole->ofs + hole->size, newfrag->ofs, newfrag->ofs + newfrag->size); | ||
611 | |||
612 | jffs2_fragtree_insert(newfrag, hole); | ||
613 | rb_insert_color(&newfrag->rb, root); | ||
614 | |||
615 | if (newfrag2) { | ||
616 | dbg_fragtree2("left the hole %#04x-%#04x at the right\n", | ||
617 | newfrag2->ofs, newfrag2->ofs + newfrag2->size); | ||
618 | jffs2_fragtree_insert(newfrag2, newfrag); | ||
619 | rb_insert_color(&newfrag2->rb, root); | ||
620 | } | ||
621 | } | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | /* | ||
627 | * This function is used when we build inode. It expects the nodes are passed | ||
628 | * in the decreasing version order. The whole point of this is to improve the | ||
629 | * inodes checking on NAND: we check the nodes' data CRC only when they are not | ||
630 | * obsoleted. Previously, add_frag_to_fragtree() function was used and | ||
631 | * nodes were passed to it in the increasing version ordes and CRCs of all | ||
632 | * nodes were checked. | ||
633 | * | ||
634 | * Note: tn->fn->size shouldn't be zero. | ||
635 | * | ||
636 | * Returns 0 if the node was inserted | ||
637 | * 1 if it wasn't inserted (since it is obsolete) | ||
638 | * < 0 an if error occured | ||
639 | */ | ||
640 | int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | ||
641 | struct jffs2_tmp_dnode_info *tn) | ||
642 | { | ||
643 | struct jffs2_node_frag *this, *newfrag; | ||
644 | uint32_t lastend; | ||
645 | struct jffs2_full_dnode *fn = tn->fn; | ||
646 | struct rb_root *root = &f->fragtree; | ||
647 | uint32_t fn_size = fn->size, fn_ofs = fn->ofs; | ||
648 | int err, checked = 0; | ||
649 | int ref_flag; | ||
650 | |||
651 | dbg_fragtree("insert fragment %#04x-%#04x, ver %u\n", fn_ofs, fn_ofs + fn_size, tn->version); | ||
652 | |||
653 | /* Skip all the nodes which are completed before this one starts */ | ||
654 | this = jffs2_lookup_node_frag(root, fn_ofs); | ||
655 | if (this) | ||
656 | dbg_fragtree2("'this' found %#04x-%#04x (%s)\n", this->ofs, this->ofs + this->size, this->node ? "data" : "hole"); | ||
657 | |||
658 | if (this) | ||
659 | lastend = this->ofs + this->size; | ||
660 | else | ||
661 | lastend = 0; | ||
662 | |||
663 | /* Detect the preliminary type of node */ | ||
664 | if (fn->size >= PAGE_CACHE_SIZE) | ||
665 | ref_flag = REF_PRISTINE; | ||
666 | else | ||
667 | ref_flag = REF_NORMAL; | ||
668 | |||
669 | /* See if we ran off the end of the root */ | ||
670 | if (lastend <= fn_ofs) { | ||
671 | /* We did */ | ||
672 | |||
673 | /* | ||
674 | * We are going to insert the new node into the | ||
675 | * fragment tree, so check it. | ||
676 | */ | ||
677 | err = check_node(c, f, tn); | ||
678 | if (err != 0) | ||
679 | return err; | ||
680 | |||
681 | fn->frags = 1; | ||
682 | |||
683 | newfrag = new_fragment(fn, fn_ofs, fn_size); | ||
684 | if (unlikely(!newfrag)) | ||
685 | return -ENOMEM; | ||
686 | |||
687 | err = no_overlapping_node(c, root, newfrag, this, lastend); | ||
688 | if (unlikely(err != 0)) { | ||
689 | jffs2_free_node_frag(newfrag); | ||
690 | return err; | ||
691 | } | ||
692 | |||
693 | goto out_ok; | ||
694 | } | ||
695 | |||
696 | fn->frags = 0; | ||
697 | |||
698 | while (1) { | ||
699 | /* | ||
700 | * Here we have: | ||
701 | * fn_ofs < this->ofs + this->size && fn_ofs >= this->ofs. | ||
702 | * | ||
703 | * Remember, 'this' has higher version, any non-hole node | ||
704 | * which is already in the fragtree is newer then the newly | ||
705 | * inserted. | ||
706 | */ | ||
707 | if (!this->node) { | ||
708 | /* | ||
709 | * 'this' is the hole fragment, so at least the | ||
710 | * beginning of the new fragment is valid. | ||
711 | */ | ||
712 | |||
713 | /* | ||
714 | * We are going to insert the new node into the | ||
715 | * fragment tree, so check it. | ||
716 | */ | ||
717 | if (!checked) { | ||
718 | err = check_node(c, f, tn); | ||
719 | if (unlikely(err != 0)) | ||
720 | return err; | ||
721 | checked = 1; | ||
722 | } | ||
723 | |||
724 | if (this->ofs + this->size >= fn_ofs + fn_size) { | ||
725 | /* We split the hole on two parts */ | ||
726 | |||
727 | fn->frags += 1; | ||
728 | newfrag = new_fragment(fn, fn_ofs, fn_size); | ||
729 | if (unlikely(!newfrag)) | ||
730 | return -ENOMEM; | ||
731 | |||
732 | err = split_hole(c, root, newfrag, this); | ||
733 | if (unlikely(err)) | ||
734 | return err; | ||
735 | goto out_ok; | ||
736 | } | ||
737 | |||
738 | /* | ||
739 | * The beginning of the new fragment is valid since it | ||
740 | * overlaps the hole node. | ||
741 | */ | ||
742 | |||
743 | ref_flag = REF_NORMAL; | ||
744 | |||
745 | fn->frags += 1; | ||
746 | newfrag = new_fragment(fn, fn_ofs, | ||
747 | this->ofs + this->size - fn_ofs); | ||
748 | if (unlikely(!newfrag)) | ||
749 | return -ENOMEM; | ||
750 | |||
751 | if (fn_ofs == this->ofs) { | ||
752 | /* | ||
753 | * The new node starts at the same offset as | ||
754 | * the hole and supersieds the hole. | ||
755 | */ | ||
756 | dbg_fragtree2("add the new fragment instead of hole %#04x-%#04x, refcnt %d\n", | ||
757 | fn_ofs, fn_ofs + this->ofs + this->size - fn_ofs, fn->frags); | ||
758 | |||
759 | rb_replace_node(&this->rb, &newfrag->rb, root); | ||
760 | jffs2_free_node_frag(this); | ||
761 | } else { | ||
762 | /* | ||
763 | * The hole becomes shorter as its right part | ||
764 | * is supersieded by the new fragment. | ||
765 | */ | ||
766 | dbg_fragtree2("reduce size of hole %#04x-%#04x to %#04x-%#04x\n", | ||
767 | this->ofs, this->ofs + this->size, this->ofs, this->ofs + this->size - newfrag->size); | ||
768 | |||
769 | dbg_fragtree2("add new fragment %#04x-%#04x, refcnt %d\n", fn_ofs, | ||
770 | fn_ofs + this->ofs + this->size - fn_ofs, fn->frags); | ||
771 | |||
772 | this->size -= newfrag->size; | ||
773 | jffs2_fragtree_insert(newfrag, this); | ||
774 | rb_insert_color(&newfrag->rb, root); | ||
775 | } | ||
776 | |||
777 | fn_ofs += newfrag->size; | ||
778 | fn_size -= newfrag->size; | ||
779 | this = rb_entry(rb_next(&newfrag->rb), | ||
780 | struct jffs2_node_frag, rb); | ||
781 | |||
782 | dbg_fragtree2("switch to the next 'this' fragment: %#04x-%#04x %s\n", | ||
783 | this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)"); | ||
784 | } | ||
785 | |||
786 | /* | ||
787 | * 'This' node is not the hole so it obsoletes the new fragment | ||
788 | * either fully or partially. | ||
789 | */ | ||
790 | if (this->ofs + this->size >= fn_ofs + fn_size) { | ||
791 | /* The new node is obsolete, drop it */ | ||
792 | if (fn->frags == 0) { | ||
793 | dbg_fragtree2("%#04x-%#04x is obsolete, mark it obsolete\n", fn_ofs, fn_ofs + fn_size); | ||
794 | ref_flag = REF_OBSOLETE; | ||
795 | } | ||
796 | goto out_ok; | ||
797 | } else { | ||
798 | struct jffs2_node_frag *new_this; | ||
799 | |||
800 | /* 'This' node obsoletes the beginning of the new node */ | ||
801 | dbg_fragtree2("the beginning %#04x-%#04x is obsolete\n", fn_ofs, this->ofs + this->size); | ||
802 | |||
803 | ref_flag = REF_NORMAL; | ||
804 | |||
805 | fn_size -= this->ofs + this->size - fn_ofs; | ||
806 | fn_ofs = this->ofs + this->size; | ||
807 | dbg_fragtree2("now considering %#04x-%#04x\n", fn_ofs, fn_ofs + fn_size); | ||
808 | |||
809 | new_this = rb_entry(rb_next(&this->rb), struct jffs2_node_frag, rb); | ||
810 | if (!new_this) { | ||
811 | /* | ||
812 | * There is no next fragment. Add the rest of | ||
813 | * the new node as the right-hand child. | ||
814 | */ | ||
815 | if (!checked) { | ||
816 | err = check_node(c, f, tn); | ||
817 | if (unlikely(err != 0)) | ||
818 | return err; | ||
819 | checked = 1; | ||
820 | } | ||
821 | |||
822 | fn->frags += 1; | ||
823 | newfrag = new_fragment(fn, fn_ofs, fn_size); | ||
824 | if (unlikely(!newfrag)) | ||
825 | return -ENOMEM; | ||
826 | |||
827 | dbg_fragtree2("there are no more fragments, insert %#04x-%#04x\n", | ||
828 | newfrag->ofs, newfrag->ofs + newfrag->size); | ||
829 | rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right); | ||
830 | rb_insert_color(&newfrag->rb, root); | ||
831 | goto out_ok; | ||
832 | } else { | ||
833 | this = new_this; | ||
834 | dbg_fragtree2("switch to the next 'this' fragment: %#04x-%#04x %s\n", | ||
835 | this->ofs, this->ofs + this->size, this->node ? "(data)" : "(hole)"); | ||
836 | } | ||
837 | } | ||
838 | } | ||
839 | |||
840 | out_ok: | ||
841 | BUG_ON(fn->size < PAGE_CACHE_SIZE && ref_flag == REF_PRISTINE); | ||
842 | |||
843 | if (ref_flag == REF_OBSOLETE) { | ||
844 | dbg_fragtree2("the node is obsolete now\n"); | ||
845 | /* jffs2_mark_node_obsolete() will adjust space accounting */ | ||
846 | jffs2_mark_node_obsolete(c, fn->raw); | ||
847 | return 1; | ||
848 | } | ||
849 | |||
850 | dbg_fragtree2("the node is \"%s\" now\n", ref_flag == REF_NORMAL ? "REF_NORMAL" : "REF_PRISTINE"); | ||
851 | |||
852 | /* Space accounting was adjusted at check_node_data() */ | ||
853 | spin_lock(&c->erase_completion_lock); | ||
854 | fn->raw->flash_offset = ref_offset(fn->raw) | ref_flag; | ||
855 | spin_unlock(&c->erase_completion_lock); | ||
856 | |||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state) | 404 | void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state) |
861 | { | 405 | { |
862 | spin_lock(&c->inocache_lock); | 406 | spin_lock(&c->inocache_lock); |
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index 4178b4b55948..25126a062cae 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: nodelist.h,v 1.140 2005/09/07 08:34:54 havasi Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #ifndef __JFFS2_NODELIST_H__ | 12 | #ifndef __JFFS2_NODELIST_H__ |
@@ -40,6 +38,9 @@ | |||
40 | #define cpu_to_je32(x) ((jint32_t){x}) | 38 | #define cpu_to_je32(x) ((jint32_t){x}) |
41 | #define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)}) | 39 | #define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)}) |
42 | 40 | ||
41 | #define constant_cpu_to_je16(x) ((jint16_t){x}) | ||
42 | #define constant_cpu_to_je32(x) ((jint32_t){x}) | ||
43 | |||
43 | #define je16_to_cpu(x) ((x).v16) | 44 | #define je16_to_cpu(x) ((x).v16) |
44 | #define je32_to_cpu(x) ((x).v32) | 45 | #define je32_to_cpu(x) ((x).v32) |
45 | #define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) | 46 | #define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) |
@@ -48,6 +49,9 @@ | |||
48 | #define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)}) | 49 | #define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)}) |
49 | #define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))}) | 50 | #define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))}) |
50 | 51 | ||
52 | #define constant_cpu_to_je16(x) ((jint16_t){__constant_cpu_to_be16(x)}) | ||
53 | #define constant_cpu_to_je32(x) ((jint32_t){__constant_cpu_to_be32(x)}) | ||
54 | |||
51 | #define je16_to_cpu(x) (be16_to_cpu(x.v16)) | 55 | #define je16_to_cpu(x) (be16_to_cpu(x.v16)) |
52 | #define je32_to_cpu(x) (be32_to_cpu(x.v32)) | 56 | #define je32_to_cpu(x) (be32_to_cpu(x.v32)) |
53 | #define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m))) | 57 | #define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m))) |
@@ -56,6 +60,9 @@ | |||
56 | #define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)}) | 60 | #define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)}) |
57 | #define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))}) | 61 | #define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))}) |
58 | 62 | ||
63 | #define constant_cpu_to_je16(x) ((jint16_t){__constant_cpu_to_le16(x)}) | ||
64 | #define constant_cpu_to_je32(x) ((jint32_t){__constant_cpu_to_le32(x)}) | ||
65 | |||
59 | #define je16_to_cpu(x) (le16_to_cpu(x.v16)) | 66 | #define je16_to_cpu(x) (le16_to_cpu(x.v16)) |
60 | #define je32_to_cpu(x) (le32_to_cpu(x.v32)) | 67 | #define je32_to_cpu(x) (le32_to_cpu(x.v32)) |
61 | #define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) | 68 | #define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) |
@@ -216,7 +223,20 @@ struct jffs2_tmp_dnode_info | |||
216 | uint32_t version; | 223 | uint32_t version; |
217 | uint32_t data_crc; | 224 | uint32_t data_crc; |
218 | uint32_t partial_crc; | 225 | uint32_t partial_crc; |
219 | uint32_t csize; | 226 | uint16_t csize; |
227 | uint16_t overlapped; | ||
228 | }; | ||
229 | |||
230 | /* Temporary data structure used during readinode. */ | ||
231 | struct jffs2_readinode_info | ||
232 | { | ||
233 | struct rb_root tn_root; | ||
234 | struct jffs2_tmp_dnode_info *mdata_tn; | ||
235 | uint32_t highest_version; | ||
236 | uint32_t latest_mctime; | ||
237 | uint32_t mctime_ver; | ||
238 | struct jffs2_full_dirent *fds; | ||
239 | struct jffs2_raw_node_ref *latest_ref; | ||
220 | }; | 240 | }; |
221 | 241 | ||
222 | struct jffs2_full_dirent | 242 | struct jffs2_full_dirent |
@@ -319,6 +339,15 @@ static inline struct jffs2_node_frag *frag_last(struct rb_root *root) | |||
319 | #define frag_right(frag) rb_entry((frag)->rb.rb_right, struct jffs2_node_frag, rb) | 339 | #define frag_right(frag) rb_entry((frag)->rb.rb_right, struct jffs2_node_frag, rb) |
320 | #define frag_erase(frag, list) rb_erase(&frag->rb, list); | 340 | #define frag_erase(frag, list) rb_erase(&frag->rb, list); |
321 | 341 | ||
342 | #define tn_next(tn) rb_entry(rb_next(&(tn)->rb), struct jffs2_tmp_dnode_info, rb) | ||
343 | #define tn_prev(tn) rb_entry(rb_prev(&(tn)->rb), struct jffs2_tmp_dnode_info, rb) | ||
344 | #define tn_parent(tn) rb_entry(rb_parent(&(tn)->rb), struct jffs2_tmp_dnode_info, rb) | ||
345 | #define tn_left(tn) rb_entry((tn)->rb.rb_left, struct jffs2_tmp_dnode_info, rb) | ||
346 | #define tn_right(tn) rb_entry((tn)->rb.rb_right, struct jffs2_tmp_dnode_info, rb) | ||
347 | #define tn_erase(tn, list) rb_erase(&tn->rb, list); | ||
348 | #define tn_last(list) rb_entry(rb_last(list), struct jffs2_tmp_dnode_info, rb) | ||
349 | #define tn_first(list) rb_entry(rb_first(list), struct jffs2_tmp_dnode_info, rb) | ||
350 | |||
322 | /* nodelist.c */ | 351 | /* nodelist.c */ |
323 | void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); | 352 | void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); |
324 | void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); | 353 | void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); |
@@ -333,8 +362,7 @@ struct rb_node *rb_next(struct rb_node *); | |||
333 | struct rb_node *rb_prev(struct rb_node *); | 362 | struct rb_node *rb_prev(struct rb_node *); |
334 | void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); | 363 | void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); |
335 | int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); | 364 | int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); |
336 | void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); | 365 | uint32_t jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); |
337 | int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); | ||
338 | struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c, | 366 | struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c, |
339 | struct jffs2_eraseblock *jeb, | 367 | struct jffs2_eraseblock *jeb, |
340 | uint32_t ofs, uint32_t len, | 368 | uint32_t ofs, uint32_t len, |
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index d88376992ed9..dbc908ad622b 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: nodemgmt.c,v 1.127 2005/09/20 15:49:12 dedekind Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -172,6 +170,11 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, | |||
172 | static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) | 170 | static void jffs2_close_nextblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) |
173 | { | 171 | { |
174 | 172 | ||
173 | if (c->nextblock == NULL) { | ||
174 | D1(printk(KERN_DEBUG "jffs2_close_nextblock: Erase block at 0x%08x has already been placed in a list\n", | ||
175 | jeb->offset)); | ||
176 | return; | ||
177 | } | ||
175 | /* Check, if we have a dirty block now, or if it was dirty already */ | 178 | /* Check, if we have a dirty block now, or if it was dirty already */ |
176 | if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) { | 179 | if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) { |
177 | c->dirty_size += jeb->wasted_size; | 180 | c->dirty_size += jeb->wasted_size; |
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h index 8d92e45168ca..80daea96bbc2 100644 --- a/fs/jffs2/os-linux.h +++ b/fs/jffs2/os-linux.h | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2002-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: os-linux.h,v 1.64 2005/09/30 13:59:13 dedekind Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #ifndef __JFFS2_OS_LINUX_H__ | 12 | #ifndef __JFFS2_OS_LINUX_H__ |
diff --git a/fs/jffs2/pushpull.h b/fs/jffs2/pushpull.h deleted file mode 100644 index c0c2a9158dff..000000000000 --- a/fs/jffs2/pushpull.h +++ /dev/null | |||
@@ -1,72 +0,0 @@ | |||
1 | /* | ||
2 | * JFFS2 -- Journalling Flash File System, Version 2. | ||
3 | * | ||
4 | * Copyright (C) 2001, 2002 Red Hat, Inc. | ||
5 | * | ||
6 | * Created by David Woodhouse <dwmw2@infradead.org> | ||
7 | * | ||
8 | * For licensing information, see the file 'LICENCE' in this directory. | ||
9 | * | ||
10 | * $Id: pushpull.h,v 1.10 2004/11/16 20:36:11 dwmw2 Exp $ | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __PUSHPULL_H__ | ||
15 | #define __PUSHPULL_H__ | ||
16 | |||
17 | #include <linux/errno.h> | ||
18 | |||
19 | struct pushpull { | ||
20 | unsigned char *buf; | ||
21 | unsigned int buflen; | ||
22 | unsigned int ofs; | ||
23 | unsigned int reserve; | ||
24 | }; | ||
25 | |||
26 | |||
27 | static inline void init_pushpull(struct pushpull *pp, char *buf, unsigned buflen, unsigned ofs, unsigned reserve) | ||
28 | { | ||
29 | pp->buf = buf; | ||
30 | pp->buflen = buflen; | ||
31 | pp->ofs = ofs; | ||
32 | pp->reserve = reserve; | ||
33 | } | ||
34 | |||
35 | static inline int pushbit(struct pushpull *pp, int bit, int use_reserved) | ||
36 | { | ||
37 | if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) { | ||
38 | return -ENOSPC; | ||
39 | } | ||
40 | |||
41 | if (bit) { | ||
42 | pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs &7))); | ||
43 | } | ||
44 | else { | ||
45 | pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs &7))); | ||
46 | } | ||
47 | pp->ofs++; | ||
48 | |||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static inline int pushedbits(struct pushpull *pp) | ||
53 | { | ||
54 | return pp->ofs; | ||
55 | } | ||
56 | |||
57 | static inline int pullbit(struct pushpull *pp) | ||
58 | { | ||
59 | int bit; | ||
60 | |||
61 | bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1; | ||
62 | |||
63 | pp->ofs++; | ||
64 | return bit; | ||
65 | } | ||
66 | |||
67 | static inline int pulledbits(struct pushpull *pp) | ||
68 | { | ||
69 | return pp->ofs; | ||
70 | } | ||
71 | |||
72 | #endif /* __PUSHPULL_H__ */ | ||
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c index f3b86da833ba..cfe05c1966a5 100644 --- a/fs/jffs2/read.c +++ b/fs/jffs2/read.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: read.c,v 1.42 2005/11/07 11:14:41 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 717a48cf7df2..6aff38930b50 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: readinode.c,v 1.143 2005/11/07 11:14:41 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -22,30 +20,510 @@ | |||
22 | #include "nodelist.h" | 20 | #include "nodelist.h" |
23 | 21 | ||
24 | /* | 22 | /* |
25 | * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in | 23 | * Check the data CRC of the node. |
26 | * order of increasing version. | 24 | * |
25 | * Returns: 0 if the data CRC is correct; | ||
26 | * 1 - if incorrect; | ||
27 | * error code if an error occured. | ||
27 | */ | 28 | */ |
28 | static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list) | 29 | static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) |
29 | { | 30 | { |
30 | struct rb_node **p = &list->rb_node; | 31 | struct jffs2_raw_node_ref *ref = tn->fn->raw; |
31 | struct rb_node * parent = NULL; | 32 | int err = 0, pointed = 0; |
32 | struct jffs2_tmp_dnode_info *this; | 33 | struct jffs2_eraseblock *jeb; |
33 | 34 | unsigned char *buffer; | |
34 | while (*p) { | 35 | uint32_t crc, ofs, len; |
35 | parent = *p; | 36 | size_t retlen; |
36 | this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); | 37 | |
37 | 38 | BUG_ON(tn->csize == 0); | |
38 | /* There may actually be a collision here, but it doesn't | 39 | |
39 | actually matter. As long as the two nodes with the same | 40 | if (!jffs2_is_writebuffered(c)) |
40 | version are together, it's all fine. */ | 41 | goto adj_acc; |
41 | if (tn->version > this->version) | 42 | |
42 | p = &(*p)->rb_left; | 43 | /* Calculate how many bytes were already checked */ |
44 | ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); | ||
45 | len = ofs % c->wbuf_pagesize; | ||
46 | if (likely(len)) | ||
47 | len = c->wbuf_pagesize - len; | ||
48 | |||
49 | if (len >= tn->csize) { | ||
50 | dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", | ||
51 | ref_offset(ref), tn->csize, ofs); | ||
52 | goto adj_acc; | ||
53 | } | ||
54 | |||
55 | ofs += len; | ||
56 | len = tn->csize - len; | ||
57 | |||
58 | dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", | ||
59 | ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); | ||
60 | |||
61 | #ifndef __ECOS | ||
62 | /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(), | ||
63 | * adding and jffs2_flash_read_end() interface. */ | ||
64 | if (c->mtd->point) { | ||
65 | err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); | ||
66 | if (!err && retlen < tn->csize) { | ||
67 | JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); | ||
68 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | ||
69 | } else if (err) | ||
70 | JFFS2_WARNING("MTD point failed: error code %d.\n", err); | ||
43 | else | 71 | else |
44 | p = &(*p)->rb_right; | 72 | pointed = 1; /* succefully pointed to device */ |
73 | } | ||
74 | #endif | ||
75 | |||
76 | if (!pointed) { | ||
77 | buffer = kmalloc(len, GFP_KERNEL); | ||
78 | if (unlikely(!buffer)) | ||
79 | return -ENOMEM; | ||
80 | |||
81 | /* TODO: this is very frequent pattern, make it a separate | ||
82 | * routine */ | ||
83 | err = jffs2_flash_read(c, ofs, len, &retlen, buffer); | ||
84 | if (err) { | ||
85 | JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err); | ||
86 | goto free_out; | ||
87 | } | ||
88 | |||
89 | if (retlen != len) { | ||
90 | JFFS2_ERROR("short read at %#08x: %zd instead of %d.\n", ofs, retlen, len); | ||
91 | err = -EIO; | ||
92 | goto free_out; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /* Continue calculating CRC */ | ||
97 | crc = crc32(tn->partial_crc, buffer, len); | ||
98 | if(!pointed) | ||
99 | kfree(buffer); | ||
100 | #ifndef __ECOS | ||
101 | else | ||
102 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | ||
103 | #endif | ||
104 | |||
105 | if (crc != tn->data_crc) { | ||
106 | JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", | ||
107 | ofs, tn->data_crc, crc); | ||
108 | return 1; | ||
45 | } | 109 | } |
46 | 110 | ||
47 | rb_link_node(&tn->rb, parent, p); | 111 | adj_acc: |
48 | rb_insert_color(&tn->rb, list); | 112 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; |
113 | len = ref_totlen(c, jeb, ref); | ||
114 | /* If it should be REF_NORMAL, it'll get marked as such when | ||
115 | we build the fragtree, shortly. No need to worry about GC | ||
116 | moving it while it's marked REF_PRISTINE -- GC won't happen | ||
117 | till we've finished checking every inode anyway. */ | ||
118 | ref->flash_offset |= REF_PRISTINE; | ||
119 | /* | ||
120 | * Mark the node as having been checked and fix the | ||
121 | * accounting accordingly. | ||
122 | */ | ||
123 | spin_lock(&c->erase_completion_lock); | ||
124 | jeb->used_size += len; | ||
125 | jeb->unchecked_size -= len; | ||
126 | c->used_size += len; | ||
127 | c->unchecked_size -= len; | ||
128 | jffs2_dbg_acct_paranoia_check_nolock(c, jeb); | ||
129 | spin_unlock(&c->erase_completion_lock); | ||
130 | |||
131 | return 0; | ||
132 | |||
133 | free_out: | ||
134 | if(!pointed) | ||
135 | kfree(buffer); | ||
136 | #ifndef __ECOS | ||
137 | else | ||
138 | c->mtd->unpoint(c->mtd, buffer, ofs, len); | ||
139 | #endif | ||
140 | return err; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Helper function for jffs2_add_older_frag_to_fragtree(). | ||
145 | * | ||
146 | * Checks the node if we are in the checking stage. | ||
147 | */ | ||
148 | static int check_tn_node(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) | ||
149 | { | ||
150 | int ret; | ||
151 | |||
152 | BUG_ON(ref_obsolete(tn->fn->raw)); | ||
153 | |||
154 | /* We only check the data CRC of unchecked nodes */ | ||
155 | if (ref_flags(tn->fn->raw) != REF_UNCHECKED) | ||
156 | return 0; | ||
157 | |||
158 | dbg_readinode("check node %#04x-%#04x, phys offs %#08x\n", | ||
159 | tn->fn->ofs, tn->fn->ofs + tn->fn->size, ref_offset(tn->fn->raw)); | ||
160 | |||
161 | ret = check_node_data(c, tn); | ||
162 | if (unlikely(ret < 0)) { | ||
163 | JFFS2_ERROR("check_node_data() returned error: %d.\n", | ||
164 | ret); | ||
165 | } else if (unlikely(ret > 0)) { | ||
166 | dbg_readinode("CRC error, mark it obsolete.\n"); | ||
167 | jffs2_mark_node_obsolete(c, tn->fn->raw); | ||
168 | } | ||
169 | |||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static struct jffs2_tmp_dnode_info *jffs2_lookup_tn(struct rb_root *tn_root, uint32_t offset) | ||
174 | { | ||
175 | struct rb_node *next; | ||
176 | struct jffs2_tmp_dnode_info *tn = NULL; | ||
177 | |||
178 | dbg_readinode("root %p, offset %d\n", tn_root, offset); | ||
179 | |||
180 | next = tn_root->rb_node; | ||
181 | |||
182 | while (next) { | ||
183 | tn = rb_entry(next, struct jffs2_tmp_dnode_info, rb); | ||
184 | |||
185 | if (tn->fn->ofs < offset) | ||
186 | next = tn->rb.rb_right; | ||
187 | else if (tn->fn->ofs >= offset) | ||
188 | next = tn->rb.rb_left; | ||
189 | else | ||
190 | break; | ||
191 | } | ||
192 | |||
193 | return tn; | ||
194 | } | ||
195 | |||
196 | |||
197 | static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info *tn) | ||
198 | { | ||
199 | jffs2_mark_node_obsolete(c, tn->fn->raw); | ||
200 | jffs2_free_full_dnode(tn->fn); | ||
201 | jffs2_free_tmp_dnode_info(tn); | ||
202 | } | ||
203 | /* | ||
204 | * This function is used when we read an inode. Data nodes arrive in | ||
205 | * arbitrary order -- they may be older or newer than the nodes which | ||
206 | * are already in the tree. Where overlaps occur, the older node can | ||
207 | * be discarded as long as the newer passes the CRC check. We don't | ||
208 | * bother to keep track of holes in this rbtree, and neither do we deal | ||
209 | * with frags -- we can have multiple entries starting at the same | ||
210 | * offset, and the one with the smallest length will come first in the | ||
211 | * ordering. | ||
212 | * | ||
213 | * Returns 0 if the node was inserted | ||
214 | * 1 if the node is obsolete (because we can't mark it so yet) | ||
215 | * < 0 an if error occurred | ||
216 | */ | ||
217 | static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, | ||
218 | struct jffs2_readinode_info *rii, | ||
219 | struct jffs2_tmp_dnode_info *tn) | ||
220 | { | ||
221 | uint32_t fn_end = tn->fn->ofs + tn->fn->size; | ||
222 | struct jffs2_tmp_dnode_info *insert_point = NULL, *this; | ||
223 | |||
224 | dbg_readinode("insert fragment %#04x-%#04x, ver %u\n", tn->fn->ofs, fn_end, tn->version); | ||
225 | |||
226 | /* If a node has zero dsize, we only have to keep if it if it might be the | ||
227 | node with highest version -- i.e. the one which will end up as f->metadata. | ||
228 | Note that such nodes won't be REF_UNCHECKED since there are no data to | ||
229 | check anyway. */ | ||
230 | if (!tn->fn->size) { | ||
231 | if (rii->mdata_tn) { | ||
232 | /* We had a candidate mdata node already */ | ||
233 | dbg_readinode("kill old mdata with ver %d\n", rii->mdata_tn->version); | ||
234 | jffs2_kill_tn(c, rii->mdata_tn); | ||
235 | } | ||
236 | rii->mdata_tn = tn; | ||
237 | dbg_readinode("keep new mdata with ver %d\n", tn->version); | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /* Find the earliest node which _may_ be relevant to this one */ | ||
242 | this = jffs2_lookup_tn(&rii->tn_root, tn->fn->ofs); | ||
243 | if (!this) { | ||
244 | /* First addition to empty tree. $DEITY how I love the easy cases */ | ||
245 | rb_link_node(&tn->rb, NULL, &rii->tn_root.rb_node); | ||
246 | rb_insert_color(&tn->rb, &rii->tn_root); | ||
247 | dbg_readinode("keep new frag\n"); | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | /* If we add a new node it'll be somewhere under here. */ | ||
252 | insert_point = this; | ||
253 | |||
254 | /* If the node is coincident with another at a lower address, | ||
255 | back up until the other node is found. It may be relevant */ | ||
256 | while (tn->overlapped) | ||
257 | tn = tn_prev(tn); | ||
258 | |||
259 | dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); | ||
260 | |||
261 | while (this) { | ||
262 | if (this->fn->ofs > fn_end) | ||
263 | break; | ||
264 | dbg_readinode("Ponder this ver %d, 0x%x-0x%x\n", | ||
265 | this->version, this->fn->ofs, this->fn->size); | ||
266 | |||
267 | if (this->version == tn->version) { | ||
268 | /* Version number collision means REF_PRISTINE GC. Accept either of them | ||
269 | as long as the CRC is correct. Check the one we have already... */ | ||
270 | if (!check_tn_node(c, this)) { | ||
271 | /* The one we already had was OK. Keep it and throw away the new one */ | ||
272 | dbg_readinode("Like old node. Throw away new\n"); | ||
273 | jffs2_kill_tn(c, tn); | ||
274 | return 0; | ||
275 | } else { | ||
276 | /* Who cares if the new one is good; keep it for now anyway. */ | ||
277 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); | ||
278 | /* Same overlapping from in front and behind */ | ||
279 | tn->overlapped = this->overlapped; | ||
280 | jffs2_kill_tn(c, this); | ||
281 | dbg_readinode("Like new node. Throw away old\n"); | ||
282 | return 0; | ||
283 | } | ||
284 | } | ||
285 | if (this->version < tn->version && | ||
286 | this->fn->ofs >= tn->fn->ofs && | ||
287 | this->fn->ofs + this->fn->size <= fn_end) { | ||
288 | /* New node entirely overlaps 'this' */ | ||
289 | if (check_tn_node(c, tn)) { | ||
290 | dbg_readinode("new node bad CRC\n"); | ||
291 | jffs2_kill_tn(c, tn); | ||
292 | return 0; | ||
293 | } | ||
294 | /* ... and is good. Kill 'this'... */ | ||
295 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); | ||
296 | tn->overlapped = this->overlapped; | ||
297 | jffs2_kill_tn(c, this); | ||
298 | /* ... and any subsequent nodes which are also overlapped */ | ||
299 | this = tn_next(tn); | ||
300 | while (this && this->fn->ofs + this->fn->size < fn_end) { | ||
301 | struct jffs2_tmp_dnode_info *next = tn_next(this); | ||
302 | if (this->version < tn->version) { | ||
303 | tn_erase(this, &rii->tn_root); | ||
304 | dbg_readinode("Kill overlapped ver %d, 0x%x-0x%x\n", | ||
305 | this->version, this->fn->ofs, | ||
306 | this->fn->ofs+this->fn->size); | ||
307 | jffs2_kill_tn(c, this); | ||
308 | } | ||
309 | this = next; | ||
310 | } | ||
311 | dbg_readinode("Done inserting new\n"); | ||
312 | return 0; | ||
313 | } | ||
314 | if (this->version > tn->version && | ||
315 | this->fn->ofs <= tn->fn->ofs && | ||
316 | this->fn->ofs+this->fn->size >= fn_end) { | ||
317 | /* New node entirely overlapped by 'this' */ | ||
318 | if (!check_tn_node(c, this)) { | ||
319 | dbg_readinode("Good CRC on old node. Kill new\n"); | ||
320 | jffs2_kill_tn(c, tn); | ||
321 | return 0; | ||
322 | } | ||
323 | /* ... but 'this' was bad. Replace it... */ | ||
324 | rb_replace_node(&this->rb, &tn->rb, &rii->tn_root); | ||
325 | dbg_readinode("Bad CRC on old overlapping node. Kill it\n"); | ||
326 | jffs2_kill_tn(c, this); | ||
327 | return 0; | ||
328 | } | ||
329 | /* We want to be inserted under the last node which is | ||
330 | either at a lower offset _or_ has a smaller range */ | ||
331 | if (this->fn->ofs < tn->fn->ofs || | ||
332 | (this->fn->ofs == tn->fn->ofs && | ||
333 | this->fn->size <= tn->fn->size)) | ||
334 | insert_point = this; | ||
335 | |||
336 | this = tn_next(this); | ||
337 | } | ||
338 | dbg_readinode("insert_point %p, ver %d, 0x%x-0x%x, ov %d\n", | ||
339 | insert_point, insert_point->version, insert_point->fn->ofs, | ||
340 | insert_point->fn->ofs+insert_point->fn->size, | ||
341 | insert_point->overlapped); | ||
342 | /* We neither completely obsoleted nor were completely | ||
343 | obsoleted by an earlier node. Insert under insert_point */ | ||
344 | { | ||
345 | struct rb_node *parent = &insert_point->rb; | ||
346 | struct rb_node **link = &parent; | ||
347 | |||
348 | while (*link) { | ||
349 | parent = *link; | ||
350 | insert_point = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); | ||
351 | if (tn->fn->ofs > insert_point->fn->ofs) | ||
352 | link = &insert_point->rb.rb_right; | ||
353 | else if (tn->fn->ofs < insert_point->fn->ofs || | ||
354 | tn->fn->size < insert_point->fn->size) | ||
355 | link = &insert_point->rb.rb_left; | ||
356 | else | ||
357 | link = &insert_point->rb.rb_right; | ||
358 | } | ||
359 | rb_link_node(&tn->rb, &insert_point->rb, link); | ||
360 | rb_insert_color(&tn->rb, &rii->tn_root); | ||
361 | } | ||
362 | /* If there's anything behind that overlaps us, note it */ | ||
363 | this = tn_prev(tn); | ||
364 | if (this) { | ||
365 | while (1) { | ||
366 | if (this->fn->ofs + this->fn->size > tn->fn->ofs) { | ||
367 | dbg_readinode("Node is overlapped by %p (v %d, 0x%x-0x%x)\n", | ||
368 | this, this->version, this->fn->ofs, | ||
369 | this->fn->ofs+this->fn->size); | ||
370 | tn->overlapped = 1; | ||
371 | break; | ||
372 | } | ||
373 | if (!this->overlapped) | ||
374 | break; | ||
375 | this = tn_prev(this); | ||
376 | } | ||
377 | } | ||
378 | |||
379 | /* If the new node overlaps anything ahead, note it */ | ||
380 | this = tn_next(tn); | ||
381 | while (this && this->fn->ofs < fn_end) { | ||
382 | this->overlapped = 1; | ||
383 | dbg_readinode("Node ver %d, 0x%x-0x%x is overlapped\n", | ||
384 | this->version, this->fn->ofs, | ||
385 | this->fn->ofs+this->fn->size); | ||
386 | this = tn_next(this); | ||
387 | } | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | /* Trivial function to remove the last node in the tree. Which by definition | ||
392 | has no right-hand -- so can be removed just by making its only child (if | ||
393 | any) take its place under its parent. */ | ||
394 | static void eat_last(struct rb_root *root, struct rb_node *node) | ||
395 | { | ||
396 | struct rb_node *parent = rb_parent(node); | ||
397 | struct rb_node **link; | ||
398 | |||
399 | /* LAST! */ | ||
400 | BUG_ON(node->rb_right); | ||
401 | |||
402 | if (!parent) | ||
403 | link = &root->rb_node; | ||
404 | else if (node == parent->rb_left) | ||
405 | link = &parent->rb_left; | ||
406 | else | ||
407 | link = &parent->rb_right; | ||
408 | |||
409 | *link = node->rb_left; | ||
410 | /* Colour doesn't matter now. Only the parent pointer. */ | ||
411 | if (node->rb_left) | ||
412 | node->rb_left->rb_parent_color = node->rb_parent_color; | ||
413 | } | ||
414 | |||
415 | /* We put this in reverse order, so we can just use eat_last */ | ||
416 | static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn) | ||
417 | { | ||
418 | struct rb_node **link = &ver_root->rb_node; | ||
419 | struct rb_node *parent = NULL; | ||
420 | struct jffs2_tmp_dnode_info *this_tn; | ||
421 | |||
422 | while (*link) { | ||
423 | parent = *link; | ||
424 | this_tn = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); | ||
425 | |||
426 | if (tn->version > this_tn->version) | ||
427 | link = &parent->rb_left; | ||
428 | else | ||
429 | link = &parent->rb_right; | ||
430 | } | ||
431 | dbg_readinode("Link new node at %p (root is %p)\n", link, ver_root); | ||
432 | rb_link_node(&tn->rb, parent, link); | ||
433 | rb_insert_color(&tn->rb, ver_root); | ||
434 | } | ||
435 | |||
436 | /* Build final, normal fragtree from tn tree. It doesn't matter which order | ||
437 | we add nodes to the real fragtree, as long as they don't overlap. And | ||
438 | having thrown away the majority of overlapped nodes as we went, there | ||
439 | really shouldn't be many sets of nodes which do overlap. If we start at | ||
440 | the end, we can use the overlap markers -- we can just eat nodes which | ||
441 | aren't overlapped, and when we encounter nodes which _do_ overlap we | ||
442 | sort them all into a temporary tree in version order before replaying them. */ | ||
443 | static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, | ||
444 | struct jffs2_inode_info *f, | ||
445 | struct jffs2_readinode_info *rii) | ||
446 | { | ||
447 | struct jffs2_tmp_dnode_info *pen, *last, *this; | ||
448 | struct rb_root ver_root = RB_ROOT; | ||
449 | uint32_t high_ver = 0; | ||
450 | |||
451 | if (rii->mdata_tn) { | ||
452 | dbg_readinode("potential mdata is ver %d at %p\n", rii->mdata_tn->version, rii->mdata_tn); | ||
453 | high_ver = rii->mdata_tn->version; | ||
454 | rii->latest_ref = rii->mdata_tn->fn->raw; | ||
455 | } | ||
456 | #ifdef JFFS2_DBG_READINODE_MESSAGES | ||
457 | this = tn_last(&rii->tn_root); | ||
458 | while (this) { | ||
459 | dbg_readinode("tn %p ver %d range 0x%x-0x%x ov %d\n", this, this->version, this->fn->ofs, | ||
460 | this->fn->ofs+this->fn->size, this->overlapped); | ||
461 | this = tn_prev(this); | ||
462 | } | ||
463 | #endif | ||
464 | pen = tn_last(&rii->tn_root); | ||
465 | while ((last = pen)) { | ||
466 | pen = tn_prev(last); | ||
467 | |||
468 | eat_last(&rii->tn_root, &last->rb); | ||
469 | ver_insert(&ver_root, last); | ||
470 | |||
471 | if (unlikely(last->overlapped)) | ||
472 | continue; | ||
473 | |||
474 | /* Now we have a bunch of nodes in reverse version | ||
475 | order, in the tree at ver_root. Most of the time, | ||
476 | there'll actually be only one node in the 'tree', | ||
477 | in fact. */ | ||
478 | this = tn_last(&ver_root); | ||
479 | |||
480 | while (this) { | ||
481 | struct jffs2_tmp_dnode_info *vers_next; | ||
482 | int ret; | ||
483 | vers_next = tn_prev(this); | ||
484 | eat_last(&ver_root, &this->rb); | ||
485 | if (check_tn_node(c, this)) { | ||
486 | dbg_readinode("node ver %x, 0x%x-0x%x failed CRC\n", | ||
487 | this->version, this->fn->ofs, | ||
488 | this->fn->ofs+this->fn->size); | ||
489 | jffs2_kill_tn(c, this); | ||
490 | } else { | ||
491 | if (this->version > high_ver) { | ||
492 | /* Note that this is different from the other | ||
493 | highest_version, because this one is only | ||
494 | counting _valid_ nodes which could give the | ||
495 | latest inode metadata */ | ||
496 | high_ver = this->version; | ||
497 | rii->latest_ref = this->fn->raw; | ||
498 | } | ||
499 | dbg_readinode("Add %p (v %x, 0x%x-0x%x, ov %d) to fragtree\n", | ||
500 | this, this->version, this->fn->ofs, | ||
501 | this->fn->ofs+this->fn->size, this->overlapped); | ||
502 | |||
503 | ret = jffs2_add_full_dnode_to_inode(c, f, this->fn); | ||
504 | if (ret) { | ||
505 | /* Free the nodes in vers_root; let the caller | ||
506 | deal with the rest */ | ||
507 | JFFS2_ERROR("Add node to tree failed %d\n", ret); | ||
508 | while (1) { | ||
509 | vers_next = tn_prev(this); | ||
510 | if (check_tn_node(c, this)) | ||
511 | jffs2_mark_node_obsolete(c, this->fn->raw); | ||
512 | jffs2_free_full_dnode(this->fn); | ||
513 | jffs2_free_tmp_dnode_info(this); | ||
514 | this = vers_next; | ||
515 | if (!this) | ||
516 | break; | ||
517 | eat_last(&ver_root, &vers_next->rb); | ||
518 | } | ||
519 | return ret; | ||
520 | } | ||
521 | jffs2_free_tmp_dnode_info(this); | ||
522 | } | ||
523 | this = vers_next; | ||
524 | } | ||
525 | } | ||
526 | return 0; | ||
49 | } | 527 | } |
50 | 528 | ||
51 | static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) | 529 | static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) |
@@ -112,8 +590,8 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r | |||
112 | * negative error code on failure. | 590 | * negative error code on failure. |
113 | */ | 591 | */ |
114 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 592 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, |
115 | struct jffs2_raw_dirent *rd, size_t read, struct jffs2_full_dirent **fdp, | 593 | struct jffs2_raw_dirent *rd, size_t read, |
116 | uint32_t *latest_mctime, uint32_t *mctime_ver) | 594 | struct jffs2_readinode_info *rii) |
117 | { | 595 | { |
118 | struct jffs2_full_dirent *fd; | 596 | struct jffs2_full_dirent *fd; |
119 | uint32_t crc; | 597 | uint32_t crc; |
@@ -125,7 +603,8 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
125 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { | 603 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { |
126 | JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", | 604 | JFFS2_NOTICE("header CRC failed on dirent node at %#08x: read %#08x, calculated %#08x\n", |
127 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); | 605 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); |
128 | return 1; | 606 | jffs2_mark_node_obsolete(c, ref); |
607 | return 0; | ||
129 | } | 608 | } |
130 | 609 | ||
131 | /* If we've never checked the CRCs on this node, check them now */ | 610 | /* If we've never checked the CRCs on this node, check them now */ |
@@ -137,7 +616,8 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
137 | if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { | 616 | if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { |
138 | JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", | 617 | JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", |
139 | ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); | 618 | ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); |
140 | return 1; | 619 | jffs2_mark_node_obsolete(c, ref); |
620 | return 0; | ||
141 | } | 621 | } |
142 | 622 | ||
143 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; | 623 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; |
@@ -161,10 +641,13 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
161 | fd->ino = je32_to_cpu(rd->ino); | 641 | fd->ino = je32_to_cpu(rd->ino); |
162 | fd->type = rd->type; | 642 | fd->type = rd->type; |
163 | 643 | ||
644 | if (fd->version > rii->highest_version) | ||
645 | rii->highest_version = fd->version; | ||
646 | |||
164 | /* Pick out the mctime of the latest dirent */ | 647 | /* Pick out the mctime of the latest dirent */ |
165 | if(fd->version > *mctime_ver && je32_to_cpu(rd->mctime)) { | 648 | if(fd->version > rii->mctime_ver && je32_to_cpu(rd->mctime)) { |
166 | *mctime_ver = fd->version; | 649 | rii->mctime_ver = fd->version; |
167 | *latest_mctime = je32_to_cpu(rd->mctime); | 650 | rii->latest_mctime = je32_to_cpu(rd->mctime); |
168 | } | 651 | } |
169 | 652 | ||
170 | /* | 653 | /* |
@@ -201,7 +684,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
201 | * Wheee. We now have a complete jffs2_full_dirent structure, with | 684 | * Wheee. We now have a complete jffs2_full_dirent structure, with |
202 | * the name in it and everything. Link it into the list | 685 | * the name in it and everything. Link it into the list |
203 | */ | 686 | */ |
204 | jffs2_add_fd_to_list(c, fd, fdp); | 687 | jffs2_add_fd_to_list(c, fd, &rii->fds); |
205 | 688 | ||
206 | return 0; | 689 | return 0; |
207 | } | 690 | } |
@@ -210,13 +693,13 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r | |||
210 | * Helper function for jffs2_get_inode_nodes(). | 693 | * Helper function for jffs2_get_inode_nodes(). |
211 | * It is called every time an inode node is found. | 694 | * It is called every time an inode node is found. |
212 | * | 695 | * |
213 | * Returns: 0 on succes; | 696 | * Returns: 0 on success; |
214 | * 1 if the node should be marked obsolete; | 697 | * 1 if the node should be marked obsolete; |
215 | * negative error code on failure. | 698 | * negative error code on failure. |
216 | */ | 699 | */ |
217 | static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 700 | static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, |
218 | struct jffs2_raw_inode *rd, struct rb_root *tnp, int rdlen, | 701 | struct jffs2_raw_inode *rd, int rdlen, |
219 | uint32_t *latest_mctime, uint32_t *mctime_ver) | 702 | struct jffs2_readinode_info *rii) |
220 | { | 703 | { |
221 | struct jffs2_tmp_dnode_info *tn; | 704 | struct jffs2_tmp_dnode_info *tn; |
222 | uint32_t len, csize; | 705 | uint32_t len, csize; |
@@ -230,7 +713,8 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
230 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { | 713 | if (unlikely(crc != je32_to_cpu(rd->node_crc))) { |
231 | JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", | 714 | JFFS2_NOTICE("node CRC failed on dnode at %#08x: read %#08x, calculated %#08x\n", |
232 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); | 715 | ref_offset(ref), je32_to_cpu(rd->node_crc), crc); |
233 | return 1; | 716 | jffs2_mark_node_obsolete(c, ref); |
717 | return 0; | ||
234 | } | 718 | } |
235 | 719 | ||
236 | tn = jffs2_alloc_tmp_dnode_info(); | 720 | tn = jffs2_alloc_tmp_dnode_info(); |
@@ -342,6 +826,10 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
342 | tn->data_crc = je32_to_cpu(rd->data_crc); | 826 | tn->data_crc = je32_to_cpu(rd->data_crc); |
343 | tn->csize = csize; | 827 | tn->csize = csize; |
344 | tn->fn->raw = ref; | 828 | tn->fn->raw = ref; |
829 | tn->overlapped = 0; | ||
830 | |||
831 | if (tn->version > rii->highest_version) | ||
832 | rii->highest_version = tn->version; | ||
345 | 833 | ||
346 | /* There was a bug where we wrote hole nodes out with | 834 | /* There was a bug where we wrote hole nodes out with |
347 | csize/dsize swapped. Deal with it */ | 835 | csize/dsize swapped. Deal with it */ |
@@ -353,13 +841,25 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref | |||
353 | dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n", | 841 | dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n", |
354 | ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); | 842 | ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize); |
355 | 843 | ||
356 | jffs2_add_tn_to_tree(tn, tnp); | 844 | ret = jffs2_add_tn_to_tree(c, rii, tn); |
357 | 845 | ||
846 | if (ret) { | ||
847 | jffs2_free_full_dnode(tn->fn); | ||
848 | free_out: | ||
849 | jffs2_free_tmp_dnode_info(tn); | ||
850 | return ret; | ||
851 | } | ||
852 | #ifdef JFFS2_DBG_READINODE_MESSAGES | ||
853 | dbg_readinode("After adding ver %d:\n", tn->version); | ||
854 | tn = tn_first(&rii->tn_root); | ||
855 | while (tn) { | ||
856 | dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n", | ||
857 | tn, tn->version, tn->fn->ofs, | ||
858 | tn->fn->ofs+tn->fn->size, tn->overlapped); | ||
859 | tn = tn_next(tn); | ||
860 | } | ||
861 | #endif | ||
358 | return 0; | 862 | return 0; |
359 | |||
360 | free_out: | ||
361 | jffs2_free_tmp_dnode_info(tn); | ||
362 | return ret; | ||
363 | } | 863 | } |
364 | 864 | ||
365 | /* | 865 | /* |
@@ -379,7 +879,8 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re | |||
379 | JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", | 879 | JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", |
380 | je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), | 880 | je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), |
381 | je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); | 881 | je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); |
382 | return 1; | 882 | jffs2_mark_node_obsolete(c, ref); |
883 | return 0; | ||
383 | } | 884 | } |
384 | 885 | ||
385 | un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); | 886 | un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); |
@@ -407,7 +908,8 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re | |||
407 | case JFFS2_FEATURE_RWCOMPAT_DELETE: | 908 | case JFFS2_FEATURE_RWCOMPAT_DELETE: |
408 | JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", | 909 | JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", |
409 | je16_to_cpu(un->nodetype), ref_offset(ref)); | 910 | je16_to_cpu(un->nodetype), ref_offset(ref)); |
410 | return 1; | 911 | jffs2_mark_node_obsolete(c, ref); |
912 | return 0; | ||
411 | } | 913 | } |
412 | 914 | ||
413 | return 0; | 915 | return 0; |
@@ -421,92 +923,62 @@ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_re | |||
421 | * negative error code on failure. | 923 | * negative error code on failure. |
422 | */ | 924 | */ |
423 | static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 925 | static int read_more(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, |
424 | int right_size, int *rdlen, unsigned char *buf, unsigned char *bufstart) | 926 | int needed_len, int *rdlen, unsigned char *buf) |
425 | { | 927 | { |
426 | int right_len, err, len; | 928 | int err, to_read = needed_len - *rdlen; |
427 | size_t retlen; | 929 | size_t retlen; |
428 | uint32_t offs; | 930 | uint32_t offs; |
429 | 931 | ||
430 | if (jffs2_is_writebuffered(c)) { | 932 | if (jffs2_is_writebuffered(c)) { |
431 | right_len = c->wbuf_pagesize - (bufstart - buf); | 933 | int rem = to_read % c->wbuf_pagesize; |
432 | if (right_size + (int)(bufstart - buf) > c->wbuf_pagesize) | ||
433 | right_len += c->wbuf_pagesize; | ||
434 | } else | ||
435 | right_len = right_size; | ||
436 | 934 | ||
437 | if (*rdlen == right_len) | 935 | if (rem) |
438 | return 0; | 936 | to_read += c->wbuf_pagesize - rem; |
937 | } | ||
439 | 938 | ||
440 | /* We need to read more data */ | 939 | /* We need to read more data */ |
441 | offs = ref_offset(ref) + *rdlen; | 940 | offs = ref_offset(ref) + *rdlen; |
442 | if (jffs2_is_writebuffered(c)) { | ||
443 | bufstart = buf + c->wbuf_pagesize; | ||
444 | len = c->wbuf_pagesize; | ||
445 | } else { | ||
446 | bufstart = buf + *rdlen; | ||
447 | len = right_size - *rdlen; | ||
448 | } | ||
449 | 941 | ||
450 | dbg_readinode("read more %d bytes\n", len); | 942 | dbg_readinode("read more %d bytes\n", to_read); |
451 | 943 | ||
452 | err = jffs2_flash_read(c, offs, len, &retlen, bufstart); | 944 | err = jffs2_flash_read(c, offs, to_read, &retlen, buf + *rdlen); |
453 | if (err) { | 945 | if (err) { |
454 | JFFS2_ERROR("can not read %d bytes from 0x%08x, " | 946 | JFFS2_ERROR("can not read %d bytes from 0x%08x, " |
455 | "error code: %d.\n", len, offs, err); | 947 | "error code: %d.\n", to_read, offs, err); |
456 | return err; | 948 | return err; |
457 | } | 949 | } |
458 | 950 | ||
459 | if (retlen < len) { | 951 | if (retlen < to_read) { |
460 | JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", | 952 | JFFS2_ERROR("short read at %#08x: %zu instead of %d.\n", |
461 | offs, retlen, len); | 953 | offs, retlen, to_read); |
462 | return -EIO; | 954 | return -EIO; |
463 | } | 955 | } |
464 | 956 | ||
465 | *rdlen = right_len; | 957 | *rdlen += to_read; |
466 | |||
467 | return 0; | 958 | return 0; |
468 | } | 959 | } |
469 | 960 | ||
470 | /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated | 961 | /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated |
471 | with this ino, returning the former in order of version */ | 962 | with this ino. Perform a preliminary ordering on data nodes, throwing away |
963 | those which are completely obsoleted by newer ones. The naïve approach we | ||
964 | use to take of just returning them _all_ in version order will cause us to | ||
965 | run out of memory in certain degenerate cases. */ | ||
472 | static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | 966 | static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, |
473 | struct rb_root *tnp, struct jffs2_full_dirent **fdp, | 967 | struct jffs2_readinode_info *rii) |
474 | uint32_t *highest_version, uint32_t *latest_mctime, | ||
475 | uint32_t *mctime_ver) | ||
476 | { | 968 | { |
477 | struct jffs2_raw_node_ref *ref, *valid_ref; | 969 | struct jffs2_raw_node_ref *ref, *valid_ref; |
478 | struct rb_root ret_tn = RB_ROOT; | ||
479 | struct jffs2_full_dirent *ret_fd = NULL; | ||
480 | unsigned char *buf = NULL; | 970 | unsigned char *buf = NULL; |
481 | union jffs2_node_union *node; | 971 | union jffs2_node_union *node; |
482 | size_t retlen; | 972 | size_t retlen; |
483 | int len, err; | 973 | int len, err; |
484 | 974 | ||
485 | *mctime_ver = 0; | 975 | rii->mctime_ver = 0; |
486 | 976 | ||
487 | dbg_readinode("ino #%u\n", f->inocache->ino); | 977 | dbg_readinode("ino #%u\n", f->inocache->ino); |
488 | 978 | ||
489 | if (jffs2_is_writebuffered(c)) { | ||
490 | /* | ||
491 | * If we have the write buffer, we assume the minimal I/O unit | ||
492 | * is c->wbuf_pagesize. We implement some optimizations which in | ||
493 | * this case and we need a temporary buffer of size = | ||
494 | * 2*c->wbuf_pagesize bytes (see comments in read_dnode()). | ||
495 | * Basically, we want to read not only the node header, but the | ||
496 | * whole wbuf (NAND page in case of NAND) or 2, if the node | ||
497 | * header overlaps the border between the 2 wbufs. | ||
498 | */ | ||
499 | len = 2*c->wbuf_pagesize; | ||
500 | } else { | ||
501 | /* | ||
502 | * When there is no write buffer, the size of the temporary | ||
503 | * buffer is the size of the larges node header. | ||
504 | */ | ||
505 | len = sizeof(union jffs2_node_union); | ||
506 | } | ||
507 | |||
508 | /* FIXME: in case of NOR and available ->point() this | 979 | /* FIXME: in case of NOR and available ->point() this |
509 | * needs to be fixed. */ | 980 | * needs to be fixed. */ |
981 | len = sizeof(union jffs2_node_union) + c->wbuf_pagesize; | ||
510 | buf = kmalloc(len, GFP_KERNEL); | 982 | buf = kmalloc(len, GFP_KERNEL); |
511 | if (!buf) | 983 | if (!buf) |
512 | return -ENOMEM; | 984 | return -ENOMEM; |
@@ -516,8 +988,6 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
516 | if (!valid_ref && f->inocache->ino != 1) | 988 | if (!valid_ref && f->inocache->ino != 1) |
517 | JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino); | 989 | JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino); |
518 | while (valid_ref) { | 990 | while (valid_ref) { |
519 | unsigned char *bufstart; | ||
520 | |||
521 | /* We can hold a pointer to a non-obsolete node without the spinlock, | 991 | /* We can hold a pointer to a non-obsolete node without the spinlock, |
522 | but _obsolete_ nodes may disappear at any time, if the block | 992 | but _obsolete_ nodes may disappear at any time, if the block |
523 | they're in gets erased. So if we mark 'ref' obsolete while we're | 993 | they're in gets erased. So if we mark 'ref' obsolete while we're |
@@ -533,32 +1003,31 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
533 | /* | 1003 | /* |
534 | * At this point we don't know the type of the node we're going | 1004 | * At this point we don't know the type of the node we're going |
535 | * to read, so we do not know the size of its header. In order | 1005 | * to read, so we do not know the size of its header. In order |
536 | * to minimize the amount of flash IO we assume the node has | 1006 | * to minimize the amount of flash IO we assume the header is |
537 | * size = JFFS2_MIN_NODE_HEADER. | 1007 | * of size = JFFS2_MIN_NODE_HEADER. |
538 | */ | 1008 | */ |
1009 | len = JFFS2_MIN_NODE_HEADER; | ||
539 | if (jffs2_is_writebuffered(c)) { | 1010 | if (jffs2_is_writebuffered(c)) { |
1011 | int end, rem; | ||
1012 | |||
540 | /* | 1013 | /* |
541 | * We treat 'buf' as 2 adjacent wbufs. We want to | 1014 | * We are about to read JFFS2_MIN_NODE_HEADER bytes, |
542 | * adjust bufstart such as it points to the | 1015 | * but this flash has some minimal I/O unit. It is |
543 | * beginning of the node within this wbuf. | 1016 | * possible that we'll need to read more soon, so read |
1017 | * up to the next min. I/O unit, in order not to | ||
1018 | * re-read the same min. I/O unit twice. | ||
544 | */ | 1019 | */ |
545 | bufstart = buf + (ref_offset(ref) % c->wbuf_pagesize); | 1020 | end = ref_offset(ref) + len; |
546 | /* We will read either one wbuf or 2 wbufs. */ | 1021 | rem = end % c->wbuf_pagesize; |
547 | len = c->wbuf_pagesize - (bufstart - buf); | 1022 | if (rem) |
548 | if (JFFS2_MIN_NODE_HEADER + (int)(bufstart - buf) > c->wbuf_pagesize) { | 1023 | end += c->wbuf_pagesize - rem; |
549 | /* The header spans the border of the first wbuf */ | 1024 | len = end - ref_offset(ref); |
550 | len += c->wbuf_pagesize; | ||
551 | } | ||
552 | } else { | ||
553 | bufstart = buf; | ||
554 | len = JFFS2_MIN_NODE_HEADER; | ||
555 | } | 1025 | } |
556 | 1026 | ||
557 | dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); | 1027 | dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); |
558 | 1028 | ||
559 | /* FIXME: point() */ | 1029 | /* FIXME: point() */ |
560 | err = jffs2_flash_read(c, ref_offset(ref), len, | 1030 | err = jffs2_flash_read(c, ref_offset(ref), len, &retlen, buf); |
561 | &retlen, bufstart); | ||
562 | if (err) { | 1031 | if (err) { |
563 | JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err); | 1032 | JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err); |
564 | goto free_out; | 1033 | goto free_out; |
@@ -570,7 +1039,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
570 | goto free_out; | 1039 | goto free_out; |
571 | } | 1040 | } |
572 | 1041 | ||
573 | node = (union jffs2_node_union *)bufstart; | 1042 | node = (union jffs2_node_union *)buf; |
574 | 1043 | ||
575 | /* No need to mask in the valid bit; it shouldn't be invalid */ | 1044 | /* No need to mask in the valid bit; it shouldn't be invalid */ |
576 | if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) { | 1045 | if (je32_to_cpu(node->u.hdr_crc) != crc32(0, node, sizeof(node->u)-4)) { |
@@ -583,10 +1052,10 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
583 | jffs2_mark_node_obsolete(c, ref); | 1052 | jffs2_mark_node_obsolete(c, ref); |
584 | goto cont; | 1053 | goto cont; |
585 | } | 1054 | } |
586 | /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */ | 1055 | if (je16_to_cpu(node->u.magic) != JFFS2_MAGIC_BITMASK) { |
587 | if (!je32_to_cpu(node->u.hdr_crc) && !je16_to_cpu(node->u.nodetype) && | 1056 | /* Not a JFFS2 node, whinge and move on */ |
588 | !je16_to_cpu(node->u.magic) && !je32_to_cpu(node->u.totlen)) { | 1057 | JFFS2_NOTICE("Wrong magic bitmask 0x%04x in node header at %#08x.\n", |
589 | JFFS2_NOTICE("All zero node header at %#08x.\n", ref_offset(ref)); | 1058 | je16_to_cpu(node->u.magic), ref_offset(ref)); |
590 | jffs2_mark_node_obsolete(c, ref); | 1059 | jffs2_mark_node_obsolete(c, ref); |
591 | goto cont; | 1060 | goto cont; |
592 | } | 1061 | } |
@@ -596,46 +1065,34 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
596 | case JFFS2_NODETYPE_DIRENT: | 1065 | case JFFS2_NODETYPE_DIRENT: |
597 | 1066 | ||
598 | if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) { | 1067 | if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) { |
599 | err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf, bufstart); | 1068 | err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf); |
600 | if (unlikely(err)) | 1069 | if (unlikely(err)) |
601 | goto free_out; | 1070 | goto free_out; |
602 | } | 1071 | } |
603 | 1072 | ||
604 | err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver); | 1073 | err = read_direntry(c, ref, &node->d, retlen, rii); |
605 | if (err == 1) { | 1074 | if (unlikely(err)) |
606 | jffs2_mark_node_obsolete(c, ref); | ||
607 | break; | ||
608 | } else if (unlikely(err)) | ||
609 | goto free_out; | 1075 | goto free_out; |
610 | 1076 | ||
611 | if (je32_to_cpu(node->d.version) > *highest_version) | ||
612 | *highest_version = je32_to_cpu(node->d.version); | ||
613 | |||
614 | break; | 1077 | break; |
615 | 1078 | ||
616 | case JFFS2_NODETYPE_INODE: | 1079 | case JFFS2_NODETYPE_INODE: |
617 | 1080 | ||
618 | if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) { | 1081 | if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) { |
619 | err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart); | 1082 | err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf); |
620 | if (unlikely(err)) | 1083 | if (unlikely(err)) |
621 | goto free_out; | 1084 | goto free_out; |
622 | } | 1085 | } |
623 | 1086 | ||
624 | err = read_dnode(c, ref, &node->i, &ret_tn, len, latest_mctime, mctime_ver); | 1087 | err = read_dnode(c, ref, &node->i, len, rii); |
625 | if (err == 1) { | 1088 | if (unlikely(err)) |
626 | jffs2_mark_node_obsolete(c, ref); | ||
627 | break; | ||
628 | } else if (unlikely(err)) | ||
629 | goto free_out; | 1089 | goto free_out; |
630 | 1090 | ||
631 | if (je32_to_cpu(node->i.version) > *highest_version) | ||
632 | *highest_version = je32_to_cpu(node->i.version); | ||
633 | |||
634 | break; | 1091 | break; |
635 | 1092 | ||
636 | default: | 1093 | default: |
637 | if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) { | 1094 | if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) { |
638 | err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf, bufstart); | 1095 | err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf); |
639 | if (unlikely(err)) | 1096 | if (unlikely(err)) |
640 | goto free_out; | 1097 | goto free_out; |
641 | } | 1098 | } |
@@ -653,17 +1110,19 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
653 | } | 1110 | } |
654 | 1111 | ||
655 | spin_unlock(&c->erase_completion_lock); | 1112 | spin_unlock(&c->erase_completion_lock); |
656 | *tnp = ret_tn; | ||
657 | *fdp = ret_fd; | ||
658 | kfree(buf); | 1113 | kfree(buf); |
659 | 1114 | ||
1115 | f->highest_version = rii->highest_version; | ||
1116 | |||
660 | dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n", | 1117 | dbg_readinode("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n", |
661 | f->inocache->ino, *highest_version, *latest_mctime, *mctime_ver); | 1118 | f->inocache->ino, rii->highest_version, rii->latest_mctime, |
1119 | rii->mctime_ver); | ||
662 | return 0; | 1120 | return 0; |
663 | 1121 | ||
664 | free_out: | 1122 | free_out: |
665 | jffs2_free_tmp_dnode_info_list(&ret_tn); | 1123 | jffs2_free_tmp_dnode_info_list(&rii->tn_root); |
666 | jffs2_free_full_dirent_list(ret_fd); | 1124 | jffs2_free_full_dirent_list(rii->fds); |
1125 | rii->fds = NULL; | ||
667 | kfree(buf); | 1126 | kfree(buf); |
668 | return err; | 1127 | return err; |
669 | } | 1128 | } |
@@ -672,20 +1131,17 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
672 | struct jffs2_inode_info *f, | 1131 | struct jffs2_inode_info *f, |
673 | struct jffs2_raw_inode *latest_node) | 1132 | struct jffs2_raw_inode *latest_node) |
674 | { | 1133 | { |
675 | struct jffs2_tmp_dnode_info *tn; | 1134 | struct jffs2_readinode_info rii; |
676 | struct rb_root tn_list; | 1135 | uint32_t crc, new_size; |
677 | struct rb_node *rb, *repl_rb; | ||
678 | struct jffs2_full_dirent *fd_list; | ||
679 | struct jffs2_full_dnode *fn, *first_fn = NULL; | ||
680 | uint32_t crc; | ||
681 | uint32_t latest_mctime, mctime_ver; | ||
682 | size_t retlen; | 1136 | size_t retlen; |
683 | int ret; | 1137 | int ret; |
684 | 1138 | ||
685 | dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); | 1139 | dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); |
686 | 1140 | ||
1141 | memset(&rii, 0, sizeof(rii)); | ||
1142 | |||
687 | /* Grab all nodes relevant to this ino */ | 1143 | /* Grab all nodes relevant to this ino */ |
688 | ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver); | 1144 | ret = jffs2_get_inode_nodes(c, f, &rii); |
689 | 1145 | ||
690 | if (ret) { | 1146 | if (ret) { |
691 | JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); | 1147 | JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); |
@@ -693,74 +1149,42 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
693 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); | 1149 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); |
694 | return ret; | 1150 | return ret; |
695 | } | 1151 | } |
696 | f->dents = fd_list; | ||
697 | |||
698 | rb = rb_first(&tn_list); | ||
699 | 1152 | ||
700 | while (rb) { | 1153 | ret = jffs2_build_inode_fragtree(c, f, &rii); |
701 | cond_resched(); | 1154 | if (ret) { |
702 | tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb); | 1155 | JFFS2_ERROR("Failed to build final fragtree for inode #%u: error %d\n", |
703 | fn = tn->fn; | 1156 | f->inocache->ino, ret); |
704 | ret = 1; | 1157 | if (f->inocache->state == INO_STATE_READING) |
705 | dbg_readinode("consider node ver %u, phys offset " | 1158 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); |
706 | "%#08x(%d), range %u-%u.\n", tn->version, | 1159 | jffs2_free_tmp_dnode_info_list(&rii.tn_root); |
707 | ref_offset(fn->raw), ref_flags(fn->raw), | 1160 | /* FIXME: We could at least crc-check them all */ |
708 | fn->ofs, fn->ofs + fn->size); | 1161 | if (rii.mdata_tn) { |
709 | 1162 | jffs2_free_full_dnode(rii.mdata_tn->fn); | |
710 | if (fn->size) { | 1163 | jffs2_free_tmp_dnode_info(rii.mdata_tn); |
711 | ret = jffs2_add_older_frag_to_fragtree(c, f, tn); | 1164 | rii.mdata_tn = NULL; |
712 | /* TODO: the error code isn't checked, check it */ | 1165 | } |
713 | jffs2_dbg_fragtree_paranoia_check_nolock(f); | 1166 | return ret; |
714 | BUG_ON(ret < 0); | 1167 | } |
715 | if (!first_fn && ret == 0) | ||
716 | first_fn = fn; | ||
717 | } else if (!first_fn) { | ||
718 | first_fn = fn; | ||
719 | f->metadata = fn; | ||
720 | ret = 0; /* Prevent freeing the metadata update node */ | ||
721 | } else | ||
722 | jffs2_mark_node_obsolete(c, fn->raw); | ||
723 | |||
724 | BUG_ON(rb->rb_left); | ||
725 | if (rb_parent(rb) && rb_parent(rb)->rb_left == rb) { | ||
726 | /* We were then left-hand child of our parent. We need | ||
727 | * to move our own right-hand child into our place. */ | ||
728 | repl_rb = rb->rb_right; | ||
729 | if (repl_rb) | ||
730 | rb_set_parent(repl_rb, rb_parent(rb)); | ||
731 | } else | ||
732 | repl_rb = NULL; | ||
733 | |||
734 | rb = rb_next(rb); | ||
735 | |||
736 | /* Remove the spent tn from the tree; don't bother rebalancing | ||
737 | * but put our right-hand child in our own place. */ | ||
738 | if (rb_parent(&tn->rb)) { | ||
739 | if (rb_parent(&tn->rb)->rb_left == &tn->rb) | ||
740 | rb_parent(&tn->rb)->rb_left = repl_rb; | ||
741 | else if (rb_parent(&tn->rb)->rb_right == &tn->rb) | ||
742 | rb_parent(&tn->rb)->rb_right = repl_rb; | ||
743 | else BUG(); | ||
744 | } else if (tn->rb.rb_right) | ||
745 | rb_set_parent(tn->rb.rb_right, NULL); | ||
746 | 1168 | ||
747 | jffs2_free_tmp_dnode_info(tn); | 1169 | if (rii.mdata_tn) { |
748 | if (ret) { | 1170 | if (rii.mdata_tn->fn->raw == rii.latest_ref) { |
749 | dbg_readinode("delete dnode %u-%u.\n", | 1171 | f->metadata = rii.mdata_tn->fn; |
750 | fn->ofs, fn->ofs + fn->size); | 1172 | jffs2_free_tmp_dnode_info(rii.mdata_tn); |
751 | jffs2_free_full_dnode(fn); | 1173 | } else { |
1174 | jffs2_kill_tn(c, rii.mdata_tn); | ||
752 | } | 1175 | } |
1176 | rii.mdata_tn = NULL; | ||
753 | } | 1177 | } |
754 | jffs2_dbg_fragtree_paranoia_check_nolock(f); | ||
755 | 1178 | ||
756 | BUG_ON(first_fn && ref_obsolete(first_fn->raw)); | 1179 | f->dents = rii.fds; |
757 | 1180 | ||
758 | fn = first_fn; | 1181 | jffs2_dbg_fragtree_paranoia_check_nolock(f); |
759 | if (unlikely(!first_fn)) { | 1182 | |
1183 | if (unlikely(!rii.latest_ref)) { | ||
760 | /* No data nodes for this inode. */ | 1184 | /* No data nodes for this inode. */ |
761 | if (f->inocache->ino != 1) { | 1185 | if (f->inocache->ino != 1) { |
762 | JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); | 1186 | JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); |
763 | if (!fd_list) { | 1187 | if (!rii.fds) { |
764 | if (f->inocache->state == INO_STATE_READING) | 1188 | if (f->inocache->state == INO_STATE_READING) |
765 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); | 1189 | jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); |
766 | return -EIO; | 1190 | return -EIO; |
@@ -778,7 +1202,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
778 | return 0; | 1202 | return 0; |
779 | } | 1203 | } |
780 | 1204 | ||
781 | ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node); | 1205 | ret = jffs2_flash_read(c, ref_offset(rii.latest_ref), sizeof(*latest_node), &retlen, (void *)latest_node); |
782 | if (ret || retlen != sizeof(*latest_node)) { | 1206 | if (ret || retlen != sizeof(*latest_node)) { |
783 | JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n", | 1207 | JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n", |
784 | ret, retlen, sizeof(*latest_node)); | 1208 | ret, retlen, sizeof(*latest_node)); |
@@ -791,7 +1215,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
791 | crc = crc32(0, latest_node, sizeof(*latest_node)-8); | 1215 | crc = crc32(0, latest_node, sizeof(*latest_node)-8); |
792 | if (crc != je32_to_cpu(latest_node->node_crc)) { | 1216 | if (crc != je32_to_cpu(latest_node->node_crc)) { |
793 | JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n", | 1217 | JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n", |
794 | f->inocache->ino, ref_offset(fn->raw)); | 1218 | f->inocache->ino, ref_offset(rii.latest_ref)); |
795 | up(&f->sem); | 1219 | up(&f->sem); |
796 | jffs2_do_clear_inode(c, f); | 1220 | jffs2_do_clear_inode(c, f); |
797 | return -EIO; | 1221 | return -EIO; |
@@ -799,17 +1223,22 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
799 | 1223 | ||
800 | switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { | 1224 | switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { |
801 | case S_IFDIR: | 1225 | case S_IFDIR: |
802 | if (mctime_ver > je32_to_cpu(latest_node->version)) { | 1226 | if (rii.mctime_ver > je32_to_cpu(latest_node->version)) { |
803 | /* The times in the latest_node are actually older than | 1227 | /* The times in the latest_node are actually older than |
804 | mctime in the latest dirent. Cheat. */ | 1228 | mctime in the latest dirent. Cheat. */ |
805 | latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime); | 1229 | latest_node->ctime = latest_node->mtime = cpu_to_je32(rii.latest_mctime); |
806 | } | 1230 | } |
807 | break; | 1231 | break; |
808 | 1232 | ||
809 | 1233 | ||
810 | case S_IFREG: | 1234 | case S_IFREG: |
811 | /* If it was a regular file, truncate it to the latest node's isize */ | 1235 | /* If it was a regular file, truncate it to the latest node's isize */ |
812 | jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); | 1236 | new_size = jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); |
1237 | if (new_size != je32_to_cpu(latest_node->isize)) { | ||
1238 | JFFS2_WARNING("Truncating ino #%u to %d bytes failed because it only had %d bytes to start with!\n", | ||
1239 | f->inocache->ino, je32_to_cpu(latest_node->isize), new_size); | ||
1240 | latest_node->isize = cpu_to_je32(new_size); | ||
1241 | } | ||
813 | break; | 1242 | break; |
814 | 1243 | ||
815 | case S_IFLNK: | 1244 | case S_IFLNK: |
@@ -832,7 +1261,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, | |||
832 | return -ENOMEM; | 1261 | return -ENOMEM; |
833 | } | 1262 | } |
834 | 1263 | ||
835 | ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), | 1264 | ret = jffs2_flash_read(c, ref_offset(rii.latest_ref) + sizeof(*latest_node), |
836 | je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); | 1265 | je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); |
837 | 1266 | ||
838 | if (ret || retlen != je32_to_cpu(latest_node->csize)) { | 1267 | if (ret || retlen != je32_to_cpu(latest_node->csize)) { |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 7fb45bd4915c..2a1c976c7924 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -1,15 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: scan.c,v 1.125 2005/09/30 13:59:13 dedekind Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
11 | |||
13 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
14 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
15 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
@@ -636,16 +635,17 @@ scan_more: | |||
636 | 635 | ||
637 | if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { | 636 | if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { |
638 | uint32_t inbuf_ofs; | 637 | uint32_t inbuf_ofs; |
639 | uint32_t empty_start; | 638 | uint32_t empty_start, scan_end; |
640 | 639 | ||
641 | empty_start = ofs; | 640 | empty_start = ofs; |
642 | ofs += 4; | 641 | ofs += 4; |
642 | scan_end = min_t(uint32_t, EMPTY_SCAN_SIZE(c->sector_size)/8, buf_len); | ||
643 | 643 | ||
644 | D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); | 644 | D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); |
645 | more_empty: | 645 | more_empty: |
646 | inbuf_ofs = ofs - buf_ofs; | 646 | inbuf_ofs = ofs - buf_ofs; |
647 | while (inbuf_ofs < buf_len) { | 647 | while (inbuf_ofs < scan_end) { |
648 | if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) { | 648 | if (unlikely(*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)) { |
649 | printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", | 649 | printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", |
650 | empty_start, ofs); | 650 | empty_start, ofs); |
651 | if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start))) | 651 | if ((err = jffs2_scan_dirty_space(c, jeb, ofs-empty_start))) |
@@ -666,7 +666,11 @@ scan_more: | |||
666 | D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); | 666 | D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); |
667 | return BLK_STATE_CLEANMARKER; | 667 | return BLK_STATE_CLEANMARKER; |
668 | } | 668 | } |
669 | 669 | if (!buf_size && (scan_end != buf_len)) {/* XIP/point case */ | |
670 | scan_end = buf_len; | ||
671 | goto more_empty; | ||
672 | } | ||
673 | |||
670 | /* See how much more there is to read in this eraseblock... */ | 674 | /* See how much more there is to read in this eraseblock... */ |
671 | buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); | 675 | buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); |
672 | if (!buf_len) { | 676 | if (!buf_len) { |
@@ -676,6 +680,8 @@ scan_more: | |||
676 | empty_start)); | 680 | empty_start)); |
677 | break; | 681 | break; |
678 | } | 682 | } |
683 | /* point never reaches here */ | ||
684 | scan_end = buf_len; | ||
679 | D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs)); | 685 | D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs)); |
680 | err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); | 686 | err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); |
681 | if (err) | 687 | if (err) |
@@ -734,18 +740,8 @@ scan_more: | |||
734 | ofs += 4; | 740 | ofs += 4; |
735 | continue; | 741 | continue; |
736 | } | 742 | } |
737 | /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */ | ||
738 | if (!je32_to_cpu(node->hdr_crc) && !je16_to_cpu(node->nodetype) && | ||
739 | !je16_to_cpu(node->magic) && !je32_to_cpu(node->totlen)) { | ||
740 | noisy_printk(&noise, "jffs2_scan_eraseblock(): All zero node header at 0x%08x.\n", ofs); | ||
741 | if ((err = jffs2_scan_dirty_space(c, jeb, 4))) | ||
742 | return err; | ||
743 | ofs += 4; | ||
744 | continue; | ||
745 | } | ||
746 | 743 | ||
747 | if (ofs + je32_to_cpu(node->totlen) > | 744 | if (ofs + je32_to_cpu(node->totlen) > jeb->offset + c->sector_size) { |
748 | jeb->offset + c->sector_size) { | ||
749 | /* Eep. Node goes over the end of the erase block. */ | 745 | /* Eep. Node goes over the end of the erase block. */ |
750 | printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", | 746 | printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", |
751 | ofs, je32_to_cpu(node->totlen)); | 747 | ofs, je32_to_cpu(node->totlen)); |
@@ -952,8 +948,7 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
952 | struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) | 948 | struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) |
953 | { | 949 | { |
954 | struct jffs2_inode_cache *ic; | 950 | struct jffs2_inode_cache *ic; |
955 | uint32_t ino = je32_to_cpu(ri->ino); | 951 | uint32_t crc, ino = je32_to_cpu(ri->ino); |
956 | int err; | ||
957 | 952 | ||
958 | D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); | 953 | D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); |
959 | 954 | ||
@@ -966,21 +961,22 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
966 | Which means that the _full_ amount of time to get to proper write mode with GC | 961 | Which means that the _full_ amount of time to get to proper write mode with GC |
967 | operational may actually be _longer_ than before. Sucks to be me. */ | 962 | operational may actually be _longer_ than before. Sucks to be me. */ |
968 | 963 | ||
964 | /* Check the node CRC in any case. */ | ||
965 | crc = crc32(0, ri, sizeof(*ri)-8); | ||
966 | if (crc != je32_to_cpu(ri->node_crc)) { | ||
967 | printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on " | ||
968 | "node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", | ||
969 | ofs, je32_to_cpu(ri->node_crc), crc); | ||
970 | /* | ||
971 | * We believe totlen because the CRC on the node | ||
972 | * _header_ was OK, just the node itself failed. | ||
973 | */ | ||
974 | return jffs2_scan_dirty_space(c, jeb, | ||
975 | PAD(je32_to_cpu(ri->totlen))); | ||
976 | } | ||
977 | |||
969 | ic = jffs2_get_ino_cache(c, ino); | 978 | ic = jffs2_get_ino_cache(c, ino); |
970 | if (!ic) { | 979 | if (!ic) { |
971 | /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the | ||
972 | first node we found for this inode. Do a CRC check to protect against the former | ||
973 | case */ | ||
974 | uint32_t crc = crc32(0, ri, sizeof(*ri)-8); | ||
975 | |||
976 | if (crc != je32_to_cpu(ri->node_crc)) { | ||
977 | printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", | ||
978 | ofs, je32_to_cpu(ri->node_crc), crc); | ||
979 | /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ | ||
980 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen))))) | ||
981 | return err; | ||
982 | return 0; | ||
983 | } | ||
984 | ic = jffs2_scan_make_ino_cache(c, ino); | 980 | ic = jffs2_scan_make_ino_cache(c, ino); |
985 | if (!ic) | 981 | if (!ic) |
986 | return -ENOMEM; | 982 | return -ENOMEM; |
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index 52a9894a6364..bc9f6ba10823 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
13 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index 30f888414ce7..d828b296392a 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c | |||
@@ -1,16 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, | 4 | * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, |
5 | * Zoltan Sogor <weth@inf.u-szeged.hu>, | 5 | * Zoltan Sogor <weth@inf.u-szeged.hu>, |
6 | * Patrik Kluba <pajko@halom.u-szeged.hu>, | 6 | * Patrik Kluba <pajko@halom.u-szeged.hu>, |
7 | * University of Szeged, Hungary | 7 | * University of Szeged, Hungary |
8 | * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com> | 8 | * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com> |
9 | * | 9 | * |
10 | * For licensing information, see the file 'LICENCE' in this directory. | 10 | * For licensing information, see the file 'LICENCE' in this directory. |
11 | * | 11 | * |
12 | * $Id: summary.c,v 1.4 2005/09/26 11:37:21 havasi Exp $ | ||
13 | * | ||
14 | */ | 12 | */ |
15 | 13 | ||
16 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h index 6bf1f6aa4552..0c6669e21390 100644 --- a/fs/jffs2/summary.h +++ b/fs/jffs2/summary.h | |||
@@ -1,15 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, | 4 | * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, |
5 | * Zoltan Sogor <weth@inf.u-szeged.hu>, | 5 | * Zoltan Sogor <weth@inf.u-szeged.hu>, |
6 | * Patrik Kluba <pajko@halom.u-szeged.hu>, | 6 | * Patrik Kluba <pajko@halom.u-szeged.hu>, |
7 | * University of Szeged, Hungary | 7 | * University of Szeged, Hungary |
8 | * | 8 | * |
9 | * For licensing information, see the file 'LICENCE' in this directory. | 9 | * For licensing information, see the file 'LICENCE' in this directory. |
10 | * | 10 | * |
11 | * $Id: summary.h,v 1.2 2005/09/26 11:37:21 havasi Exp $ | ||
12 | * | ||
13 | */ | 11 | */ |
14 | 12 | ||
15 | #ifndef JFFS2_SUMMARY_H | 13 | #ifndef JFFS2_SUMMARY_H |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index cc7e8e71ad46..e51164a8a8d4 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: super.c,v 1.110 2005/11/07 11:14:42 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -347,7 +345,7 @@ static int __init init_jffs2_fs(void) | |||
347 | #ifdef CONFIG_JFFS2_SUMMARY | 345 | #ifdef CONFIG_JFFS2_SUMMARY |
348 | " (SUMMARY) " | 346 | " (SUMMARY) " |
349 | #endif | 347 | #endif |
350 | " (C) 2001-2006 Red Hat, Inc.\n"); | 348 | " © 2001-2006 Red Hat, Inc.\n"); |
351 | 349 | ||
352 | jffs2_inode_cachep = kmem_cache_create("jffs2_i", | 350 | jffs2_inode_cachep = kmem_cache_create("jffs2_i", |
353 | sizeof(struct jffs2_inode_info), | 351 | sizeof(struct jffs2_inode_info), |
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c index 7e4882c8a7ed..b7339c3b6ad9 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c | |||
@@ -1,17 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001, 2002 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: symlink.c,v 1.19 2005/11/07 11:14:42 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | |||
15 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
16 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
17 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index ab86031b3c07..c556e85a565c 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -1,16 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * Copyright (C) 2004 Thomas Gleixner <tglx@linutronix.de> | 5 | * Copyright © 2004 Thomas Gleixner <tglx@linutronix.de> |
6 | * | 6 | * |
7 | * Created by David Woodhouse <dwmw2@infradead.org> | 7 | * Created by David Woodhouse <dwmw2@infradead.org> |
8 | * Modified debugged and enhanced by Thomas Gleixner <tglx@linutronix.de> | 8 | * Modified debugged and enhanced by Thomas Gleixner <tglx@linutronix.de> |
9 | * | 9 | * |
10 | * For licensing information, see the file 'LICENCE' in this directory. | 10 | * For licensing information, see the file 'LICENCE' in this directory. |
11 | * | 11 | * |
12 | * $Id: wbuf.c,v 1.100 2005/09/30 13:59:13 dedekind Exp $ | ||
13 | * | ||
14 | */ | 12 | */ |
15 | 13 | ||
16 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
@@ -345,6 +343,9 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) | |||
345 | return; | 343 | return; |
346 | } | 344 | } |
347 | 345 | ||
346 | /* The summary is not recovered, so it must be disabled for this erase block */ | ||
347 | jffs2_sum_disable_collecting(c->summary); | ||
348 | |||
348 | ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, nr_refile); | 349 | ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, nr_refile); |
349 | if (ret) { | 350 | if (ret) { |
350 | printk(KERN_WARNING "Failed to allocate node refs for wbuf recovery. Data loss ensues.\n"); | 351 | printk(KERN_WARNING "Failed to allocate node refs for wbuf recovery. Data loss ensues.\n"); |
@@ -967,9 +968,9 @@ exit: | |||
967 | 968 | ||
968 | static const struct jffs2_unknown_node oob_cleanmarker = | 969 | static const struct jffs2_unknown_node oob_cleanmarker = |
969 | { | 970 | { |
970 | .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), | 971 | .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK), |
971 | .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), | 972 | .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), |
972 | .totlen = cpu_to_je32(8) | 973 | .totlen = constant_cpu_to_je32(8) |
973 | }; | 974 | }; |
974 | 975 | ||
975 | /* | 976 | /* |
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 67176792e138..c9fe0ab3a329 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: write.c,v 1.97 2005/11/07 11:14:42 gleixner Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
@@ -507,8 +505,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
507 | uint32_t alloclen; | 505 | uint32_t alloclen; |
508 | int ret; | 506 | int ret; |
509 | 507 | ||
510 | if (1 /* alternative branch needs testing */ || | 508 | if (!jffs2_can_mark_obsolete(c)) { |
511 | !jffs2_can_mark_obsolete(c)) { | ||
512 | /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ | 509 | /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ |
513 | 510 | ||
514 | rd = jffs2_alloc_raw_dirent(); | 511 | rd = jffs2_alloc_raw_dirent(); |
diff --git a/fs/jffs2/writev.c b/fs/jffs2/writev.c index c638ae1008de..b9276b11bac6 100644 --- a/fs/jffs2/writev.c +++ b/fs/jffs2/writev.c | |||
@@ -1,14 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2001, 2002 Red Hat, Inc. | 4 | * Copyright © 2001-2007 Red Hat, Inc. |
5 | * | 5 | * |
6 | * Created by David Woodhouse <dwmw2@infradead.org> | 6 | * Created by David Woodhouse <dwmw2@infradead.org> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | * $Id: writev.c,v 1.8 2005/09/09 15:11:58 havasi Exp $ | ||
11 | * | ||
12 | */ | 10 | */ |
13 | 11 | ||
14 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 4bb3f1897330..78fc08893a6c 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
13 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h index 06a5c69dcf8b..3b0ff2925937 100644 --- a/fs/jffs2/xattr.h +++ b/fs/jffs2/xattr.h | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | #ifndef _JFFS2_FS_XATTR_H_ | 12 | #ifndef _JFFS2_FS_XATTR_H_ |
12 | #define _JFFS2_FS_XATTR_H_ | 13 | #define _JFFS2_FS_XATTR_H_ |
13 | 14 | ||
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index ed046e19dbfa..8ec5765ef348 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
13 | #include <linux/jffs2.h> | 14 | #include <linux/jffs2.h> |
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index 2f8e9aa01ea0..40942bc516bb 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c | |||
@@ -1,13 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * JFFS2 -- Journalling Flash File System, Version 2. | 2 | * JFFS2 -- Journalling Flash File System, Version 2. |
3 | * | 3 | * |
4 | * Copyright (C) 2006 NEC Corporation | 4 | * Copyright © 2006 NEC Corporation |
5 | * | 5 | * |
6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> | 6 | * Created by KaiGai Kohei <kaigai@ak.jp.nec.com> |
7 | * | 7 | * |
8 | * For licensing information, see the file 'LICENCE' in this directory. | 8 | * For licensing information, see the file 'LICENCE' in this directory. |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | |||
11 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
13 | #include <linux/jffs2.h> | 14 | #include <linux/jffs2.h> |